(These are ranked in order of favourites)
Set up ctags:
apt-get install exuberant-ctags
#Then, in the directory of interest,
ctags -R
Say you have a list of types and variables from lines 25,38 (say you are building a struct):
cal_context_t calibration_info;
cal_context_t simulation_info;
group_timer_t tGroup;
mwahpx_acc_context_t **output_accumulations;
mwahpx_acc_context_t *the_accumulator;
obs_context_t **context_list;
pixelgrid_t *rubber_sheet;
primary_beam_t *reference_beam;
regrid_context_t *regrid_ctxt;
rts_options_t rts_options;
source_info_t *dummy_source;
stokes_context_t *stokes_ctxt;
vis_set_t **chanvis;
vis_set_t *bandvis;
Now, there's a huge problem. You have no idea where these things are defined.
So, run the following:
:25,38g/./exe "norm! 0wl\<c-]>:let @k = expand(\"%\")\<enter>\<c-t>ggo#include \"\<esc>\"kpa\""
There are two important steps here. The rest of it is normal vim:
\<c-]>
With the type name under the cursor, <c-]>
uses ctags to bring up the file of its definition.
Then,
:let @k = expand(\"%\")\<enter>\<c-t>
This puts the filename into register k, and then <c-t>
brings us back to our initial file.
This will grab every include file you need and put them at the top of the file:
#include "rts_common.h"
#include "rts_common.h"
#include "pix_pol_conversions.h"
#include "CalSourceList.h"
#include "rts_common.h"
#include "regrid_engine.h"
#include "rts_common.h"
#include "ionospheric_corrector.h"
#include "obs_context_t.h"
#include "mwahpx.h"
#include "mwahpx.h"
#include "timer.h"
#include "cal_context_t.h"
#include "cal_context_t.h"
Magic.
One time I was refactoring legacy C code, and ended up just cutting about 300 lines out of an ugly function and putting it somewhere else. Not knowing which variables it needed, I let make tell me. There was about 40 missing variables.
It mostly looked like this:
mwa_sim_functions.c:327:72: error: ‘dummy_source’ undeclared (first use in this function)
grid_number, grid_size_meters, reference_beam, rubber_sheet, dummy_source,
^
mwa_sim_functions.c:328:12: error: ‘stokes_ctxt’ undeclared (first use in this function)
&stokes_ctxt, ®rid_ctxt, integration_file, output_accumulations, the_accumulator,
^
mwa_sim_functions.c:328:26: error: ‘regrid_ctxt’ undeclared (first use in this function)
&stokes_ctxt, ®rid_ctxt, integration_file, output_accumulations, the_accumulator,
^
mwa_sim_functions.c:328:39: error: ‘integration_file’ undeclared (first use in this function)
&stokes_ctxt, ®rid_ctxt, integration_file, output_accumulations, the_accumulator,
^
So, I copy pasted this into vim right under the declaration of the pasted function (at line 193), and ran the following, with the error highlighted:
:'<,'>v/error/d
<esc>
qa0mx/error<enter>f:lllyiw/^int<enter>Op*yy'xPq
22@a
:'<,'>g/^m/norm mxk^yw193ggA ^[p'xfef:lllyiw193ggA ^[pA,
The first command just deletes every line that doesn't have "error" in it.
The second
command is a bit terrifying. I record a macro to run on each line
of the error message: it grabs the variable name (yiw
), goes back to the original
function (/^int<enter>
), pastes the variable, types *
to do a forward
search on the variable name, then grabs the line with the first occurence,
and pastes it above the error message ('xP
)
This always seems to get the type of the variable.
Then, I run it 22 times more to get all the types. Magic.
Then, I run another ugly command to basically grab the type
(the first symbol on the line above each error message, ^m
)
and then append it to line 193, then grab the symbol name again,
and paste it after that. Then type a comma. This gets executed on every error
message, so I end up with an almost working function with all of its missing
variables as arguments.
When can contextual code-completion do this for me?
:g
in vim is very powerful. It lets you use useful "ex" commands on lines matching a substring.
E.g., to make copies of all variables with the suffix _a
, but with _b
, below the current line,
type:
:1,6g/_a/t.|s/_a/_b/g
to search through lines 1,6
for the string _a
, then copy (t
) to below (.
) the copied line,
then (|
) search for _a
, and replace with _b
all copies (g
).
Another, to delete the last subfields in a comma-delimited file, and add "bar" to all lines matching "foo":
:'<,'>g/foo/norm $F,F,d0ibar
When highlighting a bunch of lines, type :
, then g
to load up the start of this command, then
/foo
to get lines only with that string, then norm
to enter normal mode on each line, then
you can type normal vim commands $F,F,d0ibar
to go to the end of the line ($
), go to the previous
comma twice (F,F,
), then delete to the start of the line (d0
), the insert the word bar
.