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.