diff options
-rw-r--r-- | src/nvim/ex_docmd.c | 122 | ||||
-rw-r--r-- | src/nvim/version.c | 2 |
2 files changed, 110 insertions, 14 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 5dd744834e..8c293efd58 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1138,6 +1138,96 @@ static int current_tab_nr(tabpage_T *tab) #define LAST_TAB_NR current_tab_nr(NULL) /* +* Figure out the address type for ":wincmd". +*/ +static void get_wincmd_addr_type(char_u *arg, exarg_T *eap) +{ + switch (*arg) { + case 'S': + case Ctrl_S: + case 's': + case Ctrl_N: + case 'n': + case 'j': + case Ctrl_J: + case 'k': + case Ctrl_K: + case 'T': + case Ctrl_R: + case 'r': + case 'R': + case 'K': + case 'J': + case '+': + case '-': + case Ctrl__: + case '_': + case '|': + case ']': + case Ctrl_RSB: + case 'g': + case Ctrl_G: + case Ctrl_V: + case 'v': + case 'h': + case Ctrl_H: + case 'l': + case Ctrl_L: + case 'H': + case 'L': + case '>': + case '<': + case '}': + case 'f': + case 'F': + case Ctrl_F: + case 'i': + case Ctrl_I: + case 'd': + case Ctrl_D: + /* window size or any count */ + eap->addr_type = ADDR_LINES; + break; + + case Ctrl_HAT: + case '^': + /* buffer number */ + eap->addr_type = ADDR_BUFFERS; + break; + + case Ctrl_Q: + case 'q': + case Ctrl_C: + case 'c': + case Ctrl_O: + case 'o': + case Ctrl_W: + case 'w': + case 'W': + case 'x': + case Ctrl_X: + /* window number */ + eap->addr_type = ADDR_WINDOWS; + break; + + case Ctrl_Z: + case 'z': + case 'P': + case 't': + case Ctrl_T: + case 'b': + case Ctrl_B: + case 'p': + case Ctrl_P: + case '=': + case CAR: + /* no count */ + eap->addr_type = 0; + break; + } +} + +/* * Execute one Ex command. * * If 'sourcing' is TRUE, the command will be included in the error message. @@ -1420,19 +1510,21 @@ static char_u * do_one_cmd(char_u **cmdlinep, * is equal to the lower. */ - if (ea.cmdidx != CMD_SIZE - && ea.cmdidx != CMD_USER - && ea.cmdidx != CMD_USER_BUF) { - ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type; - } else { - if (ea.cmdidx != CMD_USER && ea.cmdidx != CMD_USER_BUF) { + // ea.addr_type for user commands is set by find_ucmd + if (!IS_USER_CMDIDX(ea.cmdidx)) { + if (ea.cmdidx != CMD_SIZE) { + ea.addr_type = cmdnames[(int)ea.cmdidx].cmd_addr_type; + } else { ea.addr_type = ADDR_LINES; - // ea.addr_type for user commands is set by find_ucmd + } + // :wincmd range depends on the argument + if (ea.cmdidx == CMD_wincmd) { + get_wincmd_addr_type(p, &ea); } } - ea.cmd = cmd; /* repeat for all ',' or ';' separated addresses */ + ea.cmd = cmd; for (;; ) { ea.line1 = ea.line2; switch (ea.addr_type) { @@ -1465,20 +1557,25 @@ static char_u * do_one_cmd(char_u **cmdlinep, goto doend; if (lnum == MAXLNUM) { if (*ea.cmd == '%') { /* '%' - all lines */ - buf_T *buf; ++ea.cmd; switch (ea.addr_type) { case ADDR_LINES: ea.line1 = 1; ea.line2 = curbuf->b_ml.ml_line_count; break; - case ADDR_LOADED_BUFFERS: - buf = firstbuf; + case ADDR_LOADED_BUFFERS: { + buf_T *buf = firstbuf; while (buf->b_next != NULL && buf->b_ml.ml_mfp == NULL) { + buf = buf->b_next; + } + ea.line1 = buf->b_fnum; + buf = lastbuf; + while (buf->b_prev != NULL && buf->b_ml.ml_mfp == NULL) { buf = buf->b_prev; } ea.line2 = buf->b_fnum; break; + } case ADDR_BUFFERS: ea.line1 = firstbuf->b_fnum; ea.line2 = lastbuf->b_fnum; @@ -3616,8 +3713,7 @@ static char_u *invalid_range(exarg_T *eap) } break; case ADDR_WINDOWS: - if (eap->line1 < 1 - || eap->line2 > LAST_WIN_NR) { + if (eap->line2 > LAST_WIN_NR) { return (char_u *)_(e_invrange); } break; diff --git a/src/nvim/version.c b/src/nvim/version.c index 5e093cc728..fd5f17a838 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -207,7 +207,7 @@ static int included_patches[] = { //575, //574, //573, - //572, + 572, //571 NA //570 NA //569, |