diff options
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r-- | src/nvim/ex_docmd.c | 273 |
1 files changed, 159 insertions, 114 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3a24f194c1..870284a0f7 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1654,16 +1654,15 @@ static char_u * do_one_cmd(char_u **cmdlinep, * If we got a line, but no command, then go to the line. * If we find a '|' or '\n' we set ea.nextcmd. */ - if (*ea.cmd == NUL || *ea.cmd == '"' || - (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { - /* - * strange vi behaviour: - * ":3" jumps to line 3 - * ":3|..." prints line 3 - * ":|" prints current line - */ - if (ea.skip) /* skip this if inside :if */ + if (*ea.cmd == NUL || *ea.cmd == '"' + || (ea.nextcmd = check_nextcmd(ea.cmd)) != NULL) { + // strange vi behaviour: + // ":3" jumps to line 3 + // ":3|..." prints line 3 + // ":|" prints current line + if (ea.skip) { // skip this if inside :if goto doend; + } if (*ea.cmd == '|' || (exmode_active && ea.line1 != ea.line2)) { ea.cmdidx = CMD_print; ea.argt = RANGE | COUNT | TRLBAR; @@ -1826,9 +1825,10 @@ static char_u * do_one_cmd(char_u **cmdlinep, correct_range(&ea); - if (((ea.argt & WHOLEFOLD) || ea.addr_count >= 2) && !global_busy) { - /* Put the first line at the start of a closed fold, put the last line - * at the end of a closed fold. */ + if (((ea.argt & WHOLEFOLD) || ea.addr_count >= 2) && !global_busy + && ea.addr_type == ADDR_LINES) { + // Put the first line at the start of a closed fold, put the last line + // at the end of a closed fold. (void)hasFolding(ea.line1, &ea.line1, NULL); (void)hasFolding(ea.line2, NULL, &ea.line2); } @@ -2823,10 +2823,11 @@ set_one_cmd_context ( } } - /* no arguments allowed */ - if (!(ea.argt & EXTRA) && *arg != NUL && - vim_strchr((char_u *)"|\"", *arg) == NULL) + // no arguments allowed + if (!(ea.argt & EXTRA) && *arg != NUL + && vim_strchr((char_u *)"|\"", *arg) == NULL) { return NULL; + } /* Find start of last argument (argument just before cursor): */ p = buff; @@ -2958,8 +2959,11 @@ set_one_cmd_context ( case CMD_chdir: case CMD_lcd: case CMD_lchdir: - if (xp->xp_context == EXPAND_FILES) + case CMD_tcd: + case CMD_tchdir: + if (xp->xp_context == EXPAND_FILES) { xp->xp_context = EXPAND_DIRECTORIES; + } break; case CMD_help: xp->xp_context = EXPAND_HELP; @@ -4553,7 +4557,8 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep, char_u *rep_buf = NULL; garray_T *gap; - replace_termcodes(rep, &rep_buf, FALSE, FALSE, FALSE); + replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, false, + CPO_TO_CPO_FLAGS); if (rep_buf == NULL) { /* Can't replace termcodes - try using the string as is */ rep_buf = vim_strsave(rep); @@ -4767,14 +4772,15 @@ static void uc_list(char_u *name, size_t name_len) IObuff[len++] = ' '; } while (len < 11); - /* Address Type */ - for (j = 0; addr_type_complete[j].expand != -1; ++j) - if (addr_type_complete[j].expand != ADDR_LINES && - addr_type_complete[j].expand == cmd->uc_addr_type) { + // Address Type + for (j = 0; addr_type_complete[j].expand != -1; j++) { + if (addr_type_complete[j].expand != ADDR_LINES + && addr_type_complete[j].expand == cmd->uc_addr_type) { STRCPY(IObuff + len, addr_type_complete[j].name); len += (int)STRLEN(IObuff + len); break; } + } do { IObuff[len++] = ' '; @@ -5499,7 +5505,8 @@ int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt, int *addr_type_arg) { int i, a, b; - for (i = 0; addr_type_complete[i].expand != -1; ++i) { + + for (i = 0; addr_type_complete[i].expand != -1; i++) { a = (int)STRLEN(addr_type_complete[i].name) == vallen; b = STRNCMP(value, addr_type_complete[i].name, vallen) == 0; if (a && b) { @@ -5510,8 +5517,8 @@ int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt, if (addr_type_complete[i].expand == -1) { char_u *err = value; - for (i = 0; err[i] == NUL || !ascii_iswhite(err[i]); i++) - ; + + for (i = 0; err[i] != NUL && !ascii_iswhite(err[i]); i++) {} err[i] = NUL; EMSG2(_("E180: Invalid address type value: %s"), err); return FAIL; @@ -5648,12 +5655,13 @@ static void ex_quit(exarg_T *eap) wp = curwin; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf); - /* Refuse to quit when locked or when the buffer in the last window is - * being closed (can only happen in autocommands). */ - if (curbuf_locked() || - (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_closing)) + apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, curbuf); + // Refuse to quit when locked or when the buffer in the last window is + // being closed (can only happen in autocommands). + if (curbuf_locked() + || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_closing)) { return; + } /* @@ -5663,10 +5671,10 @@ static void ex_quit(exarg_T *eap) exiting = TRUE; if ((!P_HID(curbuf) && check_changed(curbuf, (p_awa ? CCGD_AW : 0) - | (eap->forceit ? CCGD_FORCEIT : 0) - | CCGD_EXCMD)) - || check_more(TRUE, eap->forceit) == FAIL - || (only_one_window() && check_changed_any(eap->forceit))) { + | (eap->forceit ? CCGD_FORCEIT : 0) + | CCGD_EXCMD)) + || check_more(true, eap->forceit) == FAIL + || (only_one_window() && check_changed_any(eap->forceit, true))) { not_exiting(); } else { // quit last window @@ -5715,9 +5723,10 @@ static void ex_quit_all(exarg_T *eap) if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing)) return; - exiting = TRUE; - if (eap->forceit || !check_changed_any(FALSE)) + exiting = true; + if (eap->forceit || !check_changed_any(false, false)) { getout(0); + } not_exiting(); } @@ -6002,21 +6011,22 @@ static void ex_exit(exarg_T *eap) if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing)) return; - /* - * if more files or windows we won't exit - */ - if (check_more(FALSE, eap->forceit) == OK && only_one_window()) - exiting = TRUE; - if ( ((eap->cmdidx == CMD_wq - || curbufIsChanged()) - && do_write(eap) == FAIL) - || check_more(TRUE, eap->forceit) == FAIL - || (only_one_window() && check_changed_any(eap->forceit))) { + // if more files or windows we won't exit + if (check_more(false, eap->forceit) == OK && only_one_window()) { + exiting = true; + } + if (((eap->cmdidx == CMD_wq + || curbufIsChanged()) + && do_write(eap) == FAIL) + || check_more(true, eap->forceit) == FAIL + || (only_one_window() && check_changed_any(eap->forceit, false))) { not_exiting(); } else { - if (only_one_window()) /* quit last window, exit Vim */ + if (only_one_window()) { + // quit last window, exit Vim getout(0); - /* Quit current window, may free the buffer. */ + } + // Quit current window, may free the buffer. win_close(curwin, !P_HID(curwin->w_buffer)); } } @@ -6290,10 +6300,8 @@ void ex_splitview(exarg_T *eap) if (eap->cmdidx == CMD_tabedit || eap->cmdidx == CMD_tabfind || eap->cmdidx == CMD_tabnew) { - if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab - : eap->addr_count == 0 ? 0 - : (int)eap->line2 + 1) != FAIL) { - apply_autocmds(EVENT_TABNEW, eap->arg, eap->arg, FALSE, curbuf); + if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab : eap->addr_count == 0 + ? 0 : (int)eap->line2 + 1, eap->arg) != FAIL) { do_exedit(eap, old_curwin); apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, FALSE, curbuf); @@ -6816,36 +6824,55 @@ void free_cd_dir(void) #endif -/* - * Deal with the side effects of changing the current directory. - * When "local" is TRUE then this was after an ":lcd" command. - */ -void post_chdir(int local) +/// Deal with the side effects of changing the current directory. +/// +/// @param scope Scope of the function call (global, tab or window). +void post_chdir(CdScope scope) { + // The local directory of the current window is always overwritten. xfree(curwin->w_localdir); curwin->w_localdir = NULL; - if (local) { - /* If still in global directory, need to remember current - * directory as global directory. */ - if (globaldir == NULL && prev_dir != NULL) + + // Overwrite the local directory of the current tab page for `cd` and `tcd` + if (scope >= kCdScopeTab) { + xfree(curtab->localdir); + curtab->localdir = NULL; + } + + if (scope < kCdScopeGlobal) { + // If still in global directory, need to remember current directory as + // global directory. + if (globaldir == NULL && prev_dir != NULL) { globaldir = vim_strsave(prev_dir); - /* Remember this local directory for the window. */ - if (os_dirname(NameBuff, MAXPATHL) == OK) - curwin->w_localdir = vim_strsave(NameBuff); - } else { - /* We are now in the global directory, no need to remember its - * name. */ + } + } + + switch (scope) { + case kCdScopeGlobal: + // We are now in the global directory, no need to remember its name. xfree(globaldir); globaldir = NULL; + break; + case kCdScopeTab: + // Remember this local directory for the tab page. + if (os_dirname(NameBuff, MAXPATHL) == OK) { + curtab->localdir = vim_strsave(NameBuff); + } + break; + case kCdScopeWindow: + // Remember this local directory for the window. + if (os_dirname(NameBuff, MAXPATHL) == OK) { + curwin->w_localdir = vim_strsave(NameBuff); + } + break; } shorten_fnames(TRUE); } -/* - * ":cd", ":lcd", ":chdir" and ":lchdir". - */ + +/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. void ex_cd(exarg_T *eap) { char_u *new_dir; @@ -6886,10 +6913,25 @@ void ex_cd(exarg_T *eap) new_dir = NameBuff; } #endif - if (new_dir == NULL || vim_chdir(new_dir)) + if (vim_chdir(new_dir)) { EMSG(_(e_failed)); - else { - post_chdir(eap->cmdidx == CMD_lcd || eap->cmdidx == CMD_lchdir); + } else { + CdScope scope = kCdScopeGlobal; // Depends on command invoked + + switch (eap->cmdidx) { + case CMD_tcd: + case CMD_tchdir: + scope = kCdScopeTab; + break; + case CMD_lcd: + case CMD_lchdir: + scope = kCdScopeWindow; + break; + default: + break; + } + + post_chdir(scope); /* Echo the new current directory if the command was typed. */ if (KeyTyped || p_verbose >= 5) @@ -7033,9 +7075,9 @@ static void ex_operators(exarg_T *eap) oa.start.lnum = eap->line1; oa.end.lnum = eap->line2; oa.line_count = eap->line2 - eap->line1 + 1; - oa.motion_type = MLINE; - virtual_op = FALSE; - if (eap->cmdidx != CMD_yank) { /* position cursor for undo */ + oa.motion_type = kMTLineWise; + virtual_op = false; + if (eap->cmdidx != CMD_yank) { // position cursor for undo setpcmark(); curwin->w_cursor.lnum = eap->line1; beginline(BL_SOL | BL_FIX); @@ -7423,10 +7465,10 @@ static int mksession_nl = FALSE; /* use NL only in put_eol() */ static void ex_mkrc(exarg_T *eap) { FILE *fd; - int failed = FALSE; - int view_session = FALSE; - int using_vdir = FALSE; /* using 'viewdir'? */ - char_u *viewFile = NULL; + int failed = false; + int view_session = false; + int using_vdir = false; // using 'viewdir'? + char *viewFile = NULL; unsigned *flagp; if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) { @@ -7437,32 +7479,34 @@ static void ex_mkrc(exarg_T *eap) * short file name when 'acd' is set, that is checked later. */ did_lcd = FALSE; - char_u *fname; - /* ":mkview" or ":mkview 9": generate file name with 'viewdir' */ + char *fname; + // ":mkview" or ":mkview 9": generate file name with 'viewdir' if (eap->cmdidx == CMD_mkview && (*eap->arg == NUL || (ascii_isdigit(*eap->arg) && eap->arg[1] == NUL))) { - eap->forceit = TRUE; - fname = (char_u *)get_view_file(*eap->arg); - if (fname == NULL) + eap->forceit = true; + fname = get_view_file(*eap->arg); + if (fname == NULL) { return; + } viewFile = fname; - using_vdir = TRUE; - } else if (*eap->arg != NUL) - fname = eap->arg; - else if (eap->cmdidx == CMD_mkvimrc) - fname = (char_u *)VIMRC_FILE; - else if (eap->cmdidx == CMD_mksession) - fname = (char_u *)SESSION_FILE; - else - fname = (char_u *)EXRC_FILE; + using_vdir = true; + } else if (*eap->arg != NUL) { + fname = (char *) eap->arg; + } else if (eap->cmdidx == CMD_mkvimrc) { + fname = VIMRC_FILE; + } else if (eap->cmdidx == CMD_mksession) { + fname = SESSION_FILE; + } else { + fname = EXRC_FILE; + } /* When using 'viewdir' may have to create the directory. */ if (using_vdir && !os_isdir(p_vdir)) { vim_mkdir_emsg(p_vdir, 0755); } - fd = open_exfile(fname, eap->forceit, WRITEBIN); + fd = open_exfile((char_u *) fname, eap->forceit, WRITEBIN); if (fd != NULL) { if (eap->cmdidx == CMD_mkview) flagp = &vop_flags; @@ -7506,8 +7550,9 @@ static void ex_mkrc(exarg_T *eap) || os_chdir((char *)dirnow) != 0) *dirnow = NUL; if (*dirnow != NUL && (ssop_flags & SSOP_SESDIR)) { - if (vim_chdirfile(fname) == OK) - shorten_fnames(TRUE); + if (vim_chdirfile((char_u *) fname) == OK) { + shorten_fnames(true); + } } else if (*dirnow != NUL && (ssop_flags & SSOP_CURDIR) && globaldir != NULL) { if (os_chdir((char *)globaldir) == 0) @@ -7552,15 +7597,14 @@ static void ex_mkrc(exarg_T *eap) failed |= fclose(fd); - if (failed) + if (failed) { EMSG(_(e_write)); - else if (eap->cmdidx == CMD_mksession) { - /* successful session write - set this_session var */ - char_u *tbuf; - - tbuf = xmalloc(MAXPATHL); - if (vim_FullName((char *)fname, (char *)tbuf, MAXPATHL, FALSE) == OK) + } else if (eap->cmdidx == CMD_mksession) { + // successful session write - set this_session var + char *const tbuf = xmalloc(MAXPATHL); + if (vim_FullName(fname, tbuf, MAXPATHL, false) == OK) { set_vim_var_string(VV_THIS_SESSION, tbuf, -1); + } xfree(tbuf); } #ifdef MKSESSION_NL @@ -9145,16 +9189,15 @@ static char *get_view_file(int c) */ int put_eol(FILE *fd) { - if ( -#ifdef USE_CRNL - ( -# ifdef MKSESSION_NL - !mksession_nl && -# endif - (putc('\r', fd) < 0)) || +#if defined(USE_CRNL) && defined(MKSESSION_NL) + if ((!mksession_nl && putc('\r', fd) < 0) || putc('\n', fd) < 0) { +#elif defined(USE_CRNL) + if (putc('\r', fd) < 0 || putc('\n', fd) < 0) { +#else + if (putc('\n', fd) < 0) { #endif - (putc('\n', fd) < 0)) return FAIL; + } return OK; } @@ -9456,12 +9499,14 @@ static void ex_folddo(exarg_T *eap) static void ex_terminal(exarg_T *eap) { - // We will call termopen() with ['shell'] if not given a {cmd}. - char *name = (char *)p_sh; + char *name = (char *)p_sh; // Default to 'shell' if {cmd} is not given. + bool mustfree = false; char *lquote = "['"; char *rquote = "']"; + if (*eap->arg != NUL) { name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\"); + mustfree = true; lquote = rquote = "\""; } @@ -9471,7 +9516,7 @@ static void ex_terminal(exarg_T *eap) eap->forceit==TRUE ? "!" : "", lquote, name, rquote); do_cmdline_cmd(ex_cmd); - if (name != (char *)p_sh) { + if (mustfree) { xfree(name); } } |