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

Reply via email to