0
0
mirror of https://github.com/vim/vim.git synced 2025-09-28 04:24:06 -04:00

patch 8.2.4165: the nv_g_cmd() function is too long

Problem:    The nv_g_cmd() function is too long.
Solution:   Move code to separate functions. (Yegappan Lakshmanan,
            closes #9576)
This commit is contained in:
Yegappan Lakshmanan
2022-01-20 20:18:27 +00:00
committed by Bram Moolenaar
parent 6f0ddbf00d
commit 05386ca1d4
2 changed files with 305 additions and 292 deletions

View File

@@ -5890,72 +5890,26 @@ nv_suspend(cmdarg_T *cap)
} }
/* /*
* Commands starting with "g".
*/
static void
nv_g_cmd(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
pos_T tpos;
int i;
int flag = FALSE;
switch (cap->nchar)
{
case Ctrl_A:
case Ctrl_X:
#ifdef MEM_PROFILE
/*
* "g^A": dump log of used memory.
*/
if (!VIsual_active && cap->nchar == Ctrl_A)
vim_mem_profile_dump();
else
#endif
/*
* "g^A/g^X": sequentially increment visually selected region
*/
if (VIsual_active)
{
cap->arg = TRUE;
cap->cmdchar = cap->nchar;
cap->nchar = NUL;
nv_addsub(cap);
}
else
clearopbeep(oap);
break;
/*
* "gR": Enter virtual replace mode.
*/
case 'R':
cap->arg = TRUE;
nv_Replace(cap);
break;
case 'r':
nv_vreplace(cap);
break;
case '&':
do_cmdline_cmd((char_u *)"%s//~/&");
break;
/*
* "gv": Reselect the previous Visual area. If Visual already active, * "gv": Reselect the previous Visual area. If Visual already active,
* exchange previous and current Visual area. * exchange previous and current Visual area.
*/ */
case 'v': static void
if (checkclearop(oap)) nv_gv_cmd(cmdarg_T *cap)
break; {
pos_T tpos;
int i;
if ( curbuf->b_visual.vi_start.lnum == 0 if (checkclearop(cap->oap))
return;
if (curbuf->b_visual.vi_start.lnum == 0
|| curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count || curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count
|| curbuf->b_visual.vi_end.lnum == 0) || curbuf->b_visual.vi_end.lnum == 0)
beep_flush();
else
{ {
beep_flush();
return;
}
// set w_cursor to the start of the Visual area, tpos to the end // set w_cursor to the start of the Visual area, tpos to the end
if (VIsual_active) if (VIsual_active)
{ {
@@ -5992,11 +5946,10 @@ nv_g_cmd(cmdarg_T *cap)
curwin->w_cursor = tpos; curwin->w_cursor = tpos;
check_cursor(); check_cursor();
update_topline(); update_topline();
/*
* When called from normal "g" command: start Select mode when // When called from normal "g" command: start Select mode when
* 'selectmode' contains "cmd". When called for K_SELECT, always // 'selectmode' contains "cmd". When called for K_SELECT, always
* start Select mode. // start Select mode.
*/
if (cap->arg) if (cap->arg)
{ {
VIsual_select = TRUE; VIsual_select = TRUE;
@@ -6012,100 +5965,23 @@ nv_g_cmd(cmdarg_T *cap)
#endif #endif
redraw_curbuf_later(INVERTED); redraw_curbuf_later(INVERTED);
showmode(); showmode();
} }
break;
/*
* "gV": Don't reselect the previous Visual area after a Select mode
* mapping of menu.
*/
case 'V':
VIsual_reselect = FALSE;
break;
/* /*
* "gh": start Select mode. * "g0", "g^" : Like "0" and "^" but for screen lines.
* "gH": start Select line mode.
* "g^H": start Select block mode.
*/
case K_BS:
cap->nchar = Ctrl_H;
// FALLTHROUGH
case 'h':
case 'H':
case Ctrl_H:
# ifdef EBCDIC
// EBCDIC: 'v'-'h' != '^v'-'^h'
if (cap->nchar == Ctrl_H)
cap->cmdchar = Ctrl_V;
else
# endif
cap->cmdchar = cap->nchar + ('v' - 'h');
cap->arg = TRUE;
nv_visual(cap);
break;
// "gn", "gN" visually select next/previous search match
// "gn" selects next match
// "gN" selects previous match
case 'N':
case 'n':
if (!current_search(cap->count1, cap->nchar == 'n'))
clearopbeep(oap);
break;
/*
* "gj" and "gk" two new funny movement keys -- up and down
* movement based on *screen* line rather than *file* line.
*/
case 'j':
case K_DOWN:
// with 'nowrap' it works just like the normal "j" command.
if (!curwin->w_p_wrap)
{
oap->motion_type = MLINE;
i = cursor_down(cap->count1, oap->op_type == OP_NOP);
}
else
i = nv_screengo(oap, FORWARD, cap->count1);
if (i == FAIL)
clearopbeep(oap);
break;
case 'k':
case K_UP:
// with 'nowrap' it works just like the normal "k" command.
if (!curwin->w_p_wrap)
{
oap->motion_type = MLINE;
i = cursor_up(cap->count1, oap->op_type == OP_NOP);
}
else
i = nv_screengo(oap, BACKWARD, cap->count1);
if (i == FAIL)
clearopbeep(oap);
break;
/*
* "gJ": join two lines without inserting a space.
*/
case 'J':
nv_join(cap);
break;
/*
* "g0", "g^" and "g$": Like "0", "^" and "$" but for screen lines.
* "gm": middle of "g0" and "g$". * "gm": middle of "g0" and "g$".
*/ */
case '^': static void
flag = TRUE; nv_g_home_m_cmd(cmdarg_T *cap)
// FALLTHROUGH {
int i;
int flag = FALSE;
case '0': if (cap->nchar == '^')
case 'm': flag = TRUE;
case K_HOME:
case K_KHOME: cap->oap->motion_type = MCHAR;
oap->motion_type = MCHAR; cap->oap->inclusive = FALSE;
oap->inclusive = FALSE;
if (curwin->w_p_wrap && curwin->w_width != 0) if (curwin->w_p_wrap && curwin->w_width != 0)
{ {
int width1 = curwin->w_width - curwin_col_off(); int width1 = curwin->w_width - curwin_col_off();
@@ -6134,33 +6010,28 @@ nv_g_cmd(cmdarg_T *cap)
curwin->w_valid &= ~VALID_WCOL; curwin->w_valid &= ~VALID_WCOL;
} }
curwin->w_set_curswant = TRUE; curwin->w_set_curswant = TRUE;
break; }
case 'M': /*
{ * "g_": to the last non-blank character in the line or <count> lines
oap->motion_type = MCHAR; * downward.
oap->inclusive = FALSE; */
i = linetabsize(ml_get_curline()); static void
if (cap->count0 > 0 && cap->count0 <= 100) nv_g_underscore_cmd(cmdarg_T *cap)
coladvance((colnr_T)(i * cap->count0 / 100)); {
else char_u *ptr;
coladvance((colnr_T)(i / 2));
curwin->w_set_curswant = TRUE;
}
break;
case '_':
// "g_": to the last non-blank character in the line or <count> lines
// downward.
cap->oap->motion_type = MCHAR; cap->oap->motion_type = MCHAR;
cap->oap->inclusive = TRUE; cap->oap->inclusive = TRUE;
curwin->w_curswant = MAXCOL; curwin->w_curswant = MAXCOL;
if (cursor_down((long)(cap->count1 - 1), if (cursor_down((long)(cap->count1 - 1),
cap->oap->op_type == OP_NOP) == FAIL) cap->oap->op_type == OP_NOP) == FAIL)
clearopbeep(cap->oap);
else
{ {
char_u *ptr = ml_get_curline(); clearopbeep(cap->oap);
return;
}
ptr = ml_get_curline();
// In Visual mode we may end up after the line. // In Visual mode we may end up after the line.
if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL) if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL)
@@ -6172,13 +6043,16 @@ nv_g_cmd(cmdarg_T *cap)
--curwin->w_cursor.col; --curwin->w_cursor.col;
curwin->w_set_curswant = TRUE; curwin->w_set_curswant = TRUE;
adjust_for_sel(cap); adjust_for_sel(cap);
} }
break;
case '$': /*
case K_END: * "g$" : Like "$" but for screen lines.
case K_KEND: */
{ static void
nv_g_dollar_cmd(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
int i;
int col_off = curwin_col_off(); int col_off = curwin_col_off();
oap->motion_type = MCHAR; oap->motion_type = MCHAR;
@@ -6204,11 +6078,9 @@ nv_g_cmd(cmdarg_T *cap)
curwin->w_set_curswant = FALSE; curwin->w_set_curswant = FALSE;
if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) if (curwin->w_cursor.col > 0 && curwin->w_p_wrap)
{ {
/* // Check for landing on a character that got split at
* Check for landing on a character that got split at // the end of the line. We do not want to advance to
* the end of the line. We do not want to advance to // the next screen line.
* the next screen line.
*/
if (curwin->w_virtcol > (colnr_T)i) if (curwin->w_virtcol > (colnr_T)i)
--curwin->w_cursor.col; --curwin->w_cursor.col;
} }
@@ -6241,45 +6113,16 @@ nv_g_cmd(cmdarg_T *cap)
curwin->w_curswant = curwin->w_virtcol; curwin->w_curswant = curwin->w_virtcol;
curwin->w_set_curswant = FALSE; curwin->w_set_curswant = FALSE;
} }
} }
break;
/* /*
* "g*" and "g#", like "*" and "#" but without using "\<" and "\>"
*/
case '*':
case '#':
#if POUND != '#'
case POUND: // pound sign (sometimes equal to '#')
#endif
case Ctrl_RSB: // :tag or :tselect for current identifier
case ']': // :tselect for current identifier
nv_ident(cap);
break;
/*
* ge and gE: go back to end of word
*/
case 'e':
case 'E':
oap->motion_type = MCHAR;
curwin->w_set_curswant = TRUE;
oap->inclusive = TRUE;
if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL)
clearopbeep(oap);
break;
/*
* "g CTRL-G": display info about cursor position
*/
case Ctrl_G:
cursor_pos_info(NULL);
break;
/*
* "gi": start Insert at the last position. * "gi": start Insert at the last position.
*/ */
case 'i': static void
nv_gi_cmd(cmdarg_T *cap)
{
int i;
if (curbuf->b_last_insert.lnum != 0) if (curbuf->b_last_insert.lnum != 0)
{ {
curwin->w_cursor = curbuf->b_last_insert; curwin->w_cursor = curbuf->b_last_insert;
@@ -6294,11 +6137,197 @@ nv_g_cmd(cmdarg_T *cap)
} }
cap->cmdchar = 'i'; cap->cmdchar = 'i';
nv_edit(cap); nv_edit(cap);
}
/*
* Commands starting with "g".
*/
static void
nv_g_cmd(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
int i;
switch (cap->nchar)
{
case Ctrl_A:
case Ctrl_X:
#ifdef MEM_PROFILE
// "g^A": dump log of used memory.
if (!VIsual_active && cap->nchar == Ctrl_A)
vim_mem_profile_dump();
else
#endif
// "g^A/g^X": sequentially increment visually selected region
if (VIsual_active)
{
cap->arg = TRUE;
cap->cmdchar = cap->nchar;
cap->nchar = NUL;
nv_addsub(cap);
}
else
clearopbeep(oap);
break; break;
/* // "gR": Enter virtual replace mode.
* "gI": Start insert in column 1. case 'R':
*/ cap->arg = TRUE;
nv_Replace(cap);
break;
case 'r':
nv_vreplace(cap);
break;
case '&':
do_cmdline_cmd((char_u *)"%s//~/&");
break;
// "gv": Reselect the previous Visual area. If Visual already active,
// exchange previous and current Visual area.
case 'v':
nv_gv_cmd(cap);
break;
// "gV": Don't reselect the previous Visual area after a Select mode
// mapping of menu.
case 'V':
VIsual_reselect = FALSE;
break;
// "gh": start Select mode.
// "gH": start Select line mode.
// "g^H": start Select block mode.
case K_BS:
cap->nchar = Ctrl_H;
// FALLTHROUGH
case 'h':
case 'H':
case Ctrl_H:
# ifdef EBCDIC
// EBCDIC: 'v'-'h' != '^v'-'^h'
if (cap->nchar == Ctrl_H)
cap->cmdchar = Ctrl_V;
else
# endif
cap->cmdchar = cap->nchar + ('v' - 'h');
cap->arg = TRUE;
nv_visual(cap);
break;
// "gn", "gN" visually select next/previous search match
// "gn" selects next match
// "gN" selects previous match
case 'N':
case 'n':
if (!current_search(cap->count1, cap->nchar == 'n'))
clearopbeep(oap);
break;
// "gj" and "gk" two new funny movement keys -- up and down
// movement based on *screen* line rather than *file* line.
case 'j':
case K_DOWN:
// with 'nowrap' it works just like the normal "j" command.
if (!curwin->w_p_wrap)
{
oap->motion_type = MLINE;
i = cursor_down(cap->count1, oap->op_type == OP_NOP);
}
else
i = nv_screengo(oap, FORWARD, cap->count1);
if (i == FAIL)
clearopbeep(oap);
break;
case 'k':
case K_UP:
// with 'nowrap' it works just like the normal "k" command.
if (!curwin->w_p_wrap)
{
oap->motion_type = MLINE;
i = cursor_up(cap->count1, oap->op_type == OP_NOP);
}
else
i = nv_screengo(oap, BACKWARD, cap->count1);
if (i == FAIL)
clearopbeep(oap);
break;
// "gJ": join two lines without inserting a space.
case 'J':
nv_join(cap);
break;
// "g0", "g^" : Like "0" and "^" but for screen lines.
// "gm": middle of "g0" and "g$".
case '^':
case '0':
case 'm':
case K_HOME:
case K_KHOME:
nv_g_home_m_cmd(cap);
break;
case 'M':
{
oap->motion_type = MCHAR;
oap->inclusive = FALSE;
i = linetabsize(ml_get_curline());
if (cap->count0 > 0 && cap->count0 <= 100)
coladvance((colnr_T)(i * cap->count0 / 100));
else
coladvance((colnr_T)(i / 2));
curwin->w_set_curswant = TRUE;
}
break;
// "g_": to the last non-blank character in the line or <count> lines
// downward.
case '_':
nv_g_underscore_cmd(cap);
break;
// "g$" : Like "$" but for screen lines.
case '$':
case K_END:
case K_KEND:
nv_g_dollar_cmd(cap);
break;
// "g*" and "g#", like "*" and "#" but without using "\<" and "\>"
case '*':
case '#':
#if POUND != '#'
case POUND: // pound sign (sometimes equal to '#')
#endif
case Ctrl_RSB: // :tag or :tselect for current identifier
case ']': // :tselect for current identifier
nv_ident(cap);
break;
// ge and gE: go back to end of word
case 'e':
case 'E':
oap->motion_type = MCHAR;
curwin->w_set_curswant = TRUE;
oap->inclusive = TRUE;
if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL)
clearopbeep(oap);
break;
// "g CTRL-G": display info about cursor position
case Ctrl_G:
cursor_pos_info(NULL);
break;
// "gi": start Insert at the last position.
case 'i':
nv_gi_cmd(cap);
break;
// "gI": Start insert in column 1.
case 'I': case 'I':
beginline(0); beginline(0);
if (!checkclearopq(oap)) if (!checkclearopq(oap))
@@ -6306,10 +6335,8 @@ nv_g_cmd(cmdarg_T *cap)
break; break;
#ifdef FEAT_SEARCHPATH #ifdef FEAT_SEARCHPATH
/* // "gf": goto file, edit file under cursor
* "gf": goto file, edit file under cursor // "]f" and "[f": can also be used.
* "]f" and "[f": can also be used.
*/
case 'f': case 'f':
case 'F': case 'F':
nv_gotofile(cap); nv_gotofile(cap);
@@ -6324,26 +6351,20 @@ nv_g_cmd(cmdarg_T *cap)
nv_gomark(cap); nv_gomark(cap);
break; break;
/* // "gs": Goto sleep.
* "gs": Goto sleep.
*/
case 's': case 's':
do_sleep(cap->count1 * 1000L, FALSE); do_sleep(cap->count1 * 1000L, FALSE);
break; break;
/* // "ga": Display the ascii value of the character under the
* "ga": Display the ascii value of the character under the // cursor. It is displayed in decimal, hex, and octal. -- webb
* cursor. It is displayed in decimal, hex, and octal. -- webb
*/
case 'a': case 'a':
do_ascii(NULL); do_ascii(NULL);
break; break;
/* // "g8": Display the bytes used for the UTF-8 character under the
* "g8": Display the bytes used for the UTF-8 character under the // cursor. It is displayed in hex.
* cursor. It is displayed in hex. // "8g8" finds illegal byte sequence.
* "8g8" finds illegal byte sequence.
*/
case '8': case '8':
if (cap->count0 == 8) if (cap->count0 == 8)
utf_find_illegal(); utf_find_illegal();
@@ -6356,25 +6377,21 @@ nv_g_cmd(cmdarg_T *cap)
show_sb_text(); show_sb_text();
break; break;
/* // "gg": Goto the first line in file. With a count it goes to
* "gg": Goto the first line in file. With a count it goes to // that line number like for "G". -- webb
* that line number like for "G". -- webb
*/
case 'g': case 'g':
cap->arg = FALSE; cap->arg = FALSE;
nv_goto(cap); nv_goto(cap);
break; break;
/* // Two-character operators:
* Two-character operators: // "gq" Format text
* "gq" Format text // "gw" Format text and keep cursor position
* "gw" Format text and keep cursor position // "g~" Toggle the case of the text.
* "g~" Toggle the case of the text. // "gu" Change text to lower case.
* "gu" Change text to lower case. // "gU" Change text to upper case.
* "gU" Change text to upper case. // "g?" rot13 encoding
* "g?" rot13 encoding // "g@" call 'operatorfunc'
* "g@" call 'operatorfunc'
*/
case 'q': case 'q':
case 'w': case 'w':
oap->cursor_start = curwin->w_cursor; oap->cursor_start = curwin->w_cursor;
@@ -6387,19 +6404,15 @@ nv_g_cmd(cmdarg_T *cap)
nv_operator(cap); nv_operator(cap);
break; break;
/* // "gd": Find first occurrence of pattern under the cursor in the
* "gd": Find first occurrence of pattern under the cursor in the // current function
* current function // "gD": idem, but in the current file.
* "gD": idem, but in the current file.
*/
case 'd': case 'd':
case 'D': case 'D':
nv_gd(oap, cap->nchar, (int)cap->count0); nv_gd(oap, cap->nchar, (int)cap->count0);
break; break;
/* // g<*Mouse> : <C-*mouse>
* g<*Mouse> : <C-*mouse>
*/
case K_MIDDLEMOUSE: case K_MIDDLEMOUSE:
case K_MIDDLEDRAG: case K_MIDDLEDRAG:
case K_MIDDLERELEASE: case K_MIDDLERELEASE:
@@ -6423,9 +6436,7 @@ nv_g_cmd(cmdarg_T *cap)
case K_IGNORE: case K_IGNORE:
break; break;
/* // "gP" and "gp": same as "P" and "p" but leave cursor just after new text
* "gP" and "gp": same as "P" and "p" but leave cursor just after new text
*/
case 'p': case 'p':
case 'P': case 'P':
nv_put(cap); nv_put(cap);

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4165,
/**/ /**/
4164, 4164,
/**/ /**/