summaryrefslogtreecommitdiffstats
path: root/src/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ops.c')
-rw-r--r--src/ops.c590
1 files changed, 0 insertions, 590 deletions
diff --git a/src/ops.c b/src/ops.c
index 5e9de4d7cc..9ab355596b 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -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);
- int r;
- char_u *fex;
-
- /*
- * Set v:lnum to the first line number and v:count to the number of lines.
- * Set v:char to the character to be inserted (can be NUL).
- */
- set_vim_var_nr(VV_LNUM, lnum);
- set_vim_var_nr(VV_COUNT, count);
- set_vim_var_char(c);
-
- // Make a copy, the option could be changed while calling it.
- fex = vim_strsave(curbuf->b_p_fex);
- if (fex == NULL)
- return 0;
-
- /*
- * Evaluate the function.
- */
- if (use_sandbox)
- ++sandbox;
- r = (int)eval_to_number(fex);
- if (use_sandbox)
- --sandbox;
-
- set_vim_var_string(VV_CHAR, NULL, -1);
- vim_free(fex);
-
- return r;
-}
-#endif
-
-/*
- * Format "line_count" lines, starting at the cursor position.
- * When "line_count" is negative, format until the end of the paragraph.
- * Lines after the cursor line are saved for undo, caller must have saved the
- * first line.
- */
- void
-format_lines(
- linenr_T line_count,
- int avoid_fex) // don't use 'formatexpr'
-{
- int max_len;
- int is_not_par; // current line not part of parag.
- int next_is_not_par; // next line not part of paragraph
- int is_end_par; // at end of paragraph
- int prev_is_end_par = FALSE;// prev. line not part of parag.
- int next_is_start_par = FALSE;
- int leader_len = 0; // leader len of current line
- int next_leader_len; // leader len of next line
- char_u *leader_flags = NULL; // flags for leader of current line
- char_u *next_leader_flags; // flags for leader of next line
- int do_comments; // format comments
- int do_comments_list = 0; // format comments with 'n' or '2'
- int advance = TRUE;
- int second_indent = -1; // indent for second line (comment
- // aware)
- int do_second_indent;
- int do_number_indent;
- int do_trail_white;
- int first_par_line = TRUE;
- int smd_save;
- long count;
- int need_set_indent = TRUE; // set indent of next paragraph
- int force_format = FALSE;
- int old_State = State;
-
- // length of a line to force formatting: 3 * 'tw'
- max_len = comp_textwidth(TRUE) * 3;
-
- // check for 'q', '2' and '1' in 'formatoptions'
- do_comments = has_format_option(FO_Q_COMS);
- do_second_indent = has_format_option(FO_Q_SECOND);
- do_number_indent = has_format_option(FO_Q_NUMBER);
- do_trail_white = has_format_option(FO_WHITE_PAR);
-
- /*
- * Get info about the previous and current line.
- */
- if (curwin->w_cursor.lnum > 1)
- is_not_par = fmt_check_par(curwin->w_cursor.lnum - 1
- , &leader_len, &leader_flags, do_comments);
- else
- is_not_par = TRUE;
- next_is_not_par = fmt_check_par(curwin->w_cursor.lnum
- , &next_leader_len, &next_leader_flags, do_comments);
- is_end_par = (is_not_par || next_is_not_par);
- if (!is_end_par && do_trail_white)
- is_end_par = !ends_in_white(curwin->w_cursor.lnum - 1);
-
- curwin->w_cursor.lnum--;
- for (count = line_count; count != 0 && !got_int; --count)
- {
- /*
- * Advance to next paragraph.
- */
- if (advance)
- {
- curwin->w_cursor.lnum++;
- prev_is_end_par = is_end_par;
- is_not_par = next_is_not_par;
- leader_len = next_leader_len;
- leader_flags = next_leader_flags;
- }
-
- /*
- * The last line to be formatted.
- */
- if (count == 1 || curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
- {
- next_is_not_par = TRUE;
- next_leader_len = 0;
- next_leader_flags = NULL;
- }
- else
- {
- next_is_not_par = fmt_check_par(curwin->w_cursor.lnum + 1
- , &next_leader_len, &next_leader_flags, do_comments);
- if (do_number_indent)
- next_is_start_par =
- (get_number_indent(curwin->w_cursor.lnum + 1) > 0);
- }
- advance = TRUE;
- is_end_par = (is_not_par || next_is_not_par || next_is_start_par);
- if (!is_end_par && do_trail_white)
- is_end_par = !ends_in_white(curwin->w_cursor.lnum);
-
- /*
- * Skip lines that are not in a paragraph.
- */
- if (is_not_par)
- {
- if (line_count < 0)
- break;
- }
- else
- {
- /*
- * For the first line of a paragraph, check indent of second line.
- * Don't do this for comments and empty lines.
- */
- if (first_par_line
- && (do_second_indent || do_number_indent)
- && prev_is_end_par
- && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
- {
- if (do_second_indent && !LINEEMPTY(curwin->w_cursor.lnum + 1))
- {
- if (leader_len == 0 && next_leader_len == 0)
- {
- // no comment found
- second_indent =
- get_indent_lnum(curwin->w_cursor.lnum + 1);
- }
- else
- {
- second_indent = next_leader_len;
- do_comments_list = 1;
- }
- }
- else if (do_number_indent)
- {
- if (leader_len == 0 && next_leader_len == 0)
- {
- // no comment found
- second_indent =
- get_number_indent(curwin->w_cursor.lnum);
- }
- else
- {
- // get_number_indent() is now "comment aware"...
- second_indent =
- get_number_indent(curwin->w_cursor.lnum);
- do_comments_list = 1;
- }
- }
- }
-
- /*
- * When the comment leader changes, it's the end of the paragraph.
- */
- if (curwin->w_cursor.lnum >= curbuf->b_ml.ml_line_count
- || !same_leader(curwin->w_cursor.lnum,
- leader_len, leader_flags,
- next_leader_len, next_leader_flags))
- is_end_par = TRUE;
-
- /*
- * If we have got to the end of a paragraph, or the line is
- * getting long, format it.
- */
- if (is_end_par || force_format)
- {
- if (need_set_indent)
- // replace indent in first line with minimal number of
- // tabs and spaces, according to current options
- (void)set_indent(get_indent(), SIN_CHANGED);
-
- // put cursor on last non-space
- State = NORMAL; // don't go past end-of-line
- coladvance((colnr_T)MAXCOL);
- while (curwin->w_cursor.col && vim_isspace(gchar_cursor()))
- dec_cursor();
-
- // do the formatting, without 'showmode'
- State = INSERT; // for open_line()
- smd_save = p_smd;
- p_smd = FALSE;
- insertchar(NUL, INSCHAR_FORMAT
- + (do_comments ? INSCHAR_DO_COM : 0)
- + (do_comments && do_comments_list
- ? INSCHAR_COM_LIST : 0)
- + (avoid_fex ? INSCHAR_NO_FEX : 0), second_indent);
- State = old_State;
- p_smd = smd_save;
- second_indent = -1;
- // at end of par.: need to set indent of next par.
- need_set_indent = is_end_par;
- if (is_end_par)
- {
- // When called with a negative line count, break at the
- // end of the paragraph.
- if (line_count < 0)
- break;
- first_par_line = TRUE;
- }
- force_format = FALSE;
- }
-
- /*
- * When still in same paragraph, join the lines together. But
- * first delete the leader from the second line.
- */
- if (!is_end_par)
- {
- advance = FALSE;
- curwin->w_cursor.lnum++;
- curwin->w_cursor.col = 0;
- if (line_count < 0 && u_save_cursor() == FAIL)
- break;
- if (next_leader_len > 0)
- {
- (void)del_bytes((long)next_leader_len, FALSE, FALSE);
- mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
- (long)-next_leader_len, 0);
- }
- else if (second_indent > 0) // the "leader" for FO_Q_SECOND
- {
- int indent = getwhitecols_curline();
-
- if (indent > 0)
- {
- (void)del_bytes(indent, FALSE, FALSE);
- mark_col_adjust(curwin->w_cursor.lnum,
- (colnr_T)0, 0L, (long)-indent, 0);
- }
- }
- curwin->w_cursor.lnum--;
- if (do_join(2, TRUE, FALSE, FALSE, FALSE) == FAIL)
- {
- beep_flush();
- break;
- }
- first_par_line = FALSE;
- // If the line is getting long, format it next time
- if (STRLEN(ml_get_curline()) > (size_t)max_len)
- force_format = TRUE;
- else
- force_format = FALSE;
- }
- }
- line_breakcheck();
- }
-}
-
-/*
- * Return TRUE if line "lnum" ends in a white character.
- */
- static int
-ends_in_white(linenr_T lnum)
-{
- char_u *s = ml_get(lnum);
- size_t l;
-
- if (*s == NUL)
- return FALSE;
- // Don't use STRLEN() inside VIM_ISWHITE(), SAS/C complains: "macro
- // invocation may call function multiple times".
- l = STRLEN(s) - 1;
- return VIM_ISWHITE(s[l]);
-}
-
-/*
- * Blank lines, and lines containing only the comment leader, are left
- * untouched by the formatting. The function returns TRUE in this
- * case. It also returns TRUE when a line starts with the end of a comment
- * ('e' in comment flags), so that this line is skipped, and not joined to the
- * previous line. A new paragraph starts after a blank line, or when the
- * comment leader changes -- webb.
- */
- static int
-fmt_check_par(
- linenr_T lnum,
- int *leader_len,
- char_u **leader_flags,
- int do_comments)
-{
- char_u *flags = NULL; // init for GCC
- char_u *ptr;
-
- ptr = ml_get(lnum);
- if (do_comments)
- *leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE);
- else
- *leader_len = 0;
-
- if (*leader_len > 0)
- {
- /*
- * Search for 'e' flag in comment leader flags.
- */
- flags = *leader_flags;
- while (*flags && *flags != ':' && *flags != COM_END)
- ++flags;
- }
-
- return (*skipwhite(ptr + *leader_len) == NUL
- || (*leader_len > 0 && *flags == COM_END)
- || startPS(lnum, NUL, FALSE));
-}
-
-/*
- * Return TRUE when a paragraph starts in line "lnum". Return FALSE when the
- * previous line is in the same paragraph. Used for auto-formatting.
- */
- int
-paragraph_start(linenr_T lnum)
-{
- char_u *p;
- int leader_len = 0; // leader len of current line
- char_u *leader_flags = NULL; // flags for leader of current line
- int next_leader_len; // leader len of next line
- char_u *next_leader_flags; // flags for leader of next line
- int do_comments; // format comments
-
- if (lnum <= 1)
- return TRUE; // start of the file
-
- p = ml_get(lnum - 1);
- if (*p == NUL)
- return TRUE; // after empty line
-
- do_comments = has_format_option(FO_Q_COMS);
- if (fmt_check_par(lnum - 1, &leader_len, &leader_flags, do_comments))
- return TRUE; // after non-paragraph line
-
- if (fmt_check_par(lnum, &next_leader_len, &next_leader_flags, do_comments))
- return TRUE; // "lnum" is not a paragraph line
-
- if (has_format_option(FO_WHITE_PAR) && !ends_in_white(lnum - 1))
- return TRUE; // missing trailing space in previous line.
-
- if (has_format_option(FO_Q_NUMBER) && (get_number_indent(lnum) > 0))
- return TRUE; // numbered item starts in "lnum".
-
- if (!same_leader(lnum - 1, leader_len, leader_flags,
- next_leader_len, next_leader_flags))
- return TRUE; // change of comment leader.
-
- return FALSE;
-}
-
-/*
* prepare a few things for block mode yank/delete/tilde
*
* for delete: