I am used to the way Sublime Text highlights function declarations vs function calls and am trying to emulate something similar with Vim. There are posts addressing something like this, but they seem to highlight declarations and calls the same way.
int function1() {
function3();
}
int function2()
{
...
}
Here, function1 and function2 should be of one color and function3 should be of another color. I am trying to write regular expressions to match each of these cases and then going from there.
So far, I came up with
syn match cFunDecl "\zs\w\+\ze(.*){"
syn match cFunCall "\zs\w\+\ze(.*);"
These don't really seem to work. Following this approach, I also expect to run into issues with header files where declarations are highlighted as calls but will probably deal with that later.
This is possible with Neovim and nvim-treesitter. I will note, it's probably also possible with LSP plugins such as vim-lsp-cxx-highlight, but I've found those to be a nightmare to work with.
First of all, you want to create a fork of nvim-treesitter. The reason is that, currently, function calls and declarations are highlighted the same in the c module. That's really easy to change, though. In your fork, go to queries/c/highlights.scm. Lower in the file you should see something like this:
(function_declarator
declarator: (identifier) #function)
That #function bit specifies the colour to use. If you replace it with something else, you can get different highlighting. You can find the list of available captures in CONTRIBUTING.md. For example, I just used #number, so I changed the above code to look like this:
(function_declarator
declarator: (identifier) #number)
Then, you can just install nvim-treesitter from your fork as normal. For me, that meant:
Adding this to my ~/.vimrc:
Plug 'vladh/nvim-treesitter', {'do': ':TSUpdate'}
lua <<EOF
require'nvim-treesitter.configs'.setup {
highlight = { enable = true },
}
EOF
:PlugInstall
:TSInstall c cpp
If everything worked correctly, your function declarations should now be highlighted differently! I also really wanted this feature, and fortunately nvim-treesitter now seems to be stable enough to do this easily.
Related
I'm new to Vim and curious how to highlight a function call after the function has been defined. As an example, in the SublimeText version, totalForArray is green when it is defined, as well as when it is called on line 12. This is what my Vim looks like imgur.com/q2WMQ4d, and I'm wondering how to make totalForArray highlighted when it's called.
An improvement on Vitor's regex matching.
This will highlight nested function calls while respecting highlighting for keywords like while, if, for, etc... and also allows for whitespace between function name and parenthesis
e.g. myFunction (int argc) { ... }
syn match dFunction "\zs\(\k\w*\)*\s*\ze("
hi link dFunction Function
Vim's syntax parsing usually only colors the function definition, because that one is easy to locate with a regular expression. For function calls, it would have to maintain a list of detected functions.
There are plugins that extend syntax highlighting with such a list, usually taken from the tags database. For example, the easytags.vim plugin performs automatic tags updates and can highlight those via the :HighlightTags command.
As a simpler alternative to what was proposed by #Ingo, you can also define a syntax to match any keyword that is directly followed by a parentheses:
syn match jsFunction "\<\k\+\ze("
hi link jsFunction Function
Searching in github I was also able to find the vim-javascript plugin, which appears to have various extensions to the default Javascript syntax included in Vim. In particular, it contains the following syntax definition:
syntax match jsFuncCall /\k\+\%(\s*(\)\#=/
This will implement the same syntax highlight I described before, but by using this plugin you might also benefit from other improvements that are included in it.
I switched over to Sublime Text 3 but now that I was coding some Haskell in ST3 I noticed something quite odd, which is the syntax highlighting logic for guards.
As you can see, when I write it this way, it highlights the first guard in white colour and the different sign in a mix of white/magenta:
Only when I use this wrong syntax (with an equal sign after the argument) it displays correctly.
Does anyone know how to fix this?
You're probably using the default Haskell syntax highlighting. I would recommend disabling the Haskell package and installing SublimeHaskell. Its syntax highlighting is much better, and it recognizes things like otherwise as being a "built-in" (it's mainly Prelude functions that are considered built-in).
If you're using the built-in Haskell highlighting, you can check that it's buggy by using the CtrlAltShiftP shortcut. Highlight each guard pipe individually and then hit this shortcut. In the status bar it'll briefly show the syntax scope names associated with the region. For the first pipe, you'll get source.haskell meta.function.type-declaration.haskell, and for the second you'll get source.haskell keyword.operator.haskell. Using SublimeHaskell's syntax you'll get source.haskell keyword.operator.haskell for both pipes. I won't say that SublimeHaskell's is perfect (try indenting an entire file after module Name where), but it's definitely better. Since the syntaxes have the same name and because SublimeHaskell comes with snippets and whatnot that cover everything that the built-in does, I recommend disabling the Haskell plugin and only leaving SublimeHaskell's syntax selectable.
(NOT SURE!!!)
I now believe this is not a bug, instead I believe this is actually ST3's way of telling you you have non-exaustive patterns in that function.
Non-exaustive: http://i.imgur.com/74o4sgp.png
Exaustive: http://i.imgur.com/M9a4TTL.png
I'd like to add a command to my .vimrc that allows to, within a visual selection or the range of the current fold level to
yank all, but only those lines that match a certain pattern.
and as a bonus to
reverse their order
and
perform a small pattern substitution.
Specifically the idea is to reduce the legwork in writing the common C idiom fail-goto-rollback, i.e. (can be found in lot of C projects most prominently the Linux kernel) if the body of a function (or a block) is this
someErrorType errorcode;
if(fail1) {
errorcode = someError1;
goto error_1;
}
prepare_a();
if(fail2) {
errorcode = someError2;
goto error_2;
}
then the result of the desired transformation shall be this.
error_2:
/* <insert cleanup code operation that did not fail1 here> */
error_1:
for the "yanking all", you can do:
normal mode: qaq to clear reg a
do visual selection
press :, vim will auto add '<,'>, then g/pattern/y A<Enter>
all your needed lines are in reg a, you can "ap to paste. for the reversing order requirement, I don't understand. What output do you expect. A concrete before/after example may help.
For adding boilerplate code, the usual solution is via a snippets plugin, which solves this (at least partially) in a generic way, instead of building a (possibly brittle) special solution with Vim built-ins.
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.
There are three things to evaluate: First, the features of the snippet engine itself, second, the quality and breadth of snippets provided by the author or others; third, how easy it is to add new snippets.
I think I understand the difference between function and function!: if a function with the same name already exists function! silently replaces it, but function yields an error.
I end up using function! always. Because if I use simple function sooner or later it returns and bites me with:
E122: Function my_lib#MyHandyFunction already exists, add ! to replace it
Are there any situations when one should use simple function without !?
In scripts, it doesn't hurt to use :function!, but you should use script-local (s:Foo) or autoload-scoped (myscript#Foo) functions to properly namespace them. So, the override error for :function is helpful to alert you to redefinitions of global functions, but in scripts, you shouldn't need this precaution.
You have to use :function! when you want to reload the script during development (instead of restarting the whole Vim). (And plugins like my ReloadScript plugin can deal with the include guards.)
Another empirical point: Most of the plugins I have use :function!, probably for the easy reload.
The same goes for :command! and :normal!, where (usually), the version with ! should be used.
You should normally use function. Doing such, you would at least recognize when there's a name collision.
When using function! by default, you don't have any feedback that you're about to override an existing function (i.e. change existing functionality)!
Just have a look at the error message you've posted:
E122: Function my_lib#MyHandyFunction already exists, add ! to replace it
This means: careful, dude! If you use function! now, the users of my_lib#MyHandyFunction will experience things they never expected!
I'm using Vim's SmartTabs plugin to alingn C code with tabs up to the indentation level, then spaces for alignment after that. It works great for things like
void fn(int a,
________int b) {
--->...
Tabs are --->, spaces are _. But it doesn't seem to work so well for cases like
--->if(some_variable >
--->--->some_other_variable) {
--->...
In the case above, Vim inserts tabs on the second line inside the parentheses. Is there a way I can modify what Vim sees as a continuation line to include cases like this, so I get:
--->if(some_variable >
--->___some_other_variable) {
--->...
If there's an indentation style that would both allow flexible indentation width according to one's preferences, and consistent alignment, your suggested scheme would be it. Unfortunately, this style requires some basic understanding of the underlying syntax (e.g. whether some_other_variable is part of the line-broken conditional (→ Spaces) or a function call within the conditional (→ Tab)), and this makes implementing it difficult.
I'm not aware of any existing Vim plugin. The 'copyindent' and 'preserveindent' options help a bit, but essentially you have to explicitly insert the non-indent with Space yourself (and probably :set list to verify).
I don't know about that other Editor, but the situation is similar for most other inferior code editors. Without good automatic support, this otherwise elegant style will have a hard time gaining acceptance. I would love to see such a plugin for Vim.