vim grep not finding anything - vim

According to this documentation
http://vim.wikia.com/wiki/Find_in_files_within_Vim
if grep is used like
:vim[grep][!] /{pattern}/[g][j] {file} ...
it should be able to find files by a matching pattern.
I have a text file named text.txt in the directory where I am starting vim from.
Content of text.txt is
look for me
In vim I enter the command
:grep /look/gj *.txt
but I don't get any results. Although the file text.txt contains the string "look".

You are simply confusing two commands: :vimgrep and :grep.
:help :vimgrep uses internal methods for searching files and has its own syntax and flags.
:help :grep uses an external program for searching so it doesn't have a defined syntax; the syntax you use is determined by what external program is used under the hood.
You can't really expect the :vimgrep syntax to work in :grep.

You're using vim's syntax for grep instead of using grep(1) syntax.
As written here: How do I search in all files of my project using VIM?
Syntax for :grep is, by default, the same as the grep(1) command:
:grep 'my pattern.*' /path/to/dir
By default it will search the current directory (:pwd).
The major difference between :grep and :vimgrep is that :vimgrep (:vim for >short) uses Vim-compatible regular expressions, whereas :grep uses whatever >regular expressions your &grepprg uses.

The searches generally work in the current directory as well so I would check the output of :pwd and :ls to see if you are seeing what you expect to be seeing.
If you :cd ~ however, you can search subdirectories with vimgrep by using ** as the path:
:vim /look for me/ **/*.txt
I would also suggest that unless you have specific requirements, you do not use the g or j flags after the search pattern.

Related

How to add user command to vi/vim to have multiple conditions to search the content?

Our servers only have vi/vim to check the log files and I feel searching in vi is painful and limited.
I wonder if it's possible to provide an executable file in the path and then use the vi user command to call it and the user command is able to accept multiple conditions like A=value1 && B=value2, A=value1 || B=value2, etc and then it searches the content in the open vi editor and places the cursor in matching text.
If it's possible please describe a bit the steps.
If what you have on your machines is actually Vim, you should be able to leverage the "quickfix" feature. In a nutshell, you can:
feed a list of locations to Vim,
optionally tell Vim how to parse that list,
go through that list with commands like :cnext or :lprevious,
display that list in a special window,
batch operate on every line in the list.
In the simplest scenario, your hypothetical external program would output a list formatted in a way Vim already understand, like:
filename.txt:3067:12:some text
filename.txt:4321:7:some text
which could be fed "directly" to Vim:
$ vim -q <(yourcommand)
# also open the quickfix window
$ vim -q <(yourcommand) +cwindow
or via some file:
$ vim -q yourfile
It can all be done from within Vim by telling it to use your program instead of grep for the :grep command:
set grepprg=yourcommand
and doing:
:grep <your arguments>
References:
:help quickfix
:help :cnext
:help :lprevious
:help -q
:help -+c
:help :cwindow
:help :grep
:help 'grepprg'
:help 'grepformat'

Vim search across directories for a file or directory

I am using Vim to create Markdown files. For relative links like:
- [Configure AWS with Role Credentials](/group/product/latest/operations/cloud-providers/configure-aws-cloud-provider-roles)
I'd like to be able to check for the directory/file in the link and see if it exists across a range of directories.
I was wanting to use something like:
:vim 'word' **./*.md | copen
which is what i use to find words/phrases across directories. Is there a way to do something like this, from the Vim command line?
For searching, a lot of Vim users install libraries like Ack, The Silver Searcher (AKA Ag), or RipGrep (AKA Rg). These can be run via the command line or with library-specific Vim plugins.
If searching the word with vanilla Vim is your goal, you could use :grep or :vimgrep. Enter command mode with shift + :, and then search:
:grep word **/*.md
Where word is your word and **/*.md is the directory where your markdown files are stored. Adjust the asterisks to include more directories.
Matches would be available in the Quickfix List, which you can see with :cw, also command mode.
:vimgrep and :grep are powerful; check out :help :vimgrep and :help :grep to learn more.

Vim: How do I map vimgrep command to avoid typing the file pattern?

I usually search in my projects using vimgrep command in this fahsion:
:vimgrep /{pattern}/gj app_name/**/*.py
All the significant source code lives inside the app_name directory and I always search inside Python files, so I would like to create a command to avoid writing the search path over and over (I'm using a project specific vimrc for custom mappings). Something like this:
:proj_search {pattern}
You can use command
command -nargs=1 ProjSearch vimgrep /<args>/gj app_name/**/*.py
:h 40.2
Edit: As mcubik pointed out
User-defined commands must start with a capital letter. You
cannot use ":X", ":Next" and ":Print". The underscore cannot be
used! You can use digits, but this is discouraged.

Open all files that match a certain pattern in Vim

I’m in ~/src. I can do git grep _pattern_ and get a list of all *.cpp or *.hpp files that match this pattern.
Now I would like to go through all the files that match the pattern and make edits on them. How do I do this in Vim? (Basically, I want Vim to go through my directory like git grep does, and jump me to the right files.)
You can use the single inverted commas (also a unix shell feature), something like:
vim `git grep --name-only <your expression>`
In bash, you could do
vim $(grep -l _pattern_ *.cpp *.hpp)
but that's a bash feature, not a vim feature.
you can use the args ex command:
:args *.cpp *.hpp
This will open all cpp and hpp files in the current directory.
You can use any file path expansions available to :grep as well.
You could possibly set the grepprg and grepformat options to run git grep... and interpret the result. This would then let you run the command :grep and read the results into the quickfix buffer - see :h quickfix for more information. You can then step through them with :cnext and :cprev, or :copen to open a separate window with the list of files - putting the cursor on a filename and pressing return will open that file for editing.
The advantage of this over Zoran's and ammoQ's suggestions is that it will not read the files into memory until you want to edit them. Their suggestion will load possibly hundreds of files into memory at once, and can be a nightmare to manage. It is also cross platform so should work on Windows without having to use a third-party shell such as cygwin bash.
By properly using the quickfix list, you can even go immediately to the the right line (using the :help quickfix commands, eg. :cn or :cw). So, if you are using bash or zsh:
vim -q &lt(git grep foo)

redirection to a file of a search in Vim

My problem is simple. I search a specific pattern in a file (let's say label in a Tex file)
:g/label/#
but there are lots of occurrences. So I'd like to redirect this output to another file to be able to work easily with it.
Do you have a trick or a command that I don't know?
it's not clear from the original post what you mean by "work easily with it" but it's often useful to see and quickly jump between all of the matches in a buffer without "extracting" the matches to a separate buffer.
vim has an internal grep built in. your example would be something like this (in vim, % denotes the current file)
:vimgrep /label/ %
This will take you to the first occurrence and report how many matches there were. What's cool is that you can look at all of the matches listed by opening up the quickfix error list using
:cope
Now you can just scroll around and press enter on a line to jump to the exact position of the match.
The quickfix error list is exactly the same buffer you use if you run make from inside vim and your compiler throws errors: it gives you a list of what and where the errors are.
After you've jumped to one location pointed by quickfix, you can go to forwards and backwards in the list via :cn and :cp. :ccl closes the error list.
You can also expand your "error" list via :vimgrepa /newpattern/ % or :vimgrepadd
The (documented) caveat is that vim's internal grep is slower than most native grep implementations (but you do get it "for free" in windows, for example). If you do have a grep installed, you can use :grep instead of :vimgrep for similar results.
quoting :help grep
Vim has two ways to find matches for a
pattern: Internal and external. The
advantage of the internal grep is that
it works on all systems and uses the
powerful Vim search patterns. An
external grep program can be used when
the Vim grep does not do what you
want.
The internal method will be slower,
because files are read into memory.
The advantages are:
- Line separators and encoding are automatically recognized, as if a file
is being edited.
- Uses Vim search patterns. Multi-line patterns can be used.
- When plugins are enabled: compressed and remote files can be searched.
You can also use the location list if you're already using the error list for dealing with compilation errors. just add l (for location) to the beginning of the grep command (:lvimgrep,:lvimgrepa :lgrep, :lgrepa) and use :lopen :ln :lp :lcl instead of the :c* ones.
For more commands consult
:help grep
:help quickfix-window
:help quickfix
:help quickfix-error-lists
:redir > matches.txt|execute 'g/foo/#'|redir END
See :h :redir, you can also redirect to registers, variables, the clipboard etc.
What you're doing is essentially 'grep -n label file' from command line. So you can run that command and > it into a file easily enough.
The derivation of 'grep' is even from basically the same source.
I've gotten this of the net at some point:
function GoToLine(mainbuffer)
let linenumber = expand("<cword>")
silent bd!
silent execute "buffer" a:mainbuffer
silent execute ":"linenumber
silent nunmap <Enter>
endfunction
command -nargs=1 GoToLine :call GoToLine(<f-args>)
function GrepToBuffer(pattern)
let mainbuffer = bufnr("%")
silent %yank g
enew
silent put! g
execute "%!egrep -n" a:pattern "| cut -b1-80 | sed 's/:/ /'"
silent 1s/^/\="# Press Enter on a line to view it\n"/
silent :2
silent execute "nmap <Enter> 0:silent GoToLine" mainbuffer "<Enter>"
" silent nmap <C-G> <C-O>:bd!<Enter>
endfunction
command -nargs=+ Grep :call GrepToBuffer(<q-args>)
Put it in your .vimrc, then :Grep Foo
Requires external grep program to work properly.
(Just an idea -- untested.)
You can delete all the lines with your pattern in it, write to another file, and undo the delete.
:g/label/d
:w matches
u

Resources