aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_docmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_docmd.c')
-rw-r--r--src/nvim/ex_docmd.c256
1 files changed, 158 insertions, 98 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index cbe7c1a231..2d17b31f0f 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -381,15 +381,14 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
suppress_errthrow = FALSE;
}
- /*
- * If requested, store and reset the global values controlling the
- * exception handling (used when debugging). Otherwise clear it to avoid
- * a bogus compiler warning when the optimizer uses inline functions...
- */
- if (flags & DOCMD_EXCRESET)
+ // If requested, store and reset the global values controlling the
+ // exception handling (used when debugging). Otherwise clear it to avoid
+ // a bogus compiler warning when the optimizer uses inline functions...
+ if (flags & DOCMD_EXCRESET) {
save_dbg_stuff(&debug_saved);
- else
- memset(&debug_saved, 0, 1);
+ } else {
+ memset(&debug_saved, 0, sizeof(debug_saved));
+ }
initial_trylevel = trylevel;
@@ -1702,9 +1701,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
p = vim_strnsave(ea.cmd, p - ea.cmd);
int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, TRUE, NULL);
xfree(p);
- if (ret && !aborting()) {
- p = find_command(&ea, NULL);
- }
+ // If the autocommands did something and didn't cause an error, try
+ // finding the command again.
+ p = (ret && !aborting()) ? find_command(&ea, NULL) : NULL;
}
if (p == NULL) {
@@ -2348,8 +2347,11 @@ static char_u *find_command(exarg_T *eap, int *full)
eap->cmdidx = CMD_k;
++p;
} else if (p[0] == 's'
- && ((p[1] == 'c' && p[2] != 's' && p[2] != 'r'
- && p[3] != 'i' && p[4] != 'p')
+ && ((p[1] == 'c'
+ && (p[2] == NUL
+ || (p[2] != 's' && p[2] != 'r'
+ && (p[3] == NUL
+ || (p[3] != 'i' && p[4] != 'p')))))
|| p[1] == 'g'
|| (p[1] == 'i' && p[2] != 'm' && p[2] != 'l' && p[2] != 'g')
|| p[1] == 'I'
@@ -2676,16 +2678,25 @@ set_one_cmd_context (
p = cmd + 1;
} else {
p = cmd;
- while (ASCII_ISALPHA(*p) || *p == '*') /* Allow * wild card */
- ++p;
- /* check for non-alpha command */
- if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL)
- ++p;
- /* for python 3.x: ":py3*" commands completion */
+ while (ASCII_ISALPHA(*p) || *p == '*') { // Allow * wild card
+ p++;
+ }
+ // a user command may contain digits
+ if (ASCII_ISUPPER(cmd[0])) {
+ while (ASCII_ISALNUM(*p) || *p == '*') {
+ p++;
+ }
+ }
+ // for python 3.x: ":py3*" commands completion
if (cmd[0] == 'p' && cmd[1] == 'y' && p == cmd + 2 && *p == '3') {
- ++p;
- while (ASCII_ISALPHA(*p) || *p == '*')
- ++p;
+ p++;
+ while (ASCII_ISALPHA(*p) || *p == '*') {
+ p++;
+ }
+ }
+ // check for non-alpha command
+ if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL) {
+ p++;
}
len = (int)(p - cmd);
@@ -2699,9 +2710,11 @@ set_one_cmd_context (
(size_t)len) == 0)
break;
- if (cmd[0] >= 'A' && cmd[0] <= 'Z')
- while (ASCII_ISALNUM(*p) || *p == '*') /* Allow * wild card */
- ++p;
+ if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
+ while (ASCII_ISALNUM(*p) || *p == '*') { // Allow * wild card
+ p++;
+ }
+ }
}
/*
@@ -5656,8 +5669,13 @@ static void ex_quit(exarg_T *eap)
|| (only_one_window() && check_changed_any(eap->forceit))) {
not_exiting();
} else {
- if (only_one_window()) {
- // quit last window
+ // quit last window
+ // Note: only_one_window() returns true, even so a help window is
+ // still open. In that case only quit, if no address has been
+ // specified. Example:
+ // :h|wincmd w|1q - don't quit
+ // :h|wincmd w|q - quit
+ if (only_one_window() && (firstwin == lastwin || eap->addr_count == 0)) {
getout(0);
}
/* close window; may free buffer */
@@ -6345,7 +6363,7 @@ static void ex_tabnext(exarg_T *eap)
*/
static void ex_tabmove(exarg_T *eap)
{
- int tab_number = 9999;
+ int tab_number;
if (eap->arg && *eap->arg != NUL) {
char_u *p = eap->arg;
@@ -6361,17 +6379,35 @@ static void ex_tabmove(exarg_T *eap)
} else
p = eap->arg;
- if (p == skipdigits(p)) {
- /* No numbers as argument. */
- eap->errmsg = e_invarg;
- return;
+ if (relative == 0) {
+ if (STRCMP(p, "$") == 0) {
+ tab_number = LAST_TAB_NR;
+ } else if (p == skipdigits(p)) {
+ // No numbers as argument.
+ eap->errmsg = e_invarg;
+ return;
+ } else {
+ tab_number = getdigits(&p);
+ }
+ } else {
+ if (*p != NUL) {
+ tab_number = getdigits(&p);
+ } else {
+ tab_number = 1;
+ }
+ tab_number = tab_number * relative + tabpage_index(curtab);
+ if (relative == -1) {
+ --tab_number;
+ }
}
-
- tab_number = getdigits_int(&p);
- if (relative != 0)
- tab_number = tab_number * relative + tabpage_index(curtab) - 1; ;
- } else if (eap->addr_count != 0)
+ } else if (eap->addr_count != 0) {
tab_number = eap->line2;
+ if (**eap->cmdlinep == '-') {
+ --tab_number;
+ }
+ } else {
+ tab_number = LAST_TAB_NR;
+ }
tabpage_move(tab_number);
}
@@ -8257,16 +8293,22 @@ static char_u *arg_all(void)
retval[len] = ' ';
++len;
}
- for (; *p != NUL; ++p) {
- if (*p == ' ' || *p == '\\') {
- /* insert a backslash */
- if (retval != NULL)
+ for (; *p != NUL; p++) {
+ if (*p == ' '
+#ifndef BACKSLASH_IN_FILENAME
+ || *p == '\\'
+#endif
+ ) {
+ // insert a backslash
+ if (retval != NULL) {
retval[len] = '\\';
- ++len;
+ }
+ len++;
}
- if (retval != NULL)
+ if (retval != NULL) {
retval[len] = *p;
- ++len;
+ }
+ len++;
}
}
@@ -8345,8 +8387,7 @@ makeopens (
{
int only_save_windows = TRUE;
int nr;
- int cnr = 1;
- int restore_size = TRUE;
+ int restore_size = true;
win_T *wp;
char_u *sname;
win_T *edited_win = NULL;
@@ -8463,7 +8504,8 @@ makeopens (
tab_firstwin = firstwin; /* first window in tab page "tabnr" */
tab_topframe = topframe;
for (tabnr = 1;; ++tabnr) {
- int need_tabnew = FALSE;
+ int need_tabnew = false;
+ int cnr = 1;
if ((ssop_flags & SSOP_TABPAGES)) {
tabpage_T *tp = find_tabpage(tabnr);
@@ -8742,19 +8784,18 @@ static int ses_do_frame(frame_T *fr)
return FALSE;
}
-/*
- * Return non-zero if window "wp" is to be stored in the Session.
- */
+/// Return non-zero if window "wp" is to be stored in the Session.
static int ses_do_win(win_T *wp)
{
if (wp->w_buffer->b_fname == NULL
- /* When 'buftype' is "nofile" can't restore the window contents. */
- || bt_nofile(wp->w_buffer)
- )
+ // When 'buftype' is "nofile" can't restore the window contents.
+ || (!wp->w_buffer->terminal && bt_nofile(wp->w_buffer))) {
return ssop_flags & SSOP_BLANK;
- if (wp->w_buffer->b_help)
+ }
+ if (wp->w_buffer->b_help) {
return ssop_flags & SSOP_HELP;
- return TRUE;
+ }
+ return true;
}
/*
@@ -9190,9 +9231,9 @@ char_u *get_behave_arg(expand_T *xp, int idx)
return NULL;
}
-static int filetype_detect = FALSE;
-static int filetype_plugin = FALSE;
-static int filetype_indent = FALSE;
+static TriState filetype_detect = kNone;
+static TriState filetype_plugin = kNone;
+static TriState filetype_indent = kNone;
/*
* ":filetype [plugin] [indent] {on,off,detect}"
@@ -9206,27 +9247,27 @@ static int filetype_indent = FALSE;
static void ex_filetype(exarg_T *eap)
{
char_u *arg = eap->arg;
- int plugin = FALSE;
- int indent = FALSE;
+ bool plugin = false;
+ bool indent = false;
if (*eap->arg == NUL) {
/* Print current status. */
smsg("filetype detection:%s plugin:%s indent:%s",
- filetype_detect ? "ON" : "OFF",
- filetype_plugin ? (filetype_detect ? "ON" : "(on)") : "OFF",
- filetype_indent ? (filetype_detect ? "ON" : "(on)") : "OFF");
+ filetype_detect == kTrue ? "ON" : "OFF",
+ filetype_plugin == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF", // NOLINT(whitespace/line_length)
+ filetype_indent == kTrue ? (filetype_detect == kTrue ? "ON" : "(on)") : "OFF"); // NOLINT(whitespace/line_length)
return;
}
/* Accept "plugin" and "indent" in any order. */
for (;; ) {
if (STRNCMP(arg, "plugin", 6) == 0) {
- plugin = TRUE;
+ plugin = true;
arg = skipwhite(arg + 6);
continue;
}
if (STRNCMP(arg, "indent", 6) == 0) {
- indent = TRUE;
+ indent = true;
arg = skipwhite(arg + 6);
continue;
}
@@ -9234,15 +9275,15 @@ static void ex_filetype(exarg_T *eap)
}
if (STRCMP(arg, "on") == 0 || STRCMP(arg, "detect") == 0) {
if (*arg == 'o' || !filetype_detect) {
- source_runtime((char_u *)FILETYPE_FILE, TRUE);
- filetype_detect = TRUE;
+ source_runtime((char_u *)FILETYPE_FILE, true);
+ filetype_detect = kTrue;
if (plugin) {
- source_runtime((char_u *)FTPLUGIN_FILE, TRUE);
- filetype_plugin = TRUE;
+ source_runtime((char_u *)FTPLUGIN_FILE, true);
+ filetype_plugin = kTrue;
}
if (indent) {
- source_runtime((char_u *)INDENT_FILE, TRUE);
- filetype_indent = TRUE;
+ source_runtime((char_u *)INDENT_FILE, true);
+ filetype_indent = kTrue;
}
}
if (*arg == 'd') {
@@ -9252,21 +9293,37 @@ static void ex_filetype(exarg_T *eap)
} else if (STRCMP(arg, "off") == 0) {
if (plugin || indent) {
if (plugin) {
- source_runtime((char_u *)FTPLUGOF_FILE, TRUE);
- filetype_plugin = FALSE;
+ source_runtime((char_u *)FTPLUGOF_FILE, true);
+ filetype_plugin = kFalse;
}
if (indent) {
- source_runtime((char_u *)INDOFF_FILE, TRUE);
- filetype_indent = FALSE;
+ source_runtime((char_u *)INDOFF_FILE, true);
+ filetype_indent = kFalse;
}
} else {
- source_runtime((char_u *)FTOFF_FILE, TRUE);
- filetype_detect = FALSE;
+ source_runtime((char_u *)FTOFF_FILE, true);
+ filetype_detect = kFalse;
}
} else
EMSG2(_(e_invarg2), arg);
}
+/// Do ":filetype plugin indent on" if user did not already do some
+/// permutation thereof.
+void filetype_maybe_enable(void)
+{
+ if (filetype_detect == kNone
+ && filetype_plugin == kNone
+ && filetype_indent == kNone) {
+ source_runtime((char_u *)FILETYPE_FILE, true);
+ filetype_detect = kTrue;
+ source_runtime((char_u *)FTPLUGIN_FILE, true);
+ filetype_plugin = kTrue;
+ source_runtime((char_u *)INDENT_FILE, true);
+ filetype_indent = kTrue;
+ }
+}
+
/*
* ":setfiletype {name}"
*/
@@ -9304,59 +9361,62 @@ static void ex_nohlsearch(exarg_T *eap)
redraw_all_later(SOME_VALID);
}
-/*
- * ":[N]match {group} {pattern}"
- * Sets nextcmd to the start of the next command, if any. Also called when
- * skipping commands to find the next command.
- */
+// ":[N]match {group} {pattern}"
+// Sets nextcmd to the start of the next command, if any. Also called when
+// skipping commands to find the next command.
static void ex_match(exarg_T *eap)
{
- char_u *p;
- char_u *g = NULL;
- char_u *end;
+ char_u *p;
+ char_u *g = NULL;
+ char_u *end;
int c;
int id;
- if (eap->line2 <= 3)
+ if (eap->line2 <= 3) {
id = eap->line2;
- else {
+ } else {
EMSG(e_invcmd);
return;
}
- /* First clear any old pattern. */
- if (!eap->skip)
- match_delete(curwin, id, FALSE);
+ // First clear any old pattern.
+ if (!eap->skip) {
+ match_delete(curwin, id, false);
+ }
- if (ends_excmd(*eap->arg))
+ if (ends_excmd(*eap->arg)) {
end = eap->arg;
- else if ((STRNICMP(eap->arg, "none", 4) == 0
- && (ascii_iswhite(eap->arg[4]) || ends_excmd(eap->arg[4]))))
+ } else if ((STRNICMP(eap->arg, "none", 4) == 0
+ && (ascii_iswhite(eap->arg[4]) || ends_excmd(eap->arg[4])))) {
end = eap->arg + 4;
- else {
+ } else {
p = skiptowhite(eap->arg);
- if (!eap->skip)
+ if (!eap->skip) {
g = vim_strnsave(eap->arg, (int)(p - eap->arg));
+ }
p = skipwhite(p);
if (*p == NUL) {
- /* There must be two arguments. */
+ // There must be two arguments.
+ xfree(g);
EMSG2(_(e_invarg2), eap->arg);
return;
}
- end = skip_regexp(p + 1, *p, TRUE, NULL);
+ end = skip_regexp(p + 1, *p, true, NULL);
if (!eap->skip) {
if (*end != NUL && !ends_excmd(*skipwhite(end + 1))) {
+ xfree(g);
eap->errmsg = e_trailing;
return;
}
if (*end != *p) {
+ xfree(g);
EMSG2(_(e_invarg2), p);
return;
}
c = *end;
*end = NUL;
- match_add(curwin, g, p + 1, 10, id, NULL);
+ match_add(curwin, g, p + 1, 10, id, NULL, NULL);
xfree(g);
*end = c;
}