So when I want to create a new file by using the :e command I don't want to specify the whole path, just the new filename. Can it be done?
As already suggested, you can use autochdir, which will change to the directory of the file you opened, the other option is
:cd mydirectory
which will change the directory. This can be an absolute or relative path, so :cd .. will move up one level. Or you can use :cd %:h which will also change to the directory the current file is in, but without setting autochdir.
:cd
will change directory to your home directory (or on windows, print the current directory).
:cd -
will change the directory to the previous directory you visited.
Also if you are browsing the filesystem with the netrw file explorer you can set the current directory by pressing the c key.
Edit: for newer versions try cd if c doesn't work.
Try adding set autochdir to your .vimrc. If you want to change it just this once, use :cd (or :cd! to force it).
With netrw: in addition to pressing the c key to set the current directory, you may also put:
let g:netrw_keepdir= 0
in your .vimrc; this means that netrw will keep the browsing directory the same as the current directory.
I don't know what is wrong with vim. I want the directory where I start up vim as the current.
I have followed the tip about autochd above and set that to noautcd in my .vimrc.
I haven't done it yet, but I am about to start up vim like this from now on:
vim —cmd 'cd `pwd`'
That will make it stick to the current directory!
Adding this to my .vimrc automatically changes Vim's working dir to the current file:
autocmd BufEnter * silent! :lcd%:p:h
Update:
Now I just use those code instead of install a plugin
" 自动切nvim到当前文件所在路径, 避免leaderF每个命令前都要敲一下 :pwd.
" 代替autochdir: Switch to the directory of the current file unless it breaks something.
au AG BufEnter * call AutoDiR()
func! AutoDiR()
" Don't mess with vim on startup.
let should_cd = (!exists("v:vim_did_enter") || v:vim_did_enter)
" 或
" v:vim_did_enter :
" 0 during startup
" 1 just before VimEnter.
" forbid for some filetypes
" let should_cd = should_cd && david#init#find_ft_match(['help', 'dirvish', 'qf']) < 0
" Only change to real files:
let should_cd = should_cd && filereadable(expand("%"))
" filereadable()
" The result is a Number, which is |TRUE| when a file with the
" name {file} exists, and can be read.
if should_cd
silent! cd %:p:h
endif
endf
" cdh: cd here
nno cd :cd %:p:h<cr><cmd>pwd<cr><cmd>let g:Lf_WorkingDirectory=getcwd()<cr><cmd>echo "Lf目录:"..g:Lf_WorkingDirectory<cr>
" nno cdh
cnorea <expr> cdh ( getcmdtype() == ":" && getcmdline() == 'cdh') ?
\ 'cd %:p:h<cr> :pwd<cr>'
\ : 'cdh'
" 方法2: 不好使? 要敲一次pwd触发?
" au AG VimEnter * set autochdir | pwd | echom '设置了autochdir'
" Note: When this option is on, some plugins may not work.
" 貌似不行:
" Plug 'https://github.com/airblade/vim-rooter'
" 对于vscode-nvim
" vscode用wsl的nvim作为bin时,pwd永远是Microsoft VS Code. 等邮件通知更新吧. 其实不影响使用?
" 我的笔记: https://github.com/vscode-neovim/vscode-neovim/issues/520#issuecomment-1013853745
"
" 这个也不行:
" au AG BufEnter * silent! lcd %:p:h
" lcd: local window cd ?
" Like |:cd|, but only set the current directory for the current window.
You could install the Rooter Vim plugin, which automatically changes the working directory to the automatically-detected project root when you open a file or directory. After Rooter has set the working directory for you, if you try to edit a file like :e example.txt, Vim will edit example.txt in the project root.
If you’re using the vim-plug plugin manager, you can install Rooter by adding the following to your .vimrc, then reloading Vim and running :PlugInstall.
Plug 'airblade/vim-rooter'
Related
I have NERDTREE installed.
If I open up a whole directory with vim . I see the following:
If I open up a specific file in the directory with vim file1.txt, I see the following:
Is there a way to have vim . not open up the file browser twice? I get that it has no specific file to open, but I'd rather have it just open up only the left hand pane and then nothing on the right, instead of having to always manually close the right side.
Here's the relevant section of my .vimrc if that helps
" === Plugins
filetype off
call vundle#begin('$HOME/.vim/bundle')
Plugin 'VundleVim/Vundle.vim' " required
Plugin 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
call vundle#end()
filetype plugin indent on
" === Auto Commands
autocmd VimEnter * NERDTree " Start NERDTree on startup
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree")
\ && b:NERDTree.isTabTree()) | q | endif " Close NERDTree explore after last window closes
" === Config
let NERDTreeMinimalUI = 1 " NERDTree Minimal UI
let NERDTreeDirArrows = 1 " NERDTREE Directional Arrows
let NERDTreeShowHidden = 1 " Show hidden files
Nerdtree doesn't know what you have open in your main pane. Vim doesn't know what Nerdtree does with its side pane.
If you're only concerned about the situation described where you want to open vim in the current directory, vim (just the command with no arguments) will open up the welcome screen, and Nerdtree with your autocommands will open in the side pane based on the current directory.
If you're concerned about pointing vim at a directory other than cwd, you could disable the Nerdtree plugin autocommands so it doesn't open automatically, or rewrite the autocommand to trigger iff the thing you told vim to open is a file. Something like this?
augroup NerdTree
autocmd!
autocmd VimEnter * | if isdirectory(expand("<afile>")) | :NERDTreeToggle | endif
augroup END
Though I can't quite get it to work right. Maybe someone else can play off what I have so far.
I'd like to open CtrlP if I am opening a directory with vim, but not a file. I like to have it automatically open in I just open a directory for convenience. However, it is slightly inconvenient if I know exactly which file I want to open because of the added loading time.
Currently I just have this in my .vimrc:
autocmd vimenter * CtrlP
Thanks in advance for any responses!
You can write a function to test the args to see if a single directory was passed in and if it was, execute CtrlP. Here is a very rudimentary solution:
function! MaybeCtrlP()
if argc() == 1 && isdirectory(argv()[0])
" Uncomment this to remove the Netrw buffer (optional)
" execute "bdelete"
execute "CtrlP"
endif
endfunction
autocmd VimEnter * :call MaybeCtrlP()
In .bash_profile, create an alias:
alias vimCtrlP="vim +CtrlP"
Then every time you need this, use vimCtrlP as you would issue vim in shell, followed by the directory.
Disclaimer: I'm new to vim/tmux. I'm on a Mac using MacVim
I was told to use version control on my dotfiles.
Before my dot files were all placed in my root ~ like so:
~/
.vimrc
.tmux.conf
.vim
/bundle
/autoload
.viminfo
etc
But then I figured it would be a good idea to make a folder named "dotfiles", and house them all in there and then upload it to github so I can have them anywhere.
Like so:
~/
/dotfiles
.vimrc
.tmux.conf
.vim
/bundle
/autoload
.viminfo
etc
At first I thought everything was okay, becuase I never closed Vim, but when I reloaded it later, I realized none of my commands were working anymore. So I went in an changed some paths in my .vimrc and in my .tmux.conf in hopes that it would work again, but no luck.
Here is my full .vimrc:
set nocompatible " be iMproved, required
filetype off " required
" set the runtime path to include Vundle and initialize
set rtp+=~/dotfiles/.vim/bundle/Vundle.vim
call vundle#begin()
" " alternatively, pass a path where Vundle should install plugins
" "call vundle#begin('~/some/path/here')
"
" " let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'
Plugin 'christoomey/vim-tmux-navigator'
" " All of your Plugins must be added before the following line
call vundle#end() " required
filetype plugin indent on " required
" " To ignore plugin indent changes, instead use:
" "filetype plugin on
" "
" " Brief help
" " :PluginList - lists configured plugins
" " :PluginInstall - installs plugins; append `!` to update or just
" :PluginUpdate
" " :PluginSearch foo - searches for foo; append `!` to refresh local cache
" " :PluginClean - confirms removal of unused plugins; append `!` to
" auto-approve removal
" "
" " see :h vundle for more details or wiki for FAQ
" " Put your non-Plugin stuff after this line
execute pathogen#infect()
syntax on
filetype plugin indent on
set mouse=a
let g:tmux_navigator_no_mappings = 1
nnoremap <silent> <c-h> :TmuxNavigateLeft<cr>
nnoremap <silent> <c-j> :TmuxNavigateDown<cr>
nnoremap <silent> <c-k> :TmuxNavigateUp<cr>
nnoremap <silent> <c-l> :TmuxNavigateRight<cr>
nnoremap <silent> <c-/> :TmuxNavigatePrevious<cr>
let g:tmux_navigator_save_on_switch = 1
vnoremap <C-c> "*y
set runtimepath^=~/dotfiles/.vim/bundle/ctrlp.vim
As you can see, the paths have been corrected to incorporate the /dotfiles/ directory, yet anytime I try to run a plugin or something in my .vimrc, I get a generic 'Not an editor command' error.
Incidentally, tmux and all its configuration seems to be working fine after it being moved around.
Any Ideas?
I was told to use version control on my dotfiles.
Maybe you should turn to the people who told you to do that for support, don't you think?
Putting all your dotfiles in a single repo is not a requisite or even an objectively good idea. It could work for some people but only if you manage to point your programs to that centralized place (great) or if you symlink those files to their regular location (which kind of defeats the point). The people who told you to use version control on your dotfiles should have told you how to do that from start to finish.
Vim expects your vim directory and your vimrc to be in default locations:
~/.vim
~/.vimrc or ~/.vim/vimrc
It won't look elsewhere so you'll have to symlink them from your repo to their expected location:
$ ln -s /Users/username/dotfiles/.vim /Users/username/.vim
$ ln -s /Users/username/dotfiles/.vimrc /Users/username/.vimrc
This idea to put all of your dotfiles in a same directory is not bad as #romainl said in his answer you have to symlink them to their original place.
That's what I did so you may be interested in the script I created to automatically save the current dotfiles in my home directory and replace them with a simlink to the dotfiles in my repo. (You can also clone my repo, replace the dotfiles by yours and execute the script. I tried to make the readme as clear as possible but if you're interested in using my solution don't hesitate to message me for support)
Suppose I have a folder with lots of .h and .cpp files. I frequently need to do the following:
open a file prefix_SomeReallyLongFileName.h,
make some changes to it,
and then open prefix_SomeReallyLongFileName.cpp.
I can do this using :e <filename> using auto-complete, but as the prefix is same for many of the files, this becomes inconvenient.
Is there a quick way to open a file with same name as current file, but a different extension?
Do other people come across this situation too, and if so what is your preferred way of navigating the C++ files in a directory? Thanks.
You can use the :r (root) filename modifier which removes the last extension (check out :h filename-modifiers for more information)
:e %:r.cpp
where
% is shorthand for current filename.
:r removes the extension
.cpp simply appends that string at the end.
This effectively substitutes the current file's extension with another, then open the file with the newer extension.
An even shorter way (courtesy of Peter Rincker),
:e %<.cpp
Relevant documentation at :h extension-removal
According to the Vim wiki there are quite a few suggested ways.
I will outline a few options from the article:
a.vim or FSwitch.vim plugins
using ctags
:e %<.c or :e %<.h. %< represents the current file w/o the extension
A quick mapping nnoremap <F4> :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR>. Add this to your ~/.vimrc.
Install “unimpaired” and then use ]f and [f to go the previous and next file. Since source and header have they same name except for the suffix, they are next and previous files.
This is just using simple(?!) vimscript, so you can put it into your vimrc,
now it works for .c files, but can be modified pretty easily for .cpp (obviously), it even has some "error handling" in the inner if-statements (that is probably pointless), but if anyone needs it, hey, it's there! Without it it's way much shorter (just leave the :e %<.h, for example), so choose whatever you want.
function! HeaderToggle() " bang for overwrite when saving vimrc
let file_path = expand("%")
let file_name = expand("%<")
let extension = split(file_path, '\.')[-1] " '\.' is how you really split on dot
let err_msg = "There is no file "
if extension == "c"
let next_file = join([file_name, ".h"], "")
if filereadable(next_file)
:e %<.h
else
echo join([err_msg, next_file], "")
endif
elseif extension == "h"
let next_file = join([file_name, ".c"], "")
if filereadable(next_file)
:e %<.c
else
echo join([err_msg, next_file], "")
endif
endif
endfunction
then add further to your vimrc something along these lines:
let mapleader = "," " <Leader>
nnoremap <Leader>h :call HeaderToggle()<CR>
Now whenever you're in normal mode, you press comma , (this is our <Leader> button) then h and function from the above gets called, and you will toggle between files. Tada!
Adding my two cents ;) to the above great answers:
Install Exuberant Ctags
Put the following code into your .vimrc
" Jump to a file whose extension corresponds to the extension of the current
" file. The `tags' file, created with:
" $ ctags --extra=+f -R .
" has to be present in the current directory.
function! JumpToCorrespondingFile()
let l:extensions = { 'c': 'h', 'h': 'c', 'cpp': 'hpp', 'hpp': 'cpp' }
let l:fe = expand('%:e')
if has_key(l:extensions, l:fe)
execute ':tag ' . expand('%:t:r') . '.' . l:extensions[l:fe]
else
call PrintError(">>> Corresponding extension for '" . l:fe . "' is not specified")
endif
endfunct
" jump to a file with the corresponding extension (<C-F2> aka <S-F14>)
nnoremap <S-F14> :call JumpToCorrespondingFile()<CR>
inoremap <S-F14> <C-o>:call JumpToCorrespondingFile()<CR>
" Print error message.
function! PrintError(msg) abort
execute 'normal! \<Esc>'
echohl ErrorMsg
echomsg a:msg
echohl None
endfunction
https://github.com/ericcurtin/CurtineIncSw.vim is an option.
Once configured searches the current directory recursively and the directory your source file is in recursively for the file you want to switch to.
You can switch from .cc to .h files with :VH.
NERDTree shows in viewport disk c: regardless from which disk do I open the file.
When I use gvim in windows I open files using:
gvim.exe --remote-tab-silent [FILE]
I'm loading NERDTree with this line in _vimrc:
au VimEnter * NERDTree
Can NERDTree automaticaly change drive to correct drive somehow?
Actually, my last answer does not work because once the NERDTree have been opened, it does not open again in the new buffer dir. It must work similarly to NERDTreeFind but it does not have a Toggle feature.
I made a function and mapped it to my key and now it works perfectly even opening the Ruby project if you have the vim-rails plugin.
Add this to your vimrc:
function! NTFinderP()
"" Check if NERDTree is open
if exists("t:NERDTreeBufName")
let s:ntree = bufwinnr(t:NERDTreeBufName)
else
let s:ntree = -1
endif
if (s:ntree != -1)
"" If NERDTree is open, close it.
:NERDTreeClose
else
"" Try to open a :Rtree for the rails project
if exists(":Rtree")
"" Open Rtree (using rails plugin, it opens in project dir)
:Rtree
else
"" Open NERDTree in the file path
:NERDTreeFind
endif
endif
endfunction
"" Toggles NERDTree
map <silent> <F1> :call NTFinderP()<CR>
It should work now.
Previous answer below:
You could map the key you use to open
NERDTree like this(in .vimrc):
map <silent> <F1> :NERDTreeToggle %:p:h<CR>
This maps my F1 key to
toggle(open/close) NERDTree using the
path of the currently active buffer.
If no buffer is open, it opens in the
currently launched Macvim directory.
NERDTree provides several Ex commands to manipulate its buffer (see
:help NERDTreeGlobalCommands). Among them there is the :NERDTreeFind
command which behaves the same way as the :NERDTree command except it opens
the NERDTree buffer in the directory containing currently opened file.
So, in order to achieve the desired effect described in the question, you can
simply change the auto-command to read
:autocmd VimEnter * NERDTreeFind
I use mapping for NERDTree and in this way when I open it always opens in current dir
" NERDTree mappings
nnoremap <silent> <F9> :NERDTreeToggle <cr>
inoremap <silent> <F9> <Esc>:NERDTreeToggle <cr>
But if you open a file like gvim ~/other/dir/file NERDTree will open current dir from where gvim was called. So this is not a real solution to your problem.
Perhaps if you cd in working dir before calling gvim will solve your problem. In this case even your au VimEnter * NERDTree in _vimrc must work as you espect .
About changing directory and setting working dir set autochdir read here
Add
au VimEnter,BufWinEnter * NERDTreeFind
to your .vimrc.
VimEnter part makes it work on load.
BufWinEnter makes it happen you open a new file.
* tells it to do this with all files
NERDTreeFind is the command to run
srcs:
http://vimdoc.sourceforge.net/htmldoc/autocmd.html