diff options
Diffstat (limited to 'src/edit.c')
-rw-r--r-- | src/edit.c | 567 |
1 files changed, 0 insertions, 567 deletions
diff --git a/src/edit.c b/src/edit.c index 0ac63ec8fd..5252334ce5 100644 --- a/src/edit.c +++ b/src/edit.c @@ -28,8 +28,6 @@ static void ins_ctrl_v(void); static void init_prompt(int cmdchar_todo); #endif static void insert_special(int, int, int); -static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c); -static void check_auto_format(int); static void redo_literal(int c); static void start_arrow_common(pos_T *end_insert_pos, int change); #ifdef FEAT_SPELL @@ -104,8 +102,6 @@ static int ins_need_undo; // call u_save() before inserting a // char. Set when edit() is called. // after that arrow_used is used. -static int did_add_space = FALSE; // auto_format() added an extra space - // under the cursor static int dont_sync_undo = FALSE; // CTRL-G U prevents syncing undo for // the next left/right cursor key @@ -2063,8 +2059,6 @@ insert_special( # define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^') #endif -#define WHITECHAR(cc) (VIM_ISWHITE(cc) && (!enc_utf8 || !utf_iscomposing(utf_ptr2char(ml_get_cursor() + 1)))) - /* * "flags": INSCHAR_FORMAT - force formatting * INSCHAR_CTRLV - char typed just after CTRL-V @@ -2302,567 +2296,6 @@ insertchar( } /* - * Format text at the current insert position. - * - * If the INSCHAR_COM_LIST flag is present, then the value of second_indent - * will be the comment leader length sent to open_line(). - */ - static void -internal_format( - int textwidth, - int second_indent, - int flags, - int format_only, - int c) // character to be inserted (can be NUL) -{ - int cc; - int save_char = NUL; - int haveto_redraw = FALSE; - int fo_ins_blank = has_format_option(FO_INS_BLANK); - int fo_multibyte = has_format_option(FO_MBYTE_BREAK); - int fo_white_par = has_format_option(FO_WHITE_PAR); - int first_line = TRUE; - colnr_T leader_len; - int no_leader = FALSE; - int do_comments = (flags & INSCHAR_DO_COM); -#ifdef FEAT_LINEBREAK - int has_lbr = curwin->w_p_lbr; - - // make sure win_lbr_chartabsize() counts correctly - curwin->w_p_lbr = FALSE; -#endif - - /* - * When 'ai' is off we don't want a space under the cursor to be - * deleted. Replace it with an 'x' temporarily. - */ - if (!curbuf->b_p_ai && !(State & VREPLACE_FLAG)) - { - cc = gchar_cursor(); - if (VIM_ISWHITE(cc)) - { - save_char = cc; - pchar_cursor('x'); - } - } - - /* - * Repeat breaking lines, until the current line is not too long. - */ - while (!got_int) - { - int startcol; // Cursor column at entry - int wantcol; // column at textwidth border - int foundcol; // column for start of spaces - int end_foundcol = 0; // column for start of word - colnr_T len; - colnr_T virtcol; - int orig_col = 0; - char_u *saved_text = NULL; - colnr_T col; - colnr_T end_col; - int wcc; // counter for whitespace chars - - virtcol = get_nolist_virtcol() - + char2cells(c != NUL ? c : gchar_cursor()); - if (virtcol <= (colnr_T)textwidth) - break; - - if (no_leader) - do_comments = FALSE; - else if (!(flags & INSCHAR_FORMAT) - && has_format_option(FO_WRAP_COMS)) - do_comments = TRUE; - - // Don't break until after the comment leader - if (do_comments) - leader_len = get_leader_len(ml_get_curline(), NULL, FALSE, TRUE); - else - leader_len = 0; - - // If the line doesn't start with a comment leader, then don't - // start one in a following broken line. Avoids that a %word - // moved to the start of the next line causes all following lines - // to start with %. - if (leader_len == 0) - no_leader = TRUE; - if (!(flags & INSCHAR_FORMAT) - && leader_len == 0 - && !has_format_option(FO_WRAP)) - - break; - if ((startcol = curwin->w_cursor.col) == 0) - break; - - // find column of textwidth border - coladvance((colnr_T)textwidth); - wantcol = curwin->w_cursor.col; - - curwin->w_cursor.col = startcol; - foundcol = 0; - - /* - * Find position to break at. - * Stop at first entered white when 'formatoptions' has 'v' - */ - while ((!fo_ins_blank && !has_format_option(FO_INS_VI)) - || (flags & INSCHAR_FORMAT) - || curwin->w_cursor.lnum != Insstart.lnum - || curwin->w_cursor.col >= Insstart.col) - { - if (curwin->w_cursor.col == startcol && c != NUL) - cc = c; - else - cc = gchar_cursor(); - if (WHITECHAR(cc)) - { - // remember position of blank just before text - end_col = curwin->w_cursor.col; - - // find start of sequence of blanks - wcc = 0; - while (curwin->w_cursor.col > 0 && WHITECHAR(cc)) - { - dec_cursor(); - cc = gchar_cursor(); - - // Increment count of how many whitespace chars in this - // group; we only need to know if it's more than one. - if (wcc < 2) - wcc++; - } - if (curwin->w_cursor.col == 0 && WHITECHAR(cc)) - break; // only spaces in front of text - - // Don't break after a period when 'formatoptions' has 'p' and - // there are less than two spaces. - if (has_format_option(FO_PERIOD_ABBR) && cc == '.' && wcc < 2) - continue; - - // Don't break until after the comment leader - if (curwin->w_cursor.col < leader_len) - break; - if (has_format_option(FO_ONE_LETTER)) - { - // do not break after one-letter words - if (curwin->w_cursor.col == 0) - break; // one-letter word at begin - // do not break "#a b" when 'tw' is 2 - if (curwin->w_cursor.col <= leader_len) - break; - col = curwin->w_cursor.col; - dec_cursor(); - cc = gchar_cursor(); - - if (WHITECHAR(cc)) - continue; // one-letter, continue - curwin->w_cursor.col = col; - } - - inc_cursor(); - - end_foundcol = end_col + 1; - foundcol = curwin->w_cursor.col; - if (curwin->w_cursor.col <= (colnr_T)wantcol) - break; - } - else if (cc >= 0x100 && fo_multibyte) - { - // Break after or before a multi-byte character. - if (curwin->w_cursor.col != startcol) - { - // Don't break until after the comment leader - if (curwin->w_cursor.col < leader_len) - break; - col = curwin->w_cursor.col; - inc_cursor(); - // Don't change end_foundcol if already set. - if (foundcol != curwin->w_cursor.col) - { - foundcol = curwin->w_cursor.col; - end_foundcol = foundcol; - if (curwin->w_cursor.col <= (colnr_T)wantcol) - break; - } - curwin->w_cursor.col = col; - } - - if (curwin->w_cursor.col == 0) - break; - - col = curwin->w_cursor.col; - - dec_cursor(); - cc = gchar_cursor(); - - if (WHITECHAR(cc)) - continue; // break with space - // Don't break until after the comment leader - if (curwin->w_cursor.col < leader_len) - break; - - curwin->w_cursor.col = col; - - foundcol = curwin->w_cursor.col; - end_foundcol = foundcol; - if (curwin->w_cursor.col <= (colnr_T)wantcol) - break; - } - if (curwin->w_cursor.col == 0) - break; - dec_cursor(); - } - - if (foundcol == 0) // no spaces, cannot break line - { - curwin->w_cursor.col = startcol; - break; - } - - // Going to break the line, remove any "$" now. - undisplay_dollar(); - - /* - * Offset between cursor position and line break is used by replace - * stack functions. VREPLACE does not use this, and backspaces - * over the text instead. - */ - if (State & VREPLACE_FLAG) - orig_col = startcol; // Will start backspacing from here - else - replace_offset = startcol - end_foundcol; - - /* - * adjust startcol for spaces that will be deleted and - * characters that will remain on top line - */ - curwin->w_cursor.col = foundcol; - while ((cc = gchar_cursor(), WHITECHAR(cc)) - && (!fo_white_par || curwin->w_cursor.col < startcol)) - inc_cursor(); - startcol -= curwin->w_cursor.col; - if (startcol < 0) - startcol = 0; - - if (State & VREPLACE_FLAG) - { - /* - * In VREPLACE mode, we will backspace over the text to be - * wrapped, so save a copy now to put on the next line. - */ - saved_text = vim_strsave(ml_get_cursor()); - curwin->w_cursor.col = orig_col; - if (saved_text == NULL) - break; // Can't do it, out of memory - saved_text[startcol] = NUL; - - // Backspace over characters that will move to the next line - if (!fo_white_par) - backspace_until_column(foundcol); - } - else - { - // put cursor after pos. to break line - if (!fo_white_par) - curwin->w_cursor.col = foundcol; - } - - /* - * Split the line just before the margin. - * Only insert/delete lines, but don't really redraw the window. - */ - open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX - + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) - + (do_comments ? OPENLINE_DO_COM : 0) - + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0) - , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); - if (!(flags & INSCHAR_COM_LIST)) - old_indent = 0; - - replace_offset = 0; - if (first_line) - { - if (!(flags & INSCHAR_COM_LIST)) - { - /* - * This section is for auto-wrap of numeric lists. When not - * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST - * flag will be set and open_line() will handle it (as seen - * above). The code here (and in get_number_indent()) will - * recognize comments if needed... - */ - if (second_indent < 0 && has_format_option(FO_Q_NUMBER)) - second_indent = - get_number_indent(curwin->w_cursor.lnum - 1); - if (second_indent >= 0) - { - if (State & VREPLACE_FLAG) - change_indent(INDENT_SET, second_indent, - FALSE, NUL, TRUE); - else - if (leader_len > 0 && second_indent - leader_len > 0) - { - int i; - int padding = second_indent - leader_len; - - // We started at the first_line of a numbered list - // that has a comment. the open_line() function has - // inserted the proper comment leader and positioned - // the cursor at the end of the split line. Now we - // add the additional whitespace needed after the - // comment leader for the numbered list. - for (i = 0; i < padding; i++) - ins_str((char_u *)" "); - } - else - { - (void)set_indent(second_indent, SIN_CHANGED); - } - } - } - first_line = FALSE; - } - - if (State & VREPLACE_FLAG) - { - /* - * In VREPLACE mode we have backspaced over the text to be - * moved, now we re-insert it into the new line. - */ - ins_bytes(saved_text); - vim_free(saved_text); - } - else - { - /* - * Check if cursor is not past the NUL off the line, cindent - * may have added or removed indent. - */ - curwin->w_cursor.col += startcol; - len = (colnr_T)STRLEN(ml_get_curline()); - if (curwin->w_cursor.col > len) - curwin->w_cursor.col = len; - } - - haveto_redraw = TRUE; -#ifdef FEAT_CINDENT - can_cindent = TRUE; -#endif - // moved the cursor, don't autoindent or cindent now - did_ai = FALSE; -#ifdef FEAT_SMARTINDENT - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; -#endif - line_breakcheck(); - } - - if (save_char != NUL) // put back space after cursor - pchar_cursor(save_char); - -#ifdef FEAT_LINEBREAK - curwin->w_p_lbr = has_lbr; -#endif - if (!format_only && haveto_redraw) - { - update_topline(); - redraw_curbuf_later(VALID); - } -} - -/* - * Called after inserting or deleting text: When 'formatoptions' includes the - * 'a' flag format from the current line until the end of the paragraph. - * Keep the cursor at the same position relative to the text. - * The caller must have saved the cursor line for undo, following ones will be - * saved here. - */ - void -auto_format( - int trailblank, // when TRUE also format with trailing blank - int prev_line) // may start in previous line -{ - pos_T pos; - colnr_T len; - char_u *old; - char_u *new, *pnew; - int wasatend; - int cc; - - if (!has_format_option(FO_AUTO)) - return; - - pos = curwin->w_cursor; - old = ml_get_curline(); - - // may remove added space - check_auto_format(FALSE); - - // Don't format in Insert mode when the cursor is on a trailing blank, the - // user might insert normal text next. Also skip formatting when "1" is - // in 'formatoptions' and there is a single character before the cursor. - // Otherwise the line would be broken and when typing another non-white - // next they are not joined back together. - wasatend = (pos.col == (colnr_T)STRLEN(old)); - if (*old != NUL && !trailblank && wasatend) - { - dec_cursor(); - cc = gchar_cursor(); - if (!WHITECHAR(cc) && curwin->w_cursor.col > 0 - && has_format_option(FO_ONE_LETTER)) - dec_cursor(); - cc = gchar_cursor(); - if (WHITECHAR(cc)) - { - curwin->w_cursor = pos; - return; - } - curwin->w_cursor = pos; - } - - // With the 'c' flag in 'formatoptions' and 't' missing: only format - // comments. - if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) - && get_leader_len(old, NULL, FALSE, TRUE) == 0) - return; - - /* - * May start formatting in a previous line, so that after "x" a word is - * moved to the previous line if it fits there now. Only when this is not - * the start of a paragraph. - */ - if (prev_line && !paragraph_start(curwin->w_cursor.lnum)) - { - --curwin->w_cursor.lnum; - if (u_save_cursor() == FAIL) - return; - } - - /* - * Do the formatting and restore the cursor position. "saved_cursor" will - * be adjusted for the text formatting. - */ - saved_cursor = pos; - format_lines((linenr_T)-1, FALSE); - curwin->w_cursor = saved_cursor; - saved_cursor.lnum = 0; - - if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) - { - // "cannot happen" - curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; - coladvance((colnr_T)MAXCOL); - } - else - check_cursor_col(); - - // Insert mode: If the cursor is now after the end of the line while it - // previously wasn't, the line was broken. Because of the rule above we - // need to add a space when 'w' is in 'formatoptions' to keep a paragraph - // formatted. - if (!wasatend && has_format_option(FO_WHITE_PAR)) - { - new = ml_get_curline(); - len = (colnr_T)STRLEN(new); - if (curwin->w_cursor.col == len) - { - pnew = vim_strnsave(new, len + 2); - pnew[len] = ' '; - pnew[len + 1] = NUL; - ml_replace(curwin->w_cursor.lnum, pnew, FALSE); - // remove the space later - did_add_space = TRUE; - } - else - // may remove added space - check_auto_format(FALSE); - } - - check_cursor(); -} - -/* - * When an extra space was added to continue a paragraph for auto-formatting, - * delete it now. The space must be under the cursor, just after the insert - * position. - */ - static void -check_auto_format( - int end_insert) // TRUE when ending Insert mode -{ - int c = ' '; - int cc; - - if (did_add_space) - { - cc = gchar_cursor(); - if (!WHITECHAR(cc)) - // Somehow the space was removed already. - did_add_space = FALSE; - else - { - if (!end_insert) - { - inc_cursor(); - c = gchar_cursor(); - dec_cursor(); - } - if (c != NUL) - { - // The space is no longer at the end of the line, delete it. - del_char(FALSE); - did_add_space = FALSE; - } - } - } -} - -/* - * Find out textwidth to be used for formatting: - * if 'textwidth' option is set, use it - * else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin' - * if invalid value, use 0. - * Set default to window width (maximum 79) for "gq" operator. - */ - int -comp_textwidth( - int ff) // force formatting (for "gq" command) -{ - int textwidth; - - textwidth = curbuf->b_p_tw; - if (textwidth == 0 && curbuf->b_p_wm) - { - // The width is the window width minus 'wrapmargin' minus all the - // things that add to the margin. - textwidth = curwin->w_width - curbuf->b_p_wm; -#ifdef FEAT_CMDWIN - if (cmdwin_type != 0) - textwidth -= 1; -#endif -#ifdef FEAT_FOLDING - textwidth -= curwin->w_p_fdc; -#endif -#ifdef FEAT_SIGNS - if (signcolumn_on(curwin)) - textwidth -= 1; -#endif - if (curwin->w_p_nu || curwin->w_p_rnu) - textwidth -= 8; - } - if (textwidth < 0) - textwidth = 0; - if (ff && textwidth == 0) - { - textwidth = curwin->w_width - 1; - if (textwidth > 79) - textwidth = 79; - } - return textwidth; -} - -/* * Put a character in the redo buffer, for when just after a CTRL-V. */ static void |