Patch 7.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)
Files:      src/Makefile, src/testdir/Make_all.mak,
            src/testdir/test_getcwd.in, src/testdir/test_getcwd.ok,
            runtime/doc/eval.txt, patching file src/eval.c


*** ../vim-7.4.1125/src/Makefile        2016-01-16 21:50:32.586161476 +0100
--- src/Makefile        2016-01-17 21:28:52.162346195 +0100
***************
*** 1946,1951 ****
--- 1946,1952 ----
        test_erasebackword \
        test_eval \
        test_fixeol \
+       test_getcwd \
        test_insertcount \
        test_listchars \
        test_listlbr \
*** ../vim-7.4.1125/src/testdir/Make_all.mak    2016-01-17 21:15:17.843322552 
+0100
--- src/testdir/Make_all.mak    2016-01-17 21:29:08.646164479 +0100
***************
*** 103,108 ****
--- 103,109 ----
        test_erasebackword.out \
        test_eval.out \
        test_fixeol.out \
+       test_getcwd.out \
        test_insertcount.out \
        test_listchars.out \
        test_listlbr.out \
*** ../vim-7.4.1125/src/testdir/test_getcwd.in  2016-01-17 21:46:42.638552834 
+0100
--- src/testdir/test_getcwd.in  2016-01-17 21:28:04.398872762 +0100
***************
*** 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
+ 
+ 
*** ../vim-7.4.1125/src/testdir/test_getcwd.ok  2016-01-17 21:46:42.646552746 
+0100
--- src/testdir/test_getcwd.ok  2016-01-17 21:28:04.398872762 +0100
***************
*** 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
*** ../vim-7.4.1125/runtime/doc/eval.txt        2016-01-17 21:15:17.839322597 
+0100
--- runtime/doc/eval.txt        2016-01-17 21:38:39.355875311 +0100
***************
*** 1842,1848 ****
  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
  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}
--- 1851,1857 ----
  getcmdtype()                  String  return current command-line type
  getcmdwintype()                       String  return current command-line 
window type
  getcurpos()                   List    position of the cursor
! 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}
***************
*** 1873,1879 ****
                                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|
  hasmapto( {what} [, {mode} [, {abbr}]])
                                Number  TRUE if mapping to {what} exists
  histadd( {history},{item})    String  add an item to a history
