Search in GVIM word with "/" and "[" - vim

I want to search in gvim words that include the below symbols
"/" & "["
each time I need to add backslash.
Is there any GVIM configuration to prevent doing it?

Related

cscope: ctrl + ']' does not work

I just installed cscope-15.8b, then go to linux-next folder, run "cscope -R", after build the tags, then open a file through "Find this file" // so far so good.
Now if I want to go to a symbol's defination, by ctrl + ], it will throw error: "E433: No tags file" "E426: tag not found".
If I open the cscope.out file, I will see it looks like broken (see below). How do Ifix this?
1 ^B
~<¡dio.h
>
2 ^B
~<¡dlib.h
>
3 ^B
~
The fact that the cscope.out file looks "broken" is normal, the file format is sort-of text but includes some non-printing characters as well.
Your problem is that ctrl + ] doesn't search cscope databases by default, it only searches ctags files which are entirely different. You need to set cscopetag in your .vimrc file to make it search both. From the vim help:
If 'cscopetag' is set, the commands ":tag" and CTRL-] as well as "vim -t"
will always use :cstag instead of the default :tag behavior. Effectively,
by setting 'cst', you will always search your cscope databases as well as
your tag files. The default is off.
Add these lines to your ~/.vimrc file:
set cscopetag
set csto=0
set tags=./tags,tags;/
cs add cscope.out
Better yet, copy this entire file into the ~/.vimrc file: http://cscope.sourceforge.net/cscope_maps.vim

In Vim how to switch quickly between .h and .cpp files with the same name?

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.

in vim, how to append/insert text with argdo?

