I am new to Vim and trying to add a new shortcut. I was wondering how I can put current file's path to the command dynamically. So that every time I use that shortcut, my command will executed with correct filepath in it.
What you are looking for is expand("%"). It will return the file you are currently editing. If you use expand("%:p") you will get the full path of that file. So say you would want to have a shortcut to print your current file in the command bar and you wanted it mapped to F5. Then you would add the following in your .vimrc:
map <F5> :echo expand("%:p")<CR>
nnoremap <expr> <leader>cd (expand("%:p:h") !~ '^/tmp') ? ":lcd %:p:h\<CR>:echo expand(\"%:p:h\")\<CR>" : "echo \"foo\"\<CR>"
I have this line in my .vimrc to what you want. My leader is ',' so when I type ,cd it changes the local directory to that of the current file.
Related
If I have a file with a shebang line (e.g. #!/bin/bash) open in Vim and the file has execute permissions (i.e. chmod +x) I know I can type this to execute it without leaving the editor:
:! %:p
: for command mode
! to run a shell command
% to refer to the file in the current buffer
:p to use the full path of the current file
Is there a shorter shortcut for this frequent task?
e.g. there is a ZZ shortcut for :wq, etc.
:!%:p
,without the spaces, is shorter.
If you want an even shorter shortcut, you can create a custom mapping:
nnoremap <F9> :!%:p
or the more "mnemonic":
nnoremap <leader>r :!%:p
If you haven't set permissions you can run:
:! sh %
None of the previous answers work if your filename/directory path has spaces in it. Simple fix.
:!"%:p"
After you've executed that once, a short :!! will repeat it.
When starting vi, specify file path explicitly, like this "vi ./blablabla"
vi ./yourscript.pl
Then start with !%
The other variant is to invoke the vi command like this
!./%
You can add a key mapping to your .vimrc
map <F5> :!%
I find myself in the position where I want to create a new file in the same directory as the one that the open file is in. How do I create a new file in the directory of the open file in vim? Also, is there a a place where I can learn these things on my own? Googling didn't help.
From within Vim, new files are created like existing files are edited, via commands like :edit filename or :split filename. To persist them to disk, you need to (optionally type in contents and) persist them via :write.
Like a command prompt, Vim has a notion of current directory (:pwd lists it). All file paths are relative to it. You don't need to duplicate the path to your current file, there are some nice shortcuts for them: % refers to the current file, :h is a modifier for its directory, minus the file name (cp. :help filename-modifiers). So,
:e %:h/filename
:w
will create a new file named filename in the same directory as the currently open file, and write it.
Alternatively, some people like Vim to always change to the current file's directory. This can be configured by placing
:set autochdir
into your ~/.vimrc file (which is read on Vim startup). Then, above becomes simply
:e filename
:w
Finally, Vim has a great built-in :help. Learn to navigate and search it!
you should have a try with "nerdtree" plugin.
In the nerdtree window, you typed key m, and file operation choices will display to you
If you want to create a new file and also show it in the window next to your current file, you can try this:
:vsp newfile
The vsp stands for vertical split, and it splits the screen in half, one showing your current file, the other showing your new file (also works with just sp, which is a horizontal split).
Per #MartinLyne's comment above, this will create the file in the directory of the file in which you opened vim. To adjust for this, you can change the current working directory as follows:
:cd %:p:h
This command changes the current working directory to the directory of the active file, meaning that running the vsp command (or any of the commands above) will create the file in that directory.
I usually use:
:tabnew my-file
Then add some content and:
:w
It will create new tab with new file.
(I use Vim 8)
When you have opened vim in non existent location like
$ vim /etc/<some_folder/<next_folder>/file.cfg
then to create a new directory while being inside vim, just run in normal mode
:! mkdir -p /etc/<some_folder/<next_folder>
next save your doc as usual :w :x ZZ (whatever you like)
that's it
I'm quite late to the party, but another option is to open NERDtree with :E or :Explore (or its splitting alternatives :Vexplore/:Sexplore == :Vex/:Sex).
In NerdTree you can create a new file with %, and type the name. It will automatically open the file, and create it after you :w/save it.
This is for Gvim!
Enter this to see the current directory.
:cd
then change it with
:cd desktop/somefolder
then save or make new file there
:enew asd.cpp
now again see the file
:cd
With NERDtree
ma <FILENAME>
ma <DIRECTORY NAME> + /
I'm trying to add a key mapping so that it opens up command and populate it with :e /path/to/current/file
I can get the current directory using :pwd but I'm having a trouble to use it in the mapping
I think it will be along the lines of setting pwd to a variable and use that variable as such:
noremap <C-q> <C-o>:e *pwdvariable*<Space>
Should I create a function to perform this?
I guess you need
nnoremap <C-q> <C-\><C-n>:e <C-r>=fnameescape(expand('%:p:h'))<CR>
%:p:h will get the full path of the current file (without trailing slash). Read more in :help filename-modifiers.
Not exactly, what you have asked for, but maybe more helpful: Vim tip 64: Set working directory to the current file: In short, add the following line to .vimrc:
autocmd BufEnter * silent! lcd %:p:h
Interesting for you would be also Easy edit of files in the same directory.
I’m trying Vim for the first couple of hours with Ruby on Rails, and I’m loving it so far.
Specifically, the gf command is great, but I miss something:
If the file under the cursor does not exist yet, gf returns an error.
Is there a command to actually create and open the file if it does not exist?
Or, what is the most straightforward way to create it?
One can define a custom variant of the gf command that opens
a new buffer if the file under the cursor does not exist:
:noremap <leader>gf :e <cfile><cr>
where the :e command could be replaced with :tabe (to open
the buffer for the new file in a separate tab) or another
file-opening command.
It is also possible to just create a file with the name under the
cursor without opening it; see my answer to a similar question
“Create a file under the cursor in Vim”.
gf -> opens the file in a new tab
cf -> creates the file (if it doesn't exist) and opens it in new tab
nnoremap gf <C-W>gf
noremap <leader>cf :call CreateFile(expand("<cfile>"))<CR>
function! CreateFile(tfilename)
" complete filepath from the file where this is called
let newfilepath=expand('%:p:h') .'/'. expand(a:tfilename)
if filereadable(newfilepath)
echo "File already exists"
:norm gf
else
:execute "!touch ". expand(newfilepath)
echom "File created: ". expand(newfilepath)
:norm gf
endif
endfunction
I sometimes open a read-only file in vi, forgetting to do chmod +w before opening it. Is there way to change the file from within vi?
Something like !r chmod +w [filename]?
Is there a shortcut to refer to the currently open file without spelling it's long name?
Just use
:!chmod +w %
in command mode. % will be replaced by the current file name.
If you have the rights to write to the file, then you can just use exclamation mark to force it:
:w!
If you don't have the rights and need to change user, but still want to write to the file, sometimes you may go for something like
:w !sudo tee %
I know this is an old post, but with Vim Version8 a function has been included with which you can change file permissions.
According to the version8.txt file:
setfperm() set the permissions of a file
This function can then be called via the "call" command in Vim.
This is done as follows:
:call setfperm("file name","permissions")
The structure of the "permissions" string takes the same form as described in the Vim documentation:
getfperm({fname}) getfperm()
The result is a String, which is the read, write, and execute
permissions of the given file {fname}.
If {fname} does not exist or its directory cannot be read, an
empty string is returned.
The result is of the form "rwxrwxrwx", where each group of
"rwx" flags represent, in turn, the permissions of the owner
of the file, the group the file belongs to, and other users.
If a user does not have a given permission the flag for this
is replaced with the string "-". Example:
:echo getfperm("/etc/passwd")
This will hopefully (from a security point of view) display
the string "rw-r--r--" or even "rw-------".
A minimal example:
:call setfperm("foo.txt","rwxrwxrwx")
This adds read, write and execute permissions to the "foo.txt" file in the current directory.
Have you tried
!chmod +w %
The % represents the current filename.
You could also map a key to this like Ctrl-W.
:map <C-w> :!chmod +w %<CR>
Note that you type Ctrl-V Ctrl-M to get the <CR>
After editing your file with vim, press "esc" and then ":".
Then type the following command:
w !sudo tee %
Then press "Enter".
Then type
:q!
to successfully exit from the editor.
:!chmod <perms> <file>
and if vi still doesn't want to write it,
:se cpo-=W
As David pointed out, setfperm() is the way to do this within vim.
Here are the mappings I use to add write or execute permissions to the current file:
function! ChmodPlus(expr, pat)
let file = expand('%')
let oldperms = getfperm(file)
let newperms = substitute(oldperms, a:expr, a:pat, '')
if (oldperms != newperms)
call setfperm(file, newperms)
endif
echom(printf('Permissions: %s', newperms))
endfunction
function! ChmodPlusX()
call ChmodPlus('^\(..\).', '\1x')
endfunction
function! ChmodPlusW()
call ChmodPlus('^\(.\).', '\1w')
endfunction
" Make current file writeable
noremap <silent> <Leader>W :call ChmodPlusW()<CR>
" Make current file executable
noremap <silent> <Leader>X :call ChmodPlusX()<CR>
You can also do this with the netrw module that comes with vim if your lazy, example :Texplore followed by scrolling to the file in normal mode and entering gp. Octal or symbolic at least work.
It's a little more intuitive with multiple files but per buffer-window without, use your colon command history to repeat commands.