comparison src/ops.c @ 3562:5c1aaf9b4b1b v7.3.541

updated for version 7.3.541 Problem: When joining lines comment leaders need to be removed manually. Solution: Add the 'j' flag to 'formatoptions'. (Lech Lorens)
author Bram Moolenaar <bram@vim.org>
date Wed, 06 Jun 2012 16:12:59 +0200
parents 9a1dba1f969a
children 4f4db5d661c4
comparison
equal deleted inserted replaced
3561:c384f4f5f238 3562:5c1aaf9b4b1b
110 # if defined(FEAT_VISUAL) || defined(FEAT_EVAL) 110 # if defined(FEAT_VISUAL) || defined(FEAT_EVAL)
111 static void may_set_selection __ARGS((void)); 111 static void may_set_selection __ARGS((void));
112 # endif 112 # endif
113 #endif 113 #endif
114 static void dis_msg __ARGS((char_u *p, int skip_esc)); 114 static void dis_msg __ARGS((char_u *p, int skip_esc));
115 #if defined(FEAT_COMMENTS) || defined(PROTO)
116 static char_u *skip_comment __ARGS((char_u *line, int process, int include_space, int *is_comment));
117 #endif
115 #ifdef FEAT_VISUAL 118 #ifdef FEAT_VISUAL
116 static void block_prep __ARGS((oparg_T *oap, struct block_def *, linenr_T, int)); 119 static void block_prep __ARGS((oparg_T *oap, struct block_def *, linenr_T, int));
117 #endif 120 #endif
118 #if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL) 121 #if defined(FEAT_CLIPBOARD) || defined(FEAT_EVAL)
119 static void str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str, long len, long blocklen)); 122 static void str_to_reg __ARGS((struct yankreg *y_ptr, int type, char_u *str, long len, long blocklen));
1985 #endif 1988 #endif
1986 ); 1989 );
1987 curwin->w_cursor = curpos; /* restore curwin->w_cursor */ 1990 curwin->w_cursor = curpos; /* restore curwin->w_cursor */
1988 } 1991 }
1989 if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) 1992 if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
1990 (void)do_join(2, FALSE, FALSE); 1993 (void)do_join(2, FALSE, FALSE, FALSE);
1991 } 1994 }
1992 } 1995 }
1993 1996
1994 msgmore(curbuf->b_ml.ml_line_count - old_lcount); 1997 msgmore(curbuf->b_ml.ml_line_count - old_lcount);
1995 1998
4195 msg_outtrans_len(p++, 1); 4198 msg_outtrans_len(p++, 1);
4196 } 4199 }
4197 ui_breakcheck(); 4200 ui_breakcheck();
4198 } 4201 }
4199 4202
4203 #if defined(FEAT_COMMENTS) || defined(PROTO)
4204 /*
4205 * If "process" is TRUE and the line begins with a comment leader (possibly
4206 * after some white space), return a pointer to the text after it. Put a boolean
4207 * value indicating whether the line ends with an unclosed comment in
4208 * "is_comment".
4209 * line - line to be processed,
4210 * process - if FALSE, will only check whether the line ends with an unclosed
4211 * comment,
4212 * include_space - whether to also skip space following the comment leader,
4213 * is_comment - will indicate whether the current line ends with an unclosed
4214 * comment.
4215 */
4216 static char_u *
4217 skip_comment(line, process, include_space, is_comment)
4218 char_u *line;
4219 int process;
4220 int include_space;
4221 int *is_comment;
4222 {
4223 char_u *comment_flags = NULL;
4224 int lead_len;
4225 int leader_offset = get_last_leader_offset(line, &comment_flags);
4226
4227 *is_comment = FALSE;
4228 if (leader_offset != -1)
4229 {
4230 /* Let's check whether the line ends with an unclosed comment.
4231 * If the last comment leader has COM_END in flags, there's no comment.
4232 */
4233 while (*comment_flags)
4234 {
4235 if (*comment_flags == COM_END
4236 || *comment_flags == ':')
4237 break;
4238 ++comment_flags;
4239 }
4240 if (*comment_flags != COM_END)
4241 *is_comment = TRUE;
4242 }
4243
4244 if (process == FALSE)
4245 return line;
4246
4247 lead_len = get_leader_len(line, &comment_flags, FALSE, include_space);
4248
4249 if (lead_len == 0)
4250 return line;
4251
4252 /* Find:
4253 * - COM_START,
4254 * - COM_END,
4255 * - colon,
4256 * whichever comes first.
4257 */
4258 while (*comment_flags)
4259 {
4260 if (*comment_flags == COM_START
4261 || *comment_flags == COM_END
4262 || *comment_flags == ':')
4263 {
4264 break;
4265 }
4266 ++comment_flags;
4267 }
4268
4269 /* If we found a colon, it means that we are not processing a line
4270 * starting with an opening or a closing part of a three-part
4271 * comment. That's good, because we don't want to remove those as
4272 * this would be annoying.
4273 */
4274 if (*comment_flags == ':' || *comment_flags == NUL)
4275 line += lead_len;
4276
4277 return line;
4278 }
4279 #endif
4280
4200 /* 4281 /*
4201 * Join 'count' lines (minimal 2) at cursor position. 4282 * Join 'count' lines (minimal 2) at cursor position.
4202 * When "save_undo" is TRUE save lines for undo first. 4283 * When "save_undo" is TRUE save lines for undo first.
4284 * Set "use_formatoptions" to FALSE when e.g. processing
4285 * backspace and comment leaders should not be removed.
4203 * 4286 *
4204 * return FAIL for failure, OK otherwise 4287 * return FAIL for failure, OK otherwise
4205 */ 4288 */
4206 int 4289 int
4207 do_join(count, insert_space, save_undo) 4290 do_join(count, insert_space, save_undo, use_formatoptions)
4208 long count; 4291 long count;
4209 int insert_space; 4292 int insert_space;
4210 int save_undo; 4293 int save_undo;
4294 int use_formatoptions UNUSED;
4211 { 4295 {
4212 char_u *curr = NULL; 4296 char_u *curr = NULL;
4213 char_u *curr_start = NULL; 4297 char_u *curr_start = NULL;
4214 char_u *cend; 4298 char_u *cend;
4215 char_u *newp; 4299 char_u *newp;
4219 int currsize = 0; /* size of the current line */ 4303 int currsize = 0; /* size of the current line */
4220 int sumsize = 0; /* size of the long new line */ 4304 int sumsize = 0; /* size of the long new line */
4221 linenr_T t; 4305 linenr_T t;
4222 colnr_T col = 0; 4306 colnr_T col = 0;
4223 int ret = OK; 4307 int ret = OK;
4308 #if defined(FEAT_COMMENTS) || defined(PROTO)
4309 int *comments;
4310 int remove_comments = (use_formatoptions == TRUE)
4311 && has_format_option(FO_REMOVE_COMS);
4312 int prev_was_comment;
4313 #endif
4314
4224 4315
4225 if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1), 4316 if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1),
4226 (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL) 4317 (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL)
4227 return FAIL; 4318 return FAIL;
4228 4319
4230 * line. We will use it to pre-compute the length of the new line and the 4321 * line. We will use it to pre-compute the length of the new line and the
4231 * proper placement of each original line in the new one. */ 4322 * proper placement of each original line in the new one. */
4232 spaces = lalloc_clear((long_u)count, TRUE); 4323 spaces = lalloc_clear((long_u)count, TRUE);
4233 if (spaces == NULL) 4324 if (spaces == NULL)
4234 return FAIL; 4325 return FAIL;
4326 #if defined(FEAT_COMMENTS) || defined(PROTO)
4327 if (remove_comments)
4328 {
4329 comments = (int *)lalloc_clear((long_u)count * sizeof(int), TRUE);
4330 if (comments == NULL)
4331 {
4332 vim_free(spaces);
4333 return FAIL;
4334 }
4335 }
4336 #endif
4235 4337
4236 /* 4338 /*
4237 * Don't move anything, just compute the final line length 4339 * Don't move anything, just compute the final line length
4238 * and setup the array of space strings lengths 4340 * and setup the array of space strings lengths
4239 */ 4341 */
4240 for (t = 0; t < count; ++t) 4342 for (t = 0; t < count; ++t)
4241 { 4343 {
4242 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); 4344 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t));
4345 #if defined(FEAT_COMMENTS) || defined(PROTO)
4346 if (remove_comments)
4347 {
4348 /* We don't want to remove the comment leader if the
4349 * previous line is not a comment. */
4350 if (t > 0 && prev_was_comment)
4351 {
4352
4353 char_u *new_curr = skip_comment(curr, TRUE, insert_space,
4354 &prev_was_comment);
4355 comments[t] = new_curr - curr;
4356 curr = new_curr;
4357 }
4358 else
4359 curr = skip_comment(curr, FALSE, insert_space,
4360 &prev_was_comment);
4361 }
4362 #endif
4363
4243 if (insert_space && t > 0) 4364 if (insert_space && t > 0)
4244 { 4365 {
4245 curr = skipwhite(curr); 4366 curr = skipwhite(curr);
4246 if (*curr != ')' && currsize != 0 && endcurr1 != TAB 4367 if (*curr != ')' && currsize != 0 && endcurr1 != TAB
4247 #ifdef FEAT_MBYTE 4368 #ifdef FEAT_MBYTE
4325 mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t, 4446 mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t,
4326 (long)(cend - newp + spaces[t] - (curr - curr_start))); 4447 (long)(cend - newp + spaces[t] - (curr - curr_start)));
4327 if (t == 0) 4448 if (t == 0)
4328 break; 4449 break;
4329 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); 4450 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1));
4451 #if defined(FEAT_COMMENTS) || defined(PROTO)
4452 if (remove_comments)
4453 curr += comments[t - 1];
4454 #endif
4330 if (insert_space && t > 1) 4455 if (insert_space && t > 1)
4331 curr = skipwhite(curr); 4456 curr = skipwhite(curr);
4332 currsize = (int)STRLEN(curr); 4457 currsize = (int)STRLEN(curr);
4333 } 4458 }
4334 ml_replace(curwin->w_cursor.lnum, newp, FALSE); 4459 ml_replace(curwin->w_cursor.lnum, newp, FALSE);
4362 #endif 4487 #endif
4363 curwin->w_set_curswant = TRUE; 4488 curwin->w_set_curswant = TRUE;
4364 4489
4365 theend: 4490 theend:
4366 vim_free(spaces); 4491 vim_free(spaces);
4492 #if defined(FEAT_COMMENTS) || defined(PROTO)
4493 if (remove_comments)
4494 vim_free(comments);
4495 #endif
4367 return ret; 4496 return ret;
4368 } 4497 }
4369 4498
4370 #ifdef FEAT_COMMENTS 4499 #ifdef FEAT_COMMENTS
4371 /* 4500 /*
4786 if (next_leader_len > 0) 4915 if (next_leader_len > 0)
4787 mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, 4916 mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
4788 (long)-next_leader_len); 4917 (long)-next_leader_len);
4789 #endif 4918 #endif
4790 curwin->w_cursor.lnum--; 4919 curwin->w_cursor.lnum--;
4791 if (do_join(2, TRUE, FALSE) == FAIL) 4920 if (do_join(2, TRUE, FALSE, FALSE) == FAIL)
4792 { 4921 {
4793 beep_flush(); 4922 beep_flush();
4794 break; 4923 break;
4795 } 4924 }
4796 first_par_line = FALSE; 4925 first_par_line = FALSE;
4842 char_u *flags = NULL; /* init for GCC */ 4971 char_u *flags = NULL; /* init for GCC */
4843 char_u *ptr; 4972 char_u *ptr;
4844 4973
4845 ptr = ml_get(lnum); 4974 ptr = ml_get(lnum);
4846 if (do_comments) 4975 if (do_comments)
4847 *leader_len = get_leader_len(ptr, leader_flags, FALSE); 4976 *leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE);
4848 else 4977 else
4849 *leader_len = 0; 4978 *leader_len = 0;
4850 4979
4851 if (*leader_len > 0) 4980 if (*leader_len > 0)
4852 { 4981 {