Recognise #define compiler directive in fortran with ctags - vim

I would like to configure ctags to recognize compiler directives in a fortran code. More specifically, I would like to match the following vim search result
/\v[ \t]*#define[ \t]+([-[:alnum:]*+!_:\/.?]+)/
where \v induces the very magic level (see Can I turn on extended regular expressions support in Vim?). Alternatively, the search using a normal regular expression
/[ \t]*#define[ \t][ \t]*\([-[:alnum:]*+!_:\/.?][-[:alnum:]*+!_:\/.?]*\)/
could be used. If general compiler directives are found, that would help me too. A practical application would be that when pressing <C+]>, when having my cursor at _ABORT in the following piece of code
_ABORT("delta_time is too small")
I would be redirected to the corresponding definition
#define _ABORT(msg) call abimem_abort(msg, __FILE__, __LINE__)
Based on https://andrew.stwrt.ca/posts/vim-ctags/, I tried to add either
--regex-fortran=/[ \t]*#define[ \t]+([-[:alnum:]*+!_:\/.?]+)/\1/d,directives/
or
--regex-fortran=/[ \t]*#define[ \t][ \t]*\([-[:alnum:]*+!_:\/.?][-[:alnum:]*+!_:\/.?]*\)/\1/d,directives/
to ~/.ctags. Based on http://ctags.sourceforge.net/ctags.html, I also tried to add --line-directives=yes, but in neither case I could succeed in the practical application I gave as an example above. I can already see the additional kind when using
ctags --list-kinds
but that's all. What went wrong?

It seems that it works now. My current ~/.ctags is
--fortran-kinds=+i
--recurse=yes
--exclude=.git
--regex-fortran=/[ \t]*#define[ \t]+([-[:alnum:]*+!_:\/.?]+)/\1/d,directives/
Probably this has to do with the fact that I previously had put a '\v' in the ~/.ctags (and did not copied this properly to the question). Could someone explain why this '\v' must not be present there, though vim is configured to need it for extended regex's?
Another thing that happened between previous try and now is a reboot (clean-up of temporary space etc.), which might help if still stuck.
Moreover, one should remark that the extra regex is not always necessary. Following macro definition was found without the regex:
# define MSG_ERROR(msg) call libpaw_msg_hndl(msg,"ERROR" ,"PERS")

Related

Can we escape types, codes, etc. in comments section so that spell check does not consider them as typo

Vim supports spell-check only in comments section already, however, if I have a type name or something not a regular word, it will consider it as a typo. For instance, in the following example, std::endl will be highlighted as typo.
// Don't use std::endl, it will flush unnecessarily
I wish we could use `` to escape them like following.
// Don't use `std::endl`, it will flush unnecessarily
Is there any tips or solution for this besides adding everything into dictionary?
I really don't want to disable spell-check due to this, so any help is greatly appreciated.
Thank you!
You can use this syntax rule to create a new group matching a `...` block and disable spelling inside those blocks:
syntax region cCommentNoSpell start=+`+ end=+`+
\ contained containedin=cComment,cCommentL transparent
\ contains=#NoSpell
To load this for cpp and c files, add this line (by itself) to a file ~/.vim/after/syntax/c.vim, so it is loaded after the system syntax files for C++ and C. (The cpp syntax rule includes all syntax for c so you'll get it on cpp too.)
The syntax rule uses ` as both start and ending delimiter.
It uses contained and containedin to only match inside comments. The cComment rule matches traditional multi-line /* ... */ comments and cCommentL matches single-line // ... comments. (Both are defined in the syntax file for C and C++ shipped with Vim.)
The transparent attribute instructs it not to use this syntax rule as a highlighting group, so it keeps the normal highlighting for comments in the parts matched by this rule.
Finally, contains=#NoSpell is what disables spelling on the regions that match this rule. See :help spell-syntax for more details on how spelling works together with syntax highlighting.

Substitute in vim, with special characters

I am trying to use substitute command in vim to enclose all occurences of a particular pattern
\cite{author1}
\cite{author2}
with
(\cite{author1})
(\cite{author2})
Based on other answers in stack exchangeI used the following vim command
%s/\\cite{(\w\+)}/(\\cite{\1})/g
But, no luck. It says "no matches found". I put two back slashes, one of which is supposed to be the escape character. Kindly help.
I know I could use some other editor and finish the job, but I want to know my mistake. Thank you.
please escape ()
%s/\\cite{\(\w\+\)}/(\\cite{\1})/g
You do not need a capture group to get the entire match. You can use \0 or & for the whole match in the replacement portion of your substitution.
:%s/\\cite{\w\+}/(&)/g
If you do want to use a capture group, then you need to escape the capture group/parenthesis.
:%s/\(foo\)/(\1)/g
For more help see:
:h :s%
:h /magic
As mentioned, normally you need escape the parentheses.
You can use very magic mode (\v) to make the regex simpler; removing the need to escape lots of the regex parts, including the parentheses for capturing:
%s/\v(\\cite\{\w+\})/(\1)/g
Knowing what every sign in a regular expression does in vim is sometimes very
difficult, especially for all the modes and configuration variables that this
depends on. For that reason, it is very important to have visual feedback about
what text are we really matching in any moment while crafting regular
expressions.
If you work with neovim, there is a special option called inccommand that you
can enable to live preview the matches and substitution. That way you can figure
out you errors more quickly. This feature is very likely to be included also in
vim in the future, but independently of that, you can also use simple vim to
give you visual feedback if you enable the option incsearch.
With incsearch set, you can watch the matches of / and ? while you write them
just to be sure that the pattern is correct. Later you can exploit a nice
feature from the substitution: if you leave the first section empty, the last
search will be used.
So you could first make the search:
/\\cite{\w\+}/(&)/g
In the meantime, vim will be showing you the matched text visually. Once you
are sure that the pattern is correct press enter, and finally type:
:%s//(\1)<Enter>
Also, in case you want something more powerful than this simple hack, you can go
for my plugin Extend.vim, that can
do that and much more with great visual feedback.

syntax highlighting for Assembler

I need to add support for assembler language I'm working with (it is not x86, 68K, or 8051 which are well supported by vim). I looked at the existing syntax files, and here are my questions
1) When does it really make sense to use syn keyword and syn match? My understanding is that the latter supports regex and gives more flexibility. On the other way, looking at /usr/share/vim/vim70/syntax/asmh8300.vim - they define opcodes in both keyword and match, what benefit does it really give?
2) Instructions in my Asm have a common format:
INSTR OP1, OP2 ..; i.e. space delimits the instruction name from operands.
I think for this I'm ok with only defining all Asm commands in 'keyword' since space symbol is by default in 'iskeyword'. Am I right ?
3) The Asm also supports C-style structures, enums and comments. Can I just borrow its syntax definition from c.vim or it won't work and requires some tweaking?
If you have a limited set of identifiers, and if they all consist solely of keyword characters, then :syn keyword is the best choice. You're right in that :syn match provides a superset of functionality. Essentially,
:syn keyword myGroup foobar
is equivalent to
:syn match myGroup "\<foobar\>"
Beware of old versions
The syntax/asmh8300.vim syntax you've referenced is from 2002, it may not be the best example of how to write a syntax file. (For example, it omits the \<...\> around its matches, what looks like a bug to me. And it still has compatibility stuff for Vim 5 / 6 that's not needed any more.)
Also, do you actually use Vim 7.0?! Vim 7.0 is from 2007 and very outdated. It should be possible to install the latest version 7.3; if you can't find a proper package for your distribution (for Windows, check the binaries from the Cream project, it's also not very difficult to compile (e.g. from the Mercurial sources) on Linux.
Borrow other syntax elements
If other syntaxes are embedded in your syntax, and clearly delimited (e.g. like JavaScript inside HTML), you can :syn include it. But if there are just similar constructs, it's best to copy-and-paste them into your syntax (and adapt at least the group names). You need to be careful to catch all contained syntax groups, too; together with syntax clusters, the hierarchy can be quite complex!
More tips
When writing a syntax, you often need to find out which syntax group causes the highlighting. :syn list shows all active groups, but it's easier when you install the SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor plugin.

Lookup a specific kind of tag in Vim

So here's my problem. I've gotten exuberant ctags working with Vim, and it works great, most of the time. One thing that still irks me though is whenever I try to search for a function that is named the same as some variable name. I sometimes get the right tag on the first try, sometimes not. Then after I pull up the list of alternate tags with :tselect, it comes up with a list of tags for both function definitions or variable definitions/assignments. (I'm in PHP so definitions and assignments are syntactically indistinguishable).
However, I notice that there's a column labeled 'kind' that has a value of 'f' or 'v', for function and variable, respectively. I can't seem to find a whole lot of information about this field, it seems like it may not be exactly standardized or widely used. My question is: can you filter tag results in Vim by "kind"?
Ideally, the default would be to search the whole tags file, but by specifying some extra flag, you could search a specific ('f' or 'v') kind only.
This is such a small problem for me as it doesn't come up THAT often, but sometimes it's the small problems that really annoy you.
You can certainly generate ctag files with any combination of php-kinds that you want (see the ouput of the command ctags --list-kinds.)
If you feel it's worth the effort you can make a vim function tagkind and bind it to a command. The tagkind function can overwrite the current tags vim variable to point at only the tag file with the kinds that you are interested in and call :tag. Optionally, it can store the previous version of the tags variable and restore it after this one call.
Unfortunately, I don't know of anyway other than this. Perhaps someone else would know.
I generate python ctags with --python-kinds=-i to exclude tags for import statements (which are useless). Maybe you could generate with --php-kinds=-v and drop a class of tags completely.
You can read :help tag-priority. Apparently the "highest-priority" tag is chosen based on some hard-coded logic.
fzf with fzf.vim has a :Tags (for the whole project) and :BTags for the current file option that generates ctags on the fly.
An issue raised on the plugin 'Skip tag kinds in :BTags and :Tags' gives the following code that you can use to only generated tags for a particular kind. I've modified the below so that it should only search for the PHP f kind.
command! BTagsEnhanced
\ call fzf#vim#buffer_tags(<q-args>, [
\ printf('ctags -f - --sort=no --php-kinds=f --excmd=number --language-force=%s %s', &filetype, expand('%:S'))], {})
Note as per my comment on the question, there is a potential Vim tagfinder.vim plugin via a blog post on Vim and Ctags: Finding Tag Definitions. But I haven't tried it.

Preventing :make in VIM from going to a warning

I have a warning I can not easily remove from my build, every time i run ":make" from inside vim the quickfix takes me to some header file I don't care about. How can I prevent VIM from doing this and only showing me warnings and errors I do care about?
As Luc Hermite said, it is possible to ignore warnings using 'errorformat'option.
Adjusting this option is a little bit complicated; it may be helpful to check $VIMRUNTIME/compiler for some examples.
When working with avr-gcc and C++ some annoying warnings like this
tests.cpp:492: warning: only initialized variables can be placed into program memory area
shows up, and it is likely to be result of a compiler fault.
To avoid that this warnings being displayed on quickfix window I've add this to ~/.vimrc:
compiler gcc
set errorformat^=%-G%f:%l:\ %tarning:\ only\ initialized\ varia
\bles\ can\ be\ placed\ into\ program\ memory\ area
The %-G can be used to specify patterns to be ignored.
The ^= in set errorformat^=... is used to prepend the ignored warning pattern to 'errorformat' -- using += (set errorformat+=...) would append to the option and wouldn't work, as 'errorformat' is a list of formats and the first one that matches is used, thus the "normal" warning pattern would apply instead.
Maybe you could adapt these settings for your environment.
Check :h 'errorformat' (aka &efm), there are options to ignore warnings as long as you can recognize them with a pattern.
A quick and dirty way would be to write a simple shell script that runs your make and greps out the warnings you don't want to see. Then have vim use this script instead of make (Add "set makeprg=yourscript.sh" to your .vimrc).
To build on what mMontu suggested, adding this to my .vimrc did the trick for me (ignore all warnings from my gcc compiler)
set errorformat^=%-G%f:%l:\ warning:%m
Learn from Bram himself.
I can vaguely remember he talks about this somewhere in this video.
He adds a filter to ignore some gnome warnings when he's compiling gvim.
The video's well worth watching anyway.
It's around the 30 minute mark.

Resources