--- 1882,1889 ----
                                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( [{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
***************
*** 3466,3490 ****
                    ?   backward search command
                    @   |input()| command
                    -   |:insert| or |:append| command
                Only works when editing the command line, thus requires use of
                |c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
                Returns an empty string otherwise.
                Also see |getcmdpos()|, |setcmdpos()| and |getcmdline()|.
  
                                                        *getcurpos()*
  getcurpos()   Get the position of the cursor.  This is like getpos('.'), but
                includes an extra item in the list:
!                   [bufnum, lnum, col, off, curswant]
                The "curswant" number is the preferred column when moving the
                cursor vertically.
                This can be used to save and restore the cursor position: >
                        let save_cursor = getcurpos()
                        MoveTheCursorAround
                        call setpos('.', save_cursor)
! 
                                                        *getcwd()*
! getcwd()      The result is a String, which is the name of the current
                working directory.
  
  getfsize({fname})                                     *getfsize()*
                The result is a Number, which is the size in bytes of the
--- 3500,3538 ----
                    ?   backward search command
                    @   |input()| command
                    -   |:insert| or |:append| command
+                   =   |i_CTRL-R_=|
                Only works when editing the command line, thus requires use of
                |c_CTRL-\_e| or |c_CTRL-R_=| or an expression mapping.
                Returns an empty string otherwise.
                Also see |getcmdpos()|, |setcmdpos()| and |getcmdline()|.
  
+ getcmdwintype()                                               
*getcmdwintype()*
+               Return the current |command-line-window| type. Possible return
+               values are the same as |getcmdtype()|. Returns an empty string
+               when not in the command-line window.
+ 
                                                        *getcurpos()*
  getcurpos()   Get the position of the cursor.  This is like getpos('.'), but
                includes an extra item in the list:
!                   [bufnum, lnum, col, off, curswant] ~
                The "curswant" number is the preferred column when moving the
                cursor vertically.
                This can be used to save and restore the cursor position: >
                        let save_cursor = getcurpos()
                        MoveTheCursorAround
                        call setpos('.', save_cursor)
! <
                                                        *getcwd()*
! 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
***************
*** 3787,3795 ****
                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.
  
  hasmapto({what} [, {mode} [, {abbr}]])                        *hasmapto()*
                The result is a Number, which is 1 if there is a mapping that
--- 3868,3882 ----
                The result is a Number, which is 1 if |Dictionary| {dict} has
                an entry with key {key}.  Zero 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
*** ../vim-7.4.1125/src/eval.c  2016-01-17 21:15:17.843322552 +0100
--- src/eval.c  2016-01-17 21:33:57.878976609 +0100
***************
*** 861,866 ****
--- 861,867 ----
  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,3693 ****
      {
        listitem_T    *li;
        listitem_T    *ll_li = lp->ll_li;
!       int           ll_n1 = lp->ll_n1;
  
        while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1))
        {
--- 3688,3694 ----
      {
        listitem_T    *li;
        listitem_T    *ll_li = lp->ll_li;
!       int           ll_n1 = lp->ll_n1;
  
        while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1))
        {
***************
*** 8183,8189 ****
      {"getcmdtype",    0, 0, f_getcmdtype},
      {"getcmdwintype", 0, 0, f_getcmdwintype},
      {"getcurpos",     0, 0, f_getcurpos},
!     {"getcwd",                0, 0, f_getcwd},
      {"getfontname",   0, 1, f_getfontname},
      {"getfperm",      1, 1, f_getfperm},
      {"getfsize",      1, 1, f_getfsize},
--- 8184,8190 ----
      {"getcmdtype",    0, 0, f_getcmdtype},
      {"getcmdwintype", 0, 0, f_getcmdwintype},
      {"getcurpos",     0, 0, f_getcurpos},
!     {"getcwd",                0, 2, f_getcwd},
      {"getfontname",   0, 1, f_getfontname},
      {"getfperm",      1, 1, f_getfperm},
      {"getfsize",      1, 1, f_getfsize},
***************
*** 8207,8213 ****
      {"globpath",      2, 5, f_globpath},
      {"has",           1, 1, f_has},
      {"has_key",               2, 2, f_has_key},
!     {"haslocaldir",   0, 0, f_haslocaldir},
      {"hasmapto",      1, 3, f_hasmapto},
      {"highlightID",   1, 1, f_hlID},          /* obsolete */
      {"highlight_exists",1, 1, f_hlexists},    /* obsolete */
--- 8208,8214 ----
      {"globpath",      2, 5, f_globpath},
      {"has",           1, 1, f_has},
      {"has_key",               2, 2, f_has_key},
!     {"haslocaldir",   0, 2, f_haslocaldir},
      {"hasmapto",      1, 3, f_hasmapto},
      {"highlightID",   1, 1, f_hlID},          /* obsolete */
      {"highlight_exists",1, 1, f_hlexists},    /* obsolete */
***************
*** 9127,9156 ****
      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;
  }
  
  /*
--- 9128,9138 ----
      typval_T  *rettv;
  {
      win_T     *wp;
  
      rettv->vval.v_number = -1;
!     wp = find_tabwin(&argvars[0], &argvars[1]);
!     if (wp != NULL)
!       rettv->vval.v_number = wp->w_alist->id;
  }
  
  /*
***************
*** 12061,12085 ****
   */
      static void
  f_getcwd(argvars, rettv)
!     typval_T  *argvars UNUSED;
      typval_T  *rettv;
  {
      char_u    *cwd;
  
      rettv->v_type = VAR_STRING;
      rettv->vval.v_string = NULL;
!     cwd = alloc(MAXPATHL);
!     if (cwd != NULL)
      {
!       if (mch_dirname(cwd, MAXPATHL) != FAIL)
        {
!           rettv->vval.v_string = vim_strsave(cwd);
  #ifdef BACKSLASH_IN_FILENAME
!           if (rettv->vval.v_string != NULL)
!               slash_adjust(rettv->vval.v_string);
  #endif
-       }
-       vim_free(cwd);
      }
  }
  
--- 12043,12078 ----
   */
      static void
  f_getcwd(argvars, rettv)
!     typval_T  *argvars;
      typval_T  *rettv;
  {
+     win_T     *wp = NULL;
      char_u    *cwd;
  
      rettv->v_type = VAR_STRING;
      rettv->vval.v_string = NULL;
! 
!     wp = find_tabwin(&argvars[0], &argvars[1]);
!     if (wp != NULL)
      {
!       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
        {
!           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);
  #endif
      }
  }
  
***************
*** 12709,12714 ****
--- 12702,12739 ----
  }
  
  /*
+  * 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,13552 ****
   */
      static void
  f_haslocaldir(argvars, rettv)
!     typval_T  *argvars UNUSED;
      typval_T  *rettv;
  {
!     rettv->vval.v_number = (curwin->w_localdir != NULL);
  }
  
  /*
--- 13568,13580 ----
   */
      static void
  f_haslocaldir(argvars, rettv)
!     typval_T  *argvars;
      typval_T  *rettv;
  {
!     win_T     *wp = NULL;
! 
!     wp = find_tabwin(&argvars[0], &argvars[1]);
!     rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL);
  }
  
  /*
***************
*** 21851,21865 ****
      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;
            else
!                 /* backtrace level overflow. reset to max */
!                 debug_backtrace_level = i;
!         }
      }
      return funccal;
  }
--- 21879,21893 ----
      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;
            else
!               /* backtrace level overflow. reset to max */
!               debug_backtrace_level = i;
!       }
      }
      return funccal;
  }
***************
*** 23379,23386 ****
   * 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_NO_AUTOLOAD: do not use script autoloading
   * Advances "pp" to just after the function name (if no error).
   */
--- 23407,23414 ----
   * 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_NO_AUTOLOAD: do not use script autoloading
   * Advances "pp" to just after the function name (if no error).
   */
*** ../vim-7.4.1125/src/version.c       2016-01-17 21:15:17.843322552 +0100
--- src/version.c       2016-01-17 21:39:08.659552505 +0100
***************
*** 743,744 ****
--- 743,746 ----
  {   /* Add new patch number below this line */
+ /**/
+     1126,
  /**/

-- 
An alien life briefly visits earth.  Just before departing it leaves a
message in the dust on the back of a white van.  The world is shocked
and wants to know what it means.  After months of studies the worlds
best linguistic scientists are able to decipher the message: "Wash me!".

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui