lh-cpp is an heterogeneous suite of helpers for C and C++ programming.
It provides the following things:
- Smart snippets for brackets pairs, control statements
- a few templates
- a few advanced wizards, and high-level features to Generate classes and singletons, to Generate ready to fill-in function comments for Doxygen, Jump to a function implementation, Search for un-implemented or undeclared functions, etc.
- syntax highlighting for identified counter-idioms and bad practices (catch by value, assignments in conditions, throw specifications)
- an API to build even more complex wizards and advanced features
An exhaustive list of all options is also available.
The insertion of pair of brackets-like characters is eased thanks to lh-brackets.
In mode | INSERT | VISUAL | NORMAL |
---|---|---|---|
keys | Expands into .. | Surrounds the selection with ... 2 | Surrounds the current ... |
( |
(<cursor>)«» |
(<selection>) |
word |
[ |
[<cursor>]«» |
1 | 1 |
[ after a [ |
[[<cursor>]]«» |
n/a | n/a |
] before ]] |
close all ]] |
n/a | n/a |
<localleader>[ |
[<selection>] |
word | |
{ |
{<cursor>}«» 3 |
{<selection>} |
word |
<localleader>{ |
{\n<selection>\n}«» |
line | |
< | <<cursor>>«» after #include , or template on the same line |
||
" (1 double quote) |
"<cursor>"«» |
1 | 1 |
"" |
"<selection>" |
word | |
' |
'<cursor>'«» |
1 | 1 |
'' (2 single quotes) |
'<selection>' |
word | |
; |
closes all parenthesis after the cursor -- if there is nothing else |
- 1 Not defined to avoid hijacking default vim key bindings.
- 2 The visual mode mappings do not surround the current marker/placeholder selected, but trigger the INSERT-mode mappings instead.
- 3 The exact behavior of this mapping has changed with release r719 (on Google Code). Now, no newline is inserted by default. However, hitting
<cr>
in the middle of a pair of curly-bracket will expand into{\n<cursor>\n}
. «»
represents a marker/placeholder, it may be expanded with other characters like<++>
depending on your preferences.- There is no way (yet) to deactivate this feature from the
.vimrc
There exist, over the WWW, a lot of configurations and mappings regarding C programming. Once again you will find shortcuts for if
, else
, elif
(I know it is not a C keyword, but else if
are), for
, while
, do
, switch
, and main
. In C++, snippets are also provided for try
, catch
, and namespace
.
What is unique is the fact that when you type if
in insert mode, it will automatically expand into ...
if () {
}
... in respect of the context. I.e.: within comments or strings (delimited by single or double quotes) if
is not expanded. If keyword characters precede the typing, if
is not expanded as well. Thus variables like tarif
can be used without getting any headache.
Most of these same snippets, and a few variations, are
also provided as template-files for
mu-template.
This time, you just need to type the first letters of the snippet/template
name, and trigger the expansion (with <c-r><tab>
by default). If several
snippets match (like c/for, c/fori, cpp/fori and cpp/for-iterator when
you try to expand fo
), mu-template will ask you to choose which (matching)
snippet you want to expand.
In visual mode, ,if
wraps the selection within the curly brackets and inserts if ()
just before. In normal mode ,if
does the same thing under the consideration that the selection is considered to be the current line under the cursor. Actually, it is not ,if
but <LocalLeader>if,
with maplocalleader
assigned by default to the coma ,
.
In the same idea, <LocalLeader><LocalLeader>if
surrounds the selection with if (
and ) {\n«»\n}«»
.
All the three mode oriented mappings respect and force the indentation regarding the current setting and what was typed.
More precisely, regarding the value of the buffer relative option b:usemarks (cf. lh-brackets), if
could be expanded into:
if () {
«»
}«»
The exact style (Alman, Stroustroup, ...) regarding whether brackets are on a
new line, or not, can be tuned thanks to lh-dev :AddStyle
feature.
Note: in all the following mappings, ,
is actually the localleader that
lh-cpp sets to the comma characcter if it isn't set already.
tpl
expands intotemplate <<cursor>>«»
;<m-t>
insertstypedef
, ortypename
depending on what is before the cursor ;<m-r>
insertsreturn
, and tries to correctly place the semicolon, and a placeholder, depending on what follows the cursor ;<c-x>be
,<c-x>rbe
replace(foo<cursor>)
with(foo.begin(),foo.end()<cursor>)
(orrbegin
/rend
) ;<c->se
: attempt to fill-in aswitch-case
from an enumerated type ;,sc
|,dc
|,rc
|,cc
|,lc
surround the selection with ;static_cast<<cursor>>(<selection>)
,dynamic_cast
,reinterpret_cast
,const_cast
, orboost::lexical_cast
;,,sc
|,,dc
|,,rc
|,,cc
try to convert the C-cast selected into the C++-cast requested ;#d
expands into#define
,#i
into#ifdef
,#e
intoendif
,#n
into#include
;,0
surrounds the selected lines with#if 0 ... #endif
;,1
surrounds the selected lines with#if 0 ... #else ... #endif
;pub
expands intopublic:\n
,pro
expands intoprotected:\n
,pri
expands intoprivate:\n
;vir
expands intovirtual
;firend
is replaced byfriend
;<m-s>
insertsstd::
,<m-b>
insertsboost:
;?:
expands into<cursor>? «» : «»;
;<C-X>i
will look for the symbol under the cursor (or selected) in the current ctag database and it will try to automatically include the header file where the symbol is defined.<M-i>
will look for the symbol under the cursor (or selected) in the current ctag database and it will try to automatically prepend it with its missing complete scope.
- All templates, snippets and wizards respect the naming convention set for the current project thanks to lh-dev styling feature -- see my project style template for an idea of what is supported and possible.
- stream inserters, stream extractor, binary operators.
- bool operator: almost portable hack to provide a boolean operator, strongly inspired by Matthew Wilson's Imperfect C++.
- Generation of enums, and of switch-case statements from enum definition.
- constructors:
copy-constructor
,default-constructor
,destructor
,assignment-operator
(see:h :Constructor
). - Various standard types and functions (and a few from boost) have a snippet that'll automatically include the related header file there are are defined. NB: at this time, inclusions are not optimized as IncludeWhatYouUse would optimize them for us.
- When a snippet/template requires header files, they will get included automatically (as long as the snippet specifies the headers files required) ; note: so far this feature cannot detect whether a required header file is already indirectly included through other included files.
- Some snippets will try to detect the C++11 dialect (98/03/11/14/17) in
order to adapt the result produced -- it will be done through the analysis
of the option
(bg):cpp_std_flavour
, or the analysis of$CXXFLAGS
, or through the analysis of CMakeCXXFLAGS
variables (this will require lh-cmake, and the project to be configured to CMake.)
I'll try to maintain an up-to-date documentation of the snippets as most of them have options.
- class: builds a class skeleton based on the selected (simplified) semantics (value copyable, stack-based non copyable, entity non-copyable, entity clonable)
- singleton: my very own way to define singletons based on my conclusions on this anti-pattern -- you may prefer Loki's or ACE's solutions
- :DOX: analyses a function signature (parameters, return type, throw specification) and provide a default Doxygenized documentation
- :GOTOIMPL, :MOVETOIMPL: search and jump to a function definition from its declaration, provide a default one in the ad'hoc implementation file if no definition is found
- :ADDATTRIBUTE: old facility that helps define const-correct accessors and mutator, will be reworked. lh-refactor provides more ergonomic mappings for this purpose.
- :CppDisplayUnmatchedFunctions,
<c-x>u
: shows the list of functions for which there is neither a declaration, nor a definition - :Override: Ask which inherited virtual function should be overridden in the current class (feature still in its very early stages)
:Constructor
(that takes the following parameters:init
,default
,copy
,assign
), or:ConstructorInit
,:ConstructorDefault
,:ConstructorCopy
,AssignmentOperator
. They'll analyse the list of know attributes (from a ctags database) to generate the related construction functions.
- assign in condition (bad practice)
- catch by value (bad practice)
- throw specifications (do you really know what they are about, and still want them?), BTW they have been deprecated in C++11
- C casts in C++ (bad practice)
- cases that fall through the next one (code smell -- disabled by default)
- function definitions
- home like VC++: mappings that override
<home>
and<end>
to mimic how these keys behave in VC++. - omap-param: defines the o-mappings
,i
and,a
to select the current parameter (in a list of parameters). - a.vim,
- SiR,
- lh-cpp imports a C&C++ Folding plugin, which is still experimental.
- lh-dev, which is required by
lh-cpp, provides a few commands like
:NameConvert
that permits to change the naming style of a symbol. The possible styles are:upper_camel_case
,lower_camel_case
,snake
/underscore
,variable
,local
,global
,member
,constant
,static
,param
,getter
,setter
)
- Requirements: Vim 7.+, lh-vim-lib, lh-brackets, mu-template, lh-dev
- With vim-addon-manager, install lh-cpp. This is the preferred method because of the various dependencies.
ActivateAddons lh-cpp
- or with vim-flavor which also supports dependencies:
flavor 'LucHermitte/lh-cpp'
- or you can clone the git repositories (expecting I haven't forgotten anything):
git clone git@github.com:LucHermitte/lh-vim-lib.git
git clone git@github.com:LucHermitte/lh-tags.git
git clone git@github.com:LucHermitte/lh-dev.git
git clone git@github.com:LucHermitte/lh-brackets.git
git clone git@github.com:LucHermitte/searchInRuntime.git
git clone git@github.com:LucHermitte/mu-template.git
git clone git@github.com:tomtom/stakeholders_vim.git
git clone git@github.com:LucHermitte/lh-cpp.git
- or with Vundle/NeoBundle (expecting I haven't forgotten anything):
Bundle 'LucHermitte/lh-vim-lib'
Bundle 'LucHermitte/lh-tags'
Bundle 'LucHermitte/lh-dev'
Bundle 'LucHermitte/lh-brackets'
Bundle 'LucHermitte/searchInRuntime'
Bundle 'LucHermitte/mu-template'
Bundle 'tomtom/stakeholders_vim'
Bundle 'LucHermitte/lh-cpp'
Many people have to be credited:
- the Vim & VimL gurus ;
- the people I've stolen scripts and functions from: Stephen Riehm, Michael Sharpe, Georgi Slavchev, Johannes Zellner, Saul Lubkin ;
- the people that gave me many great ideas and even feedback: Gergely Kontra, Leif Wickland, Robert Kelly IV [I've also stolen scripts from them] ;
- Thomas Ribo for his feedback and features-requirements.
- and many more that I have probably forgotten.
- Documentation is under CC-BY-SA 3.0
- lh-cpp is under GPLv3 with exceptions. See acompagning license file, i.e.
- Plugin, snippets and templates are under GPLv3
- Most code generated from snippets (for control statements, proto -> definition, accessors, ...) are under the License Exception detailled in the license file.
- However, code generated from the following wizards:
class
,singleton
,enum
(1&2, switch, for),abs-rel
-> is under Boost Software Licence
- C++ tips on vim.wikia
- c.vim
- Project Management: local_vimrc
- Compilation: BuildToolsWrappers
- Errors Highlighting: syntastic, compil-hints (a non-dynamic syntastic-lite plugin that'll only highlight errors found after a compilation stage)
- CMake Integration: lh-cmake + local_vimrc + BuildToolsWrappers
- Refactoring: refactor.vim, my generic refactoring plugin
- Code Completion: YouCompleteMe, really, check this one!, or OmniCppComplete, or clang_complete
- Code Indexing: clang_indexer and vim-clang, lh-tags