diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/diff.c | 6 | ||||
-rw-r--r-- | src/ex_docmd.c | 76 | ||||
-rw-r--r-- | src/normal.c | 25 | ||||
-rw-r--r-- | src/os_vms_conf.h | 1 | ||||
-rw-r--r-- | src/proto/ex_docmd.pro | 3 | ||||
-rw-r--r-- | src/quickfix.c | 21 | ||||
-rw-r--r-- | src/tag.c | 5 | ||||
-rw-r--r-- | src/window.c | 124 |
8 files changed, 224 insertions, 37 deletions
diff --git a/src/diff.c b/src/diff.c index b28e127cc..d5cb97c4e 100644 --- a/src/diff.c +++ b/src/diff.c @@ -974,6 +974,9 @@ ex_diffpatch(eap) #ifdef FEAT_GUI need_mouse_correct = TRUE; #endif + /* don't use a new tab page, each tab page has its own diffs */ + cmdmod.tab = 0; + if (win_split(0, 0) != FAIL) { /* Pretend it was a ":split fname" command */ @@ -1031,6 +1034,9 @@ ex_diffsplit(eap) #ifdef FEAT_GUI need_mouse_correct = TRUE; #endif + /* don't use a new tab page, each tab page has its own diffs */ + cmdmod.tab = 0; + if (win_split(0, 0) != FAIL) { /* Pretend it was a ":split fname" command */ diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 73bf420f6..df6273ffc 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -155,6 +155,9 @@ static void ex_resize __ARGS((exarg_T *eap)); static void ex_stag __ARGS((exarg_T *eap)); static void ex_tabclose __ARGS((exarg_T *eap)); static void ex_tabonly __ARGS((exarg_T *eap)); +static void ex_tabnext __ARGS((exarg_T *eap)); +static void ex_tabprevious __ARGS((exarg_T *eap)); +static void ex_tabmove __ARGS((exarg_T *eap)); static void ex_tabs __ARGS((exarg_T *eap)); #else # define ex_close ex_ni @@ -163,7 +166,9 @@ static void ex_tabs __ARGS((exarg_T *eap)); # define ex_resize ex_ni # define ex_splitview ex_ni # define ex_stag ex_ni -# define ex_tab ex_ni +# define ex_tabnext ex_ni +# define ex_tabprevious ex_ni +# define ex_tabmove ex_ni # define ex_tabs ex_ni # define ex_tabclose ex_ni # define ex_tabonly ex_ni @@ -1857,7 +1862,25 @@ do_one_cmd(cmdlinep, sourcing, } continue; - case 't': if (!checkforcmd(&ea.cmd, "topleft", 2)) + case 't': if (checkforcmd(&p, "tab", 3)) + { +#ifdef FEAT_WINDOWS + tabpage_T *tp; + + if (vim_isdigit(*ea.cmd)) + cmdmod.tab = atoi((char *)ea.cmd) + 1; + else + { + cmdmod.tab = 2; + for (tp = first_tabpage; tp != curtab; + tp = tp->tp_next) + ++cmdmod.tab; + } + ea.cmd = p; +#endif + continue; + } + if (!checkforcmd(&ea.cmd, "topleft", 2)) break; #ifdef FEAT_WINDOWS cmdmod.split |= WSP_TOP; @@ -2380,7 +2403,7 @@ do_one_cmd(cmdlinep, sourcing, { n = getdigits(&ea.arg); ea.arg = skipwhite(ea.arg); - if (n <= 0 && !ni) + if (n <= 0 && !ni && (ea.argt & ZEROR) == 0) { errormsg = (char_u *)_(e_zerocount); goto doend; @@ -6957,7 +6980,7 @@ ex_splitview(eap) || eap->cmdidx == CMD_tabfind || eap->cmdidx == CMD_tabnew) { - if (win_new_tabpage() != FAIL) + if (win_new_tabpage(cmdmod.tab) != FAIL) { do_exedit(eap, NULL); @@ -6998,13 +7021,48 @@ theend: } /* - * :tab command + * Open a new tab page. */ void -ex_tab(eap) +tabpage_new() +{ + exarg_T ea; + + vim_memset(&ea, 0, sizeof(ea)); + ea.cmdidx = CMD_tabnew; + ea.cmd = (char_u *)"tabn"; + ea.arg = (char_u *)""; + ex_splitview(&ea); +} + +/* + * :tabnext command + */ + static void +ex_tabnext(eap) exarg_T *eap; { - goto_tabpage((int)eap->line2); + goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2); +} + +/* + * :tabprevious and :tabNext command + */ + static void +ex_tabprevious(eap) + exarg_T *eap; +{ + goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2); +} + +/* + * :tabmove command + */ + static void +ex_tabmove(eap) + exarg_T *eap; +{ + tabpage_move(eap->addr_count == 0 ? 9999 : (int)eap->line2); } /* @@ -7035,7 +7093,9 @@ ex_tabs(eap) wp = tp->tp_firstwin; for ( ; wp != NULL && !got_int; wp = wp->w_next) { - msg_puts((char_u *)"\n "); + msg_putchar('\n'); + msg_putchar(wp == curwin ? '>' : ' '); + msg_putchar(' '); msg_putchar(bufIsChanged(wp->w_buffer) ? '+' : ' '); msg_putchar(' '); if (buf_spname(wp->w_buffer) != NULL) diff --git a/src/normal.c b/src/normal.c index 07857f5ba..4f4ffa954 100644 --- a/src/normal.c +++ b/src/normal.c @@ -2437,13 +2437,23 @@ do_mouse(oap, c, dir, count, fixindent) c1 = TabPageIdxs[mouse_col]; if (c1 >= 0) { - /* Go to specified tab page, or next one if not clicking on a - * label. */ - goto_tabpage(c1); - - /* It's like clicking on the status line of a window. */ - if (curwin != old_curwin) + if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) + { + /* double click opens new page */ end_visual_mode(); + tabpage_new(); + tabpage_move(c1 == 0 ? 9999 : c1 - 1); + } + else + { + /* Go to specified tab page, or next one if not clicking + * on a label. */ + goto_tabpage(c1); + + /* It's like clicking on the status line of a window. */ + if (curwin != old_curwin) + end_visual_mode(); + } } else if (c1 < 0) { @@ -7895,6 +7905,9 @@ nv_g_cmd(cap) case 't': goto_tabpage((int)cap->count0); break; + case 'T': + goto_tabpage(-(int)cap->count1); + break; #endif default: diff --git a/src/os_vms_conf.h b/src/os_vms_conf.h index 006460824..2ede37d91 100644 --- a/src/os_vms_conf.h +++ b/src/os_vms_conf.h @@ -106,6 +106,7 @@ #define HAVE_FSYNC #define HAVE_GETPWUID #define HAVE_GETPWNAM +#define HAVE_STDARG_H #define HAVE_STDLIB_H #define HAVE_STRING_H #define HAVE_ERRNO_H diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro index a171e9730..94e1393ce 100644 --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -35,8 +35,7 @@ void alist_set __ARGS((alist_T *al, int count, char_u **files, int use_curbuf, i void alist_add __ARGS((alist_T *al, char_u *fname, int set_fnum)); void alist_slash_adjust __ARGS((void)); void ex_splitview __ARGS((exarg_T *eap)); -void ex_tabedit __ARGS((exarg_T *eap)); -void ex_tab __ARGS((exarg_T *eap)); +void tabpage_new __ARGS((void)); void do_exedit __ARGS((exarg_T *eap, win_T *old_curwin)); void free_cd_dir __ARGS((void)); void do_sleep __ARGS((long msec)); diff --git a/src/quickfix.c b/src/quickfix.c index a29f06784..7319e8077 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -1472,14 +1472,17 @@ qf_jump(qi, dir, errornr, forceit) /* * For ":helpgrep" find a help window or open one. */ - if (qf_ptr->qf_type == 1 && !curwin->w_buffer->b_help) + if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) { win_T *wp; int n; - for (wp = firstwin; wp != NULL; wp = wp->w_next) - if (wp->w_buffer != NULL && wp->w_buffer->b_help) - break; + if (cmdmod.tab != 0) + wp = NULL; + else + for (wp = firstwin; wp != NULL; wp = wp->w_next) + if (wp->w_buffer != NULL && wp->w_buffer->b_help) + break; if (wp != NULL && wp->w_buffer->b_nwindows > 0) win_enter(wp, TRUE); else @@ -2182,6 +2185,7 @@ ex_copen(eap) qf_info_T *qi = &ql_info; int height; win_T *win; + tabpage_T *prevtab = curtab; if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow) { @@ -2210,7 +2214,7 @@ ex_copen(eap) */ win = qf_find_win(qi); - if (win != NULL) + if (win != NULL && cmdmod.tab == 0) win_goto(win); else { @@ -2247,10 +2251,13 @@ ex_copen(eap) set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL); set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL); + /* Only set the height when still in the same tab page and there is no + * window to the side. */ + if (curtab == prevtab #ifdef FEAT_VERTSPLIT - /* Only set the height when there is no window to the side. */ - if (curwin->w_width == Columns) + && curwin->w_width == Columns #endif + ) win_setheight(height); curwin->w_p_wfh = TRUE; /* set 'winfixheight' */ if (win_valid(win)) @@ -3076,8 +3076,9 @@ jumpto_tag(lbuf, forceit, keep_help) } } - /* if it was a CTRL-W CTRL-] command split window now */ - if (postponed_split) + /* If it was a CTRL-W CTRL-] command split window now. For ":tab tag" + * open a new tab page. */ + if (postponed_split || cmdmod.tab != 0) { win_split(postponed_split > 0 ? postponed_split : 0, postponed_split_flags); diff --git a/src/window.c b/src/window.c index 548113dfc..c116dfc84 100644 --- a/src/window.c +++ b/src/window.c @@ -622,6 +622,10 @@ win_split(size, flags) int size; int flags; { + /* When the ":tab" modifier was used open a new tab page instead. */ + if (may_open_tabpage() == OK) + return OK; + /* Add flags from ":vertical", ":topleft" and ":botright". */ flags |= cmdmod.split; if ((flags & WSP_TOP) && (flags & WSP_BOT)) @@ -2303,14 +2307,13 @@ alt_tabpage() { tabpage_T *tp; - /* Use the next tab page if we are currently at the first one. */ - if (curtab == first_tabpage) + /* Use the next tab page if possible. */ + if (curtab->tp_next != NULL) return curtab->tp_next; - /* Find the previous tab page. */ - for (tp = first_tabpage; tp->tp_next != NULL; tp = tp->tp_next) - if (tp->tp_next == curtab) - break; + /* Find the last but one tab page. */ + for (tp = first_tabpage; tp->tp_next != curtab; tp = tp->tp_next) + ; return tp; } @@ -2990,14 +2993,17 @@ free_tabpage(tp) /* * Create a new Tab page with one window. * It will edit the current buffer, like after ":split". - * Put it just after the current Tab page. + * When "after" is 0 put it just after the current Tab page. + * Otherwise put it just before tab page "after". * Return FAIL or OK. */ int -win_new_tabpage() +win_new_tabpage(after) + int after; { tabpage_T *tp = curtab; tabpage_T *newtp; + int n; newtp = alloc_tabpage(); if (newtp == NULL) @@ -3015,8 +3021,25 @@ win_new_tabpage() if (win_alloc_firstwin(tp->tp_curwin) == OK) { /* Make the new Tab page the new topframe. */ - newtp->tp_next = tp->tp_next; - tp->tp_next = newtp; + if (after == 1) + { + /* New tab page becomes the first one. */ + newtp->tp_next = first_tabpage; + first_tabpage = newtp; + } + else + { + if (after > 0) + { + /* Put new tab page before tab page "after". */ + n = 2; + for (tp = first_tabpage; tp->tp_next != NULL + && n < after; tp = tp->tp_next) + ++n; + } + newtp->tp_next = tp->tp_next; + tp->tp_next = newtp; + } win_init_size(); firstwin->w_winrow = tabpageline_height(); @@ -3036,6 +3059,24 @@ win_new_tabpage() } /* + * Open a new tab page if ":tab cmd" was used. It will edit the same buffer, + * like with ":split". + * Returns OK if a new tab page was created, FAIL otherwise. + */ + int +may_open_tabpage() +{ + int n = cmdmod.tab; + + if (cmdmod.tab != 0) + { + cmdmod.tab = 0; /* reset it to avoid doing it twice */ + return win_new_tabpage(n); + } + return FAIL; +} + +/* * Create up to "maxcount" tabpages with empty windows. * Returns the number of resulting tab pages. */ @@ -3059,7 +3100,7 @@ make_tabpages(maxcount) #endif for (todo = count - 1; todo > 0; --todo) - if (win_new_tabpage() == FAIL) + if (win_new_tabpage(0) == FAIL) break; #ifdef FEAT_AUTOCMD @@ -3212,6 +3253,7 @@ goto_tabpage(n) int n; { tabpage_T *tp; + tabpage_T *ttp; int i; /* If there is only one it can't work. */ @@ -3230,6 +3272,19 @@ goto_tabpage(n) else tp = curtab->tp_next; } + else if (n < 0) + { + /* "gT": go to previous tab page, wrap around end. "N gT" repeats + * this N times. */ + ttp = curtab; + for (i = n; i < 0; ++i) + { + for (tp = first_tabpage; tp->tp_next != ttp && tp->tp_next != NULL; + tp = tp->tp_next) + ; + ttp = tp; + } + } else { /* Go to tab page "n". */ @@ -3243,7 +3298,7 @@ goto_tabpage(n) } } - if (leave_tabpage(tp->tp_curwin->w_buffer) == OK) + if (tp != curtab && leave_tabpage(tp->tp_curwin->w_buffer) == OK) { if (valid_tabpage(tp)) enter_tabpage(tp, curbuf); @@ -3253,6 +3308,51 @@ goto_tabpage(n) } /* + * Move the current tab page to before tab page "nr". + */ + void +tabpage_move(nr) + int nr; +{ + int n = nr; + tabpage_T *tp; + + if (first_tabpage->tp_next == NULL) + return; + + /* Remove the current tab page from the list of tab pages. */ + if (curtab == first_tabpage) + first_tabpage = curtab->tp_next; + else + { + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) + if (tp->tp_next == curtab) + break; + if (tp == NULL) /* "cannot happen" */ + return; + tp->tp_next = curtab->tp_next; + } + + /* Re-insert it at the specified position. */ + if (n == 0) + { + curtab->tp_next = first_tabpage; + first_tabpage = curtab; + } + else + { + for (tp = first_tabpage; tp->tp_next != NULL && n > 1; tp = tp->tp_next) + --n; + curtab->tp_next = tp->tp_next; + tp->tp_next = curtab; + } + + /* Need to redraw the tabline. Tab page contents doesn't change. */ + redraw_tabline = TRUE; +} + + +/* * Go to another window. * When jumping to another buffer, stop Visual mode. Do this before * changing windows so we can yank the selection into the '*' register. |