Vim Tips Wiki
Yaojg (talk | contribs)
(Change to TipImported template + severe manual clean)
Line 1: Line 1:
 
{{review}}
 
{{review}}
  +
{{TipImported
{{Tip
 
 
|id=1432
 
|id=1432
  +
|previous=1431
|title=File search similar to cmd-t in TextMate
 
  +
|next=1433
|created=December 4, 2006 3:37
+
|created=December 4, 2006
 
|complexity=basic
 
|complexity=basic
 
|author=Samuel Hughes
 
|author=Samuel Hughes
 
|version=5.7
 
|version=5.7
 
|rating=18/8
 
|rating=18/8
|text=
 
This adds similar capabilities as the cmd-t file search feature in TextMate. I put the "Find" function below into my .vimrc since it's relatively small. I found a similar function a while ago, but I can't trace the author in order to credit them. Anyway, I modified it a bit in order to make it more like TextMate.
 
 
}}
 
}}
  +
This adds capabilities similar to the cmd-t file search feature in TextMate. It uses the Find function from [[VimTip1234]], modified to search recursively whatever directory you are in.
   
 
For example, if I am in the "~/alumni" directory and am looking for a file named "admin_controller.rb" somewhere beneath the current directory, I could type:
It will search recursively whatever directory you are in.
 
   
  +
<pre>
So for example, I am in "~/alumni" directory and I am looking for a file named "admin_controller.rb" somewhere beneath "~/alumni", I could type:
 
:Fi adm trol
+
:Fi adm trol
  +
</pre>
   
where "adm" and "trol" are excerpts of "admin_controller.rb", and the result will be:
+
where "adm" and "trol" are excerpts of "admin_controller.rb". The results will look like this:
1 ./app/controllers/admin_controller.rb
 
2 ./test/functional/admin_controller_test.rb
 
Which ? (&lt;enter&gt;=nothing)
 
   
  +
<pre>
Then you type the number next to the file you're searching for and hit enter.
 
 
1 ./app/controllers/admin_controller.rb
 
2 ./test/functional/admin_controller_test.rb
 
Which ? (&lt;enter&gt;=nothing)
  +
</pre>
   
 
Then you type the number next to the file you're searching for and hit Enter.
In other words, it's searching with this as its input, "*adm*trol*", the asterisk's being wildcards. The wildcards replace the spaces from your original search and are also added to the beginning and end of your search keywords.
 
   
 
In other words, it's searching for "*adm*trol*", the asterisks being wildcards. The wildcards replace the spaces from your original search and are also added to the beginning and end of your search keywords.
I also mapped it to:
 
map ,f :Fi
 
which seems to be quicker.
 
   
  +
I use this map for faster access:
  +
<pre>
 
map ,f :Fi
  +
</pre>
   
And the function is:
+
The function is:
function! Find(name)
 
let l:_name = substitute(a:name, "\\s", "*", "g")
 
let l:list=system("find . -iname '*".l:_name."*' -not -name \"*.class\" -and -not -name \"*.swp\" | perl -ne 'print \"$.\\t$_\"'")
 
let l:num=strlen(substitute(l:list, "[^\n]", "", "g"))
 
if l:num &lt; 1
 
echo "'".a:name."' not found"
 
return
 
endif
 
 
if l:num != 1
 
echo l:list
 
let l:input=input("Which ? (&lt;enter&gt;=nothing)\n")
 
if strlen(l:input)==0
 
return
 
endif
 
 
if strlen(substitute(l:input, "[0-9]", "", "g"))&gt;0
 
echo "Not a number"
 
return
 
endif
 
 
if l:input&lt;1 || l:input&gt;l:num
 
echo "Out of range"
 
return
 
endif
 
 
let l:line=matchstr("\n".l:list, "\n".l:input."\t[^\n]*")
 
else
 
let l:line=l:list
 
endif
 
 
let l:line=substitute(l:line, "^[^\t]*\t./", "", "")
 
execute ":e ".l:line
 
endfunction
 
 
command! -nargs=1 Find :call Find("&lt;args&gt;")
 
   
  +
<pre>
 
function! Find(name)
 
let l:_name = substitute(a:name, "\\s", "*", "g")
 
let l:list=system("find . -iname '*".l:_name."*' -not -name \"*.class\" -and -not -name \"*.swp\" | perl -ne 'print \"$.\\t$_\"'")
 
let l:num=strlen(substitute(l:list, "[^\n]", "", "g"))
 
if l:num &lt; 1
 
echo "'".a:name."' not found"
 
return
 
endif
 
if l:num != 1
 
echo l:list
 
let l:input=input("Which ? (&lt;enter&gt;=nothing)\n")
 
if strlen(l:input)==0
 
return
 
endif
 
if strlen(substitute(l:input, "[0-9]", "", "g"))&gt;0
 
echo "Not a number"
 
return
 
endif
 
if l:input&lt;1 || l:input&gt;l:num
 
echo "Out of range"
 
return
 
endif
 
let l:line=matchstr("\n".l:list, "\n".l:input."\t[^\n]*")
 
else
 
let l:line=l:list
 
endif
 
let l:line=substitute(l:line, "^[^\t]*\t./", "", "")
 
execute ":e ".l:line
 
endfunction
 
command! -nargs=1 Find :call Find("&lt;args&gt;")
  +
</pre>
   
== Comments ==
+
==Comments==
  +
{{script|id=229|text=searchInRuntime.vim}} and {{script|id=1581}} offer similar functionality.
Hi, nice thing.
 
