Prevent CtrlP from switching to search in submodule directory - vim

I'm still learning to use vim like a pro. In the process I have noticed that when I open up a file in submodule in a project directory CtrlP plugin switches the root for search to the root of the submodule directory. Is there a way to prevent this and keep the root search directory the one of the orignal project or the the one that was opened up initially?

You probably want to tweak the g:ctrlp_working_path_mode setting. It sounds to me like you most likely want to just disable this feature all together and manually set your working directory with :cd.
From the current ctrlp docs on GitHub:
When starting up, CtrlP sets its local working directory according to this
variable:
let g:ctrlp_working_path_mode = 'ra'
c - the directory of the current file.
a - like "c", but only applies when the current working directory outside of
CtrlP isn't a direct ancestor of the directory of the current file.
r - the nearest ancestor that contains one of these directories or files:
.git .hg .svn .bzr _darcs
w - begin finding a root from the current working directory outside of CtrlP
instead of from the directory of the current file (default). Only applies
when "r" is also present.
0 or <empty> - disable this feature.
Note #1: if "a" or "c" is included with "r", use the behavior of "a" or "c" (as
a fallback) when a root can't be found.
Note #2: you can use a |b:var| to set this option on a per buffer basis.

In your .vimrc you must change CtrlP behavior by setting:
let g:ctrlp_working_path_mode = 'rw'
With this setting it will look for version control files in current working dir outside.
Then before working on your project you change dir to its main folder, where main .git is or to a dir inside that (not in a submodule):
:cd my/project/main/path
If you open a file inside a submodule and while there hit C-p, if current working dir is outside the submodule, it will still use the file were your main .git is.

I've got these mappings in my ~/.vimrc:
nnoremap <leader>f :CtrlP<CR>
nnoremap <leader>F :CtrlPCurWD<CR>
I use the first if I want to open a file anywhere in my project and the second if I want to open a nearby file.

Related

How can I change to a different directory on an FTP server in Vim?

Vim has a fancy NetRW plugin that lets me type
vim ftp://ftp.example.com/
And get a nice directory listing, which I can edit files from by simply pressing CR while on top of them.
However, I can't seem to do this with directories. In the help file that appears when I press F1, it says I should be able to:
BROWSING netrw-cr {{{2
Browsing is simple: move the cursor onto a file or directory of interest.
Hitting the <cr> (the return key) will select the file or directory.
Directories will themselves be listed, and files will be opened using the
protocol given in the original read request.
However, when I use j/k to navigate to a directory and press <cr> to try to open it, I just get:
somedirectory: Not a regular file
Vim tries to access ftp://ftp.example.com/somedirectory. Notice that it doesn't add the slash signifying that it's a directory.
I'm at a loss for why this occurs. How can I simply enter that directory within Vim, without having to exit Vim and retype vim ftp://ftp.example.com/somedirectory/?
I'm running Vim 7.4 on Ubuntu 14.04.
Vim didn't seem to know that my directory really was a directory, as it didn't show a / sign after it in the directory listing.
Luckily, I found a way to force NetRW to act like a file is a directory: gd.
FORCING TREATMENT AS A FILE OR DIRECTORY netrw-gd netrw-gf {{{2
Remote symbolic links (ie. those listed via ssh or ftp) are problematic
in that it is difficult to tell whether they link to a file or to a
directory.
To force treatment as a file: use
gf
To force treatment as a directory: use
gd
So, simply press gd instead of <cr> to change to the directory under the cursor.
I'm still not sure why NetRW thought my directory was a file. The help message only said "remote symbolic links," which they're not (I think). It may have something to do with my web host (iPage), which might be using symbolic links everywhere instead of actual directories. Or maybe something just borked on my end.

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

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.

How can I use `path` and `lvim` to find files easily?

At the moment I use :Explore to navigate to my project directory, I press 'c' to set that as the current directory. I have set path=.,, in my .vimrc, and then I use:
:lvim pattern ./**/*
to find patterns in files. This does work, but I have to type ./**/* instead of just * or *.rb for example. Is there a setting for path that I can use to avoid having to do that?
Also, I am working in an environment where I cannot use plugins at all. (Also I would rather use vim plain-and-simple anyway) Thanks!
:lvim, :lgrep, :vim and :grep don't use the path option: they work by default from the current directory, from the directory of the current file if you use ./ or from any arbitrary directory if you use an absolute path.
The value of path has no effect whatsoever: it is used for other unrelated commands.
:lvim pattern ./*.rb
would search for pattern in every Ruby file under the directory of the current file.
:lvim pattern *.rb
would search for pattern in every Ruby file under the current directory.
The current directory and the directory of the current file may or may not be the same. If both the current directory and the directory of the current file are identical, the two commands above should have the same outcome but, if they are different, those two commands could have very different outcomes so make sure you are able to tell the difference.
If you want to search in the current directory, use:
*.rb
If you want to search recursively in the current directory, use:
**/*.rb
If you want to search in the directory of the current file, use:
./*.rb
If you want to search recursively in the directory of the current file, use:
./**/*.rb
Since you have changed the current directory with netrw's c, it seems logical to assume that you want that directory to be the base for your search. The right command would therefore be:
:lvim pattern **/*.rb

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.

Searching with command-T

When I search some file with command-T it often failes to find it because I'm not in the right directory, so I have to change the directory.
Is it possible to set that command-T will search first in the directories that are bookmarked in Nerdtree or somewhere else?
I could change the directory to / but this search very large scope of files. When I change the dir to my home directory and I'm looking for something ordinary like .bashrc I will find rather many files that are located under .wine directory.
In 99 % of time I need to search files in project directories that I actively work with. Can I set these directories in some preferences?
According to the documentation you can exclude directories from your search:
*command-t-wildignore*
|'wildignore'| string (default: '')
Vim's |'wildignore'| setting is used to determine which files should be
excluded from listings. This is a comma-separated list of glob patterns.
It defaults to the empty string, but common settings include "*.o,*.obj"
(to exclude object files) or ".git,.svn" (to exclude SCM metadata
directories). For example:
:set wildignore+=*.o,*.obj,.git
A pattern such as "vendor/rails/**" would exclude all files and
subdirectories inside the "vendor/rails" directory (relative to
directory Command-T starts in).
So if you wanted to exclude a backup dir, you would write:
set wildignore+=project/backup
in your .vimrc
In addition, to ignore dotfiles/dotdirs you can look into these options:
g:CommandTNeverShowDotFiles
g:CommandTScanDotDirectories
g:CommandTMaxDepth
These allow you to:
- ignore dotfiles completely;
- stop searching recursively in dotdirs;
- specify at what depth should Command-T stop scanning.
I found this information in the author's git, but you can probably see this document by issuing in vim:
:help Command-T
(or a similar name)
I did not see any reference to preferences or bookmarks in the plugin.
However if you start vim by opening a file in said project directory you might want to add this line to your .vimrc:
set autochdir
This option will set on startup your directory to the current file's directory.
You could try Ctrl-P. I had the same problems as you do and making the change solved them.
I also ignore some folders (in .vimrc):
let g:ctrlp_custom_ignore = {
\ 'dir': '\.git$\|\.hg$\|\.svn$',
\ 'file': '\.exe$\|\.so$\|\.dll$' }

Resources