summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-01-17 21:49:33 +0100
committerBram Moolenaar <Bram@vim.org>2016-01-17 21:49:33 +0100
commitc970330676eaae7ba7cd05cfa46df5a413853ef9 (patch)
tree924e56cf3f08cdd7a0838766c53c2a4c2658586e
parente9b892ebcd8596bf813793a1eed5a460a9495a28 (diff)
patch 7.4.1126v7.4.1126
Problem: Can only get the directory of the current window. Solution: Add window and tab arguments to getcwd() and haslocaldir(). (Thinca, Hirohito Higashi)
-rw-r--r--runtime/doc/eval.txt27
-rw-r--r--src/Makefile1
-rw-r--r--src/eval.c120
-rw-r--r--src/testdir/Make_all.mak1
-rw-r--r--src/testdir/test_getcwd.in101
-rw-r--r--src/testdir/test_getcwd.ok18
-rw-r--r--src/version.c2
7 files changed, 218 insertions, 52 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 7b6ce981c4..866a7d9b17 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1851,7 +1851,7 @@ getcmdpos() Number return cursor position in command-line
getcmdtype() String return current command-line type
getcmdwintype() String return current command-line window type
getcurpos() List position of the cursor
-getcwd() String the current working directory
+getcwd( [{winnr} [, {tabnr}]]) String get the current working directory
getfontname( [{name}]) String name of font being used
getfperm( {fname}) String file permissions of file {fname}
getfsize( {fname}) Number size in bytes of file {fname}
@@ -1882,7 +1882,8 @@ globpath( {path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
String do glob({expr}) for all dirs in {path}
has( {feature}) Number TRUE if feature {feature} supported
has_key( {dict}, {key}) Number TRUE if {dict} has entry {key}
-haslocaldir() Number TRUE if current window executed |:lcd|
+haslocaldir( [{winnr} [, {tabnr}]])
+ Number TRUE if the window executed |:lcd|
hasmapto( {what} [, {mode} [, {abbr}]])
Number TRUE if mapping to {what} exists
histadd( {history},{item}) String add an item to a history
@@ -3522,8 +3523,16 @@ getcurpos() Get the position of the cursor. This is like getpos('.'), but
call setpos('.', save_cursor)
<
*getcwd()*
-getcwd() The result is a String, which is the name of the current
+getcwd([{winnr} [, {tabnr}]])
+ The result is a String, which is the name of the current
working directory.
+ Without arguments, for the current window.
+
+ With {winnr} return the local current directory of this window
+ in the current tab page.
+ With {winnr} and {tabnr} return the local current directory of
+ the window in the specified tab page.
+ Return an empty string if the arguments are invalid.
getfsize({fname}) *getfsize()*
The result is a Number, which is the size in bytes of the
@@ -3859,9 +3868,15 @@ has_key({dict}, {key}) *has_key()*
The result is a Number, which is 1 if |Dictionary| {dict} has
an entry with key {key}. Zero otherwise.
-haslocaldir() *haslocaldir()*
- The result is a Number, which is 1 when the current
- window has set a local path via |:lcd|, and 0 otherwise.
+haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()*
+ The result is a Number, which is 1 when the window has set a
+ local path via |:lcd|, and 0 otherwise.
+
+ Without arguments use the current window.
+ With {winnr} use this window in the current tab page.
+ With {winnr} and {tabnr} use the window in the specified tab
+ page.
+ Return 0 if the arguments are invalid.
hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
The result is a Number, which is 1 if there is a mapping that
diff --git a/src/Makefile b/src/Makefile
index 4977d7cb27..b23237ca48 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1946,6 +1946,7 @@ test1 \
test_erasebackword \
test_eval \
test_fixeol \
+ test_getcwd \
test_insertcount \
test_listchars \
test_listlbr \
diff --git a/src/eval.c b/src/eval.c
index c39d2cdfa3..5d0885401f 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -861,6 +861,7 @@ static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ;
static void free_funccal __ARGS((funccall_T *fc, int free_val));
static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr));
static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
+static win_T *find_tabwin __ARGS((typval_T *wvp, typval_T *tvp));
static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
@@ -3687,7 +3688,7 @@ do_unlet_var(lp, name_end, forceit)
{
listitem_T *li;
listitem_T *ll_li = lp->ll_li;
- int ll_n1 = lp->ll_n1;
+ int ll_n1 = lp->ll_n1;
while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1))
{
@@ -8183,7 +8184,7 @@ static struct fst
{"getcmdtype", 0, 0, f_getcmdtype},
{"getcmdwintype", 0, 0, f_getcmdwintype},
{"getcurpos", 0, 0, f_getcurpos},
- {"getcwd", 0, 0, f_getcwd},
+ {"getcwd", 0, 2, f_getcwd},
{"getfontname", 0, 1, f_getfontname},
{"getfperm", 1, 1, f_getfperm},
{"getfsize", 1, 1, f_getfsize},
@@ -8207,7 +8208,7 @@ static struct fst
{"globpath", 2, 5, f_globpath},
{"has", 1, 1, f_has},
{"has_key", 2, 2, f_has_key},
- {"haslocaldir", 0, 0, f_haslocaldir},
+ {"haslocaldir", 0, 2, f_haslocaldir},
{"hasmapto", 1, 3, f_hasmapto},
{"highlightID", 1, 1, f_hlID}, /* obsolete */
{"highlight_exists",1, 1, f_hlexists}, /* obsolete */
@@ -9127,30 +9128,11 @@ f_arglistid(argvars, rettv)
typval_T *rettv;
{
win_T *wp;
- tabpage_T *tp = NULL;
- long n;
rettv->vval.v_number = -1;
- if (argvars[0].v_type != VAR_UNKNOWN)
- {
- if (argvars[1].v_type != VAR_UNKNOWN)
- {
- n = get_tv_number(&argvars[1]);
- if (n >= 0)
- tp = find_tabpage(n);
- }
- else
- tp = curtab;
-
- if (tp != NULL)
- {
- wp = find_win_by_nr(&argvars[0], tp);
- if (wp != NULL)
- rettv->vval.v_number = wp->w_alist->id;
- }
- }
- else
- rettv->vval.v_number = curwin->w_alist->id;
+ wp = find_tabwin(&argvars[0], &argvars[1]);
+ if (wp != NULL)
+ rettv->vval.v_number = wp->w_alist->id;
}
/*
@@ -12061,25 +12043,36 @@ f_getcmdwintype(argvars, rettv)
*/
static void
f_getcwd(argvars, rettv)
- typval_T *argvars UNUSED;
+ typval_T *argvars;
typval_T *rettv;
{
+ win_T *wp = NULL;
char_u *cwd;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- cwd = alloc(MAXPATHL);
- if (cwd != NULL)
+
+ wp = find_tabwin(&argvars[0], &argvars[1]);
+ if (wp != NULL)
{
- if (mch_dirname(cwd, MAXPATHL) != FAIL)
+ if (wp->w_localdir != NULL)
+ rettv->vval.v_string = vim_strsave(wp->w_localdir);
+ else if(globaldir != NULL)
+ rettv->vval.v_string = vim_strsave(globaldir);
+ else
{
- rettv->vval.v_string = vim_strsave(cwd);
+ cwd = alloc(MAXPATHL);
+ if (cwd != NULL)
+ {
+ if (mch_dirname(cwd, MAXPATHL) != FAIL)
+ rettv->vval.v_string = vim_strsave(cwd);
+ vim_free(cwd);
+ }
+ }
#ifdef BACKSLASH_IN_FILENAME
- if (rettv->vval.v_string != NULL)
- slash_adjust(rettv->vval.v_string);
+ if (rettv->vval.v_string != NULL)
+ slash_adjust(rettv->vval.v_string);
#endif
- }
- vim_free(cwd);
}
}
@@ -12709,6 +12702,38 @@ find_win_by_nr(vp, tp)
}
/*
+ * Find window specified by "wvp" in tabpage "tvp".
+ */
+ static win_T *
+find_tabwin(wvp, tvp)
+ typval_T *wvp; /* VAR_UNKNOWN for current window */
+ typval_T *tvp; /* VAR_UNKNOWN for current tab page */
+{
+ win_T *wp = NULL;
+ tabpage_T *tp = NULL;
+ long n;
+
+ if (wvp->v_type != VAR_UNKNOWN)
+ {
+ if (tvp->v_type != VAR_UNKNOWN)
+ {
+ n = get_tv_number(tvp);
+ if (n >= 0)
+ tp = find_tabpage(n);
+ }
+ else
+ tp = curtab;
+
+ if (tp != NULL)
+ wp = find_win_by_nr(wvp, tp);
+ }
+ else
+ wp = curwin;
+
+ return wp;
+}
+
+/*
* "getwinvar()" function
*/
static void
@@ -13543,10 +13568,13 @@ f_has_key(argvars, rettv)
*/
static void
f_haslocaldir(argvars, rettv)
- typval_T *argvars UNUSED;
+ typval_T *argvars;
typval_T *rettv;
{
- rettv->vval.v_number = (curwin->w_localdir != NULL);
+ win_T *wp = NULL;
+
+ wp = find_tabwin(&argvars[0], &argvars[1]);
+ rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL);
}
/*
@@ -21851,15 +21879,15 @@ get_funccal()
funccal = current_funccal;
if (debug_backtrace_level > 0)
{
- for (i = 0; i < debug_backtrace_level; i++)
- {
- temp_funccal = funccal->caller;
- if (temp_funccal)
- funccal = temp_funccal;
+ for (i = 0; i < debug_backtrace_level; i++)
+ {
+ temp_funccal = funccal->caller;
+ if (temp_funccal)
+ funccal = temp_funccal;
else
- /* backtrace level overflow. reset to max */
- debug_backtrace_level = i;
- }
+ /* backtrace level overflow. reset to max */
+ debug_backtrace_level = i;
+ }
}
return funccal;
}
@@ -23379,8 +23407,8 @@ ret_free:
* Also handles a Funcref in a List or Dictionary.
* Returns the function name in allocated memory, or NULL for failure.
* flags:
- * TFN_INT: internal function name OK
- * TFN_QUIET: be quiet
+ * TFN_INT: internal function name OK
+ * TFN_QUIET: be quiet
* TFN_NO_AUTOLOAD: do not use script autoloading
* Advances "pp" to just after the function name (if no error).
*/
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 87fcbf9dbc..583bf0b56c 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -103,6 +103,7 @@ SCRIPTS_ALL = \
test_erasebackword.out \
test_eval.out \
test_fixeol.out \
+ test_getcwd.out \
test_insertcount.out \
test_listchars.out \
test_listlbr.out \
diff --git a/src/testdir/test_getcwd.in b/src/testdir/test_getcwd.in
new file mode 100644
index 0000000000..8c7b24ebf0
--- /dev/null
+++ b/src/testdir/test_getcwd.in
@@ -0,0 +1,101 @@
+Tests for getcwd(), haslocaldir(), and :lcd vim: set ft=vim :
+
+STARTTEST
+:so small.vim
+:" Do all test in a separate window to avoid E211 when we recursively
+:" delete the Xtopdir directory during cleanup
+:"
+:" This will cause a few errors, do it silently.
+:set visualbell
+:set nocp viminfo+=nviminfo
+:"
+:function! DeleteDirectory(dir)
+: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32")
+: exec "silent !rmdir /Q /S " . a:dir
+: else
+: exec "silent !rm -rf " . a:dir
+: endif
+:endfun
+:"
+:function! GetCwdInfo(win, tab)
+: let tab_changed = 0
+: let mod = ":t"
+: if a:tab > 0 && a:tab != tabpagenr()
+: let tab_changed = 1
+: exec "tabnext " . a:tab
+: endif
+: let bufname = fnamemodify(bufname(winbufnr(a:win)), mod)
+: if tab_changed
+: tabprevious
+: endif
+: if a:win == 0 && a:tab == 0
+: let dirname = fnamemodify(getcwd(), mod)
+: let lflag = haslocaldir()
+: elseif a:tab == 0
+: let dirname = fnamemodify(getcwd(a:win), mod)
+: let lflag = haslocaldir(a:win)
+: else
+: let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
+: let lflag = haslocaldir(a:win, a:tab)
+: endif
+: return bufname . ' ' . dirname . ' ' . lflag
+:endfunction
+:" On windows a stale "Xtopdir" directory may exist, remove it so that
+:" we start from a clean state.
+:call DeleteDirectory("Xtopdir")
+:let r=[]
+:new
+:let cwd=getcwd()
+:let test_out = cwd . '/test.out'
+:call mkdir('Xtopdir')
+:cd Xtopdir
+:call mkdir('Xdir1')
+:call mkdir('Xdir2')
+:call mkdir('Xdir3')
+:new a
+:new b
+:new c
+:3wincmd w
+:lcd Xdir1
+:call add(r, GetCwdInfo(0, 0))
+:wincmd W
+:call add(r, GetCwdInfo(0, 0))
+:wincmd W
+:lcd Xdir3
+:call add(r, GetCwdInfo(0, 0))
+:call add(r, GetCwdInfo(bufwinnr("a"), 0))
+:call add(r, GetCwdInfo(bufwinnr("b"), 0))
+:call add(r, GetCwdInfo(bufwinnr("c"), 0))
+:wincmd W
+:call add(r, GetCwdInfo(bufwinnr("a"), tabpagenr()))
+:call add(r, GetCwdInfo(bufwinnr("b"), tabpagenr()))
+:call add(r, GetCwdInfo(bufwinnr("c"), tabpagenr()))
+:"
+:tabnew x
+:new y
+:new z
+:3wincmd w
+:call add(r, GetCwdInfo(0, 0))
+:wincmd W
+:lcd Xdir2
+:call add(r, GetCwdInfo(0, 0))
+:wincmd W
+:lcd Xdir3
+:call add(r, GetCwdInfo(0, 0))
+:call add(r, GetCwdInfo(bufwinnr("x"), 0))
+:call add(r, GetCwdInfo(bufwinnr("y"), 0))
+:call add(r, GetCwdInfo(bufwinnr("z"), 0))
+:let tp_nr = tabpagenr()
+:tabrewind
+:call add(r, GetCwdInfo(3, tp_nr))
+:call add(r, GetCwdInfo(2, tp_nr))
+:call add(r, GetCwdInfo(1, tp_nr))
+:"
+:call writefile(r, test_out, "a")
+:q
+:exec "cd " . cwd
+:call DeleteDirectory("Xtopdir")
+:qa!
+ENDTEST
+
+
diff --git a/src/testdir/test_getcwd.ok b/src/testdir/test_getcwd.ok
new file mode 100644
index 0000000000..23699891f3
--- /dev/null
+++ b/src/testdir/test_getcwd.ok
@@ -0,0 +1,18 @@
+a Xdir1 1
+b Xtopdir 0
+c Xdir3 1
+a Xdir1 1
+b Xtopdir 0
+c Xdir3 1
+a Xdir1 1
+b Xtopdir 0
+c Xdir3 1
+x Xtopdir 0
+y Xdir2 1
+z Xdir3 1
+x Xtopdir 0
+y Xdir2 1
+z Xdir3 1
+x Xtopdir 0
+y Xdir2 1
+z Xdir3 1
diff --git a/src/version.c b/src/version.c
index 239d38535d..a444e46fd7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1126,
+/**/
1125,
/**/
1124,