Re: jumping to start of function or class in C++
- On 08/10/09 16:52, Luc Hermitte wrote:
> "James Kanze"<james.kanze@...> wrote :
>> On Oct 8, 3:21 pm, Luc Hermitte<hermi...@...> wrote:
>>> "James Kanze"<james.ka...@...> :
>>>> I'm currently having to deal with C++ code which uses the
>>>> following coding conventions:
>>>> My problem is getting [[ and ]] to advance or go back to the
>>>> next function (or class); the opening braces aren't always in
>>>> column 1; [...] I rather suspect that some parsing of the C++
>>>> itself will be necessary.
>>>> Does anyone know of any available solution?
>>> The "simplest" solution will probably consist in assembling a
>>> regex from all the functions that ctags has seen in the
>>> current file.
>> Which will still miss classes, I suppose (but it wouldn't be too
>> difficult to add "class", "struct" and "union" to the regex).
>> I'll also have to install ctags, since it's not present on this
> All tags in ctags results have a kind: class, struct, union, function, prototype, ...
> However, indeed you'll have to install ctags (which will grant you access to several features of my C++ ftplugin suite for vim ^^')
>>> As unfortunately taglist() does not permit to select tags on
>>> field values, you may have a grep the relevant tags file in
>>> search of expand('%:t'), keep only the search commands, join
>>> them in a search pattern with \|, and finally search for the
>>> newly built pattern.
>>> Another way will consist in parsing the code in search of
>>> (surrounding) pairs of brackets. A solution should possible
>>> for simple cases, but I'm afraid it won't be perfect.
>> I've enough experience with the issues that I could hack up a
>> quick parser in C++ which would return the correct position.
>> The only question then is how to get vim to use it. The idea,
>> basically, would be to invoke the program with the current
>> line number as a parameter, and the buffer on standard in, let
>> it do the search, and output the target line number. But how to
>> integrate this into vim?
> Writing the C++ parser will be much more complex than integrating its results in vim.
> There are several ways to proceed:
> - if the parser produces a tags compatible file, then calls to taglist('.') + filter()&map() will return the list of line where the function are. The parser will need to be called with something like ":!$PARSER %:p".
> - if the parser returns its result on stdout, its result can be obtained with a call to system(). Supposing it will be a list of numbers, we can have something like:
> :let lines = split(system($PARSER.' '.expand('%:p'))) " you may want to cache this information
> :call sort(lines)
> " lh#find_if is non standard, but easily implemented with a :for loop
> :let next_idx = lh#list#find_if(lines, 'v:1_>= '.line('.'))
> :exe lines[next_idx] "<~> jump to the next position
Instead of writing a parser in C++, why not write it in vimscript? I
believe that if it is possible to write "a quick parser in C++" it would
be even easier to write it in vimscript, where integrating into Vim
would be trivially easy. Both languages are admittedly not identical,
but IMHO vimscript has enough of a "C-like feel" that a C programmer
wouldn't have it hard learning it (especially, of course, if he already
has some good notions about how to use Vim). Instead of invoking a C or
C++ program with the line number as argument, you could then just invoke
a Vim user-command (with a range defaulting to the current line), and
that command would invoke a user-function (passing the first or last
line [or even both to find the innermost function etc., if any,
containing the block of lines: your choice] in the range as an argument
to it). That user-function could be either global, or script-local to
the script containing it together with the user-command.
In particular I believe that the operators =~ !~ =~? !~? =~# !~#
(testing a string for matching a Vim regexp) could be put to good use in
such a parsing function. Possibly also the Normal mode command %
(invoked as "normal %").
Beware of low-flying butterflies.
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php