Mercurial > vim
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 { |