EDIT
The scenario changed. Sorry, for posting question a bit too early.
When opening a file (vim filename.ext, or :e filename.txt, etc.), when the CWD is ~/Sites/A, vim changes to another CWD (~/Sites/B).
I found out, that vim does this because of a file in my ~/.vim/view/ folder, called ~=+Sites=+B=+src=+filename.txt=.
The file inside ~/.vim/view/ contains:
let s:so_save = &so | let s:siso_save = &siso | set so=0 siso=0
argglobal
setlocal fdm=manual
setlocal fde=0
setlocal fmr={{{,}}}
setlocal fdi=#
setlocal fdl=0
setlocal fml=1
setlocal fdn=20
setlocal fen
silent! normal! zE
let s:l = 200 - ((13 * winheight(0) + 11) / 23)
if s:l < 1 | let s:l = 1 | endif
exe s:l
normal! zt
200
normal! 030|
lcd ~/Sites/B
let &so = s:so_save | let &siso = s:siso_save
doautoall SessionLoadPost
" vim: set ft=vim :
Why is the line lcs ~/Sites/B standing in this file? Inside ~/Sites/B never existed a file called filename.ext.
For the sake of completeness, this is my question, before I localized the error:
When i vimgrep something in a codebase located in ~/Sites/a (e.g. :vimgrep DateCell src/**/*) vim's current working directory changes to another directory ~/Sites/B.
Every subsequent call to vimgrep or another working-directory-aware-command fails or returns wrong results, because it is operating in the ~/Sites/B directory.
What could cause this?
What I do, to achieve the error / wrong behaviour:
cd ~/Sites/A
vim
vimgrep something src/**/*
:!pwd shows ~/Sites/B
:quit
pwd shows ~/Sites/A
EDIT
It turns out, that the directory change also happens if I don't use vimgrep. I still don't know what produces the error.
BTW: It is always the same directory (~/Sites/B), vim changes to. No matter in which directory i am working.
Vim Version: 8.0.2
OS Version: OS X 10.10.5
The ~=+Sites=+B=+src=+filename.txt= is a saved view for ~/Sites/B/src/filename.txt. The question is: Why does it get loaded when you open a file (with the same name, or any, not entirely clear from your question) from another directory?
Normally, views have to be created and restored manually. You seem to have something in your configuration (:autocmd) that automatically restores saved views, and that something has a bug in its path lookup (or, less likely, your filesystem is messed up and you have symlinks there). Find that, and turn it off / fix it.
Related
I want these commands run on every filetype except my vimwiki file (.wiki and .md)
Here is how I'm trying to do it:
let ftToIgnore = ['wiki', 'md']
autocmd BufWinEnter * if index(ftToIgnore, &ft) < 0 | syntax on
autocmd BufWinEnter * if index(ftToIgnore, &ft) < 0 | colorscheme minimalist
It is not working. It is running these commands on every single filetype, including wiki/md.
How can I fix this?
There are several things we need to clear.
First, I think some commands are inherently global even though you have only run it for specific filetypes, for example, the above colorscheme command is a global command, you can not make it work only for one buffer.
To verify, you can open several files of different types, if some file does not match your ignore type, colorscheme command will run. Then for all the files, colorscheme will be set to that theme you choose, even though you haven't specified colorscheme for the ignored file types.
Second, you can not use &ft to check the file type of a file when reading it, at that time, file type detection is being conducted, and the type of file haven't been determined. You can use file suffix to check a file's type like this: expand('%:p:e') (this will get the suffix of a file).
In summary, you are doing two things wrong: (1) use a inherently global options or commands and expect it to work only for a certain file type (2) use &ft to decide a file's type during its opening.
If you use some options that can be local to a buffer and change the way you detect a file's type, you will find that the command can be local to that file. For example, use the following toy.vim config:
let suffix_to_ignore = ['md', ]
autocmd BufWinEnter * if index(suffix_to_ignore, expand("%:p:e")) < 0 | setlocal tabstop=4 | endif
Activate vim with vim -u toy.vim. Then edit a vim file, :e toy.vim, set tabstop? shows that tabstop is set to 4. Open a markdown file, :e test.md, set tabstop? shows that tabstop is still 8. So the command is indeed only run for other filetypes other than Markdown.
References
Does “set” command affect only the active buffer?
is per-buffer colorscheme possible?
autochdir automatically sets the current working directory to the present file that the cursor is located on. I'd like to exclude autochdir from changing the directory if the cursor is in the NERDTree window.
For example, if the present file I'm working on is in ~/foo, and the NERDTree window is in ~/lots/of/stuff/here, I'd like to go to the NERDTree window and still have the current working directory set to ~/foo.
That way, one can apply the CD keybind, which will set NERDTree's root tree node to ~/foo. Otherwise, it's terribly inconvenient to manually change the root tree node in the NERDTree window by navigating to ~/foo, and then applying the cd keybind.
From :help autochdir:
This option is provided for backward compatibility with the Vim
released with Sun ONE Studio 4 Enterprise Edition.
Note: When this option is on some plugins may not work.
I.e. it is obsolete, inflexible and breaks plugins. I suggest you don't use it, and instead use one of the alternate, more configurable mechanisms here. For instance,
autocmd BufEnter * if &ft !~ '^nerdtree$' | silent! lcd %:p:h | endif
However, while this does not change the current directory when you pull up NERDTree, it will not preserve it, either. I'm not 100% sure what you mean in your last paragraph.
I use Vim 7.4 (Mac OS) to edit and run Lua scripts. I've mapped a key in my .vimrc to save the current buffer and run an external script.
The key map in .vimrc:
map V :w!<CR> :!python "$HOME/tools/client/concli.py" --lua %<CR>
It works fine but every once in a while the files are 'touched' by Xcode (touch shell command). Then when I hit the mapped key vim warns me that the file has been changed externally and I have to confirm to write to it.
This is quite annoying since the files are often touched. How could I force vim to overwrite external changes without prompting? I tried 'w!' without success.
Thank you, Laurent
Indeed, the overwrite confirmation cannot be turned off with :w!, and :set autoread doesn't help in this case, neither. What does work is instructing Vim to explicitly check for changes before the write:
:checktime | w
I believe
set autoread
should do it. It tells Vim to automatically re-reads the file changed outside Vim.
I saw this in a mailing list. Apparently it is called if the file has changed timestamp, after a call to an external shell command.
function! ProcessFileChangedShell()
if v:fcs_reason == 'mode' || v:fcs_reason == 'time'
let v:fcs_choice = ''
else
let v:fcs_choice = 'ask'
endif
endfunction
autocmd FileChangedShell call ProcessFileChangedShell()
But it did not consistently fire for me. (Depending whether or not I had edited the file since the change, which in my case was external.)
There are some more tricks on the VimTips wiki which may help.
Add this to your ~/.vimrc file:
set autoread
nnoremap <C-u> :checktime<CR>
Now whenever you want vim to reload external changes, just click CTRL-U :)
I have the following command run as a vim plugin under ~/.vim/plugin/autohighlight.vim
:autocmd CursorMoved * exe printf('match IncSearch /\<%s\>/', expand('<cword>'))
The thing is, it throws a bunch of errors anywhere except when I'm editing a file. (file Explorer, other windows)
Is there a way to tell the script to only take effect when a file is edited and not anywhere else in VIM?
You can try this one:
autocmd CursorMoved * :if filewritable(#%)==1 |
\ call matchadd('IncSearch', '\V\<'.escape(expand('<cword>').'\>', '\'), 10, 1) |
\endif
It will do highlighting only if current buffer name is a writable file (not directory). It will fail if you are editing something which uses BufWriteCmd to perform saving (for example, if you are editing file inside a zip archive).
By the way, can you provide these errors? I was able to get an error when I used :e ., but it was not related to the fact that you are observing a directory, it appeared just because you forgot to do escaping. If you have written escape(expand('<cword>'), '\/') instead of expand('<cword>') then such error would not appear.
what I am using now is ,
autocmd BufWritePost *.py !python PythonTidy.py % %
It really call the tidy programe and change the file, but the vim does not reload the new file.
And I do not want to install another plugin for it.
=======================
note: I found it's dangerous about this feature, PythonTidy will will output a empty file if the command faild, it means if you have syntax error, you will lose your file unless press "u" to get it,but you can't save before you fix syntax error.
I call :!PythonTidy % % manually after pylint complete now.
Use BufWritePre instead of BufWritePost and combine Vim range filtering with PythonTidy’s stdin/stdout mode.
autocmd FileType python autocmd BufWritePre <buffer> let s:saveview = winsaveview() | exe '%!python PythonTidy.py' | call winrestview(s:saveview) | unlet s:saveview
(The use of autocmd FileType python autocmd BufWritePre <buffer> makes this a bit more accurate than matching on a glob pattern: it means “any time a Python file is detected, install this autocmd for that buffer” – so it works independently of file name.)
Unfortunately this cannot preserve your cursor position if you undo the filtering. (You are filtering a whole-file range; when undoing a filter operation, the cursor jumps to the first line in the range; so you end up at the top of the file.) I was hoping to find a way to create a no-op undo state, before, so you could hit u twice and get back to the right place, but I can’t make that work as yet. Maybe someone else knows how.
hi the following fixed the cursor postion problem
function! PythonTidySaver()
let oldpos=getpos('.')
%!PythonTidy
call setpos('.',oldpos)
endfunction
autocmd! bufwritepost *.py call PythonTidySaver()
Based on :help :e:
*:e* *:edit*
:e[dit] [++opt] [+cmd] Edit the current file. This is useful to re-edit the
current file, when it has been changed outside of Vim.
This fails when changes have been made to the current
buffer and 'autowriteall' isn't set or the file can't
be written.
Also see |++opt| and |+cmd|.
{Vi: no ++opt}
So you'd need to use :e after updating the file externally. However, :! doesn't let you use | normally (see :help :!), so you need to wrap it:
autocmd BufWritePost *.py execute "!python PythonTidy.py % %" | e
(:autocmd doesn't interpret | normally either, which is why you don't need to escape it yet again.)