How about making it a script?
 
Setting a list of serchable directories (something like 'tags' variable?)
 
   
 
{{Script|id=2042}} is a ruby/curses based plugin that is very similar to the TextMate functionality, though it won't work in gvim and has a few dependencies (listed on the project page).
   
kyku--AT--os.pl
 
, December 5, 2006 2:37
 
 
----
 
----
 
Change <tt>find</tt> to <tt>grep</tt>, <tt>map</tt> to <tt>\*</tt> and you get a nice intuitive 'find references' function.
Hi, this is really nice :) This tip has number 1432 . If you go to tip number 1234 ([[VimTip1234]]), you'll find my original post ;) While reading throught comments to my post, I promised to make script out of the tip, which never happened ... And also please notice that there is a fix in comments, look for "try-catch".
 
   
Happy vimming !
 
 
--
 
Vladimir
 
 
vlmarek--AT--volny.cz
 
, December 6, 2006 0:00
 
 
----
 
----
 
In order to avoid searching in .svn directories, I changed one line in the original function.
Vladimir,
 
   
  +
<pre>
I'm glad you found your way to this tip so you can get some credit. What do you think of my textmate modification? The search capability was always my biggest argument for ever using textmate, but adding this little change to your Find script makes vim work just as well. And your script alone is obviously good too.
 
 
let l:list=system("find . -path \"*/.svn\" -prune -o -iname '*".l:_name."*' -not -name \"*.class\" -and -not -name \"*.swp\" -print | perl -ne 'print \"$.\\t$_\"'")
  +
</pre>
   
Sam
 
 
 
samueljenningshughes--AT--yahoo.com
 
, December 7, 2006 17:59
 
 
----
 
----
{{Script|id=1581}} offers a similar functionality. [[User:Ipkiss|Ipkiss]] 21:32, 23 July 2007 (UTC)
 
:{{script|id=229|text=searchInRuntime.vim}} as well --[[User:Luc Hermitte|Luc Hermitte]] 13:14, 24 July 2007 (UTC)
 
----
 
 
Change find to grep, map to \* and you get a nice intuitive 'find references' function.
 
<!-- parsed by vimtips.py in 0.546246 seconds-->
 
----
 
 
{{Script|id=2042}} is a ruby/curses based plugin that is *very* similar to the TextMate functionality, though it won't work in gvim and has a few dependencies (listed on the project page)
 
 
 
Jing Guo Yao
 
, December 7, 2006 17:59
 
----
 
This tip is really helpful,
 
In order to avoid the search in .svn, I change one line in the original function.
 
 
let l:list=system("find . -path \"*/.svn\" -prune -o -iname '*".l:_name."*' -not -name \"*.class\" -and -not -name \"*.swp\" -print | perl -ne 'print \"$.\\t$_\"'")
 

Revision as of 22:21, 1 January 2008

Tip 1432 Printable Monobook Previous Next

created December 4, 2006 · complexity basic · author Samuel Hughes · version 5.7


This adds capabilities similar to the cmd-t file search feature in TextMate. It uses the Find function from VimTip1234, modified to search recursively whatever directory you are in.

For example, if I am in the "~/alumni" directory and am looking for a file named "admin_controller.rb" somewhere beneath the current directory, I could type:

:Fi adm trol

where "adm" and "trol" are excerpts of "admin_controller.rb". The results will look like this:

1 ./app/controllers/admin_controller.rb
2 ./test/functional/admin_controller_test.rb
Which ? (<enter>=nothing)

Then you type the number next to the file you're searching for and hit Enter.

In other words, it's searching for "*adm*trol*", the asterisks being wildcards. The wildcards replace the spaces from your original search and are also added to the beginning and end of your search keywords.

I use this map for faster access:

map ,f :Fi

The function is:

function! Find(name)
  let l:_name = substitute(a:name, "\\s", "*", "g")
  let l:list=system("find . -iname '*".l:_name."*' -not -name \"*.class\" -and -not -name \"*.swp\" | perl -ne 'print \"$.\\t$_\"'")
  let l:num=strlen(substitute(l:list, "[^\n]", "", "g"))
  if l:num < 1
    echo "'".a:name."' not found"
    return
  endif
  if l:num != 1
    echo l:list
    let l:input=input("Which ? (<enter>=nothing)\n")
    if strlen(l:input)==0
      return
    endif
    if strlen(substitute(l:input, "[0-9]", "", "g"))>0
      echo "Not a number"
      return
    endif
    if l:input<1 || l:input>l:num
      echo "Out of range"
      return
    endif
    let l:line=matchstr("\n".l:list, "\n".l:input."\t[^\n]*")
  else
    let l:line=l:list
  endif
  let l:line=substitute(l:line, "^[^\t]*\t./", "", "")
  execute ":e ".l:line
endfunction
command! -nargs=1 Find :call Find("<args>")

Comments

searchInRuntime.vim and script#1581 offer similar functionality.

script#2042 is a ruby/curses based plugin that is very similar to the TextMate functionality, though it won't work in gvim and has a few dependencies (listed on the project page).


Change find to grep, map to \* and you get a nice intuitive 'find references' function.


In order to avoid searching in .svn directories, I changed one line in the original function.

let l:list=system("find . -path \"*/.svn\" -prune -o -iname '*".l:_name."*' -not -name \"*.class\" -and -not -name \"*.swp\" -print | perl -ne 'print \"$.\\t$_\"'")