Is it possible that whenever I select a directory and enter that directory from the NERDTree it should become the root directory? That is, every time I select a new directory the following two commands will be triggered: cd and :NERDTreeCWD?
Thanks!
set in your vimrc: let g:NERDTreeChDirMode = 2
The NERDTree provides two mappings you could use manually to get this effect: Typing cd on a node changes the directory to it, and typing C on a node, "enters" it via the NERDTree.
Personally, I often combine them -- just type Ccd -- the C will enter the directory and leave the cursor on it, and a cd will change the working directory to it.
Now, if you do want to create just one mapping to use directly, you could use the NERDTree's extension mechanism. Read up on :help NERDTreeAPI for the details, but the short version is: put a file in ~/.vim/nerdtree_plugin/cd_mapping.vim with the following contents:
call NERDTreeAddKeyMap({
\ 'key': '_C',
\ 'callback': 'NERDTreeEnterDirectoryAndCD',
\ 'quickhelpText': 'Enter directory and cd into it' })
function! NERDTreeEnterDirectoryAndCD()
let node = g:NERDTreeDirNode.GetSelected()
exec 'cd ' . node.path.str({'format': 'Cd'})
NERDTreeCWD
endfunction
This should do the trick with the keybinding _C. Change the key property to whatever you'd like the key to be.
cd CD ( cd -> changes pwd/cwd and CD -> sets tree root to pwd/cwd)
Related
When using Vim as a text editor, is there a way to create new directories and files, while in text editor mode? Instead of going back to the command line and creating a new directory and file.
If you are in the file explorer mode, you can use:
d for creating a directory
% for creating a new file
You can get into the explorer mode with issuing a command :Sexplore or :Vexplore
There is no need to call external commands with !
Assuming you're running a shell, I would shell out for either of these commands. Enter command mode with Esc, and then:
:! touch new-file.txt
:! mkdir new-directory
A great plugin for these actions is vim-eunuch, which gives you syntactic sugar for shell commands. Here's the latter example, using vim-eunuch:
:Mdkir new-directory
Switch to file browsing mode
:Ex or if that is not working use :Explore
then press
d
and add the new directory name.
Assuming you just ran vim on new file in the directory that does not exist:
vim new_dir/new_file.txt
When you try :w you will get 'E212: Can't open file for writing'
To create new directory and file use this:
:!mkdir -p %:h
For the sake of completeness:
Shell out and use normal commands, such as :!mkdir my_dir and :!touch foo.txt (as mentioned in Jake's answer here) will create the directory and file in CURRENT working directory, which is the directory when you started your current vim process in the beginning, but NOT NECESSARILY the same directory of the file that you are currently editing, or the same directory that your :Explore explorer is currently viewing. When in doubt, always use :!pwd to check your current working directory first, and use relative path when necessary.
So if your project contains multiple sub-directories, a more convenient way is to:
type :Explore to enter the explorer mode first,
and then you can easily navigate to whatever sub-directory you like, by typing up-arrow or down-arrow (or j or k) to move cursor, typing Enter to enter a sub-directory, typing - to go up a level of directory. (Note that, all these navigation does NOT change your current working directory either);
Now you can type d to be prompted for a directory name, or type % to be prompted for a file name, and then they will be created in the directory currently shown on screen.
PS: These keys are actually mentioned in the built-in help F1.
Alternatively you can use :e . to get to explorer mode and then hit d .to create the new directory .Thought a shorter answer might be better
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.
Vim users would be familiar with getting into and viewing the current directory listing by using
:o .
In this directory view, we are able to give additional commands like d and vim will respond with "Please give directory name:". This of course allows us to create a new directory in the current directory once we provide a directory name to vim.
Similarly, we can delete an empty directory by first moving our cursor down to the listing that underlines the specific directory we want to remove and typing D.
The problem is, vim does not allow us to delete a non-empty directory.
Is that any way to insist that we delete the non-empty directory?
The directory view you're referring to is called netrw. You could read up on its entire documentation with :help netrw, but what you're looking for in this case is accessible by :help netrw-delete:
The g:netrw_rmdir_cmd variable is used to support the removal of directories.
Its default value is:
g:netrw_rmdir_cmd: ssh HOSTNAME rmdir
If removing a directory fails with g:netrw_rmdir_cmd, netrw then will attempt
to remove it again using the g:netrw_rmf_cmd variable. Its default value is:
g:netrw_rmf_cmd: ssh HOSTNAME rm -f
So, you could override the variable that contains the command to remove a directory like so:
let g:netrw_rmf_cmd = 'ssh HOSTNAME rm -rf'
EDIT: Like sehe pointed out, this is fairly risky. If you need additional confirmation in case the directory is not empty, you could write a shell script that does the prompting. A quick google turned up this SO question: bash user input if.
So, you could write a script that goes like this:
#! /bin/bash
hostname = $1
dirname = $2
# ...
# prompt the user, save the result
# ...
if $yes
then
ssh $hostname rm -rf $dirname
fi
Then, set the command to execute your script
let g:netrw_rmf_cmd = 'safe-delete HOSTNAME'
A lot of careful testing is recommended, of course :).
Andrew's answer doesn't work for me. I have found another way to this question. Try :help netrw_localrmdir.
Settings from my .vimrc file:
let g:netrw_localrmdir="rm -r"
Ok so this happens to me all the time. There has to be a better solution. Let's say you do vim /etc/somefile.conf and then you do i but realize you are not sudo and you can't write. So then I lose my changes by doing :q then sudo !! and make my changes again. Is there a better way to do this?
Try
:w !sudo tee "%"
The w ! takes the entire file and pipes it into a shell command. The shell command is sudo tee which runs tee as superuser. % is replaced with the current file name. Quotes needed for files that have either spaces or any other special characters in their names.
Depending on the extent of your changes, it might be faster to save (:w) your file with a different name, and then use sudo and cat to overwrite the content of the original file:
sudo sh -c 'cat changed > file'
Note that both cp and mv will replace the original file and its attributes (ownership, permissions, ACLs) will be lost. Do not use them unless you know how to fix the permissions afterwards.
Save the file elsewhere (like your home folder) and then sudo mv it to overwrite the original?
Save the changes as another file and the make the approrpiate replacement.
When vim starts up, the statusbar says [readonly], and the first time you try to edit, it says W10: Warning: Changing a readonly file and pauses for a full second. This is enough warning for me to quit and say sudoedit /etc/somefile.conf.
You can enforce this with a plugin: Make buffer modifiable state match file readonly state.
I use zsh templates and function completion.
Specifically this one. If I don't have write permissions, it prompts for my sudo password and automatically runs "sudo vim"…amongst other things.
I used this:
function! SaveAsSudo()
let v=winsaveview()
let a=system("stat -c \%a " . shellescape(expand('%')))
let a=substitute(a,"\n","","g")
let a=substitute(a,"\r","","g")
call system("sudo chmod 666 " . shellescape(expand('%')))
w
call system("sudo chmod " . a . " " . shellescape(expand('%')))
call winrestview(v)
endfunction
I have mapped <F2> to :w<CR>. & <F8> to :call SaveAsSudo()<CR>
Only advantage this answer provides over the sudo tee option is: vim does not complain about unsaved buffer or file modified externally.
I don't like how Vim clutters up my folders with backup files, so I have the following line in my .vimrc file:
set backupdir=~/.vim_backup
However, sometimes this folder doesn't exist because of new machines where I am copying my user files over.
How can I create this folder automatically if it doesn't exist, from within .vimrc? Or is there some better way to deal with this situation?
I think this is operating system independent:
if !isdirectory("/my/directory")
call mkdir("/my/directory", "p")
endif
You can put this into your .vimrc:
silent !mkdir ~/.vim_backup > /dev/null 2>&1
This will attempt to create the ~/.vim_backup each time you start vim. If it already exists, mkdir will signal an error, but you'll never see it.
You could use the mkdir() Vim function. It can create intermediate directories and set proper permissions on the directory as well:
if !isdirectory($HOME . "/.vim/backup")
call mkdir($HOME . "/.vim/backup", "p", 0700)
endif
I much prefer the one-liners already posted. However, I thought I'd share what I've been using:
function! EnsureDirExists (dir)
if !isdirectory(a:dir)
if exists("*mkdir")
call mkdir(a:dir,'p')
echo "Created directory: " . a:dir
else
echo "Please create directory: " . a:dir
endif
endif
endfunction
call EnsureDirExists($HOME . '/.vim_backup')
I wanted a solution to this that works on both Linux and on Windows (with Cygwin binaries on the path.) - my Vim config is shared between the two.
One problem is that 'mkdir' is, I think, built-in to the cmd shell on windows, so it can't be overridden by putting the Cygwin mkdir executable earlier in the path.
I solved this by invoking a new bash shell to perform the action: From there, 'mkdir' always means whatever mkdir executable is on the path:
!bash -c "mkdir -p ~/.vim-tmp"
However, this has the problem that. on Windows at least, it pops up a new window for the cmd shell that '!' invokes. Don't want that every time I start vim. Then I discovered the vim function 'system', which invokes a new cmd shell (the icon appears in the Windows taskbar) but the window is minimised. Hence:
call system("bash -c \"mkdir -p ~/.vim-tmp\"")
Ugly but works.
I have a command in my vimrc that enables me to make a directory corresponding to the buffer presently frontmost:
nmap <silent> ,md :!mkdir -p %:p:h<CR>
This can be used to create a directory any place you care to put one locally or remotely via netrw if you the permissions to do so.
This is built into Vim, so you can simply:
call mkdir($HOME . "/tmp")
You can also specify the p flag to have the command operate in the same way mkdir -p would:
call mkdir($HOME . "/tmp", "p")
For details see :help mkdir or the vim manual online.
This is what I am currently using in my .vimrc file and I think it looks quite clean and simple:
if empty(glob($HOME . '/.vim/undodir'))
call mkdir($HOME . '/.vim/undodir', 'p')
endif