Mercurial > vim
comparison src/normal.c @ 27273:a9f0c1f06c84 v8.2.4165
patch 8.2.4165: the nv_g_cmd() function is too long
Commit: https://github.com/vim/vim/commit/05386ca1d4823e5c98c24b8cd038af49aee62577
Author: Yegappan Lakshmanan <yegappan@yahoo.com>
Date: Thu Jan 20 20:18:27 2022 +0000
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 20 Jan 2022 21:30:03 +0100 |
parents | 93d4ee1e6113 |
children | 469e643b7729 |
comparison
equal
deleted
inserted
replaced
27272:09a65231156f | 27273:a9f0c1f06c84 |
---|---|
5888 end_visual_mode(); // stop Visual mode | 5888 end_visual_mode(); // stop Visual mode |
5889 do_cmdline_cmd((char_u *)"stop"); | 5889 do_cmdline_cmd((char_u *)"stop"); |
5890 } | 5890 } |
5891 | 5891 |
5892 /* | 5892 /* |
5893 * Commands starting with "g". | 5893 * "gv": Reselect the previous Visual area. If Visual already active, |
5894 */ | 5894 * exchange previous and current Visual area. |
5895 static void | 5895 */ |
5896 nv_g_cmd(cmdarg_T *cap) | 5896 static void |
5897 { | 5897 nv_gv_cmd(cmdarg_T *cap) |
5898 oparg_T *oap = cap->oap; | 5898 { |
5899 pos_T tpos; | 5899 pos_T tpos; |
5900 int i; | 5900 int i; |
5901 | |
5902 if (checkclearop(cap->oap)) | |
5903 return; | |
5904 | |
5905 if (curbuf->b_visual.vi_start.lnum == 0 | |
5906 || curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count | |
5907 || curbuf->b_visual.vi_end.lnum == 0) | |
5908 { | |
5909 beep_flush(); | |
5910 return; | |
5911 } | |
5912 | |
5913 // set w_cursor to the start of the Visual area, tpos to the end | |
5914 if (VIsual_active) | |
5915 { | |
5916 i = VIsual_mode; | |
5917 VIsual_mode = curbuf->b_visual.vi_mode; | |
5918 curbuf->b_visual.vi_mode = i; | |
5919 # ifdef FEAT_EVAL | |
5920 curbuf->b_visual_mode_eval = i; | |
5921 # endif | |
5922 i = curwin->w_curswant; | |
5923 curwin->w_curswant = curbuf->b_visual.vi_curswant; | |
5924 curbuf->b_visual.vi_curswant = i; | |
5925 | |
5926 tpos = curbuf->b_visual.vi_end; | |
5927 curbuf->b_visual.vi_end = curwin->w_cursor; | |
5928 curwin->w_cursor = curbuf->b_visual.vi_start; | |
5929 curbuf->b_visual.vi_start = VIsual; | |
5930 } | |
5931 else | |
5932 { | |
5933 VIsual_mode = curbuf->b_visual.vi_mode; | |
5934 curwin->w_curswant = curbuf->b_visual.vi_curswant; | |
5935 tpos = curbuf->b_visual.vi_end; | |
5936 curwin->w_cursor = curbuf->b_visual.vi_start; | |
5937 } | |
5938 | |
5939 VIsual_active = TRUE; | |
5940 VIsual_reselect = TRUE; | |
5941 | |
5942 // Set Visual to the start and w_cursor to the end of the Visual | |
5943 // area. Make sure they are on an existing character. | |
5944 check_cursor(); | |
5945 VIsual = curwin->w_cursor; | |
5946 curwin->w_cursor = tpos; | |
5947 check_cursor(); | |
5948 update_topline(); | |
5949 | |
5950 // When called from normal "g" command: start Select mode when | |
5951 // 'selectmode' contains "cmd". When called for K_SELECT, always | |
5952 // start Select mode. | |
5953 if (cap->arg) | |
5954 { | |
5955 VIsual_select = TRUE; | |
5956 VIsual_select_reg = 0; | |
5957 } | |
5958 else | |
5959 may_start_select('c'); | |
5960 setmouse(); | |
5961 #ifdef FEAT_CLIPBOARD | |
5962 // Make sure the clipboard gets updated. Needed because start and | |
5963 // end are still the same, and the selection needs to be owned | |
5964 clip_star.vmode = NUL; | |
5965 #endif | |
5966 redraw_curbuf_later(INVERTED); | |
5967 showmode(); | |
5968 } | |
5969 | |
5970 /* | |
5971 * "g0", "g^" : Like "0" and "^" but for screen lines. | |
5972 * "gm": middle of "g0" and "g$". | |
5973 */ | |
5974 static void | |
5975 nv_g_home_m_cmd(cmdarg_T *cap) | |
5976 { | |
5977 int i; | |
5901 int flag = FALSE; | 5978 int flag = FALSE; |
5979 | |
5980 if (cap->nchar == '^') | |
5981 flag = TRUE; | |
5982 | |
5983 cap->oap->motion_type = MCHAR; | |
5984 cap->oap->inclusive = FALSE; | |
5985 if (curwin->w_p_wrap && curwin->w_width != 0) | |
5986 { | |
5987 int width1 = curwin->w_width - curwin_col_off(); | |
5988 int width2 = width1 + curwin_col_off2(); | |
5989 | |
5990 validate_virtcol(); | |
5991 i = 0; | |
5992 if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0) | |
5993 i = (curwin->w_virtcol - width1) / width2 * width2 + width1; | |
5994 } | |
5995 else | |
5996 i = curwin->w_leftcol; | |
5997 // Go to the middle of the screen line. When 'number' or | |
5998 // 'relativenumber' is on and lines are wrapping the middle can be more | |
5999 // to the left. | |
6000 if (cap->nchar == 'm') | |
6001 i += (curwin->w_width - curwin_col_off() | |
6002 + ((curwin->w_p_wrap && i > 0) | |
6003 ? curwin_col_off2() : 0)) / 2; | |
6004 coladvance((colnr_T)i); | |
6005 if (flag) | |
6006 { | |
6007 do | |
6008 i = gchar_cursor(); | |
6009 while (VIM_ISWHITE(i) && oneright() == OK); | |
6010 curwin->w_valid &= ~VALID_WCOL; | |
6011 } | |
6012 curwin->w_set_curswant = TRUE; | |
6013 } | |
6014 | |
6015 /* | |
6016 * "g_": to the last non-blank character in the line or <count> lines | |
6017 * downward. | |
6018 */ | |
6019 static void | |
6020 nv_g_underscore_cmd(cmdarg_T *cap) | |
6021 { | |
6022 char_u *ptr; | |
6023 | |
6024 cap->oap->motion_type = MCHAR; | |
6025 cap->oap->inclusive = TRUE; | |
6026 curwin->w_curswant = MAXCOL; | |
6027 if (cursor_down((long)(cap->count1 - 1), | |
6028 cap->oap->op_type == OP_NOP) == FAIL) | |
6029 { | |
6030 clearopbeep(cap->oap); | |
6031 return; | |
6032 } | |
6033 | |
6034 ptr = ml_get_curline(); | |
6035 | |
6036 // In Visual mode we may end up after the line. | |
6037 if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL) | |
6038 --curwin->w_cursor.col; | |
6039 | |
6040 // Decrease the cursor column until it's on a non-blank. | |
6041 while (curwin->w_cursor.col > 0 | |
6042 && VIM_ISWHITE(ptr[curwin->w_cursor.col])) | |
6043 --curwin->w_cursor.col; | |
6044 curwin->w_set_curswant = TRUE; | |
6045 adjust_for_sel(cap); | |
6046 } | |
6047 | |
6048 /* | |
6049 * "g$" : Like "$" but for screen lines. | |
6050 */ | |
6051 static void | |
6052 nv_g_dollar_cmd(cmdarg_T *cap) | |
6053 { | |
6054 oparg_T *oap = cap->oap; | |
6055 int i; | |
6056 int col_off = curwin_col_off(); | |
6057 | |
6058 oap->motion_type = MCHAR; | |
6059 oap->inclusive = TRUE; | |
6060 if (curwin->w_p_wrap && curwin->w_width != 0) | |
6061 { | |
6062 curwin->w_curswant = MAXCOL; // so we stay at the end | |
6063 if (cap->count1 == 1) | |
6064 { | |
6065 int width1 = curwin->w_width - col_off; | |
6066 int width2 = width1 + curwin_col_off2(); | |
6067 | |
6068 validate_virtcol(); | |
6069 i = width1 - 1; | |
6070 if (curwin->w_virtcol >= (colnr_T)width1) | |
6071 i += ((curwin->w_virtcol - width1) / width2 + 1) | |
6072 * width2; | |
6073 coladvance((colnr_T)i); | |
6074 | |
6075 // Make sure we stick in this column. | |
6076 validate_virtcol(); | |
6077 curwin->w_curswant = curwin->w_virtcol; | |
6078 curwin->w_set_curswant = FALSE; | |
6079 if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) | |
6080 { | |
6081 // Check for landing on a character that got split at | |
6082 // the end of the line. We do not want to advance to | |
6083 // the next screen line. | |
6084 if (curwin->w_virtcol > (colnr_T)i) | |
6085 --curwin->w_cursor.col; | |
6086 } | |
6087 } | |
6088 else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == FAIL) | |
6089 clearopbeep(oap); | |
6090 } | |
6091 else | |
6092 { | |
6093 if (cap->count1 > 1) | |
6094 // if it fails, let the cursor still move to the last char | |
6095 (void)cursor_down(cap->count1 - 1, FALSE); | |
6096 | |
6097 i = curwin->w_leftcol + curwin->w_width - col_off - 1; | |
6098 coladvance((colnr_T)i); | |
6099 | |
6100 // if the character doesn't fit move one back | |
6101 if (curwin->w_cursor.col > 0 | |
6102 && (*mb_ptr2cells)(ml_get_cursor()) > 1) | |
6103 { | |
6104 colnr_T vcol; | |
6105 | |
6106 getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol); | |
6107 if (vcol >= curwin->w_leftcol + curwin->w_width - col_off) | |
6108 --curwin->w_cursor.col; | |
6109 } | |
6110 | |
6111 // Make sure we stick in this column. | |
6112 validate_virtcol(); | |
6113 curwin->w_curswant = curwin->w_virtcol; | |
6114 curwin->w_set_curswant = FALSE; | |
6115 } | |
6116 } | |
6117 | |
6118 /* | |
6119 * "gi": start Insert at the last position. | |
6120 */ | |
6121 static void | |
6122 nv_gi_cmd(cmdarg_T *cap) | |
6123 { | |
6124 int i; | |
6125 | |
6126 if (curbuf->b_last_insert.lnum != 0) | |
6127 { | |
6128 curwin->w_cursor = curbuf->b_last_insert; | |
6129 check_cursor_lnum(); | |
6130 i = (int)STRLEN(ml_get_curline()); | |
6131 if (curwin->w_cursor.col > (colnr_T)i) | |
6132 { | |
6133 if (virtual_active()) | |
6134 curwin->w_cursor.coladd += curwin->w_cursor.col - i; | |
6135 curwin->w_cursor.col = i; | |
6136 } | |
6137 } | |
6138 cap->cmdchar = 'i'; | |
6139 nv_edit(cap); | |
6140 } | |
6141 | |
6142 /* | |
6143 * Commands starting with "g". | |
6144 */ | |
6145 static void | |
6146 nv_g_cmd(cmdarg_T *cap) | |
6147 { | |
6148 oparg_T *oap = cap->oap; | |
6149 int i; | |
5902 | 6150 |
5903 switch (cap->nchar) | 6151 switch (cap->nchar) |
5904 { | 6152 { |
5905 case Ctrl_A: | 6153 case Ctrl_A: |
5906 case Ctrl_X: | 6154 case Ctrl_X: |
5907 #ifdef MEM_PROFILE | 6155 #ifdef MEM_PROFILE |
5908 /* | 6156 // "g^A": dump log of used memory. |
5909 * "g^A": dump log of used memory. | |
5910 */ | |
5911 if (!VIsual_active && cap->nchar == Ctrl_A) | 6157 if (!VIsual_active && cap->nchar == Ctrl_A) |
5912 vim_mem_profile_dump(); | 6158 vim_mem_profile_dump(); |
5913 else | 6159 else |
5914 #endif | 6160 #endif |
5915 /* | 6161 // "g^A/g^X": sequentially increment visually selected region |
5916 * "g^A/g^X": sequentially increment visually selected region | |
5917 */ | |
5918 if (VIsual_active) | 6162 if (VIsual_active) |
5919 { | 6163 { |
5920 cap->arg = TRUE; | 6164 cap->arg = TRUE; |
5921 cap->cmdchar = cap->nchar; | 6165 cap->cmdchar = cap->nchar; |
5922 cap->nchar = NUL; | 6166 cap->nchar = NUL; |
5924 } | 6168 } |
5925 else | 6169 else |
5926 clearopbeep(oap); | 6170 clearopbeep(oap); |
5927 break; | 6171 break; |
5928 | 6172 |
5929 /* | 6173 // "gR": Enter virtual replace mode. |
5930 * "gR": Enter virtual replace mode. | |
5931 */ | |
5932 case 'R': | 6174 case 'R': |
5933 cap->arg = TRUE; | 6175 cap->arg = TRUE; |
5934 nv_Replace(cap); | 6176 nv_Replace(cap); |
5935 break; | 6177 break; |
5936 | 6178 |
5940 | 6182 |
5941 case '&': | 6183 case '&': |
5942 do_cmdline_cmd((char_u *)"%s//~/&"); | 6184 do_cmdline_cmd((char_u *)"%s//~/&"); |
5943 break; | 6185 break; |
5944 | 6186 |
5945 /* | 6187 // "gv": Reselect the previous Visual area. If Visual already active, |
5946 * "gv": Reselect the previous Visual area. If Visual already active, | 6188 // exchange previous and current Visual area. |
5947 * exchange previous and current Visual area. | |
5948 */ | |
5949 case 'v': | 6189 case 'v': |
5950 if (checkclearop(oap)) | 6190 nv_gv_cmd(cap); |
5951 break; | |
5952 | |
5953 if ( curbuf->b_visual.vi_start.lnum == 0 | |
5954 || curbuf->b_visual.vi_start.lnum > curbuf->b_ml.ml_line_count | |
5955 || curbuf->b_visual.vi_end.lnum == 0) | |
5956 beep_flush(); | |
5957 else | |
5958 { | |
5959 // set w_cursor to the start of the Visual area, tpos to the end | |
5960 if (VIsual_active) | |
5961 { | |
5962 i = VIsual_mode; | |
5963 VIsual_mode = curbuf->b_visual.vi_mode; | |
5964 curbuf->b_visual.vi_mode = i; | |
5965 # ifdef FEAT_EVAL | |
5966 curbuf->b_visual_mode_eval = i; | |
5967 # endif | |
5968 i = curwin->w_curswant; | |
5969 curwin->w_curswant = curbuf->b_visual.vi_curswant; | |
5970 curbuf->b_visual.vi_curswant = i; | |
5971 | |
5972 tpos = curbuf->b_visual.vi_end; | |
5973 curbuf->b_visual.vi_end = curwin->w_cursor; | |
5974 curwin->w_cursor = curbuf->b_visual.vi_start; | |
5975 curbuf->b_visual.vi_start = VIsual; | |
5976 } | |
5977 else | |
5978 { | |
5979 VIsual_mode = curbuf->b_visual.vi_mode; | |
5980 curwin->w_curswant = curbuf->b_visual.vi_curswant; | |
5981 tpos = curbuf->b_visual.vi_end; | |
5982 curwin->w_cursor = curbuf->b_visual.vi_start; | |
5983 } | |
5984 | |
5985 VIsual_active = TRUE; | |
5986 VIsual_reselect = TRUE; | |
5987 | |
5988 // Set Visual to the start and w_cursor to the end of the Visual | |
5989 // area. Make sure they are on an existing character. | |
5990 check_cursor(); | |
5991 VIsual = curwin->w_cursor; | |
5992 curwin->w_cursor = tpos; | |
5993 check_cursor(); | |
5994 update_topline(); | |
5995 /* | |
5996 * When called from normal "g" command: start Select mode when | |
5997 * 'selectmode' contains "cmd". When called for K_SELECT, always | |
5998 * start Select mode. | |
5999 */ | |
6000 if (cap->arg) | |
6001 { | |
6002 VIsual_select = TRUE; | |
6003 VIsual_select_reg = 0; | |
6004 } | |
6005 else | |
6006 may_start_select('c'); | |
6007 setmouse(); | |
6008 #ifdef FEAT_CLIPBOARD | |
6009 // Make sure the clipboard gets updated. Needed because start and | |
6010 // end are still the same, and the selection needs to be owned | |
6011 clip_star.vmode = NUL; | |
6012 #endif | |
6013 redraw_curbuf_later(INVERTED); | |
6014 showmode(); | |
6015 } | |
6016 break; | 6191 break; |
6017 /* | 6192 |
6018 * "gV": Don't reselect the previous Visual area after a Select mode | 6193 // "gV": Don't reselect the previous Visual area after a Select mode |
6019 * mapping of menu. | 6194 // mapping of menu. |
6020 */ | |
6021 case 'V': | 6195 case 'V': |
6022 VIsual_reselect = FALSE; | 6196 VIsual_reselect = FALSE; |
6023 break; | 6197 break; |
6024 | 6198 |
6025 /* | 6199 // "gh": start Select mode. |
6026 * "gh": start Select mode. | 6200 // "gH": start Select line mode. |
6027 * "gH": start Select line mode. | 6201 // "g^H": start Select block mode. |
6028 * "g^H": start Select block mode. | |
6029 */ | |
6030 case K_BS: | 6202 case K_BS: |
6031 cap->nchar = Ctrl_H; | 6203 cap->nchar = Ctrl_H; |
6032 // FALLTHROUGH | 6204 // FALLTHROUGH |
6033 case 'h': | 6205 case 'h': |
6034 case 'H': | 6206 case 'H': |
6051 case 'n': | 6223 case 'n': |
6052 if (!current_search(cap->count1, cap->nchar == 'n')) | 6224 if (!current_search(cap->count1, cap->nchar == 'n')) |
6053 clearopbeep(oap); | 6225 clearopbeep(oap); |
6054 break; | 6226 break; |
6055 | 6227 |
6056 /* | 6228 // "gj" and "gk" two new funny movement keys -- up and down |
6057 * "gj" and "gk" two new funny movement keys -- up and down | 6229 // movement based on *screen* line rather than *file* line. |
6058 * movement based on *screen* line rather than *file* line. | |
6059 */ | |
6060 case 'j': | 6230 case 'j': |
6061 case K_DOWN: | 6231 case K_DOWN: |
6062 // with 'nowrap' it works just like the normal "j" command. | 6232 // with 'nowrap' it works just like the normal "j" command. |
6063 if (!curwin->w_p_wrap) | 6233 if (!curwin->w_p_wrap) |
6064 { | 6234 { |
6083 i = nv_screengo(oap, BACKWARD, cap->count1); | 6253 i = nv_screengo(oap, BACKWARD, cap->count1); |
6084 if (i == FAIL) | 6254 if (i == FAIL) |
6085 clearopbeep(oap); | 6255 clearopbeep(oap); |
6086 break; | 6256 break; |
6087 | 6257 |
6088 /* | 6258 // "gJ": join two lines without inserting a space. |
6089 * "gJ": join two lines without inserting a space. | |
6090 */ | |
6091 case 'J': | 6259 case 'J': |
6092 nv_join(cap); | 6260 nv_join(cap); |
6093 break; | 6261 break; |
6094 | 6262 |
6095 /* | 6263 // "g0", "g^" : Like "0" and "^" but for screen lines. |
6096 * "g0", "g^" and "g$": Like "0", "^" and "$" but for screen lines. | 6264 // "gm": middle of "g0" and "g$". |
6097 * "gm": middle of "g0" and "g$". | |
6098 */ | |
6099 case '^': | 6265 case '^': |
6100 flag = TRUE; | |
6101 // FALLTHROUGH | |
6102 | |
6103 case '0': | 6266 case '0': |
6104 case 'm': | 6267 case 'm': |
6105 case K_HOME: | 6268 case K_HOME: |
6106 case K_KHOME: | 6269 case K_KHOME: |
6107 oap->motion_type = MCHAR; | 6270 nv_g_home_m_cmd(cap); |
6108 oap->inclusive = FALSE; | |
6109 if (curwin->w_p_wrap && curwin->w_width != 0) | |
6110 { | |
6111 int width1 = curwin->w_width - curwin_col_off(); | |
6112 int width2 = width1 + curwin_col_off2(); | |
6113 | |
6114 validate_virtcol(); | |
6115 i = 0; | |
6116 if (curwin->w_virtcol >= (colnr_T)width1 && width2 > 0) | |
6117 i = (curwin->w_virtcol - width1) / width2 * width2 + width1; | |
6118 } | |
6119 else | |
6120 i = curwin->w_leftcol; | |
6121 // Go to the middle of the screen line. When 'number' or | |
6122 // 'relativenumber' is on and lines are wrapping the middle can be more | |
6123 // to the left. | |
6124 if (cap->nchar == 'm') | |
6125 i += (curwin->w_width - curwin_col_off() | |
6126 + ((curwin->w_p_wrap && i > 0) | |
6127 ? curwin_col_off2() : 0)) / 2; | |
6128 coladvance((colnr_T)i); | |
6129 if (flag) | |
6130 { | |
6131 do | |
6132 i = gchar_cursor(); | |
6133 while (VIM_ISWHITE(i) && oneright() == OK); | |
6134 curwin->w_valid &= ~VALID_WCOL; | |
6135 } | |
6136 curwin->w_set_curswant = TRUE; | |
6137 break; | 6271 break; |
6138 | 6272 |
6139 case 'M': | 6273 case 'M': |
6140 { | 6274 { |
6141 oap->motion_type = MCHAR; | 6275 oap->motion_type = MCHAR; |
6147 coladvance((colnr_T)(i / 2)); | 6281 coladvance((colnr_T)(i / 2)); |
6148 curwin->w_set_curswant = TRUE; | 6282 curwin->w_set_curswant = TRUE; |
6149 } | 6283 } |
6150 break; | 6284 break; |
6151 | 6285 |
6286 // "g_": to the last non-blank character in the line or <count> lines | |
6287 // downward. | |
6152 case '_': | 6288 case '_': |
6153 // "g_": to the last non-blank character in the line or <count> lines | 6289 nv_g_underscore_cmd(cap); |
6154 // downward. | |
6155 cap->oap->motion_type = MCHAR; | |
6156 cap->oap->inclusive = TRUE; | |
6157 curwin->w_curswant = MAXCOL; | |
6158 if (cursor_down((long)(cap->count1 - 1), | |
6159 cap->oap->op_type == OP_NOP) == FAIL) | |
6160 clearopbeep(cap->oap); | |
6161 else | |
6162 { | |
6163 char_u *ptr = ml_get_curline(); | |
6164 | |
6165 // In Visual mode we may end up after the line. | |
6166 if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL) | |
6167 --curwin->w_cursor.col; | |
6168 | |
6169 // Decrease the cursor column until it's on a non-blank. | |
6170 while (curwin->w_cursor.col > 0 | |
6171 && VIM_ISWHITE(ptr[curwin->w_cursor.col])) | |
6172 --curwin->w_cursor.col; | |
6173 curwin->w_set_curswant = TRUE; | |
6174 adjust_for_sel(cap); | |
6175 } | |
6176 break; | 6290 break; |
6177 | 6291 |
6292 // "g$" : Like "$" but for screen lines. | |
6178 case '$': | 6293 case '$': |
6179 case K_END: | 6294 case K_END: |
6180 case K_KEND: | 6295 case K_KEND: |
6181 { | 6296 nv_g_dollar_cmd(cap); |
6182 int col_off = curwin_col_off(); | |
6183 | |
6184 oap->motion_type = MCHAR; | |
6185 oap->inclusive = TRUE; | |
6186 if (curwin->w_p_wrap && curwin->w_width != 0) | |
6187 { | |
6188 curwin->w_curswant = MAXCOL; // so we stay at the end | |
6189 if (cap->count1 == 1) | |
6190 { | |
6191 int width1 = curwin->w_width - col_off; | |
6192 int width2 = width1 + curwin_col_off2(); | |
6193 | |
6194 validate_virtcol(); | |
6195 i = width1 - 1; | |
6196 if (curwin->w_virtcol >= (colnr_T)width1) | |
6197 i += ((curwin->w_virtcol - width1) / width2 + 1) | |
6198 * width2; | |
6199 coladvance((colnr_T)i); | |
6200 | |
6201 // Make sure we stick in this column. | |
6202 validate_virtcol(); | |
6203 curwin->w_curswant = curwin->w_virtcol; | |
6204 curwin->w_set_curswant = FALSE; | |
6205 if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) | |
6206 { | |
6207 /* | |
6208 * Check for landing on a character that got split at | |
6209 * the end of the line. We do not want to advance to | |
6210 * the next screen line. | |
6211 */ | |
6212 if (curwin->w_virtcol > (colnr_T)i) | |
6213 --curwin->w_cursor.col; | |
6214 } | |
6215 } | |
6216 else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == FAIL) | |
6217 clearopbeep(oap); | |
6218 } | |
6219 else | |
6220 { | |
6221 if (cap->count1 > 1) | |
6222 // if it fails, let the cursor still move to the last char | |
6223 (void)cursor_down(cap->count1 - 1, FALSE); | |
6224 | |
6225 i = curwin->w_leftcol + curwin->w_width - col_off - 1; | |
6226 coladvance((colnr_T)i); | |
6227 | |
6228 // if the character doesn't fit move one back | |
6229 if (curwin->w_cursor.col > 0 | |
6230 && (*mb_ptr2cells)(ml_get_cursor()) > 1) | |
6231 { | |
6232 colnr_T vcol; | |
6233 | |
6234 getvvcol(curwin, &curwin->w_cursor, NULL, NULL, &vcol); | |
6235 if (vcol >= curwin->w_leftcol + curwin->w_width - col_off) | |
6236 --curwin->w_cursor.col; | |
6237 } | |
6238 | |
6239 // Make sure we stick in this column. | |
6240 validate_virtcol(); | |
6241 curwin->w_curswant = curwin->w_virtcol; | |
6242 curwin->w_set_curswant = FALSE; | |
6243 } | |
6244 } | |
6245 break; | 6297 break; |
6246 | 6298 |
6247 /* | 6299 // "g*" and "g#", like "*" and "#" but without using "\<" and "\>" |
6248 * "g*" and "g#", like "*" and "#" but without using "\<" and "\>" | |
6249 */ | |
6250 case '*': | 6300 case '*': |
6251 case '#': | 6301 case '#': |
6252 #if POUND != '#' | 6302 #if POUND != '#' |
6253 case POUND: // pound sign (sometimes equal to '#') | 6303 case POUND: // pound sign (sometimes equal to '#') |
6254 #endif | 6304 #endif |
6255 case Ctrl_RSB: // :tag or :tselect for current identifier | 6305 case Ctrl_RSB: // :tag or :tselect for current identifier |
6256 case ']': // :tselect for current identifier | 6306 case ']': // :tselect for current identifier |
6257 nv_ident(cap); | 6307 nv_ident(cap); |
6258 break; | 6308 break; |
6259 | 6309 |
6260 /* | 6310 // ge and gE: go back to end of word |
6261 * ge and gE: go back to end of word | |
6262 */ | |
6263 case 'e': | 6311 case 'e': |
6264 case 'E': | 6312 case 'E': |
6265 oap->motion_type = MCHAR; | 6313 oap->motion_type = MCHAR; |
6266 curwin->w_set_curswant = TRUE; | 6314 curwin->w_set_curswant = TRUE; |
6267 oap->inclusive = TRUE; | 6315 oap->inclusive = TRUE; |
6268 if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL) | 6316 if (bckend_word(cap->count1, cap->nchar == 'E', FALSE) == FAIL) |
6269 clearopbeep(oap); | 6317 clearopbeep(oap); |
6270 break; | 6318 break; |
6271 | 6319 |
6272 /* | 6320 // "g CTRL-G": display info about cursor position |
6273 * "g CTRL-G": display info about cursor position | |
6274 */ | |
6275 case Ctrl_G: | 6321 case Ctrl_G: |
6276 cursor_pos_info(NULL); | 6322 cursor_pos_info(NULL); |
6277 break; | 6323 break; |
6278 | 6324 |
6279 /* | 6325 // "gi": start Insert at the last position. |
6280 * "gi": start Insert at the last position. | |
6281 */ | |
6282 case 'i': | 6326 case 'i': |
6283 if (curbuf->b_last_insert.lnum != 0) | 6327 nv_gi_cmd(cap); |
6284 { | |
6285 curwin->w_cursor = curbuf->b_last_insert; | |
6286 check_cursor_lnum(); | |
6287 i = (int)STRLEN(ml_get_curline()); | |
6288 if (curwin->w_cursor.col > (colnr_T)i) | |
6289 { | |
6290 if (virtual_active()) | |
6291 curwin->w_cursor.coladd += curwin->w_cursor.col - i; | |
6292 curwin->w_cursor.col = i; | |
6293 } | |
6294 } | |
6295 cap->cmdchar = 'i'; | |
6296 nv_edit(cap); | |
6297 break; | 6328 break; |
6298 | 6329 |
6299 /* | 6330 // "gI": Start insert in column 1. |
6300 * "gI": Start insert in column 1. | |
6301 */ | |
6302 case 'I': | 6331 case 'I': |
6303 beginline(0); | 6332 beginline(0); |
6304 if (!checkclearopq(oap)) | 6333 if (!checkclearopq(oap)) |
6305 invoke_edit(cap, FALSE, 'g', FALSE); | 6334 invoke_edit(cap, FALSE, 'g', FALSE); |
6306 break; | 6335 break; |
6307 | 6336 |
6308 #ifdef FEAT_SEARCHPATH | 6337 #ifdef FEAT_SEARCHPATH |
6309 /* | 6338 // "gf": goto file, edit file under cursor |
6310 * "gf": goto file, edit file under cursor | 6339 // "]f" and "[f": can also be used. |
6311 * "]f" and "[f": can also be used. | |
6312 */ | |
6313 case 'f': | 6340 case 'f': |
6314 case 'F': | 6341 case 'F': |
6315 nv_gotofile(cap); | 6342 nv_gotofile(cap); |
6316 break; | 6343 break; |
6317 #endif | 6344 #endif |
6318 | 6345 |
6319 // "g'm" and "g`m": jump to mark without setting pcmark | 6346 // "g'm" and "g`m": jump to mark without setting pcmark |
6320 case '\'': | 6347 case '\'': |
6321 cap->arg = TRUE; | 6348 cap->arg = TRUE; |
6322 // FALLTHROUGH | 6349 // FALLTHROUGH |
6323 case '`': | 6350 case '`': |
6324 nv_gomark(cap); | 6351 nv_gomark(cap); |
6325 break; | 6352 break; |
6326 | 6353 |
6327 /* | 6354 // "gs": Goto sleep. |
6328 * "gs": Goto sleep. | |
6329 */ | |
6330 case 's': | 6355 case 's': |
6331 do_sleep(cap->count1 * 1000L, FALSE); | 6356 do_sleep(cap->count1 * 1000L, FALSE); |
6332 break; | 6357 break; |
6333 | 6358 |
6334 /* | 6359 // "ga": Display the ascii value of the character under the |
6335 * "ga": Display the ascii value of the character under the | 6360 // cursor. It is displayed in decimal, hex, and octal. -- webb |
6336 * cursor. It is displayed in decimal, hex, and octal. -- webb | |
6337 */ | |
6338 case 'a': | 6361 case 'a': |
6339 do_ascii(NULL); | 6362 do_ascii(NULL); |
6340 break; | 6363 break; |
6341 | 6364 |
6342 /* | 6365 // "g8": Display the bytes used for the UTF-8 character under the |
6343 * "g8": Display the bytes used for the UTF-8 character under the | 6366 // cursor. It is displayed in hex. |
6344 * cursor. It is displayed in hex. | 6367 // "8g8" finds illegal byte sequence. |
6345 * "8g8" finds illegal byte sequence. | |
6346 */ | |
6347 case '8': | 6368 case '8': |
6348 if (cap->count0 == 8) | 6369 if (cap->count0 == 8) |
6349 utf_find_illegal(); | 6370 utf_find_illegal(); |
6350 else | 6371 else |
6351 show_utf8(); | 6372 show_utf8(); |
6354 // "g<": show scrollback text | 6375 // "g<": show scrollback text |
6355 case '<': | 6376 case '<': |
6356 show_sb_text(); | 6377 show_sb_text(); |
6357 break; | 6378 break; |
6358 | 6379 |
6359 /* | 6380 // "gg": Goto the first line in file. With a count it goes to |
6360 * "gg": Goto the first line in file. With a count it goes to | 6381 // that line number like for "G". -- webb |
6361 * that line number like for "G". -- webb | |
6362 */ | |
6363 case 'g': | 6382 case 'g': |
6364 cap->arg = FALSE; | 6383 cap->arg = FALSE; |
6365 nv_goto(cap); | 6384 nv_goto(cap); |
6366 break; | 6385 break; |
6367 | 6386 |
6368 /* | 6387 // Two-character operators: |
6369 * Two-character operators: | 6388 // "gq" Format text |
6370 * "gq" Format text | 6389 // "gw" Format text and keep cursor position |
6371 * "gw" Format text and keep cursor position | 6390 // "g~" Toggle the case of the text. |
6372 * "g~" Toggle the case of the text. | 6391 // "gu" Change text to lower case. |
6373 * "gu" Change text to lower case. | 6392 // "gU" Change text to upper case. |
6374 * "gU" Change text to upper case. | 6393 // "g?" rot13 encoding |
6375 * "g?" rot13 encoding | 6394 // "g@" call 'operatorfunc' |
6376 * "g@" call 'operatorfunc' | |
6377 */ | |
6378 case 'q': | 6395 case 'q': |
6379 case 'w': | 6396 case 'w': |
6380 oap->cursor_start = curwin->w_cursor; | 6397 oap->cursor_start = curwin->w_cursor; |
6381 // FALLTHROUGH | 6398 // FALLTHROUGH |
6382 case '~': | 6399 case '~': |
6385 case '?': | 6402 case '?': |
6386 case '@': | 6403 case '@': |
6387 nv_operator(cap); | 6404 nv_operator(cap); |
6388 break; | 6405 break; |
6389 | 6406 |
6390 /* | 6407 // "gd": Find first occurrence of pattern under the cursor in the |
6391 * "gd": Find first occurrence of pattern under the cursor in the | 6408 // current function |
6392 * current function | 6409 // "gD": idem, but in the current file. |
6393 * "gD": idem, but in the current file. | |
6394 */ | |
6395 case 'd': | 6410 case 'd': |
6396 case 'D': | 6411 case 'D': |
6397 nv_gd(oap, cap->nchar, (int)cap->count0); | 6412 nv_gd(oap, cap->nchar, (int)cap->count0); |
6398 break; | 6413 break; |
6399 | 6414 |
6400 /* | 6415 // g<*Mouse> : <C-*mouse> |
6401 * g<*Mouse> : <C-*mouse> | |
6402 */ | |
6403 case K_MIDDLEMOUSE: | 6416 case K_MIDDLEMOUSE: |
6404 case K_MIDDLEDRAG: | 6417 case K_MIDDLEDRAG: |
6405 case K_MIDDLERELEASE: | 6418 case K_MIDDLERELEASE: |
6406 case K_LEFTMOUSE: | 6419 case K_LEFTMOUSE: |
6407 case K_LEFTDRAG: | 6420 case K_LEFTDRAG: |
6421 break; | 6434 break; |
6422 | 6435 |
6423 case K_IGNORE: | 6436 case K_IGNORE: |
6424 break; | 6437 break; |
6425 | 6438 |
6426 /* | 6439 // "gP" and "gp": same as "P" and "p" but leave cursor just after new text |
6427 * "gP" and "gp": same as "P" and "p" but leave cursor just after new text | |
6428 */ | |
6429 case 'p': | 6440 case 'p': |
6430 case 'P': | 6441 case 'P': |
6431 nv_put(cap); | 6442 nv_put(cap); |
6432 break; | 6443 break; |
6433 | 6444 |