Resharper : subtituate macro with multi-line code - c++

Is it possible to make Resharper Substituate macro call in separate-lines mode?
Example
I have this code :-
#define TEST(T) int T=5; \
T++;
TEST(apple);
If I click
Substituate macro call and all nested calls like this :-
The line TEST(apple); will become :-
int apple=5; apple++;;
I hope there is an option to make the result be 2 separate lines :-
int apple=5;
apple++;;
Other notes
I know that macro with \ is finally interpreted as a single line,
but it would be nice if there is an option to show it as many lines for eye-candy.
(Even it may break the macro behavior, e.g. those with __LINE__ )
It would be useful for debugging for a 10+ lines macro.

It's not possible at the moment, but you can always select the resulting code after a macro substitution and invoke "Reformat Code" (Ctrl+Alt+Enter) to make it readable.

Related

Preprocessing simple integer arithmetic with cpp

I have a following input file:
#define __SIZE_K(x) (x * 1024)
#define DT_FLASH_SIZE __SIZE_K(128)
reg = <0x08000000 DT_FLASH_SIZE>;
If I run that through a preprocessor I get this:
$ cpp -x assembler-with-cpp input.dts -E -P
reg = <0x08000000 (128 * 1024)>;
If it possible to get the macro fully evaluated? I would like to have:
reg = <0x08000000 131072>;
I would like to have devicetree source files "fully-preprocessed" and I would prefer to do this entirely in the preprocessor, but I'm not sure this is possible... The final devicetree consists of multiple files, some of which define the layout, some are headers with macros and various values depending on selected chip.
If it possible to get the macro fully evaluated?
Theoretically, yes. But it's not usable in the context you want to use it.
Preprocessor is a simple text replacement tool. It replaces one text for the other. First, you have to implement a table of all possible combinations of replacements:
#define MUL_1_1 1
#define MUL_1_2 2
#define MUL_1_3 3
// etc. for **billions** of lines
#define MUL_128_1024 the_result_here
// etc.
After those bilions of lines, you can finally write:
#define MUL_(a, b) MUL_##a##_##b
#define MUL(a, b) MUL_(a, b)
After that you can do:
#define __SIZE_K(x) MUL(x, 1024)
You can use a library - like P99_MUL or BOOST_PP_MUL - and they are basically implemented in almost the same way, with a lot of optimizations to shorten the list.
There is no point in using specifically C preprocessor in this context anyway. Use M4 or Python's Jinja2 or PHP - a full programming language, instead of some limited preprocessing C tool.

Remove pressed key from vim input buffer

I'm writing a vim auto-command for cpp files where I want an abbreviation for #include lines.
The goal is for the abbreviation to expand to #include <▐> with the pipe being the location of the cursor after expansion.
Since naturally the abbreviation is to be followed by a space I'm trying to remove the input space from the register and move on.
However even after exiting insert mode and returning, or any trick I could think of: deleting next key, keying in bs etc, the space is being entered after whatever series of commands the iabbrev includes.
Therefore I'm looking for something that will remove the space from the register AND put me still in insert mode.
Thanks.
Add this to your .vimrc:
autocmd FileType cpp iab <buffer> #i #include <><Left><C-R>=Eatchar('\s')<CR>
func Eatchar(pat)
let c = nr2char(getchar(0))
return (c =~ a:pat) ? '' : c
endfunc
In lh-cpp, I have in a C ftplugin (the place where such definitions should be)
iab <buffer> #n <C-R>=lh#map#no_context("#n ",'\<esc\>0i#include')<CR>
:Brackets < > -open=function('lh#cpp#brackets#lt') -visual=0
With lh#map#no_context() that prevents the expansion of #n within string and comment contexts -- sometimes, we want to be able to type auto s = "#n";, and lh#cpp#brackets#lt that recognizes a few contexts in which I can expand my < into <> (includes, templates, castings, etc).
As you see I don't automatically append "" nor <> here as I want to be able to choose between #include <foo> and #include "foo"
Back to abbreviations that don't eat the space characters, the answer is in the help, see Menix's answer.
To simplify my task, I've defined a command that automatically applies such function (in lh-brackets this time):
command! -narg=+ Iabbr execute "iabbr " <q-args>."<C-R>=lh#map#eat_char('\\s')<CR>"
command! -narg=+ Inoreabbr
\ execute "inoreabbr " <q-args>."<C-R>=lh#map#eat_char('\\s')<CR>"
Thus, I would define your abbreviation this way
:Inoreabbr <silent> <buffer> #n< #include <><left>
:Inoreabbr <silent> <buffer> #n" #include ""<left>
Or even better to not see these abbreviations triggerred in string and comment contexts:
:Inoreab <buffer> <silent> #n< <C-R>=lh#map#no_context("#n< ",'\<esc\>0i#include <>\<left\>')<CR>
" and so on
As you can see from #LucHermitte's answer (and the similar attempt by #Meninx before), eating that character is a bit involved.
Instead, I would recommend you upgrade to a snippets plugin (if you don't use one already). Snippets are like the built-in :abbreviate on steroids, usually with parameter insertions, mirroring, and multiple stops inside them. One of the first, very famous (and still widely used) Vim plugins is snipMate (inspired by the TextMate editor); unfortunately, it's not maintained any more; though there is a fork. A modern alternative (that requires Python though) is UltiSnips. There are more, see this list on the Vim Tips Wiki.
Depending on the snippet plugin, the expansion may need to be explicitly triggered, others may already support insertion without the trailing space. Usually, you can configure a default for the included filename (that can be overwritten easily) - this functionality cannot be had via Vim abbreviations alone.
alternative
If you don't want full snippets functionality just for this, I would recommend to define the abbreviation based on triggering it with <Enter> instead of <Space>. This should fit well for this example (the next code / #include will be on a new line, anyway), and so you don't have to artificially remove anything.

SAS code stops running after submit, nothing in log either

I am writing a SAS program which also uses some macros. However, SAS suddenly stopped running the codes that I submitted. If I select and submit a part of the code, I can see it copied in the log but that's it. No note, error or warning. Neither is the code executed. Doesn't matter if the code is a simple data step without any macro variables.
Am I missing anything? What should I check or verify?
This sounds like a classic case of unbalanced quotes within one of your macros. Running the code below should clear it, then you will need to check the code for the error.
*); */; /*’*/ /*”*/; %mend;
This same problem happened with me during macro coding except it was unmatched parentheses. Original line of problem code was
"...%then %let DLINE=%str(if (P ge 22 and STAFF eq 0 then STAFF=1;);"
Note unmatched "(" character before P variable. Either removing the "("
or adding ")" after "eq 0" solves problem.
I figure out why I also got this issue.
When I collapse all the macro code ( a temporary one just in the same file of my project code), and rerun it.
SAS actually just run the collapsed part, so it is just the first row of the macro.
The code above solves my problem, but I also need to rerun the expanded macro code again to avoid future error.

