]> granicus.if.org Git - vim/commitdiff
patch 7.4.1126 v7.4.1126
authorBram Moolenaar <Bram@vim.org>
Sun, 17 Jan 2016 20:49:33 +0000 (21:49 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 17 Jan 2016 20:49:33 +0000 (21:49 +0100)
Problem:    Can only get the directory of the current window.
Solution:   Add window and tab arguments to getcwd() and haslocaldir().
            (Thinca, Hirohito Higashi)

runtime/doc/eval.txt
src/Makefile
src/eval.c
src/testdir/Make_all.mak
src/testdir/test_getcwd.in [new file with mode: 0644]
src/testdir/test_getcwd.ok [new file with mode: 0644]
src/version.c

index 7b6ce981c4a2f00301b704abd167780f822de32c..866a7d9b17b492988a95d9e19ae4455b1e02a4f1 100644 (file)
@@ -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
index 4977d7cb27f7831697d948077c4420784973a6e5..b23237ca487d7ac1c181ab67a5fe4e288184a1f0 100644 (file)
@@ -1946,6 +1946,7 @@ test1 \
        test_erasebackword \
        test_eval \
        test_fixeol \
+       test_getcwd \
        test_insertcount \
        test_listchars \
        test_listlbr \
index c39d2cdfa39782a333a4add2ed49f2bdb8baf0c8..5d0885401f085a7d5ba118bab34c0205a53e1a7f 100644 (file)
@@ -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);
     }
 }
 
@@ -12708,6 +12701,38 @@ find_win_by_nr(vp, tp)
 #endif
 }
 
+/*
+ * 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
  */
@@ -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).
  */
index 87fcbf9dbc9dd4675f067aa67235099f0fb42da3..583bf0b56c763193aaf6fd4d432d68a50e04e71e 100644 (file)
@@ -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 (file)
index 0000000..8c7b24e
--- /dev/null
@@ -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 (file)
index 0000000..2369989
--- /dev/null
@@ -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
index 239d38535d2568c9c0e738357e310b48f3efcf9c..a444e46fd761b6cc4dbadf7fa7f59e97d9c8f7cc 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1126,
 /**/
     1125,
 /**/