diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Make_cyg_ming.mak | 1 | ||||
-rw-r--r-- | src/Make_morph.mak | 1 | ||||
-rw-r--r-- | src/Make_mvc.mak | 4 | ||||
-rw-r--r-- | src/Make_vms.mms | 5 | ||||
-rw-r--r-- | src/Makefile | 10 | ||||
-rw-r--r-- | src/README.md | 1 | ||||
-rw-r--r-- | src/edit.c | 567 | ||||
-rw-r--r-- | src/getchar.c | 40 | ||||
-rw-r--r-- | src/ops.c | 590 | ||||
-rw-r--r-- | src/option.c | 12 | ||||
-rw-r--r-- | src/proto.h | 1 | ||||
-rw-r--r-- | src/proto/edit.pro | 2 | ||||
-rw-r--r-- | src/proto/getchar.pro | 1 | ||||
-rw-r--r-- | src/proto/ops.pro | 4 | ||||
-rw-r--r-- | src/proto/option.pro | 1 | ||||
-rw-r--r-- | src/proto/textformat.pro | 11 | ||||
-rw-r--r-- | src/textformat.c | 1088 | ||||
-rw-r--r-- | src/version.c | 2 |
18 files changed, 1165 insertions, 1176 deletions
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 7964b0a1f2..94561e51b2 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -787,6 +787,7 @@ OBJ = \ $(OUTDIR)/tag.o \ $(OUTDIR)/term.o \ $(OUTDIR)/testing.o \ + $(OUTDIR)/textformat.o \ $(OUTDIR)/textobject.o \ $(OUTDIR)/textprop.o \ $(OUTDIR)/time.o \ diff --git a/src/Make_morph.mak b/src/Make_morph.mak index d326174cd2..43414e72cf 100644 --- a/src/Make_morph.mak +++ b/src/Make_morph.mak @@ -103,6 +103,7 @@ SRC = arabic.c \ tag.c \ term.c \ testing.c \ + textformat.c \ textobject.c \ textprop.c \ time.c \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index c873ca0840..ffe6e4914c 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -806,6 +806,7 @@ OBJ = \ $(OUTDIR)\tag.obj \ $(OUTDIR)\term.obj \ $(OUTDIR)\testing.obj \ + $(OUTDIR)\textformat.obj \ $(OUTDIR)\textobject.obj \ $(OUTDIR)\textprop.obj \ $(OUTDIR)\time.obj \ @@ -1745,6 +1746,8 @@ $(OUTDIR)/term.obj: $(OUTDIR) term.c $(INCL) $(OUTDIR)/term.obj: $(OUTDIR) testing.c $(INCL) +$(OUTDIR)/textformat.obj: $(OUTDIR) textformat.c $(INCL) + $(OUTDIR)/textobject.obj: $(OUTDIR) textobject.c $(INCL) $(OUTDIR)/textprop.obj: $(OUTDIR) textprop.c $(INCL) @@ -1945,6 +1948,7 @@ proto.h: \ proto/tag.pro \ proto/term.pro \ proto/testing.pro \ + proto/textformat.pro \ proto/textobject.pro \ proto/textprop.pro \ proto/time.pro \ diff --git a/src/Make_vms.mms b/src/Make_vms.mms index e04020172a..954d50a14f 100644 --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -382,6 +382,7 @@ SRC = \ term.c \ termlib.c \ testing.c \ + textformat.c \ textobject.c \ textprop.c \ time.c \ @@ -492,6 +493,7 @@ OBJ = \ term.obj \ termlib.obj \ testing.obj \ + textformat.obj \ textobject.obj \ textprop.obj \ time.obj \ @@ -991,6 +993,9 @@ termlib.obj : termlib.c vim.h [.auto]config.h feature.h os_unix.h \ testing.obj : testing.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h +textformat.obj : textformat.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ + [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h textobject.obj : textobject.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h diff --git a/src/Makefile b/src/Makefile index 8a12cb8016..6c7ef85a92 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1680,6 +1680,7 @@ BASIC_SRC = \ term.c \ terminal.c \ testing.c \ + textformat.c \ textobject.c \ textprop.c \ time.c \ @@ -1823,6 +1824,7 @@ OBJ_COMMON = \ objects/term.o \ objects/terminal.o \ objects/testing.o \ + objects/textformat.o \ objects/textobject.o \ objects/textprop.o \ objects/time.o \ @@ -1998,6 +2000,7 @@ PRO_AUTO = \ terminal.pro \ termlib.pro \ testing.pro \ + textformat.pro \ textobject.pro \ textprop.pro \ time.pro \ @@ -3479,6 +3482,9 @@ objects/terminal.o: terminal.c $(TERM_DEPS) objects/testing.o: testing.c $(CCC) -o $@ testing.c +objects/textformat.o: textformat.c + $(CCC) -o $@ textformat.c + objects/textobject.o: textobject.c $(CCC) -o $@ textobject.c @@ -4073,6 +4079,10 @@ objects/testing.o: testing.c vim.h protodef.h auto/config.h feature.h os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/textformat.o: textformat.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/textobject.o: textobject.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/README.md b/src/README.md index 765313da7e..624bd6a829 100644 --- a/src/README.md +++ b/src/README.md @@ -80,6 +80,7 @@ syntax.c | syntax and other highlighting tag.c | tags term.c | terminal handling, termcap codes testing.c | testing: assert and test functions +textformat.c | text formatting textobject.c | text objects textprop.c | text properties time.c | time and timer functions 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 diff --git a/src/getchar.c b/src/getchar.c index 7bbdf35834..9d8c0d4bff 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -685,6 +685,46 @@ stuffnumReadbuff(long n) } /* + * Stuff a string into the typeahead buffer, such that edit() will insert it + * literally ("literally" TRUE) or interpret is as typed characters. + */ + void +stuffescaped(char_u *arg, int literally) +{ + int c; + char_u *start; + + while (*arg != NUL) + { + // Stuff a sequence of normal ASCII characters, that's fast. Also + // stuff K_SPECIAL to get the effect of a special key when "literally" + // is TRUE. + start = arg; + while ((*arg >= ' ' +#ifndef EBCDIC + && *arg < DEL // EBCDIC: chars above space are normal +#endif + ) + || (*arg == K_SPECIAL && !literally)) + ++arg; + if (arg > start) + stuffReadbuffLen(start, (long)(arg - start)); + + // stuff a single special character + if (*arg != NUL) + { + if (has_mbyte) + c = mb_cptr2char_adv(&arg); + else + c = *arg++; + if (literally && ((c < ' ' && c != TAB) || c == DEL)) + stuffcharReadbuff(Ctrl_V); + stuffcharReadbuff(c); + } + } +} + +/* * Read a character from the redo buffer. Translates K_SPECIAL, CSI and * multibyte characters. * The redo buffer is left as it is. @@ -17,8 +17,6 @@ static void shift_block(oparg_T *oap, int amount); static void mb_adjust_opend(oparg_T *oap); static int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1); -static int ends_in_white(linenr_T lnum); -static int fmt_check_par(linenr_T, int *, char_u **, int do_comments); // Flags for third item in "opchars". #define OPF_LINES 1 // operator always works on lines @@ -591,46 +589,6 @@ block_insert( } /* - * Stuff a string into the typeahead buffer, such that edit() will insert it - * literally ("literally" TRUE) or interpret is as typed characters. - */ - void -stuffescaped(char_u *arg, int literally) -{ - int c; - char_u *start; - - while (*arg != NUL) - { - // Stuff a sequence of normal ASCII characters, that's fast. Also - // stuff K_SPECIAL to get the effect of a special key when "literally" - // is TRUE. - start = arg; - while ((*arg >= ' ' -#ifndef EBCDIC - && *arg < DEL // EBCDIC: chars above space are normal -#endif - ) - || (*arg == K_SPECIAL && !literally)) - ++arg; - if (arg > start) - stuffReadbuffLen(start, (long)(arg - start)); - - // stuff a single special character - if (*arg != NUL) - { - if (has_mbyte) - c = mb_cptr2char_adv(&arg); - else - c = *arg++; - if (literally && ((c < ' ' && c != TAB) || c == DEL)) - stuffcharReadbuff(Ctrl_V); - stuffcharReadbuff(c); - } - } -} - -/* * Handle a delete operation. * * Return FAIL if undo failed, OK otherwise. @@ -2171,554 +2129,6 @@ theend: } /* - * Return TRUE if the two comment leaders given are the same. "lnum" is - * the first line. White-space is ignored. Note that the whole of - * 'leader1' must match 'leader2_len' characters from 'leader2' -- webb - */ - static int -same_leader( - linenr_T lnum, - int leader1_len, - char_u *leader1_flags, - int leader2_len, - char_u *leader2_flags) -{ - int idx1 = 0, idx2 = 0; - char_u *p; - char_u *line1; - char_u *line2; - - if (leader1_len == 0) - return (leader2_len == 0); - - /* - * If first leader has 'f' flag, the lines can be joined only if the - * second line does not have a leader. - * If first leader has 'e' flag, the lines can never be joined. - * If fist leader has 's' flag, the lines can only be joined if there is - * some text after it and the second line has the 'm' flag. - */ - if (leader1_flags != NULL) - { - for (p = leader1_flags; *p && *p != ':'; ++p) - { - if (*p == COM_FIRST) - return (leader2_len == 0); - if (*p == COM_END) - return FALSE; - if (*p == COM_START) - { - if (*(ml_get(lnum) + leader1_len) == NUL) - return FALSE; - if (leader2_flags == NULL || leader2_len == 0) - return FALSE; - for (p = leader2_flags; *p && *p != ':'; ++p) - if (*p == COM_MIDDLE) - return TRUE; - return FALSE; - } - } - } - - /* - * Get current line and next line, compare the leaders. - * The first line has to be saved, only one line can be locked at a time. - */ - line1 = vim_strsave(ml_get(lnum)); - if (line1 != NULL) - { - for (idx1 = 0; VIM_ISWHITE(line1[idx1]); ++idx1) - ; - line2 = ml_get(lnum + 1); - for (idx2 = 0; idx2 < leader2_len; ++idx2) - { - if (!VIM_ISWHITE(line2[idx2])) - { - if (line1[idx1++] != line2[idx2]) - break; - } - else - while (VIM_ISWHITE(line1[idx1])) - ++idx1; - } - vim_free(line1); - } - return (idx2 == leader2_len && idx1 == leader1_len); -} - -/* - * Implementation of the format operator 'gq'. - */ - static void -op_format( - oparg_T *oap, - int keep_cursor) // keep cursor on same text char -{ - long old_line_count = curbuf->b_ml.ml_line_count; - - // Place the cursor where the "gq" or "gw" command was given, so that "u" - // can put it back there. - curwin->w_cursor = oap->cursor_start; - - if (u_save((linenr_T)(oap->start.lnum - 1), - (linenr_T)(oap->end.lnum + 1)) == FAIL) - return; - curwin->w_cursor = oap->start; - - if (oap->is_VIsual) - // When there is no change: need to remove the Visual selection - redraw_curbuf_later(INVERTED); - - if (!cmdmod.lockmarks) - // Set '[ mark at the start of the formatted area - curbuf->b_op_start = oap->start; - - // For "gw" remember the cursor position and put it back below (adjusted - // for joined and split lines). - if (keep_cursor) - saved_cursor = oap->cursor_start; - - format_lines(oap->line_count, keep_cursor); - - /* - * Leave the cursor at the first non-blank of the last formatted line. - * If the cursor was moved one line back (e.g. with "Q}") go to the next - * line, so "." will do the next lines. - */ - if (oap->end_adjusted && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) - ++curwin->w_cursor.lnum; - beginline(BL_WHITE | BL_FIX); - old_line_count = curbuf->b_ml.ml_line_count - old_line_count; - msgmore(old_line_count); - - if (!cmdmod.lockmarks) - // put '] mark on the end of the formatted area - curbuf->b_op_end = curwin->w_cursor; - - if (keep_cursor) - { - curwin->w_cursor = saved_cursor; - saved_cursor.lnum = 0; - } - - if (oap->is_VIsual) - { - win_T *wp; - - FOR_ALL_WINDOWS(wp) - { - if (wp->w_old_cursor_lnum != 0) - { - // When lines have been inserted or deleted, adjust the end of - // the Visual area to be redrawn. - if (wp->w_old_cursor_lnum > wp->w_old_visual_lnum) - wp->w_old_cursor_lnum += old_line_count; - else - wp->w_old_visual_lnum += old_line_count; - } - } - } -} - -#if defined(FEAT_EVAL) || defined(PROTO) -/* - * Implementation of the format operator 'gq' for when using 'formatexpr'. - */ - static void -op_formatexpr(oparg_T *oap) -{ - if (oap->is_VIsual) - // When there is no change: need to remove the Visual selection - redraw_curbuf_later(INVERTED); - - if (fex_format(oap->start.lnum, oap->line_count, NUL) != 0) - // As documented: when 'formatexpr' returns non-zero fall back to - // internal formatting. - op_format(oap, FALSE); -} - - int -fex_format( - linenr_T lnum, - long count, - int c) // character to be inserted -{ - int use_sandbox = was_set_insecurely((char_u *)"formatexpr", - OPT_LOCAL); |