Vim: Use file name in mapping without extension - vim

I have a command that let me jump to a specific nested yaml key called :YamlGoToKey, and I've mapped it to a shortcut.
nmap <leader>yx :YamlGoToKey<space>
Now I want to prepend the language of the file to the command, to save me some time when typing (and I can copy paste keys without the leading locale), e.g. it should look like this after the shortcut
:YamlGoToKey en.
I tried it with this mapping
nmap <leader>yx :YamlGoToKey<space>!shellescape(expand('%:t:r')).
but the result is
:YamlGoToKey<space>!shellescape(expand('%:t:r')).
So, how can I get the name of the current file, without the extension, to show up in my command?

Use Ctrl-R= (:help c_CTRL-R_=):
:nmap <leader>yx :YamlGoToKey <c-r>=expand('%:t:r')<cr>.

Related

VIM: How to open another file from same location as an already open file

Let's say I am in my home directory. I open a file that is present in some deep nested directory structure:
vim /some/really/long/path/file.txt
Now, within vim, I want to start a vertical split with another file from that same long location (but I don't want to change the current directory to that path, I still want to be in the home directory).
A layman (like me) will do something like:
:vsp /some/really/long/path/file2.txt
But I want to find out from all you VIM geniuses out there, is there an easier way to do this?
On the same note, if I had multiple files already open residing in different paths, can VIM automatically assign some sort of internal variables to all the locations? And then when I want to start a new VSP or SP with one of the files from one of those locations, I simply use those internal variables?
Try this:
:vs %:p:h/otherfile
as %:p:h gives you the path of the current file.
See :help %:p for more info.
Edit another file in the same directory:
:vs %<Tab><C-w><C-w><C-w>file2<Tab>
With a mapping:
nnoremap <key> :vs <C-R>=expand('%:p:h')<CR>
If you like more navigation than typing the commands, a convenient option could be the use of the embedded Explore command, which opens a window with the list files in the directory of the file in current buffer. Then you can navigate with the cursors and press v when over the file you want to open in a vertical split.
A convenient way is to map the Explore command, like:
" open embedded file system navigator
map <leader>\ :Explore<cr>
Press <leader>\ and navigate to the file, then press v.
With some versions of vim, the Explore window stays open after pressing v -- in that case, if you want to avoid extra burden to close the Explore window, you can do first the vertical split with :vsp, invoke :Expore and open the desired file by pressing Enter.

How can I create a map combination using Tab in command mode?

I want to create a key combination that would copy the text under the cursor, open the :find command, yank the word and then press Tab to autocomplete to the first filename in the list, so (in 99% of cases) I would have just to press enter to open the file.
map <Leader>o yw:find <C-R>"<Tab>
However, when I press <Leader>o, I get :find FileName^I in the command line instead. How can I make it react the same way as if I pressed the key myself?
You need the wildcharm options:
set wildcharm=<C-z>
map <Leader>o yw:find <C-R>"<C-z>
See :help 'wildcharm'.
Here is a more solid, non-recursive, alternative that doesn't clobber the unnamed register for no reason:
nnoremap <leader>o :find <C-r><C-w><C-z>
The gf (goto file) command should do the same thing as your mapping. This opens the file whose name is under or after the cursor.
If not getting the expected behaviour, it's worth checking the contents of the isfname option (use set isfname? to check). This specifies a list of characters that are treated as valid characters for file path names.
It’s also worth checking / setting the contents of Vim’s path option which lists the directories which are searched when using gf, :find and similar commands, e.g., the default setting on MS Windows is .,,:
. searches relative to the directory of the file currently being edited
,, (empty string) searches the current directory; use the cd command to check (or set) your current directory.
See
help gf
help isfname
help path

How to edit an existing key mapping in vim?

How do I edit an existing mapping in vim? I set the mapping in my .vim file using one of the standard mapping commands:
map ^A o]]></code>^M<GRD minus="" summary="">^M^M<p></p>^M^M</GRD>^M^M<code><![CDATA[0kkkkkk5ehi
I want to edit this long command to use "matlab" instead of code, e.g.:
map ^A o]]></matlab>^M<GRD minus="" summary="">^M^M<p></p>^M^M</GRD>^M^M<matlab><![CDATA[0kkkkkk5ehi
However, I don't want to edit the .vim file -- I will use the original mapping again. I just want to change the mapping for my current session. I tried :map ^A, but this only displays the current mapping, and I cannot copy the displayed text.
P.S. Note that the ^M and ^A characters are inserted with Ctrl-Q Ctrl-M, etc.
Tweaking a mapping for a current session only is unusual; probably that's why it's supported poorly. I would guess that you're not actually concerned about a session, but rather a Matlab filetype. For that, there's excellent support. If the 'filetype' is detected as matlab, you can put a buffer-local mapping variant in ~/.vim/after/ftplugin/matlab.vim:
map <buffer> ^A ...
Direct editing
If you'd rather stick with your original plan, I would do it like that:
Open configuration: :split ~/.vimrc
Edit the mapping in-place
Yank the line: yy
Execute to activate for the current session: :#"
Abort the edit without saving: :bdelete!
Alternative
For a more general solution, you could also capture the output of the original :map ^A command via :redir, then :put that into a :newscratch buffer, and finally :source that. It's more manual steps and typing, but could be automated by a custom command. Worthwhile if you need this often.
To set your map for the current session only, do
:map ^A o]]></matlab>^M<GRD minus="" summary="">^M^M<p></p>^M^M</GRD>^M^M<matlab><![CDATA[0kkkkkk5ehi

How to use an external command in Vim to modify the selection

Something I've found useful in other editors is the ability to:
take the selected text
run an external command and pass the selection to its stdin
take the external commands stdout and replace the current selection with it.
This way you can write useful text tools which operate on the selection using any language that can do basic io.
How can this be done with vim?
(Directly in the command line, or via a key binding?)
:'<,'>!command
'<,'> represents the (linewise) visual selection and is automatically inserted when you hit : and have something selected.
Example:
If you select a line containing:
print("Hello!")
and run the Vim command:
:'<,'>!python
the text will be replaced with Hello!.
If you want to set this to a key-binding (F5 to evaluate for example)
vnoremap <F5> :!python<cr>

Editable vimgrep string in command line

I use vimgrep a lot to navigate in files and usually use the last search from the history to modify the search pattern and run it again.
Is there a way to display in the command line an editable string like the one below, with the cursor already positioned between the two search pattern slashes (and the pattern being empty)?
:vimgrep // **/*[ch]|copen
I don't want to use a constant mapping (like the one at this vim tip) since I want to be able to add/change options (\c etc.).
I'd recommend using the command-line window for this (q: opens it from normal mode), since you
can edit the command with the regular normal mode keystrokes (and you get syntax highlighting too).
You can also move around in your history just like in a normal buffer. So ?vimgrep<Enter>nnn... will search for and move you to all your old vimgrep commands.
Just hit <Enter> as normal when you are done editing, or :q<Enter> to abort the command and quit the window like you would any other.
Finally, here's a mapping to quickly bring up your empty vimgrep template in the command-line window.
:nnoremap \v q:ivimgrep<Space>//<Space>**/*[ch]<Bar>copen<Esc>F/;i
Reference: :help cmdline-window

Resources