I am currently writing an antrl4 grammar with multiple lexical modes. And it is easy to push modes that have an explicit name and then return to the default mode by popping the current mode.
OPEN_PARENTHESIS : '(' -> pushMode(IN_PARENTHESES);
mode IN_PARENTHESES;
CLOSE_PARENTHESIS : ')' -> popMode;
But now I am in a situation where there are several modes on the stack, and I still want to return to the default mode without popping everything that is on the stack. So my question is, is it possible to return to the default mode by doing something along the lines of pushMode(DEFAULT)?
I think what you're looking for is -> mode(DEFAULT_MODE)
See: https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md#mode-pushmode-popmode-and-more
Related
I'm using indentation style of C++ like LLVM, and clang-format. I need options to be like that:
set cinoptions=:0,g0,(0,Ws,l
set autoindent
set smartindent
set cinkeys=0{,0},0),:,0#,!^F,o,O,e
set cinwords=if,else,while,do,for
Problem with that, that whenever i refer to namespace and press namespace: - it triggers :0 option. When pressed second : - it triggers back. Yes, all is correct. But triggering always for : - very bad for my brain. I wanna static behavior. Not whenever i'm trying to use some namespace and press double :. I need triggering :0 only for the case in switch statement. I hope you can understand what i'm talking about. Please help.
switch(number) {
case 4: // i wanna triggering of:0 only for this line of code.
cout << "Good indentation";
break;
}
if (true) {
namespace: // NOT FOR THAT!
namespace:: // triggers back - all is correct. First triggering is very bad!
}
You're looking for L0; see :h cino-L. It's -1 by default, which means jumping to col 1. It's worth noting the wording in the documentation as well: "If N is non-negative, the indent of the label will be the prevailing indent minus N." -- that's why N = 0 works. It preserves the current indentation level by not subtracting anything from it, and through that, avoiding the jumping.
It only affects labels and not the switch statements' case x:. Note that this means if you want labels to be indented differently, but don't want jumping for the :: operator, you'll probably need to find an LSP with that type of indent support, because cino doesn't support that. You'll either have to live with it jumping on the first : and back on ::, or not having label indentation automatically differ from your normal source code indentation, and having = reset any manual changes you do to label indentation.
Anyway, it also means :0 was never actually triggered. cino's default options meant L-1 was triggered on namespace: - switch case labels aren't the same as normal labels, which meant another option was to blame.
And finally, for the sake of completeness:
set cinoptions=:0,g0,(0,Ws,l,L0
My autocomplete for vim inserts something like this for C++ code:
if( ){
}
Inside the () is where my cursor is going to be. Suppose I want to type
if(X[i] == 0){
}
I would type X, then [ and the closing brace will automatically be inserted, ].
I then type i, now my cursor is between i and closing ]. How do I get out so that I can keep typing the rest, the == 0 part?
If there is no autocomplete for the if statement, then it would be easy because I do not have to worry about the ( ). I can just type, if, (, X[i]. To get out of the bracket, I would just use append, A and then go on to type the rest: == 0 ).
Normally, I would use the arrow key or hl to move out of the brackets. Is there another way to do this?
There are several parts to your problem, and plugins that solve them -- of course you could reimplement them...
Regarding the auto-pairing, most (all?) bracketing plugins provide a jump over the closing bracket character by hitting the related key. Here for instance you could simply type ] instead of <right> or <esc>la as you would have done without the auto-pairing feature.
Note: contrary to most solutions you could copy paste from a 1990's vi trick, the plugins will permit to redo (:h .) an insertion where brackets appear.
I'm quite sure the exact technical solution has already been given here and/or on vi.SE.
There is another issue you haven't mentioned: jumping to in-between the curly brackets corresponding to the true branch of the if. To achieve this, we rely on placeholders. They could be inserted by snippet plugins, or through very advanced abbreviations.
The trendy snippet plugins have discrete placeholders. The plugins I'm maintaining have more intrusive placeholders (lh-cpp, mu-template. Placeholders that my bracketing plugin also inserts by default. What does this means? It means that typing if or [ will insert the same placeholders that also serve as jump points. As a consequence, I can use the same jump keybinding (CTRL+J by default in terminal vim) to jump after the closing ] or in between the {} -- hitting ] works as well when the cursor is just before a ], etc.
I am trying to use to remap the emmet-vim functions, but I have some problems :
using :
map <c-e>e <plug>(EmmetExpandAbbr)
nmap <c-e>e <plug>(EmmetExpandAbbr)
or
map! <c-e>e <plug>(EmmetExpandAbbr)
nothing appens in any mode,
and using :
imap <c-e>e <plug>(EmmetExpandAbbr)
then comes a weird problem :
first, doing the sequence e in editmode,
div_
( '_' = cursor position)
becomes :
div<Plug>(EmmetExpandAbbr)_
And moreover, strange thing, the original map <c-y>, give the same result...
I heard that the map using is a better way to permit the user to custom the shortcuts rather than using global variables... So how to do this with the emmet plug-in (I already succeed to custom shortcuts with other plugins)?
Thank you !
I am learning ANTLR4 and was trying to play with lexical modes. How can I have the same token appear in multiple lexical modes? As a very simple example, let's say my grammar has two modes, and I want to match white space and end-of-lines in both of them how can I do it without ending with WS_MODE1 and WS_MODE2 for example. Is there a way to reuse the same definition in both cases? I am hoping to get WS tokens in the output stream for all white space irrespective of the mode. The same applies to EOL and other keywords that can appear in both modes.
The rules have to have different names, but you can use the -> type(...) lexer command to give them the same type.
WS : [ \t]+;
mode Mode1;
Mode1_WS : WS -> type(WS);
mode Mode2;
Mode2_WS : WS -> type(WS);
Even though Mode1_WS and Mode2_WS are not fragment rules, the code generator will see the type command and know that you reassigned their types, so it will not define tokens for them.
I've noticed on occasion that that using * to search for the word under the cursor occasionally will have slightly different behavior (usually when I'm switching between various computers). The issue is when I perform a search for a word that has a * in front of it (like a c++ pointer). For example:
MyPointer *foo;
...
foo = new MyPointer();
When I move the cursor over the first occurrence of "foo", it usually does a search for that exact word (e.g. /\<foo\>), but sometimes it will include the * character in its search (e.g. /\<*foo\>) which causes it to fail to find any other occurrences of that variable since it's including the * character.
Does anyone know what causes this behavior and/or how to control it?
The behavior is affected by the isk(iskeyword) option.
It may different when you switch to a different buffer.
You can type :help 'isk' to read more.