After I have opened a file include()ed with gf, how can I copy text from that file into the original file's search function?
For instance, if I am working on a PHP file and it has a line:
include("someFile.php");
I would put the cursor on someFile.php and press gf. In that file I see the text function reallyLongFunctionName() {}. I would like to search for that function in the original file. I can copy the function name with v and then Ctrl-O my way back to the original file, but now how do I perform the search?
Thanks!
You can just press * on the function name, and when you return to the original file it will already be highlighted. Press n to find the first instance. * locates all instances of the word under the cursor in all buffers.
It sounds like you're doing a tag lookup (Ctl-]) in reverse.
I'd simply load the other file, navigate back (C-o) and start
reaC-n
to invoke buffer completion... (C-n and C-p work in pairs).
This sounds like exactly the problem ctags solves. Grab that, build a tags file, and then you just hit Ctrl-] over the function name (any tag name, actually) to search for that tag
Related
I move a lot between files from within Vim by highlighting a path and pressing the keys gf. I'm creating a makeshift Vim wiki for note-taking purposes, and I wanted to write only the beginning of a filename to be used as a link, because the way I have it, each filename begins with a unique identifier and so there would be no other matches, like so:
/notes/20190712*
I'm wondering if a simple asterisk wildcard could suffice for Vim to properly follow the incomplete filename, like how it autocompletes when :edit,:find or similar commands.
Vim's help alludes to some sort of expansion that takes place if it can't find a file, using something called includeexpr:
...used for the gf command if an unmodified file name can't be found.
Allows doing "gf" on the name after an 'include' statement.
Any help is appreciated. Thank you.
I've created a help file under $VIM\vimfiles\doc. After nearly deleting it I wanted to edit it elsewhere and then copy it to the doc directory and then regenerate the tags.
The tags are generated , I can see them in the tagfile, but the file that I copy in, unique name, when I do :h sfcontents for eg and then ctrl-] on a tag I get the error "e426 tag not found"
If I edit the file in the $VIM\vimfiles\doc directory and then run either :Helptags or :helptags $VIM\vimfiles\doc the tag jump works
I can't attach a file but the help file looks something like
vim: filetype=help foldmethod=indent foldclose=all modifiable noreadonly
Table of Contents *sfcontents*
*sfsearch* - Search specific commands help
|count-matches-of-pattern|
|match-specific-column|
...
==============================================================================
count-matches-of-pattern
*count-matches-of-pattern*
:%s/pattern//gn
counts the number of the matches in a file eg count the number of spaces
not at the beginning of a line
:%s/[^ ]\+//gn
==============================================================================
*match-specific-column*
c=column l=line v=virtual column, ie ignore tabs and special chars
/\%5cx will match all occurrences of x at column 5.
/\%>5vx will match all occurrences of x after character 5. If there is a
tab character between poition 1 and position 5 the /\%5>v. against the
following line with a tab at position 4 will return the number 4
123 45
/\%>4cx\%<7cx will match all occurrences of x after column 4 and before
column 7
Or use |YankMatchesToReg| eg YankMatchesToReg /\%265v./x which copies
column 265 to register x across the whole file
==============================================================================
...
vim:tw=88:ts=4:ft=help:norl
I've ended up doing the archive out of the vim directory with the following;
nmap <leader>c :sp C:\Progra~2\vim\vimfiles\doc\commands.txt<cr>
nmap <leader>co :call BackupCommands()<cr>
function! BackupCommands()
exec "silent! !copy C:\\Progra~2\\Vim\\vimfiles\\doc\\commands.txt
C:\\Progra~2\\vimutils\\vimtips\\commands_back.txt"
exec "helptags C:\\Progra~2\\Vim\\vimfiles\\doc\\"
endfunction
I'd prefer to copy from the archive to the doc directory rather than the other way round. Any suggestions.
Straight from Vim's help files (:h write-local-help):
The first line is actually the only one for which the format matters. It will
be extracted from the help file to be put in the "LOCAL ADDITIONS:" section of
help.txt |local-additions|. The first "*" must be in the first column of the
first line. After adding your help file do ":help" and check that the entries
line up nicely.
Short: You're missing *sfsearch.txt* as first characters in your file!
Vim wont add to |local-additions|, therefore wont be searched, assuming your tags file was generated correctly. You can verify that by opening the tags file in the /doc directory and finding your tags there manually. There should be a tags file in each correctly helptagged /doc directory (:helptags <doc-dir>).
IMO, fear of "nearly deleting" a file is not a proper reason for editing in another location and copying back and forth. In fact, you've now introduced another risk of accidentally losing file contents via a wrong copy command.
Instead, use proper version control (Git, Mercurial, etc.), or, if that's too heavyweight, you can try my writebackup plugin, a pure Vimscript implementation. With the companion writebackupToAdjacentDir plugin, you can even backup to other directories.
That said, tag jumping should work even with your copy regime, provided that you run :helptags $VIM\vimfiles\doc after copying your help file to that exact location.
I've got some method calls all over the place in a large file, I'd like to match these lines, select and then yank them as one so I can put them all in a single place.
I can find all the lines I want with :g/>set but how do I visually select each line?
You can't have multiple visual selections in Vim.
But you can clear a register and append all the matching lines to it:
:let #a = ''
:g/>set/y A
then create an empty buffer (or navigate to an existing one):
:vnew
and paste from register a:
"ap
But you probably want something like TagList or TagBar.
edit
:[something]y a
means "yank into register a".
:[something]y A
means "append to register a".
What I usually do is :
Remove all the lines without the pattern :v/pattern/d
Select the whole new file with ggyG
Paste somewhere the result with p
Use undo a few times with u to get the file back to its initial state
This is a bit cumbersome, I would welcome a simpler solution.
I just ran :help registers in Vim and noticed that # 'contains the name of the alternate file'.
I have seen an example for renaming files that goes like this:
" Save the current file, foo.txt, as bar.txt
:w bar.txt
" Start editing bar.txt
:e#
So apparently in that case, the file you just saved out is the "alternate file."
Can someone give me a more general definition for the "alternate file" and what else you might use it for?
The alternate file is the file that was last edited in the current window. Actually when you use some command to open a new buffer, if the buffer that was displayed had a filename associated with it, that filename is recorded as alternate file name.
See :help alternate-file.
Very useful for...
Pasting in the name of a file I've just been looking at into the current file.
You can use <C-R># for this in insert mode or "#p in normal mode.
Not that useful for...
Jumping back and forth between two files. It does the job very well, but this is just something I don't generally need to do.
Even in the example given, I'd probably use:saveas bar.txt instead.
An Example:
Say if you're doing a bit of C programming and want to call some function. You can't remember the name of the function, so you place a mark on your current location mA and jump into several different files using tags or grep to find out where the function is declared and what it's actually called.
Ah - found it. You can copy the name and return to the mark yiw'A
Uh-oh - we also need to #include the file! Easy - just use the alternate file name register to paste the file name in... Gi#include"<C-R>#"
Be pleased that you've avoided the distraction of having to go back to the function's declaration and copy out the file name via :let #"=#% or something similar.
What I'd rather do when jumping between files:
When editing two files, it's probably easier to split them, so you can keep both on screen at the same time. If I'm editing 2 files I'll usually be comparing them in some way.
Usually I'm interested in 1-3 files (any more and I get confused). I'll often jump into or directly open many other files. Marking the interesting files, or traversing the jump list is usually the way to get around in this case.
If you're editing C/C++ where you're switching between a file and it's header, use a plugin! It will be much more convenient.
I use it in the buffer context to return to the last buffer that I was editing
vim foo bar
:n
:e#
will take you back to foo in that case
I 've always interpreted the "alternate file" as being the "previous file", so it is an handy way to jump back to the buffer you were editing.
To insert text from a file in the current Vim buffer I use :r filename to insert the text below the cursor or :0r filename to insert in the first line.
How do you insert the contents of a file where [Cursor] is located?
Actual line with some coding [Cursor] // TODO for later version
Line below actual line ...
This inserts the contents of the file whose path is at the cursor position:
:r <cfile>
Insert a line break, read the file, and then take out the line break...
I propose Ctrl-R Ctrl-O = join(readfile('filename','b'), "\n")
Other solution:
Possibly open the other file in another window, use :%yh (h is a register name) and in your original file, in normal mode use "hp or "hP or in insert mode, Ctrl-R Ctrl-O h
To expand on the accepted answer with actual code, since I tried the suggestion and it worked nicely;
Here is an example of it working to insert a little php snippet:
`nnoremap <leader>php a<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
In general the syntax is
`nnoremap [KEY SEQUENCE] a<CR><ESC>:.-1read [FILE PATH]<CR>I<BS><ESC>j0i<BS><ESC>l`
Just to break it down:
nnoremap : I'm about to define a new key mapping for normal mode
<leader>php : I would like to trigger the command sequence when this key combination is pressed. In my case <leader> is , so I type ,php to trigger the command.
Now for the command, bit by bit:
a<CR><ESC> : go into insert mode (after the cursor), insert a line break, go back into normal mode.
:.-1read <file><CR> : this enters the desired file on the line above the current line.
I<BS><ESC> : jump to the start of the line, delete line break, return to normal mode.
j0i<BS><ESC>l : Go down one line (to the remainder of the line that you were initially on), jump to the start, enter insert mode, delete the line break, return to normal mode.
l : position the cursor to the right of the pasted file (this just made the command work more like how you expect it to).
note
You have a choice of whether to paste before or after the cursor. I have chosen in this example to paste after the cursor because that is how the p command usually works to paste yanked text. Alternately, to paste before the cursor you should change the a at the start of the command to an i. You could use one of these exclusively, or you could bind them both to different but related key sequences. For example:
`nnoremap <leader>php i<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
Could paste text before the cursor,
and :
`nnoremap <leader><leader>php a<CR><ESC>:.-1read $SNIPPETS/php<CR>I<BS><ESC>j0i<BS><ESC>l`
could paste text after the cursor. Or vice versa. I have made 'before the cursor' easier to trigger because I use it more often when pasting in-line.
other note
This solution is mainly useful if you're reading from a file that you expect to use often enough that it's worthwhile setting up a key mapping for it (ie reading a snippet from a file). This doesn't really help if you just want to read in a random files whenever since you won't have the key mapping ready.
Since it is very formulaic, I'm sure it would be possible to define a function that would take the file name as an argument and do the same thing though. I've never written a function in vimscript though so if someone who knows more feels like editing this answer to contain that solution - I urge them to do so!
" put this in your ~/.vimrc
" in insert mode press ,n
"
imap ,n <c-r>=expand("%:p")<cr>
Read more in wikia.