comparison src/ex_getln.c @ 29964:444dd4cc49d6 v9.0.0320

patch 9.0.0320: command line type of CmdlineChange differs from getcmdtype() Commit: https://github.com/vim/vim/commit/54acb90d9e672315e3bd13f8dc71f828df97c868 Author: zeertzjq <zeertzjq@outlook.com> Date: Mon Aug 29 16:21:25 2022 +0100 patch 9.0.0320: command line type of CmdlineChange differs from getcmdtype() Problem: Command line type of CmdlineChange differs from getcmdtype(). Solution: Use the same type. (closes https://github.com/vim/vim/issues/11005)
author Bram Moolenaar <Bram@vim.org>
date Mon, 29 Aug 2022 17:30:03 +0200
parents 4fcf816aa806
children 5dfd4bd66ad8
comparison
equal deleted inserted replaced
29963:ee373646730e 29964:444dd4cc49d6
4112 return &prev_ccline; 4112 return &prev_ccline;
4113 return NULL; 4113 return NULL;
4114 } 4114 }
4115 #endif 4115 #endif
4116 4116
4117 #if defined(FEAT_EVAL) || defined(PROTO)
4118 /*
4119 * Get the current command line in allocated memory.
4120 * Only works when the command line is being edited.
4121 * Returns NULL when something is wrong.
4122 */
4123 static char_u *
4124 get_cmdline_str(void)
4125 {
4126 cmdline_info_T *p;
4127
4128 if (cmdline_star > 0)
4129 return NULL;
4130 p = get_ccline_ptr();
4131 if (p == NULL)
4132 return NULL;
4133 return vim_strnsave(p->cmdbuff, p->cmdlen);
4134 }
4135
4136 /*
4137 * Get the current command-line completion type.
4138 */
4139 static char_u *
4140 get_cmdline_completion(void)
4141 {
4142 cmdline_info_T *p;
4143
4144 if (cmdline_star > 0)
4145 return NULL;
4146
4147 p = get_ccline_ptr();
4148 if (p != NULL && p->xpc != NULL)
4149 {
4150 char_u *cmd_compl;
4151
4152 set_expand_context(p->xpc);
4153
4154 cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context);
4155 if (cmd_compl != NULL)
4156 return vim_strsave(cmd_compl);
4157 }
4158
4159 return NULL;
4160 }
4161
4162 /*
4163 * "getcmdcompltype()" function
4164 */
4165 void
4166 f_getcmdcompltype(typval_T *argvars UNUSED, typval_T *rettv)
4167 {
4168 rettv->v_type = VAR_STRING;
4169 rettv->vval.v_string = get_cmdline_completion();
4170 }
4171
4172 /*
4173 * "getcmdline()" function
4174 */
4175 void
4176 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
4177 {
4178 rettv->v_type = VAR_STRING;
4179 rettv->vval.v_string = get_cmdline_str();
4180 }
4181
4182 /*
4183 * "getcmdpos()" function
4184 */
4185 void
4186 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
4187 {
4188 cmdline_info_T *p = get_ccline_ptr();
4189
4190 rettv->vval.v_number = 0;
4191 if (p != NULL)
4192 rettv->vval.v_number = p->cmdpos + 1;
4193 }
4194
4195 /*
4196 * Get the command line cursor screen position.
4197 */
4198 static int
4199 get_cmdline_screen_pos(void)
4200 {
4201 cmdline_info_T *p = get_ccline_ptr();
4202
4203 if (p == NULL)
4204 return -1;
4205 return p->cmdspos;
4206 }
4207
4208 /*
4209 * "getcmdscreenpos()" function
4210 */
4211 void
4212 f_getcmdscreenpos(typval_T *argvars UNUSED, typval_T *rettv)
4213 {
4214 rettv->vval.v_number = get_cmdline_screen_pos() + 1;
4215 }
4216
4217 // Set the command line str to "str".
4218 // Returns 1 when failed, 0 when OK.
4219 int
4220 set_cmdline_str(char_u *str, int pos)
4221 {
4222 cmdline_info_T *p = get_ccline_ptr();
4223 int cmdline_type;
4224 int len;
4225
4226 if (p == NULL)
4227 return 1;
4228
4229 len = (int)STRLEN(str);
4230 realloc_cmdbuff(len + 1);
4231 p->cmdlen = len;
4232 STRCPY(p->cmdbuff, str);
4233
4234 p->cmdpos = pos < 0 || pos > p->cmdlen ? p->cmdlen : pos;
4235 new_cmdpos = p->cmdpos;
4236
4237 redrawcmd();
4238
4239 // Trigger CmdlineChanged autocommands.
4240 cmdline_type = ccline.cmdfirstc == NUL ? '-' : ccline.cmdfirstc;
4241 trigger_cmd_autocmd(cmdline_type, EVENT_CMDLINECHANGED);
4242
4243 return 0;
4244 }
4245
4246 /*
4247 * Set the command line byte position to "pos". Zero is the first position.
4248 * Only works when the command line is being edited.
4249 * Returns 1 when failed, 0 when OK.
4250 */
4251 static int
4252 set_cmdline_pos(
4253 int pos)
4254 {
4255 cmdline_info_T *p = get_ccline_ptr();
4256
4257 if (p == NULL)
4258 return 1;
4259
4260 // The position is not set directly but after CTRL-\ e or CTRL-R = has
4261 // changed the command line.
4262 if (pos < 0)
4263 new_cmdpos = 0;
4264 else
4265 new_cmdpos = pos;
4266 return 0;
4267 }
4268
4269 // "setcmdline()" function
4270 void
4271 f_setcmdline(typval_T *argvars, typval_T *rettv)
4272 {
4273 int pos = -1;
4274
4275 if (check_for_string_arg(argvars, 0) == FAIL
4276 || check_for_opt_number_arg(argvars, 1) == FAIL)
4277 return;
4278
4279 if (argvars[1].v_type != VAR_UNKNOWN)
4280 {
4281 int error = FALSE;
4282
4283 pos = (int)tv_get_number_chk(&argvars[1], &error) - 1;
4284 if (error)
4285 return;
4286 if (pos < 0)
4287 {
4288 emsg(_(e_argument_must_be_positive));
4289 return;
4290 }
4291 }
4292
4293 rettv->vval.v_number = set_cmdline_str(argvars[0].vval.v_string, pos);
4294 }
4295
4296 /*
4297 * "setcmdpos()" function
4298 */
4299 void
4300 f_setcmdpos(typval_T *argvars, typval_T *rettv)
4301 {
4302 int pos;
4303
4304 if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
4305 return;
4306
4307 pos = (int)tv_get_number(&argvars[0]) - 1;
4308 if (pos >= 0)
4309 rettv->vval.v_number = set_cmdline_pos(pos);
4310 }
4311 #endif
4312
4313 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) 4117 #if defined(FEAT_EVAL) || defined(FEAT_CMDWIN)
4314 /* 4118 /*
4315 * Get the current command-line type. 4119 * Get the current command-line type.
4316 * Returns ':' or '/' or '?' or '@' or '>' or '-' 4120 * Returns ':' or '/' or '?' or '@' or '>' or '-'
4317 * Only works when the command line is being edited. 4121 * Only works when the command line is being edited.
4334 } 4138 }
4335 #endif 4139 #endif
4336 4140
4337 #if defined(FEAT_EVAL) || defined(PROTO) 4141 #if defined(FEAT_EVAL) || defined(PROTO)
4338 /* 4142 /*
4143 * Get the current command line in allocated memory.
4144 * Only works when the command line is being edited.
4145 * Returns NULL when something is wrong.
4146 */
4147 static char_u *
4148 get_cmdline_str(void)
4149 {
4150 cmdline_info_T *p;
4151
4152 if (cmdline_star > 0)
4153 return NULL;
4154 p = get_ccline_ptr();
4155 if (p == NULL)
4156 return NULL;
4157 return vim_strnsave(p->cmdbuff, p->cmdlen);
4158 }
4159
4160 /*
4161 * Get the current command-line completion type.
4162 */
4163 static char_u *
4164 get_cmdline_completion(void)
4165 {
4166 cmdline_info_T *p;
4167
4168 if (cmdline_star > 0)
4169 return NULL;
4170
4171 p = get_ccline_ptr();
4172 if (p != NULL && p->xpc != NULL)
4173 {
4174 char_u *cmd_compl;
4175
4176 set_expand_context(p->xpc);
4177
4178 cmd_compl = cmdcomplete_type_to_str(p->xpc->xp_context);
4179 if (cmd_compl != NULL)
4180 return vim_strsave(cmd_compl);
4181 }
4182
4183 return NULL;
4184 }
4185
4186 /*
4187 * "getcmdcompltype()" function
4188 */
4189 void
4190 f_getcmdcompltype(typval_T *argvars UNUSED, typval_T *rettv)
4191 {
4192 rettv->v_type = VAR_STRING;
4193 rettv->vval.v_string = get_cmdline_completion();
4194 }
4195
4196 /*
4197 * "getcmdline()" function
4198 */
4199 void
4200 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
4201 {
4202 rettv->v_type = VAR_STRING;
4203 rettv->vval.v_string = get_cmdline_str();
4204 }
4205
4206 /*
4207 * "getcmdpos()" function
4208 */
4209 void
4210 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
4211 {
4212 cmdline_info_T *p = get_ccline_ptr();
4213
4214 rettv->vval.v_number = p != NULL ? p->cmdpos + 1 : 0;
4215 }
4216
4217 /*
4218 * "getcmdscreenpos()" function
4219 */
4220 void
4221 f_getcmdscreenpos(typval_T *argvars UNUSED, typval_T *rettv)
4222 {
4223 cmdline_info_T *p = get_ccline_ptr();
4224
4225 rettv->vval.v_number = p != NULL ? p->cmdspos + 1 : 0;
4226 }
4227
4228 /*
4339 * "getcmdtype()" function 4229 * "getcmdtype()" function
4340 */ 4230 */
4341 void 4231 void
4342 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv) 4232 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv)
4343 { 4233 {
4348 rettv->vval.v_string[0] = get_cmdline_type(); 4238 rettv->vval.v_string[0] = get_cmdline_type();
4349 rettv->vval.v_string[1] = NUL; 4239 rettv->vval.v_string[1] = NUL;
4350 } 4240 }
4351 } 4241 }
4352 4242
4243 // Set the command line str to "str".
4244 // Returns 1 when failed, 0 when OK.
4245 static int
4246 set_cmdline_str(char_u *str, int pos)
4247 {
4248 cmdline_info_T *p = get_ccline_ptr();
4249 int len;
4250
4251 if (p == NULL)
4252 return 1;
4253
4254 len = (int)STRLEN(str);
4255 realloc_cmdbuff(len + 1);
4256 p->cmdlen = len;
4257 STRCPY(p->cmdbuff, str);
4258
4259 p->cmdpos = pos < 0 || pos > p->cmdlen ? p->cmdlen : pos;
4260 new_cmdpos = p->cmdpos;
4261
4262 redrawcmd();
4263
4264 // Trigger CmdlineChanged autocommands.
4265 trigger_cmd_autocmd(get_cmdline_type(), EVENT_CMDLINECHANGED);
4266
4267 return 0;
4268 }
4269
4270 /*
4271 * Set the command line byte position to "pos". Zero is the first position.
4272 * Only works when the command line is being edited.
4273 * Returns 1 when failed, 0 when OK.
4274 */
4275 static int
4276 set_cmdline_pos(
4277 int pos)
4278 {
4279 cmdline_info_T *p = get_ccline_ptr();
4280
4281 if (p == NULL)
4282 return 1;
4283
4284 // The position is not set directly but after CTRL-\ e or CTRL-R = has
4285 // changed the command line.
4286 if (pos < 0)
4287 new_cmdpos = 0;
4288 else
4289 new_cmdpos = pos;
4290 return 0;
4291 }
4292
4293 // "setcmdline()" function
4294 void
4295 f_setcmdline(typval_T *argvars, typval_T *rettv)
4296 {
4297 int pos = -1;
4298
4299 if (check_for_string_arg(argvars, 0) == FAIL
4300 || check_for_opt_number_arg(argvars, 1) == FAIL)
4301 return;
4302
4303 if (argvars[1].v_type != VAR_UNKNOWN)
4304 {
4305 int error = FALSE;
4306
4307 pos = (int)tv_get_number_chk(&argvars[1], &error) - 1;
4308 if (error)
4309 return;
4310 if (pos < 0)
4311 {
4312 emsg(_(e_argument_must_be_positive));
4313 return;
4314 }
4315 }
4316
4317 rettv->vval.v_number = set_cmdline_str(argvars[0].vval.v_string, pos);
4318 }
4319
4320 /*
4321 * "setcmdpos()" function
4322 */
4323 void
4324 f_setcmdpos(typval_T *argvars, typval_T *rettv)
4325 {
4326 int pos;
4327
4328 if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
4329 return;
4330
4331 pos = (int)tv_get_number(&argvars[0]) - 1;
4332 if (pos >= 0)
4333 rettv->vval.v_number = set_cmdline_pos(pos);
4334 }
4353 #endif 4335 #endif
4354 4336
4355 /* 4337 /*
4356 * Return the first character of the current command line. 4338 * Return the first character of the current command line.
4357 */ 4339 */