How to prevent syntastic from creating a directory for every vim instance? - vim

When using the syntastic plugin with vim, I see a new /tmp/vXXXXXXX directory every time I open a new vim instance. When the syntastic plugin gets disabled, no such directories are created.
When I ran inotify, I found that a numeric file is created in that directory every time I save a file. Is it possible to make syntastic (or vim) create a temporary directory on demand? Failing on that, can I make it use a single directory instead? For example, /tmp/vim-syntastic/vXXXXXXX/?

According to the developer, syntastic does not create temporary directories by itself, that is handled by vim. Looking a bit further, I found that vim uses $TMPDIR to set a temporary directory. If the directory is unwritable, then it gets ignored.
So, as a solution, the following lines set the temporary directory to /tmp/vim-USERNAME, and then create it (ignoring errors that normally occur when the directory exists):
" Keep all vim-related temp files in a single directory
let $TMPDIR = '/tmp/vim-' . $USER
silent! call mkdir($TMPDIR, '', 0700)
Now, I do not have a lot of /tmp/vXXXXXX/ directories anymore. Instead, they appear in /tmp/vim-peter/vXXXXXX/ which is great.

If you look in the syntastic helpfiles, you'll see that syntastic uses a 'tail' file for storing the output of a given make program. You can override the default tail for a given filetype and subchecker by adding the following to your vimrc:
let g:syntastic_<filetype>_<subchecker>_tail = "> /tmp/vim-syntastic/your-file-here"
So for example if you wanted mri to output to /tmp/vim-syntastic/ruby-mri, you would write:
let g:syntastic_ruby_mri_tail = "> /tmp/vim-syntastic/ruby-mri"
See :help syntastic-config-makeprg for more info. Here's a direct link on git. As far as I know there's no built-in way to set the default directory for all syntastic output, unfortunately.
Edit: Lekenstein found another solution, which he posted in the linked Github issue.
let $TMPDIR = '/tmp/vim-' . $USER
silent! call mkdir($TMPDIR, '', 0700)
This will make a special directory for all vim-related temporary files. That means it will also affect temporary files not related to syntastic.

Related

What is the line to add to vimrc for storing .swp files in /tmp on Ubuntu

I feel like I've literally tried everything, but no matter what I add to vimrc, I can't get it to store its annoying .swp files in /tmp. I'm using Ubuntu 16.04. I've obviously looked up this issue extensively, but again, no command I enter seems to work. I always end up with:
E510: Can't make backup file
(add ! to override)
Things I've tried:
set backupdir=$~/tmp//
set directory=$~/tmp//
set backupdir=~/tmp//
set backupdir=$HOME~/tmp//
set backupdir=/tmp//
I mean you name it, I've tried it. So, explicitly, what is the exact code I need to type in vimrc to make it so vim saves it's .swp files in my temporary folder, instead of cluttering my workspace?
Thank you.
Adding the following line to my ~/.vimrc puts .swp files for currently open buffers under /tmp
set directory=/tmp
If you've tried this without issues are you able to verify that vim is reading your vimrc at all?
It appears the issue was I didn't really understand what ~ means. I created a folder called 'tmp' in my home directory, and from there used:
set backupdir=~/tmp//

How to run vim commands/scripts from project root?

