aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-05-26 16:33:10 +0200
committerGitHub <noreply@github.com>2019-05-26 16:33:10 +0200
commit2b4c0181ba5a064b13f4e96e364124245e6f494c (patch)
tree5235096650cc259e01ecc1c5af2c88eaafacc0a6
parent52215f57526f27c7752685ae280865ae71105969 (diff)
parent58d6e2d3cc4c39f7a2c78a3060758bee31f831e4 (diff)
downloadrneovim-2b4c0181ba5a064b13f4e96e364124245e6f494c.tar.gz
rneovim-2b4c0181ba5a064b13f4e96e364124245e6f494c.tar.bz2
rneovim-2b4c0181ba5a064b13f4e96e364124245e6f494c.zip
Merge #10064 from janlazo/vim-8.1.0211
vim-patch:8.1.{211,307}
-rw-r--r--runtime/doc/eval.txt30
-rw-r--r--src/nvim/eval.c26
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/ex_docmd.c16
-rw-r--r--src/nvim/if_cscope.c6
-rw-r--r--src/nvim/os/env.c4
-rw-r--r--src/nvim/testdir/test_window_id.vim20
-rw-r--r--src/nvim/window.c35
-rw-r--r--test/functional/legacy/expand_spec.lua13
9 files changed, 139 insertions, 12 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 7682a1a584..32783f0851 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2377,6 +2377,7 @@ win_screenpos({nr}) List get screen position of window {nr}
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr}
+winlayout([{tabnr}]) List layout of windows in tab {tabnr}
winline() Number window line of the cursor
winnr([{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes
@@ -8538,6 +8539,35 @@ winheight({nr}) *winheight()*
Examples: >
:echo "The current window has " . winheight(0) . " lines."
<
+winlayout([{tabnr}]) *winlayout()*
+ The result is a nested List containing the layout of windows
+ in a tabpage.
+
+ Without {tabnr} use the current tabpage, otherwise the tabpage
+ with number {tabnr}. If the tabpage {tabnr} is not found,
+ returns an empty list.
+
+ For a leaf window, it returns:
+ ['leaf', {winid}]
+ For horizontally split windows, which form a column, it
+ returns:
+ ['col', [{nested list of windows}]]
+ For vertically split windows, which form a row, it returns:
+ ['row', [{nested list of windows}]]
+
+ Example: >
+ " Only one window in the tab page
+ :echo winlayout()
+ ['leaf', 1000]
+ " Two horizontally split windows
+ :echo winlayout()
+ ['col', [['leaf', 1000], ['leaf', 1001]]]
+ " Three horizontally split windows, with two
+ " vertically split windows in the middle window
+ :echo winlayout(2)
+ ['col', [['leaf', 1002], ['row', ['leaf', 1003],
+ ['leaf', 1001]]], ['leaf', 1000]]
+<
*winline()*
winline() The result is a Number, which is the screen line of the cursor
in the window. This is counting screen lines from the top of
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 12e309bfdc..868305c88d 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8868,8 +8868,8 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} else {
len = strlen(fname);
size_t usedlen = 0;
- (void)modify_fname((char_u *)mods, &usedlen, (char_u **)&fname, &fbuf,
- &len);
+ (void)modify_fname((char_u *)mods, false, &usedlen,
+ (char_u **)&fname, &fbuf, &len);
}
rettv->v_type = VAR_STRING;
@@ -17872,6 +17872,25 @@ static void f_winheight(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
}
+// "winlayout()" function
+static void f_winlayout(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tabpage_T *tp;
+
+ tv_list_alloc_ret(rettv, 2);
+
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ tp = curtab;
+ } else {
+ tp = find_tabpage((int)tv_get_number(&argvars[0]));
+ if (tp == NULL) {
+ return;
+ }
+ }
+
+ get_framelayout(tp->tp_topframe, rettv->vval.v_list, true);
+}
+
/*
* "winline()" function
*/
@@ -22623,6 +22642,7 @@ void reset_v_option_vars(void)
int
modify_fname(
char_u *src, // string with modifiers
+ bool tilde_file, // "~" is a file name, not $HOME
size_t *usedlen, // characters after src that are used
char_u **fnamep, // file name so far
char_u **bufp, // buffer for allocated file name or NULL
@@ -22652,8 +22672,8 @@ repeat:
|| (*fnamep)[1] == '\\'
# endif
|| (*fnamep)[1] == NUL)
-
#endif
+ && !(tilde_file && (*fnamep)[1] == NUL)
) {
*fnamep = expand_env_save(*fnamep);
xfree(*bufp); /* free any allocated file name */
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index aad2de5d30..dea00c3edd 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -352,6 +352,7 @@ return {
winbufnr={args=1},
wincol={},
winheight={args=1},
+ winlayout={args={0, 1}},
winline={},
winnr={args={0, 1}},
winrestcmd={},
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 979daf24fe..aa76355bad 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -8552,6 +8552,7 @@ eval_vars (
size_t resultlen;
buf_T *buf;
int valid = VALID_HEAD | VALID_PATH; // Assume valid result.
+ bool tilde_file = false;
int skip_mod = false;
char strbuf[30];
@@ -8608,9 +8609,11 @@ eval_vars (
case SPEC_PERC: /* '%': current file */
if (curbuf->b_fname == NULL) {
result = (char_u *)"";
- valid = 0; /* Must have ":p:h" to be valid */
- } else
+ valid = 0; // Must have ":p:h" to be valid
+ } else {
result = curbuf->b_fname;
+ tilde_file = STRCMP(result, "~") == 0;
+ }
break;
case SPEC_HASH: /* '#' or "#99": alternate file */
@@ -8659,9 +8662,11 @@ eval_vars (
*lnump = ECMD_LAST;
if (buf->b_fname == NULL) {
result = (char_u *)"";
- valid = 0; /* Must have ":p:h" to be valid */
- } else
+ valid = 0; // Must have ":p:h" to be valid
+ } else {
result = buf->b_fname;
+ tilde_file = STRCMP(result, "~") == 0;
+ }
}
break;
@@ -8746,7 +8751,8 @@ eval_vars (
resultlen = (size_t)(s - result);
}
} else if (!skip_mod) {
- valid |= modify_fname(src, usedlen, &result, &resultbuf, &resultlen);
+ valid |= modify_fname(src, tilde_file, usedlen, &result,
+ &resultbuf, &resultlen);
if (result == NULL) {
*errormsg = (char_u *)"";
return NULL;
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index 4cb0c9a4ae..84721ee96c 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -425,9 +425,11 @@ cs_add_common(
expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL);
size_t len = STRLEN(fname);
fbuf = (char_u *)fname;
- (void)modify_fname((char_u *)":p", &usedlen, (char_u **)&fname, &fbuf, &len);
- if (fname == NULL)
+ (void)modify_fname((char_u *)":p", false, &usedlen,
+ (char_u **)&fname, &fbuf, &len);
+ if (fname == NULL) {
goto add_err;
+ }
fname = (char *)vim_strnsave((char_u *)fname, len);
xfree(fbuf);
FileInfo file_info;
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 7d1021962c..b067de608b 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -870,8 +870,8 @@ size_t home_replace(const buf_T *const buf, const char_u *src,
size_t usedlen = 0;
size_t flen = strlen(homedir_env_mod);
char_u *fbuf = NULL;
- (void)modify_fname((char_u *)":p", &usedlen, (char_u **)&homedir_env_mod,
- &fbuf, &flen);
+ (void)modify_fname((char_u *)":p", false, &usedlen,
+ (char_u **)&homedir_env_mod, &fbuf, &flen);
flen = strlen(homedir_env_mod);
assert(homedir_env_mod != homedir_env);
if (vim_ispathsep(homedir_env_mod[flen - 1])) {
diff --git a/src/nvim/testdir/test_window_id.vim b/src/nvim/testdir/test_window_id.vim
index b3b506d04d..d10d831650 100644
--- a/src/nvim/testdir/test_window_id.vim
+++ b/src/nvim/testdir/test_window_id.vim
@@ -101,3 +101,23 @@ func Test_win_getid_curtab()
call assert_equal(win_getid(1), win_getid(1, 1))
tabclose!
endfunc
+
+func Test_winlayout()
+ let w1 = win_getid()
+ call assert_equal(['leaf', w1], winlayout())
+
+ split
+ let w2 = win_getid()
+ call assert_equal(['col', [['leaf', w2], ['leaf', w1]]], winlayout())
+
+ split
+ let w3 = win_getid()
+ call assert_equal(['col', [['leaf', w3], ['leaf', w2], ['leaf', w1]]], winlayout())
+
+ 2wincmd w
+ vsplit
+ let w4 = win_getid()
+ call assert_equal(['col', [['leaf', w3], ['row', [['leaf', w4], ['leaf', w2]]], ['leaf', w1]]], winlayout())
+
+ only!
+endfunc
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 2ce3b7067b..e6b19cf88d 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -6658,6 +6658,41 @@ void win_findbuf(typval_T *argvars, list_T *list)
}
}
+// Get the layout of the given tab page for winlayout().
+void get_framelayout(const frame_T *fr, list_T *l, bool outer)
+{
+ list_T *fr_list;
+
+ if (fr == NULL) {
+ return;
+ }
+
+ if (outer) {
+ // outermost call from f_winlayout()
+ fr_list = l;
+ } else {
+ fr_list = tv_list_alloc(2);
+ tv_list_append_list(l, fr_list);
+ }
+
+ if (fr->fr_layout == FR_LEAF) {
+ if (fr->fr_win != NULL) {
+ tv_list_append_string(fr_list, "leaf", -1);
+ tv_list_append_number(fr_list, fr->fr_win->handle);
+ }
+ } else {
+ tv_list_append_string(fr_list, fr->fr_layout == FR_ROW ? "row" : "col", -1);
+
+ list_T *const win_list = tv_list_alloc(kListLenUnknown);
+ tv_list_append_list(fr_list, win_list);
+ const frame_T *child = fr->fr_child;
+ while (child != NULL) {
+ get_framelayout(child, win_list, false);
+ child = child->fr_next;
+ }
+ }
+}
+
void win_ui_flush_positions(void)
{
FOR_ALL_TAB_WINDOWS(tp, wp) {
diff --git a/test/functional/legacy/expand_spec.lua b/test/functional/legacy/expand_spec.lua
index 7bf6fb67dc..1b735080f4 100644
--- a/test/functional/legacy/expand_spec.lua
+++ b/test/functional/legacy/expand_spec.lua
@@ -62,6 +62,14 @@ describe('expand file name', function()
call delete('Xdir ~ dir', 'd')
call assert_false(isdirectory('Xdir ~ dir'))
endfunc
+
+ func Test_expand_tilde_filename()
+ split ~
+ call assert_equal('~', expand('%'))
+ call assert_notequal(expand('%:p'), expand('~/'))
+ call assert_match('\~', expand('%:p'))
+ bwipe!
+ endfunc
]])
end)
@@ -74,4 +82,9 @@ describe('expand file name', function()
call('Test_with_tilde')
expected_empty()
end)
+
+ it('does not expand tilde if it is a filename', function()
+ call('Test_expand_tilde_filename')
+ expected_empty()
+ end)
end)