2

Vim is my daily driver for C++ (this would apply to C as well). As it stands, I use coc-vim with coc-clangd for code analysis.

For example, when working with C++, I place my declarations in a header file and yank/paste declarations from the header files into the source files. I then have to prepend every definition with a ClassName::, but after the return type, which is a bit annoying.

Does anyone know of a plugin that can create definitions for you in an appropriate source file?

4
  • "this would apply to C as well" - if C had classes.
    – Friedrich
    Commented Jun 5 at 5:40
  • 1
    What I meant to say in my previous comment is that it's not obvious what you would expect to happen in C. Please edit and clarify. Depending on your expectations, it might be better to ask a separate question for C (in that case, please remove the [filetype-c] tag).
    – Friedrich
    Commented Jun 5 at 7:20
  • 1
    @Friedrich - I just reworded. This definitely relates to C, so going to leave it.
    – trozzel
    Commented Jun 5 at 9:44
  • Do you still have something open in your question? How can we help you further? Otherwise maybe could you accept one of the solutions using the v button next to the arrow voting buttons. It allow the question to rest :-) Commented Jun 6 at 5:36

2 Answers 2

3

Here is a vimscript function that creates a definition based on the current line declaration:

function! CreateDefinition() abort
  let state=winsaveview()
  yank
  normal! [{?class\s\+\zs\h\+"cyiw
  call winrestview(state)
  edit %:p:r.cpp
  $normal! ]p
  substitute /\~\?\h\+(/\=@c . '::' . submatch(0)/
  substitute /;/\r{\r}\r/
endfunction
  • let state=winsaveview used to be able to restore the state of the windows after the few search that will be needed to capture the class name into the register c
  • yank copy the declaration
  • normal! [{?class\s\+\zs\h\+"cyiw search the class name and yank it into the register c
    • [{ search the outer {
    • ?class\s\+\zs\h\+ search the class name
    • "cyiw yank the class name into the register c
  • call winrestview(state) restore the cursor position
  • edit %:p:r.cpp open the cpp buffer (assuming the .cpp is next to the .h file in the file system)
  • $normal! ]p paste the declaration at the end of the buffer with indentation adjusted
  • substitute /\~\?\h\+(/\=@c . '::' . submatch(0)/ add the class name classifier
  • substitute /;/\r{\r}\r/ add an empty body

Remark: For cpp editing you could be interested by the lh-cpp plugin from @LucHermitte.

5
  • That is some dark-magic there. Thanks
    – trozzel
    Commented Jun 5 at 9:45
  • Thanks for the feedback! I have tried to explain the dark-magic. If there is still something mysterious let me know we like to share the dark-magic :-) Commented Jun 5 at 9:47
  • 1
    Thanks for the ad :). And indeed I have everything needed in lh-cpp. I'll write a full answer. Commented Jun 5 at 11:55
  • 1
    I've made a few stylistic edits to the code, the most important of which is to spell out command names—I generally prefer example code to be as clear as possible (interactive use is another matter).
    – D. Ben Knoble
    Commented Jun 6 at 0:26
  • Thanks @D.BenKnoble I have same rule but I still have to follow it more strictly :-) Commented Jun 6 at 0:30
2

Note: I'm under the impression I've already given these information here or on SO... IOW, other answers and solutions may be available there.

I have the :GOTOIMPL (and :MOVEIMPL) commands in lh-cpp that generates empty function definitions from function declarations -- but one at the time.

The implementation in the main branch has several limitations (no support for templates, C array parameters (who use them anyway? ;), ...). This initial implementation is closely related to a 2 decades old tip in vim.wikia. It contains a lot of :substitute/regex calls to handle comments, parameters, extract return types, function names, scopes (ns::ns::cls::cls...), ignore some keywords (virtual, override, static...) and so on. That's why I won't describe it here.

The improved version resides in a gotoimpl_with_libclang branch, it depends on another plugin of mine (vim-clang; branch V2Upgrade), which in turn depends on the Python bindings of libclang. Most of the complex cases are now handled. I've haven't tried (yet) to support trailing return types though.

PS: At the moment, the v2 of MOVEIMPL command has a few issues that I haven't taken the time to tackle. (I'd like to extract the formatting used in function declarations to reproduce it).

2
  • 1. I don't see templates being an issue. 2. Concerning C array parameters, not an issue. Does the source file have to be in same directory as header? Can you force the definition order (top-down) in the cpp file match that of the header?
    – trozzel
    Commented Jun 6 at 14:28
  • There are many options to tune where the alternate .cpp will be generated. Or whether it won't be .cpp but an inline file (to be included as well). See github.com/LucHermitte/lh-cpp/blob/gotoimpl_with_libclang/doc/… Other options wlll be used by my alternate-lite plugin Commented Jun 6 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.