I have a multitude of commands I'd like to run not in the current directory, but in the project root directory. i.e. going up directories until I reach some indication of a root, like .git directory for example.
For example running vimgrep -r (recursive) on all my project, or running tags generation recursively on whole project.
How do I get that path? The only close indication I found is this:set tags=./tags;~/Projects
But that just saves the string as it is into tags. Assigning something similar but for the use case described, gets me the string verbatim.
Any help is greatly appreciated!
Thanks!
Avoid the idea of "changing the working directory" or distinguishing between "working directory and project root", because almost no tool is prepared to properly handle those concepts.
The only tools that do (e.g. git) are those that don't care about the current directory to begin with.
Otherwise, it's madness to try to get everything working without bad side effects. "Working directory" is a concept too fundamental to even attempt to change within a running program.
The best approach is open a new Vim sessions inside directories where you want to do "local" things - and switch back to the "project" session to run project commands. Vim will protect you from accidentally overwriting changes in another session.
The alternative is to wrap commands in shells so they can have their "own" working directories, e.g.:
:!cd ../../..; ctags -R
(Which would allow you to regenerate tags file for the project, and not just the current dir)
or:
:!cd ../../..; grep -r foo **/*
But any output with file names would be relative to that root directory, and not the current one.
So you may prefer to do:
:!cd ../../..; vim
which creates a new Vim session within the current one, but in the context of the root directory.
Or, you may prefer the reverse (assuming Vim is running in the project root):
:!cd $(dirname %); vim
Which lets you work in the directory of the current file - and you'd have to exit to the main session to run project-wide tools again.
So instead of "changing" directories, you're "changing vim sessions" (either by having 2 sessions or "nesting" one in another like above).
I use a local_vimrc plugin to set project related variables. Then, I use (/write) plugins that rely on (buffer/project)-local variables to do stuff. (Unfortunately, most plugin out there rely of global variables which is not the best choice to specialize their behaviour to the current project in multi-projects sessions)
Regarding ctags generation, in use lh-tags that requires a few variables to be set.
Regarding grepping, as other, I usually start from the current directory which is often the root directory of my project. But you could also easily have a plugin/command that would run something like:
exe "vimgrep -r ".pattern." ".
\ map(file_extensions,
\ string(lh#option#get('project_root_directory').'/**').'v:val')
EDIT:
If you don't want other configuration files, and if the .git/ directory is enough to identify your project root directory, then, you can have this kind of function to get your project root directory:
function! ProjectRootDirectory()
return fnamemodify(finddir('.git', '.;'), ':h')
endfunction
Then when you'll run ctags, you'll have to execute ctags from the result of this vim function. I don't know which plugin you use to run ctags, at this moment. My lh-tags doesn't support functions through its configuration variables. It can easily been added if need be.
However, I don't see a simple way to configure &tags once from the .vimrc in order to configure this setting on a per project basis.
I personally like to keep it simple and have my current directory be my project root. I can use % to represent the current file in commands, e.g. :!git add %. Along with % you can use filename modifiers, e.g. :e %:h/foo.txt. See :h filename-modifiers.
However you mentioned that you use CtrlP and you like the way it changes the current directory. This means you need to be a bit more creative.
Here is what I would recommend:
Update your tags via git hooks. See Effortless Ctags with Git
If your tags are in .git/tags fugitive.vim will automatically setup these tags for you.
Use :Ggrep which uses git grep so it already know about your project root directory and as a bonus is much faster than :vimgrep.
Running arbitrary commands from the root is trickier. I use projectionist to manage my projects. Projectionist provides the command, :ProjectDo, which does exactly what you want.
Now a word of caution: Vim has no understanding of a "project". The closest thing to is 'exrc' option (See :h 'exrc') which is pretty lame.

Cannot get Pathogen to work in Vim

I know there are multiple posts on this question but I have tried with no avail to get this simple part of Vim to work. I would like to get the pathogen plugin to work with Vim. As a few points, I am working on a Windows system. I have downloaded pathogen via github and have created the directories .vim and subdirectories autoload and bundle. My .vimrc is the default created with mkvimrc with:
call pathogen#infect()
syntax on
filetype plugin indent on
added to the bottom. Addressing other postings I have seen:
:set cp? = nocompatible
One area I am guessing is part of the issue is after I run :scriptnames I don't get the .vim directory. I only get the Vim\.vimrc and vim73 directories. How do I address this? I have been at this a long time and apologize if this is obvious to others here.
On Windows the default location of the local user configuration is $HOME/vimfiles. If your files are in $HOME/.vim then you either need to move them to vimfiles or add .vim to your runtimepath in your .vimrc:
set runtimepath+=~/.vim
Also, if Pathogen is in a subdirectory of bundle you will need to run it explicitly from there, since by default Vim will only look in ~/.vim/. Put this in your .vimrc before the pathogen#infect call:
runtime bundle/pathogen/autoload/pathogen.vim
The solution for me was re-downloading the pathogen.vim as it had somehow failed to download by failing to follow a redirect. The URL specified on tpope's github has the following step:
mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
You will know the redirect failed to download as the contents of pathogen.vim will be a 302 redirect page. Just download from the URL contained in the redirect e.g:
wget -N -O ~/.vim/autoload/pathogen.vim https://raw.githubusercontent.com/tpope/vim-pathogen/master/autoload/pathogen.vim
Open Vim with disabled plugins and type :set rtp - notice that:
if you are on Unix, then by default: the first goes ~/.vim and the last goes ~/.vim/after;
if you are on Windows, then by default: the first goes ~/vimfiles and the last goes ~/vimfiles/after.
This is sort of Vim convention. after directories are used to forcefully override Vim's defaults or plugins' settings, which is important sometimes. That's why they are the last in the rtp.
Pathogen actually parses the structure of your current rtp variable and uses it to inject paths of plugins into the rtp properly. For example, look at my rtp:
runtimepath=
~/.vim,
~\.vim\plugins\NERDCommenter,
~\.vim\plugins\NERDTree,
~\.vim\plugins\SameSyntaxMotion,
~\.vim\plugins\Tabular,
~\.vim\plugins\UltiSnips,
~\.vim\plugins\c.vim,
~\.vim\plugins\clang_complete,
~\.vim\plugins\CountJump,
~\.vim\plugins\delimitMate,
~\.vim\plugins\fswitch,
~\.vim\plugins\matchit,
~\.vim\plugins\matlab,
~\.vim\plugins\neocomplcache,
~\.vim\plugins\protodef,
~\.vim\plugins\python-syntax,
~\.vim\plugins\solarized,
~\.vim\plugins\syntastic,
~\.vim\plugins\vim-creole,
~\.vim\plugins\vim-latex,
~\.vim\plugins\vim-markdown,
~\.vim\plugins\vim-python-pep8-indent,
~/vimfiles,
D:\Applications\Vim/vimfiles,
D:\Applications\Vim,
D:\Applications\Vim/vimfiles/after,
~/vimfiles/after,
~\.vim\plugins\Tabular\after,
~\.vim\plugins\UltiSnips\after,
~\.vim\plugins\vim-markdown\after,
~/.vim/after
Notice how pathogen injected paths. It has detected that several plugins have after directory and put them right before ~/.vim/after - so that the last word is always mine.
To achieve this pathogen needs a pair of either ~/.vim and ~/.vim/after or ~/vimfiles and ~/vimfiles/after or even ~/stuff and ~/stuff/after (not sure about the last case though) as anchors to inject plugins' paths in the right order.
If any directory from this pair is missing, then you will have some nasty experience with pathogen (as I did sometime ago, until I found out all the aforementioned stuff and skimmed through pathogen source code) - because paths will not be able to be injected correctly.
Now you can see that the answer provided by Prince Goulash is completely wrong:
the first mistake is that he has appended ~/.vim to rtp whereas
he should have prepended it;
the second mistake is that he didn't append ~/.vim/after.
The correct solution looks as follows. If you have to work on different platforms including Windows you should rather add this into your .vimrc (I keep this in mine as well - you can infer it from my rtp example):
if has('win32') || has('win64')
set runtimepath^=~/.vim
set runtimepath+=~/.vim/after
endif
This snippet will ensure consistency across platforms. You can now use Unix-like directory .vim even in Windows and forget about the vimfiles crap - which is IMO ugly and awful.
After that you call:
call pathogen#infect('plugins') " or wherever your plugins reside
call pathogen#helptags() " optional, but really cool
NOTE: 'plugins' denotes the ~/.vim/plugins directory, so it is relative of ~/.vim.

gvim: change the default working directory

when I open gvim using Alt+F2 it takes as its default working directory my home folder.
How can I change the working folder after or while running gvim? can i pass that folder as a parameter when open gvim?
You could use a shortcut.
The simplest way, though, would be to
:edit $MYVIMRC
append a line
cd /home/user/my/work/dir
save (optionally execute :w|source % to immediately reload)
Inside vim
use
:pwd
:cd some/other/dir
To view/change current working directory.
Use e.g.
:cd %:h
to change to the directory containing the file loaded in the active window.
If you need/want to do this often, consider just setting 'autochdir'
:se autochdir
From the docs:
When on, Vim will change the current working directory
whenever you open a file, switch buffers, delete a
buffer or open/close a window. It will change to the
directory containing the file which was opened or
selected. 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.
You can pass an a folder to gvim (when you have NERDTree then it will be a file tree) You can cd before start to begin in directory you want or use :cd <path> command to change current working directory, which can be passed to -c flag when running Vim:
$ [g]vim -c 'cd <path>'
You can also check current dir using :pwd command.
You can change the working directory with the :cd command. You can also pass this in a command-line option like this:
vim -c "cd wherever"
If you like the working directory to always be the file you're currently editing you can use the set autochdir option. Put that in your ~/.vimrc or see :help autochdir.
I know I'm late, but I started using CDargs which is a bash tool to mark certain directories as bookmarks, then use cdb and press tab to list all the bookmarked directories.
There is a vim plugin that interacts with the settingsfile of this tool: vim-cdargs.
This combo works really nice for me to switch between projects.
Or after opening gvim to go quickly to some bookmarked folder, then use Ctrl-p plugin to quickly find the file I want to edit.
extra hint: I don't even want to type :Cdb so I abbreviated c to expand to :Cdb by adding this to my vimrc:
cnoreabbrev c Cdb
after which typing :c followed by a space, will expand into :Cdb.
EDIT: I now use vim-startify which provides a start page for vim that shows the most recent used files. And with the option let g:startify_change_to_vcs_root = 1 it will change the working directory to the outermost vcs root folder of the file you opened. Which is almost always what I want.
Furthemore, I created my own 'plugin' with some key mappings that will switch to the closest or furthest directory, in the path of the current buffer, containing a .git directory or file. In order to easily switch between searching for files in the current git submodule or in the overal supermodule.
Also I switched to fzf with fzf-vim instead of Ctrl-p, which works significantly faster and is more highly configurable.

What is the most elegant way to deal with sourced files that themselves source (relative) source files in VIM?

I am editing a file like
/path/to/file.txt with vim, hence the current directory is
/path/to.
Now, I have a directory
/other/path/to/vim/files
that contains sourceA.vim. Also, there is a sourceB.vim file in
/other/path/to/vim/files/lib/sourceB.vim
In sourceA.vim, I want to source sourceB.vim, so I put a
so lib/sourceB.vim
into it.
Now, in my file.txt, I do a
:so /other/path/to/vim/files/sourceA.vim
which fails, because the sourcing system is obviously not prepared for relative path names along with sourcing from another directory.
In order to fix this, I put a
execute "so " . expand("<sfile>:p:h") . "/lib/sourceB.vim"
into sourceA.vim which does what I want.
However, I find the solution a bit clumsy and was wondering if there is a more elegant solution to it.
I cannot put the sourceA.vim nor sourceB.vim into vim's plugin folder.
Maybe you could modify your runtimepath in your vimrc or elsewhere:
set runtimepath+=/other/path/to/vim/files
Then use :runtime instead of :source in your sourceA.vim file:
runtime lib/sourceB.vim
You can then use the same ":so /../../../sourceA.vim" command as before...

Resources