Loading ...
Sorry, an error occurred while loading the content.

Re: jumping to start of function or class in C++

Expand Messages
  • Tony Mechelynck
    ... @James: 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
    Message 1 of 5 , Nov 6, 2009
    • 0 Attachment
      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
      >> machine.
      > 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 %").

      :help 40.2
      :help usr_41.txt
      :help user-commands
      :help user-functions
      :help expression-commands
      :help getline()
      :help expr4
      :help :normal

      Best regards,
      Beware of low-flying butterflies.

      You received this message from the "vim_use" maillist.
      For more information, visit http://www.vim.org/maillist.php
    Your message has been successfully submitted and would be delivered to recipients shortly.