summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/diff.c6
-rw-r--r--src/ex_docmd.c76
-rw-r--r--src/normal.c25
-rw-r--r--src/os_vms_conf.h1
-rw-r--r--src/proto/ex_docmd.pro3
-rw-r--r--src/quickfix.c21
-rw-r--r--src/tag.c5
-rw-r--r--src/window.c124
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))
diff --git a/src/tag.c b/src/tag.c
index ed2889e4b..8cef850d2 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -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.