On Fri, 12 May 2006 at 10:23am, Benjamin Reitzammer wrote:

> Hi,
> wow, this is awesome. And flattering ;) I inspired a plugin by Hari ;)
>
> It works great, exactly what I was looking for. Incidentally I just
> yesterday managed to compile and install vim7.
>
> The only thing, that's not optimal for me right now, is the generating
> of the tags file. The proposed shell command, which is also in the
> head of the plugin, puts the complete (relative) filename as tag into
> the tags file. But I would rather only search for the filenames only
> (without the directory in which the files are located).
>
> A line in the tags file should look like
>
> .htaccess      /home/benjamin/public_html/.htaccess 1
>
> instead of
>
> /home/benjamin/public_html/.htaccess     
/home/benjamin/public_html/.htaccess 1
>
>
> I know this may generate a lot of duplicates, which is problematic for
> the file selection popup, which only shows the filename and not the
> directory in which the file is located.
>
> So this might be "feature request": Show the complete path of the
> files that are presented in the popup.
>
> Ragarding the shell snippet: Seems like I must learn awk ;)
>
> Thanks for the plugin ....
>
> Cheers
>
> Benjamin
>

Lookup by just the filename is already possible, it just depends on how
you generate the tags file. I found a much simpler way to generate the
tags file:

find . -type f -printf "%f\t%p\t1\n" | sort

If you rather like the absolute pathname to show up in the lookup, you
can change it as:

find `pwd` -type f -printf "%f\t%p\t1\n" | sort

With this change, you will now search only on the filename (not path),
but the lookup will still work the same. I am attaching a new version
with some simple changes to make typing the pattern easier. I have
identified some issues so far, which are also in the script header:

- Vim sometimes automatically replaces the pattern with the first filename
  from the popup. You have to select back the original pattern using ^P
  (this is the only reason the pattern is also included as part of the
  popup).
- When pressing backspace to remove characters from pattern, I see Vim
  automatically showing a different set of matches, not set by the plugin.
  I don't know what the origin of this matches is.
- The taglist() function's performance (on which this plugin depends on)
  seems to be bad, even when the same pattern can be looked up much faster
  using the :tag command. Use a sufficient g:lookupfile_MinPatLength for

I wonder if these are bugs in Vim7 itself or I am missing something. The
plugin seems to be usable, even with these issues, however, on a huge
file with more than 70000 lines, it seems to choke on the first few
characters typed. I think the problem is with the taglist() function,
itself. If I set the same tag file to 'tags' and use vim command-line
completion, say ":ta t<Tab>", it comes back pretty quickly with the
list, so may be taglist() function is spending too much time creating
the list of dictionaries. May be adding a minlength to trigger the popup
will help (4 characters seems to be fine, though it really depends on
the match size)?

Does anyone think it will be useful to upload this in the current state
to vim.org?

-- 
Thanks,
Hari

__________________________________________________
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: 12-May-2006 @ 11:34
" Created:     11-May-2006
" Requires:    Vim-7.0, genutils.vim(1.19)
" Version:     1.0.2
" 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 . -type f -printf "%f\t%p\t1\n" | sort >& ./filenametags
"
"     Typically you would want to exclude generated files such as .class and
"     .o. You can do this easily by passing the above output through a grep
"     filter (before are after sort).
"
"   - 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.
" Known Issues:
"   - Vim sometimes automatically replaces the pattern with the first filename
"     from the popup. You have to select back the original pattern using ^P
"     (this is the only reason the pattern is also included as part of the
"     popup).
"   - When pressing backspace to remove characters from pattern, I see Vim
"     automatically showing a different set of matches, not set by the plugin.
"     I don't know what the origin of this matches is.
"   - The taglist() function's performance (on which this plugin depends on)
"     seems to be bad, even when the same pattern can be looked up much faster
"     using the :tag command. Use a sufficient g:lookupfile_MinPatLength for
"     now to avoid this call from choking up (the default is 4).

if exists('loaded_lookupfile')
  finish
endif
if v:version < 700
  echomsg 'lookupfile: You need at least Vim 7.0'
  finish
endif
if !exists('loaded_genutils')
  runtime plugin/genutils.vim
endif
if !exists('loaded_genutils') || loaded_genutils < 119
  echomsg 'lookupfile: You need a newer version of genutils.vim plugin'
  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

if !exists('g:lookupfile_MinPatLength')
  " Min. length of the pattern to trigger lookup.
  let g:lookupfile_MinPatLength = 4
endif

" Some onetime initialization of variables
if !exists('s:myBufNum')
  let s:windowName = '[Lookup File]'
  let s:myBufNum = -1
endif

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>

let s:_backspace = &backspace
function! s:SetupLookingUp(enable)
  aug LookupFile
    au!
    if a:enable
      let s:_backspace = &backspace
      let &backspace = 'start'
      au CursorMovedI * call <SID>LookupFile()
      au CursorMoved * call <SID>CursorMoved()
      call s:SetupBuffer()
    else
      let &backspace = s:_backspace
    endif
  aug END
endfunction

function! s:CursorMoved()
  " Ignore the event while in the same buffer.
  if bufnr('%') == s:myBufNum
    return
  endif
  call s:SetupLookingUp(0)
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> pumvisible()?"\<C-Y>\<Esc>O":"\<CR>"
  inoremap <buffer> <expr> <Esc> pumvisible()?"\<C-E>\<C-C>":"\<Esc>"
  nnoremap <silent> <buffer> O :call <SID>OpenCurFile()<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
  if strlen(part) < g:lookupfile_MinPatLength
    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
ߎ¼ã]¼ß_;çÍuã¾:Û~=

Reply via email to