There's the ":a" command, but that's multi-line, and argdo asks you for the text again for each file.
The docs mention the global command (g/pat/command) that will use an alternative version of ":a" that is terminated by a newline instead of by "." on a line (you can include newlines by escaping them with "\"). But I couldn't get this to work.
The only way I've seen is to first yank the text-to-be-added into a named register, then use:
:argdo put x " where x is the register
I'm hoping for something like
:argdo append myTextHere
I'm unclear where you're trying to insert the text in the buffer. If you want it after the current line:
:argdo exe 'normal osometext'
Inserting text with linebreaks in it:
:argdo exe "normal osometext\<CR>anewline"
To append text after line nr 10:
:argdo call append(10, "hello world")
To append text to the line 10:
:argdo call setline(10, getline(10)."textappended")
Yanking a text in vim will put it in the default buffer, which is ". You can paste that buffer in insert mode for example by typing <C-R>". So all you need is argdo put "

Yank file name / path of current buffer in Vim

Assuming the current buffer is a file open for edit, so :e does not display E32: No file name.
I would like to yank one or all of:
The file name exactly as show on the status line, e.g. ~\myfile.txt
A full path to the file, e.g. c:\foo\bar\myfile.txt
Just the file name, e.g. myfile.txt
TL;DR
:let #" = expand("%")>
this will copy the file name to the unamed register, then you can use good old p to paste it. and of course you can map this to a key for quicker use.
:nmap cp :let #" = expand("%")<cr>
you can also use this for full path
:let #" = expand("%:p")
Explanation
Vim uses the unnamed register to store text that has been deleted or copied (yanked), likewise when you paste it reads the text from this register.
Using let we can manually store text in the register using :let #" = "text" but we can also store the result of an expression.
In the above example we use the function expand which expands wildcards and keywords. in our example we use expand('%') to expand the current file name. We can modify it as expand('%:p') for the full file name.
See :help let :help expand :help registers for details
Almost what you're asking for, and it might do: in INSERT mode, Ctrl+R % pulls the current filename into where you are (command prompt, edit buffer, ...). See this Vim Tip for more.
If you want to put the current buffer filename in your system-level clipboard, try changing the register to #+:
" relative path
:let #+ = expand("%")
" full path
:let #+ = expand("%:p")
" just filename
:let #+ = expand("%:t")
Edit 20140421:
I commonly use these, so I created some shortcuts. Linux Vims apparently operate slightly differently than Mac Vims, so there is a special case for that as well. If you put the following in your ~/.vimrc:
" copy current file name (relative/absolute) to system clipboard
if has("mac") || has("gui_macvim") || has("gui_mac")
" relative path (src/foo.txt)
nnoremap <leader>cf :let #*=expand("%")<CR>
" absolute path (/something/src/foo.txt)
nnoremap <leader>cF :let #*=expand("%:p")<CR>
" filename (foo.txt)
nnoremap <leader>ct :let #*=expand("%:t")<CR>
" directory name (/something/src)
nnoremap <leader>ch :let #*=expand("%:p:h")<CR>
endif
" copy current file name (relative/absolute) to system clipboard (Linux version)
if has("gui_gtk") || has("gui_gtk2") || has("gui_gnome") || has("unix")
" relative path (src/foo.txt)
nnoremap <leader>cf :let #+=expand("%")<CR>
" absolute path (/something/src/foo.txt)
nnoremap <leader>cF :let #+=expand("%:p")<CR>
" filename (foo.txt)
nnoremap <leader>ct :let #+=expand("%:t")<CR>
" directory name (/something/src)
nnoremap <leader>ch :let #+=expand("%:p:h")<CR>
endif
Then for example <leader>cf will copy the relative path of the current buffer (the default leader is backslash (\)). I often use these for running commands on a file or doing other things on the command line. I don't really use the last filename / directory name often.
You might consider more intuitive mappings like <leader>cfr for relative, <leader>cfa for absolute, <leader>cff for just filename, <leader>cfd for directory.
Answer tested on Neovim/Ubunutu.
:let #+=#%
From what I can tell, the % register already contains the relative filepath, so it's as simple as moving the contents of the % register to whatever register represents your favourite clipboard.
This SO answer deals with copying from one register to another
Seems pretty straightforward to me. No need for any hard-to-remember expand() stuff.
If you do :reg you will see the name of the current file in the % register. You can paste it with "%p, for example.
If, like me, you often switch to the 'alternate' buffer, it is very handy that its full path-and-file-name are put in the # register. You can paste it with "#p, for example.
Note (just in case this is behaviour specific to my setup): I am using VIM 7.4.52 on Ubuntu 14.04.4 LTS.
Combining information from a couple of other answers: If you want to yank the current full path to a file and put it into the command buffer in another window, first do :let #" = expand("%:p"), then move to another window and type Ctrl+R ".
Useful for copying a file while staying in the same directory and keeping the old one open. For example:
Start: Editing src/com/benatkin/paint/shapes/Circle.java
Type :let #" = expand("%:p") (The path gets yanked to the main clipboard buffer.)
Open a new window with :sp
Type :e Ctrl+R"
Use the arrow keys to go back to Circle and change it to Square, and press <CR>
End: Editing src/com/benatkin/paint/shapes/Square.java
Here is my solution:
" filename / dirname of the current file {{{
" copy result to the system clipboard and echo the result
" the cb> prompt means the clipboard
" *f*ile *n*ame, ex. init.vim
map <Leader>fn :let #+ = expand("%:t") \| echo 'cb> ' . #+<CR>
" *f*ile *p*ath, ex. /home/user/nvim/init.vim
map <Leader>fp :let #+ = expand("%:p") \| echo 'cb> ' . #+<CR>
" *d*irectory *p*ath, ex. /home/user/nvim
map <Leader>dp :let #+ = expand("%:p:h") \| echo 'cb> ' . #+<CR>
" *d*irectory *n*ame, ex. nvim
map <Leader>dn :let #+ = expand("%:p:h:t") \| echo 'cb> ' . #+<CR>
" }}}
If you're on terminal vim, and want to copy to system clipboard: For something easy to remember, that doesn't requiring predefined mappings/functions:
:!echo %
prints the current buffer's relative path to terminal, where you can copy it and then ENTER back to vim. (as already mentioned, you can postfix the command with :p or :t to get absolute or basename, if you can remember that....)
I put it in my vimc:
nnoremap yl :let #" = expand("%:p")<cr>
I use xclip to access X's clipboard, so I use:
nmap <localleader>d :call system("xclip -i -selection clipboard", expand("%:p"))<CR>
If you wish to simply yank the path of the currently open file name then simply press:
step1: ctrl + g [You will see the entire root path at the bottom of window]
step2: select the path with the mouse
step3: Paste with the middle mouse wheel

How can you list the matches of Vim's search?

I would like to list the matches, when I hit:
/example
so that I see where all matches are at once.
:g//p
In its longer form:
:global/regular-expression/print
You can leave out the pattern/regex and Vim will re-use the previous search term.
Trivia: The grep tool was named after this command sequence.
You can also do a :
g/pattern/#
that will print the pattern you want and the number of the line.
if you want to look at this list and jump quickly between the matches, consider using
:vimgrep example %
or
:grep example %
This will populate the "error list" with all of the matches so that you can use :copen to list them all in the quickfix buffer, press enter on a particular line to jump to that match, or use commands like :cn and :cp to go back and forth.
for a thorough explanation, see my reply to a similar question
Just learned a new one: the Location List!
Type :lvim foo % to search for foo in the current file and enter all matches containing foo into the location list.
Type :lopen to open the location list in the quickfix window, which is fully navigable as usual.
Use :lnext/:lprevious to to through the list (use tpope/unimpaired mappings for the best experience)
Another possibility is to use the include file search commands.
[I
This will list all occurrences of the word under the cursor. It may be more than you need though, because it will also search any files that are included in the current file.
But the nice thing about this command is that the search result display also shows a count of the number of matches, in addition to the line number of each match.
:help include-search
to see lots of variants.
A note about
:g//p
This can be reduced further to
:g//
because, as others have said, p(rint) is the default action.
you can get a nice quickfix window with the matches form your current search pattern
:vim // %
:copen
super handy if you previously crafted a complex search pattern using just /pattern
Edit: just found out this also works for all open buffers
:bufdo vimgrepadd // %
:copen
Using :set hlsearch will highlight all the matches in yellow allowing you to scan the file easily for matches. That may not be what you want though, after searching, :g//p will give you the listed matches
To elaborate on this ... instead of
/example
:g//p
you can also write directly
:g/example/p
or, as p(rint) is the default action for the :g(lobal) command, this can be shortened to
:g/example
And instead of p(rint), other actions are possible, e.g. d(elete). See :help :global
g/pattern
If you have :set number, the above command displays line numbers as well.
If you haven't :set number, then
g/pattern/#
will display the line numbers.
" put in your ~/.vimrc file
" START search related configs and helps
"
" ignore case when searching
set ignorecase
" search as characters are entered, as you type in more characters, the search is refined
set incsearch
" highlight matches, in normal mode try typing * or even g* when cursor on string
set hlsearch
" yank those cheat commands, in normal mode type q: than p to paste in the opened cmdline
" how-to search for a string recursively
" :grep! "\<doLogErrorMsg\>" . -r
"
" how-to search recursively , omit log and git files
" :vimgrep /srch/ `find . -type f \| grep -v .git \| grep -v .log`
" :vimgrep /srch/ `find . -type f -name '*.pm' -o -name '*.pl'`
"
" how-to search for the "srch" from the current dir recursively in the shell
" vim -c ':vimgrep /srch/ `find . -type f \| grep -v .git \| grep -v .log`'
"
" how-to highlight the after the search the searchable string
" in normmal mode press g* when the cursor is on a matched string
" how-to jump between the search matches - open the quick fix window by
" :copen 22
" how-to to close the quick fix window
" :ccl
" F5 will find the next occurrence after vimgrep
map <F5> :cp!<CR>
" F6 will find the previous occurrence after vimgrep
map <F6> :cn!<CR>
" F8 search for word under the cursor recursively , :copen , to close -> :ccl
nnoremap <F8> :grep! "\<<cword>\>" . -r<CR>:copen 33<CR>
" omit a dir from all searches to perform globally
set wildignore+=**/node_modules/**
" use perl regexes - src: http://andrewradev.com/2011/05/08/vim-regexes/
noremap / /\v
"
" STOP search related configs and helps
I have written a piece of code for this. It actually avoids the problems in vimgrep. It works even with unnamed files. And it is easier to use.
function! Matches(pat)
let buffer=bufnr("") "current buffer number
let b:lines=[]
execute ":%g/" . a:pat . "/let b:lines+=[{'bufnr':" . 'buffer' . ", 'lnum':" . "line('.')" . ", 'text': escape(getline('.'),'\"')}]"
call setloclist(0, [], ' ', {'items': b:lines})
lopen
endfunction
When you call it with a pattern, it opens the location windows with all the matches.
This could be a command
command! -nargs=1 Mat call Matches(<f-args>)
So all you need to do is to type :Mat pattern
I also use the following mapping to get the matches of the current visual selection.
vnoremap Y "xy:call Matches(#x)<CR>
Ctrl-f to list all search result:
nmap <C-f> :vimgrep /<C-r>//g %<CR> \| !:copen <Enter>

Resources