#define directive with multiple replacements?

I am relatively new to programming, and I am trying to learn to use wxWidgets in C++ (with Visual Studio 2010).
I was looking through the wxWidgets header file "app.h" and I see some #define directives that I can't understand. Here is an example:
#define wxIMPLEMENT_APP(appname) \
wxIMPLEMENT_WX_THEME_SUPPORT \
wxIMPLEMENT_APP_NO_THEMES(appname)"
I'm used to seeing #define with one "identifier" and one "replacement", so I can't understand if this macro has two "identifiers" (wxIMPLEMENT_APP(appname) and wxIMPLEMENT_WX_THEME_SUPPORT) and one "replacement" (wxIMPLEMENT_APP_NO_THEMES (appname)), or one "identifier" (wxIMPLEMENT_APP(appname)) and two "replacements" (wxIMPLEMENT_WX_THEME_SUPPORT and wxIMPLEMENT_APP_NO_THEMES(appname)).
How am I to understand this macro?
I tried looking online and in text books, searching under "macros", "pre-processor directives", "text replacement macros", "#define directive", and similar, but I could not find any examples with explanation that look like the one I have here.
This preprocessor macro has a single replacement split across multiple lines. The \ at the end of the line lets you write a single "logical" line on multiple lines of text.
Everything that follows wxIMPLEMENT_APP(appname) will be placed in the text of the program when wxIMPLEMENT_APP(appname) pattern is matched; presumably, both these definitions will be further processed by the preprocessor, because they look like references to other macro definitions.

Easily comment (C++) code in vim

I have looked at the following question:
How to comment out a block of Python code in Vim
But that does not seem to work for me. How do I comment code easily without resorting to plugins/scripts?
Use ctrl-V to do a block selection and then hit I followed by //[ESC].
Alternatively, use shift-V to do a line-based select and then type :s:^://[Enter]. The latter part could easily go into a mapping. eg:
:vmap // :s:^://<CR>
Then you just shift-V, select the range, and type // (or whatever you bind it to).
You can add this to your .vimrc file
map <C-c> :s/^/\/\//<Enter>
Then when you need to comment a section just select all lines (Shift-V + movement) and then press CtrlC.
To un-comment you can define in a similar way
map <C-u> :s/^\/\///<Enter>
that removes a // at begin of line from the selected range when pressing CtrlU.
You can use the NERD commenter plugin for vim, which has support for a whole bunch of languages (I'm sure C++ is one of them). With this installed, to comment/uncomment any line, use <Leader>ci. To do the same for a block of text, select text by entering the visual mode and use the same command as above.
There are other features in this such as comment n lines by supplying a count before the command, yank before comment with <Leader>cy, comment to end of line with <Leader>c$, and many others, which you can read about in the link. I've found this plugin to be extremely useful and is one of my 'must have' plugins.
There's always #ifdef CHECK_THIS_LATER ... #endif which has the advantage of not causing problems with nested C-style comments (if you use them) and is easy to find and either uncomment or remove completely later.