Actually, I started with the below idea, and created a plugin that works
more or less like what the OP wanted. It uses the Vim completion
mechanism to bringup a popup dialog with matching filenames. Works best
when you have a dedicated tags file the way I originaly proposed (see
the script header). Can anyone try the attached plugin and give me
feedback?
--
Thanks,
Hari
On Wed, 10 May 2006 at 1:54pm, Hari Krishna Dara wrote:
>
> On Wed, 10 May 2006 at 8:10am, Benjamin Reitzammer wrote:
>
> > Hi,
> >
> > thanks a lot, for all your responses. And for being so blazingly fast.
> > Just like vim itself ;)
> >
> > Using a tags file is the closest to the described functionality I was
> > looking for. Although I must say that having to press the <tab> key to
> > request a completion is not nearly as nice as having a list
> > automatically update.
> >
> > Yakov said, getting something like this in vim would be quite hard, but
> > I think, that I might give it a shot nonetheless. You sure will hear
> > about it, if I do so.
> >
> > Thanks again for being so helpful
> >
> > Cheers
> >
> > Benjamin
>
> If you go with the tag file approach, it is not that hard to cook up
> something quickly, without having to press tab. Here is something very
> unpolished, but shows the approach (code copied from my execmap.vim
> plugin):
>
> function! LookupFile()
> " Open a new buffer to show the results.
> new
> redraw
>
> " Generate a line with spaces to clear the previous message.
> let i = 1
> let clearLine = "\r"
> while i < &columns
> let clearLine = clearLine . ' '
> let i = i + 1
> endwhile
>
> let str = ""
> call Prompt(str)
> let breakLoop = 0
> let accepted = 0
> while !breakLoop
> try
> let char = getchar()
> catch /^Vim:Interrupt$/
> let char = "\<Esc>"
> endtry
> if char == '^\d\+$' || type(char) == 0
> let char = nr2char(char)
> endif " It is the ascii code.
> if char == "\<BS>"
> let str = strpart(str, 0, strlen(str) - 1)
> elseif char == "\<Esc>"
> let breakLoop = 1
> elseif char == "\<CR>"
> let accepted = 1
> let breakLoop = 1
> else
> let str = str . char
> endif
>
> " Show the matches for what is typed so far.
> silent! 1,$delete
> let _tags = &tags
> set tags=/tmp/tags
> try
> let tags = taglist(str)
> finally
> let &tags = _tags
> endtry
> for ta in tags
> "Why does this generates syntax errors?
> "silent put =ta["filename"]
> call append('$', ta["filename"])
> endfor
> redraw
>
> echon clearLine
> call Prompt(str)
> endwhile
> endfunction
>
> function! Prompt(str)
> echon "\rLookup file containg: " . a:str
> endfunction
>
> If you call LookupFile(), it brings an empty buffer and prompts you to
> enter a string. Entering each character makes the buffer show all the
> matching filenames. What you sould do in addition is to:
> - Avoid hardcoding the tags file.
> - Don't lookup tags for each entered character, but only after a short
> delay (this could be tricky). This may not be important thought.
> - When user finds the file, make it easy to open it (like pressing O on it,
> or even opening the file right-away if there is only one match).
> - Use a scratch buffer to show results and reuse one buffer. I have
> numerous examples in my all my plugins (selectbuf, breakpts etc.)
> - Plugginize it, creating maps etc. to invoke the function. Again, if
> you don't have much experience, there are several that you can follow.
> You can look at my plugins, I try to follow all the plugin writing
> rules that Vim doc lists.
>
>
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com " lookupfile.vim: Lookup filenames from tagfiles.
" Author: Hari Krishna (hari_vim at yahoo dot com)
" Last Change: 11-May-2006 @ 18:48
" Created: 11-May-2006
" Requires: Vim-7.0
" Version: 1.0.0
" Licence: This program is free software; you can redistribute it and/or
" modify it under the terms of the GNU General Public License.
" See http://www.gnu.org/copyleft/gpl.txt
" Download From:
" http://www.vim.org//script.php?script_id=
" Usage:
" - Place the file in your plugin directory.
" - Select a key to open lookup window and add the below line to your vimrc.
"
" nmap <unique> <silent> <YourKey> <Plug>LookupFile
"
" The default is <F5>.
" - Optionally, configure the tag expression. It is any valid Vim RHS, the
" evaluted value should be a valid 'tags' value. For a static string, use
" extra quotes. Ex:
"
" let g:lookupfile_TagExpr = '"./filenametags"'
"
" The default is to use the value specified in the 'tags' setting is it
" could be inefficient, so it is recommended to generate a special tags
" file containing only one tag per file. If you have unixy tools
" installed, you can run the below command to generate a tags file like
" this.
"
" find . -print | sort | awk '{printf "%s\t%s\t1\n", $0, $0;}' >
filenametag
" - To lookup a file, press the assigned key (default: F5). This will open a
" small window above the current window, where you can type in a regex,
" and the matching filenames will be shown in the Vim7 completion style.
" You can then select the matching file, and press Enter to open it. You
" can also press <Esc> and scroll back to file previous filenames. You can
" then press O on that to open that file.
if exists('loaded_lookupfile')
finish
endif
if v:version < 700
echomsg 'lookupfile: You need at least Vim 7.0'
finish
endif
let g:loaded_lookupfile = 1
" Make sure line-continuations won't cause any problem. This will be restored
" at the end
let s:save_cpo = &cpo
set cpo&vim
if !exists('g:lookupfile_TagExpr')
" Default tag expression.
let g:lookupfile_TagExpr = '&tags'
endif
let s:windowName = '[Lookup File]'
let s:myBufNum = -1
if (! exists("no_plugin_maps") || ! no_plugin_maps) &&
\ (! exists("no_lookupfile_maps") || ! no_lookupfile_maps)
if !hasmapto('<Plug>LookupFile', 'n')
nmap <unique> <silent> <F5> <Plug>LookupFile
endif
endif
noremap <script> <silent> <Plug>LookupFile :call <SID>SetupLookingUp(1)<CR>
function! s:SetupLookingUp(enable)
aug LookupFile
au!
if a:enable
au CursorMovedI * call <SID>LookupFile()
au CursorMoved * call <SID>SetupLookingUp(0)
call s:SetupBuffer()
endif
aug END
endfunction
function! s:SetupBuffer()
let origWinnr = winnr()
let _isf = &isfname
let _splitbelow = &splitbelow
set nosplitbelow
try
if s:myBufNum == -1
" Temporarily modify isfname to avoid treating the name as a pattern.
set isfname-=\
set isfname-=[
if exists('+shellslash')
call OpenWinNoEa("1sp \\\\". escape(s:windowName, ' '))
else
call OpenWinNoEa("1sp \\". escape(s:windowName, ' '))
endif
let s:myBufNum = bufnr('%')
else
let winnr = bufwinnr(s:myBufNum)
if winnr == -1
call OpenWinNoEa('1sb '. s:myBufNum)
else
let wasVisible = 1
exec winnr 'wincmd w'
endif
endif
finally
let &isfname = _isf
let &splitbelow = _splitbelow
endtry
call SetupScratchBuffer()
resize 1
setlocal nowrap
setlocal bufhidden=hide
setlocal winfixheight
startinsert!
" Setup maps to open the file.
imap <buffer> <expr> <CR> <SID>Cr()
nnoremap <silent> <buffer> O :call <SID>OpenCurFile()<CR>
endfunction
function! s:Cr()
return pumvisible()?"\<C-Y>\<Esc>O":"\<CR>"
endfunction
function! s:OpenCurFile()
if bufnr('%') != s:myBufNum
return
endif
let fileName = expand('<cfile>')
if !filereadable(fileName)
echohl ErrorMsg | echo "Can't read file: " . fileName | echohl NONE
return
endif
put=""
close
exec 'edit' fileName
endfunction
function! s:LookupFile()
let part = expand('<cWORD>')
if part == ""
return
endif
let _tags = &tags
try
exec 'let &tags =' g:lookupfile_TagExpr
let tags = taglist(part)
catch
echohl ErrorMsg | echo "Exception: " . v:exception | echohl NONE
return
finally
let &tags = _tags
endtry
" Show the matches for what is typed so far.
let files = map(tags, 'v:val["filename"]')
call complete(col('.')-strlen(part), [part]+files)
endfunction
" Restore cpo.
let &cpo = s:save_cpo
unlet s:save_cpo
" vim6:fdm=marker et sw=2