aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r--src/nvim/buffer.c101
1 files changed, 78 insertions, 23 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index a6e3fedd3f..9806623433 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -22,6 +22,7 @@
#include "nvim/api/private/handle.h"
#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
@@ -1600,21 +1601,28 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
col = 0;
if (options & GETF_SWITCH) {
- /* If 'switchbuf' contains "useopen": jump to first window containing
- * "buf" if one exists */
- if (swb_flags & SWB_USEOPEN)
+ // If 'switchbuf' contains "useopen": jump to first window containing
+ // "buf" if one exists
+ if (swb_flags & SWB_USEOPEN) {
wp = buf_jump_open_win(buf);
- /* If 'switchbuf' contains "usetab": jump to first window in any tab
- * page containing "buf" if one exists */
- if (wp == NULL && (swb_flags & SWB_USETAB))
+ }
+
+ // If 'switchbuf' contains "usetab": jump to first window in any tab
+ // page containing "buf" if one exists
+ if (wp == NULL && (swb_flags & SWB_USETAB)) {
wp = buf_jump_open_tab(buf);
- /* If 'switchbuf' contains "split" or "newtab" and the current buffer
- * isn't empty: open new window */
- if (wp == NULL && (swb_flags & (SWB_SPLIT | SWB_NEWTAB)) && !bufempty()) {
- if (swb_flags & SWB_NEWTAB) /* Open in a new tab */
+ }
+
+ // If 'switchbuf' contains "split", "vsplit" or "newtab" and the
+ // current buffer isn't empty: open new tab or window
+ if (wp == NULL && (swb_flags & (SWB_VSPLIT | SWB_SPLIT | SWB_NEWTAB))
+ && !bufempty()) {
+ if (swb_flags & SWB_NEWTAB) {
tabpage_new();
- else if (win_split(0, 0) == FAIL) /* Open in a new window */
+ } else if (win_split(0, (swb_flags & SWB_VSPLIT) ? WSP_VERT : 0)
+ == FAIL) {
return FAIL;
+ }
RESET_BINDING(curwin);
}
}
@@ -2826,7 +2834,7 @@ typedef enum {
/// @param fillchar Character to use when filling empty space in the statusline
/// @param maxwidth The maximum width to make the statusline
/// @param hltab HL attributes (can be NULL)
-/// @param tabtab tab page nrs (can be NULL)
+/// @param tabtab Tab clicks definition (can be NULL).
///
/// @return The final width of the statusline
int build_stl_str_hl(
@@ -2838,13 +2846,15 @@ int build_stl_str_hl(
int fillchar,
int maxwidth,
struct stl_hlrec *hltab,
- struct stl_hlrec *tabtab
+ StlClickRecord *tabtab
)
{
int groupitem[STL_MAX_ITEM];
struct stl_item {
// Where the item starts in the status line output buffer
- char_u *start;
+ char_u *start;
+ // Function to run for ClickFunc items.
+ char *cmd;
// The minimum width of the item
int minwid;
// The maximum width of the item
@@ -2856,10 +2866,10 @@ int build_stl_str_hl(
Middle,
Highlight,
TabPage,
+ ClickFunc,
Trunc
- } type;
- } item[STL_MAX_ITEM];
-
+ } type;
+ } item[STL_MAX_ITEM];
#define TMPLEN 70
char_u tmp[TMPLEN];
char_u *usefmt = fmt;
@@ -3164,6 +3174,24 @@ int build_stl_str_hl(
continue;
}
+ if (*fmt_p == STL_CLICK_FUNC) {
+ fmt_p++;
+ char *t = (char *) fmt_p;
+ while (*fmt_p != STL_CLICK_FUNC && *fmt_p) {
+ fmt_p++;
+ }
+ if (*fmt_p != STL_CLICK_FUNC) {
+ break;
+ }
+ item[curitem].type = ClickFunc;
+ item[curitem].start = out_p;
+ item[curitem].cmd = xmemdupz(t, (size_t) (((char *) fmt_p - t)));
+ item[curitem].minwid = minwid;
+ fmt_p++;
+ curitem++;
+ continue;
+ }
+
// Denotes the end of the minwid
// the maxwid may follow immediately after
if (*fmt_p == '.') {
@@ -3281,6 +3309,7 @@ int build_stl_str_hl(
}
break;
}
+
case STL_LINE:
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
? 0L : (long)(wp->w_cursor.lnum);
@@ -3821,16 +3850,37 @@ int build_stl_str_hl(
// Store the info about tab pages labels.
if (tabtab != NULL) {
- struct stl_hlrec *sp = tabtab;
+ StlClickRecord *cur_tab_rec = tabtab;
for (long l = 0; l < itemcnt; l++) {
if (item[l].type == TabPage) {
- sp->start = item[l].start;
- sp->userhl = item[l].minwid;
- sp++;
+ cur_tab_rec->start = (char *) item[l].start;
+ if (item[l].minwid == 0) {
+ cur_tab_rec->def.type = kStlClickDisabled;
+ cur_tab_rec->def.tabnr = 0;
+ } else {
+ int tabnr = item[l].minwid;
+ if (item[l].minwid > 0) {
+ cur_tab_rec->def.type = kStlClickTabSwitch;
+ } else {
+ cur_tab_rec->def.type = kStlClickTabClose;
+ tabnr = -tabnr;
+ }
+ cur_tab_rec->def.tabnr = tabnr;
+ }
+ cur_tab_rec->def.func = NULL;
+ cur_tab_rec++;
+ } else if (item[l].type == ClickFunc) {
+ cur_tab_rec->start = (char *) item[l].start;
+ cur_tab_rec->def.type = kStlClickFuncRun;
+ cur_tab_rec->def.tabnr = item[l].minwid;
+ cur_tab_rec->def.func = item[l].cmd;
+ cur_tab_rec++;
}
}
- sp->start = NULL;
- sp->userhl = 0;
+ cur_tab_rec->start = NULL;
+ cur_tab_rec->def.type = kStlClickDisabled;
+ cur_tab_rec->def.tabnr = 0;
+ cur_tab_rec->def.func = NULL;
}
return width;
@@ -3852,6 +3902,11 @@ void get_rel_pos(win_T *wp, char_u *buf, int buflen)
above = wp->w_topline - 1;
above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill;
+ if (wp->w_topline == 1 && wp->w_topfill >= 1) {
+ // All buffer lines are displayed and there is an indication
+ // of filler lines, that can be considered seeing all lines.
+ above = 0;
+ }
below = wp->w_buffer->b_ml.ml_line_count - wp->w_botline + 1;
if (below <= 0)
STRLCPY(buf, (above == 0 ? _("All") : _("Bot")), buflen);