On pon sty 1 2007, Mikolaj Machowski wrote:
> > Note: much faster, noticeable on big files, would be reading of
> > tags file into buffer and just g//d proper lines and add tags at the
> > end
>
> how to read tags into the buffer and what does "g//d proper lines" mean?
:new somename
:g/\t{filename}\t/d
> > - but I hate buffer management in scripts, YMMV.
> >
> > Sounds complicated but Vim should be able to perform all actions with
> > reasonable speed. The most expensive is f) .
> >
> > You should carefully consider when this function should be performed.
> > I would vote for ; and BufLeave and BufWritePre autocommands.
> >
> > m.
>
> I write the function like this, but there are some problems.
> This is my first time to write vim script, so please give me a hand.
>
> inoremap <expr> ; UpdateTags()
> func UpdateTags()
> "get the file name of the current buffer
> let currentfilename=bufname("%")
Safer::
let fname = expand('%:p')
Full path will prevent ambiguity in some corner cases.
> "get the last line number in the current buffer
> let lastline=line('$')
> let currentfile=getline(1 , lastline)
Just::
let currentfile=getline(1, '$')
> "how to define the temporary file name
> call writefile(currentfile , ".tmp.cc" , "b")
> call system('ctags --c++-kinds=+p --fields=+iaS --extra=+q -f .tags
> .tmp.cc')
> let currenttags=readfile(".tags" , "b")
As I wrote, better to skip writing of tags to file, faster and you avoid
messing with filenames::
let currenttags = system('ctags --c++-kinds=+p -- fields=+iaS
--extra=+q -f - .tmp.cc')
> "remove the comment in the tags file
> call remove(currenttags , "^!")
Another benefit of using '-f -' - ctags when dealing with STDOUT doesn't
add !comment lines. Note for future - remove() doesn't accept RE, only
indexes.
> let alltags=readfile("tags" , "b")
> call remove(alltags , currentfilename)
remove() doesn't accept regexps only indexes. To remove offending lines
use filter()::
call filter(alltags, "v:val !~ fname")
> echo currenttags
> substitute(currenttags , ".tmp.cc" , currentfilename , "g")
> "here I want to replace ".tmp.cc" with currentfilename in the new
> created tags file,
> "but vim always gives me an error "E486: Pattern not found: currenttags
> , ".tmp.cc" , currentfilename , "g")"
??? substitute() is for strings. Now you can do::
let newtags = alltags + currenttags
> "echo currenttags has showed me currenttags contains ".tmp.cc".
> call add(alltags , currenttags)
> call writefile(alltags , "tags" , "b")
call writefile(newtags, "tags", 'b')
> "I want to write the updated tags into the file "tags" , but failed.
> "The error is "E730: using List as a String"
> "I don't understand
> endfunc
>
> Zheng Da
m.