Vim syntax highlighting for Fortran OpenMP comments - vim

There was a very useful answer on how to highlight openmp directives in Fortran code (Vim syntax highlighting for multiline fortran openmp directives).
So lines like
!$omp parallel
are no longer highlighted as comments.
It would be great also to make vim not to treat as comments
lines starting with "!$", i.e. in constructs like
! Make it compile both with and without OMP
nThreads = 1
!$ nThreads = omp_get_num_threads()
I want to have !$ highlighted as fortrandirective,
and the rest of the last line highlighted normally.

You could use syn match for this:
:syn match fortranDirective "\v!\$\s"
This matches !$ with a trailing whitespace (to distinguish it from !$omp).

Related

custom 'smartindent' script for vim

I am currently thrown into a new project where the indentation style is a bit special. The basic rule is to use 'keyword+blank' spaces to indent the next line.
For example:
if () {
// indent 3 spaces here
}
while () {
// indent 6 spaces here
}
There are some (or a lot) of exeptions:
else if: use same number of spaces as if (3)
case in switch/case (2 spaces)
...
1) Is there already a plugin available that can do it for me? According to one of the developers this is called 'smart identation'. Unfortunately VIM's smartindent does something different.
2) If the answer to 1 is no. Is there an easy way to configure vim to respect these rules?
I'm not aware of any such plugin, and IMHO this scheme is anything but smart.
However, it is entirely possible to write a custom indent plugin that implements the exact requirements that you have. See :help 'indentexpr'; also, Vim ships with several indent plugins in $VIMRUNTIME/indent/*.vim that can serve as inspiration.
Basically, the algorithm would be like this:
Check the previous line for one of the keywords (if, while, and so on).
If there's a match, calculate the offset and add that to the previous line's indent (indent(v:lnum - 1)); else, use the previous line's indent as is.
If the line contains a }, find the line with the matching {, and use the indent from that line.

Latex precompiling with Vim

I am looking for a way to pre-compile a text, i.e. reformat it following some custom rules, and then compile it with Tex in Vim.
For example I would like to reformat a text like this
THM The sum $1+2+3 is equal to $$[six] 6.
% a comment line
PROOF $$ 1+2 &= 3 \\ 1+2+3 &= 6
into this
\begin{theorem}
The sum $ 1+2+3 $ is equal to
\begin{align}
\label{six}
6.
\end{align}
\end{theorem}
\begin{proof}
\begin{align*}
1+2 &= 3\\
1+2+3 &= 6
\end{align*}
\end{proof}
and then run MikTex on the latter.
Is this obtainable all inside Vim?
preprocessor
If you want to keep your custom syntax in the source file, and just generate the Latex syntax as an intermediate step to compilation with the Latex compiler, you have to insert a preprocessing step, e.g. using the C preprocessor, cpp. Sketch:
:setlocal makeprg=cpp\ -D\ THM='\\begin{theorem}'\ -\ \|\ miktex\ ...
(In reality, you probably would externalize the (many!) macro definitions in an include file instead of passing them on the command-line.)
snippets
If, on the other hand you just want to avoid typing all those long Latex definitions, but keep the Latex document as the source, you can use snippets to speed up the document creation and editing. 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.

How to remove blocks of code that starts/ end with some specific pattern in vim?

I wonder whether there is some way within vim to remove all block of code whose first/last line match a specific pattern. For instance, I have a c++ code with a lot of #if #endif blocks I want to get rid of:
#if GGSDEBUG ---|
somecode Block to delete
#endif ---|
//code
#if GGSDEBUG ---|
somecode Block to delete
#endif ---|
//code
#if GGSDEBUG ---|
somecode Block to delete
#endif ---|
Thanks,
Use the :global command to locate all start lines of your blocks, and execute a command there.
:g/^#if GGSDEBUG/ [...]
As the cursor is placed on that first line of the block, you can :delete the block by specifying a range that ends with a pattern describing your end of the block:
:.,/^#endif/delete
Put together:
:g/^#if GGSDEBUG/.,/^#endif/delete
You can adapt the patterns (e.g. by appending \n\zs$ to endif to also remove the following empty line).
For C code, you can use the built-in matching behavior:
:g/^#if\>/normal!V%d
This handles nesting properly. (At least, it should, and in my little test it does.) For other languages, use matchit and drop the !:
:runtime macros/matchit.vim
:e foo.html
:g/^<table>/normal Vh%d
:help :normal
:help %
:help matchit-install
:helptags $VIMRUNTIME/macros
:help matchit-%
From within one of those blocks, you can use this variant of Ingo's answer:
:?^#if GGSDEBUG?,/^#endif/d
:?pattern before the cursor?,/pattern after the cursor/delete
Use this: It will automatically remove all occurrences in the file.
It makes use of a non-greedy search \{-} (in place of *) and uses \(.\|\n\) (in place of a simple ".") in the pattern to extend of multiple lines:
:%s/^#if GGSDEBUG\(.\|\n\)\{-}#endif//g
Note: If you have nested blocks that end with #endif, it will only delete until the first one. But this will be a limitation of all solutions here, I guess.

Vim syntax highlighting for multiline fortran openmp directives

I'm using modern fortran for doing parallel programming. I'm using vim and it's been really annoying me that the fortran.vim syntax files don't seem to handle compiler directives like !$omp or !dir$. These just get rendered as comments in vim so they don't stand out. In c/c++ these compiler directives are done using #pragma's so everything stands out like it were preprocessor code rather than comment code. So I want similar treatment in my fortran syntax.
Here's an example of a multiline directive that I want to colour:
!$omp parallel do reduction(+: sum0) reduction(+: sum1) &
private( nn, S1, S2, Y1, Y2, rvec0, rvec1, iThreadNum)
What I have so far is a new fortran.vim file located in $HOME/.vim/after/syntax.
I've got it to recognise the '!$omp' at the start of a line and to colour that line and also to colour the multilines properly. My syntax file contains this:
syn region fortranDirective start=/!$omp.*/ end=/[^\&]$/
hi def link fortranDirective PreProc
My problem is that it now can't handle the simple case of just a single line. I.e:
!$omp parallel do blah blah
call foobar <-- this is coloured the same as the line above
I need some kind of regex rule in my syntax file to be able to correctly match both single line and continued line. Can anybody help please?
As far as I can tell, the problem is that your start regex is too greedy.
This should work:
syn region fortranDirective start=/!$omp.\{-}/ end=/[^\&]$/

Convert Notepad++ syntax highlighting file to vim (or does anyone have a q/kdb+ vim syntax highlight file?)

I have a syntax highlighting file for the q/kdb+ language and I'd like to convert it to a vim compatible file so my q code won't look any more ugly than usual.
Are there utilities available to automatically convert notepad++ xml syntax highlighting files to vi versions? I had a look around but I couldn't find anything.
Alternatively does anyone have a vim q syntax highlighting file?
a q/kdb+ vim syntax highlight files:
https://github.com/simongarland/vim
The answer to both questions is no (I don't know of any converters and I don't have a q syntax highlighting file), but the Notepad++ syntax highlighting XML format looks extremely simple. I don't have the 'Q' one to hand, but I had a look at one of the ones from the website and the translation looks pretty trivial. In that case, you could do most of the work with:
" Remove all the lines that aren't lists of keywords
" (there doesn't seem to be anything much more complicated
" than that in the definition file)
:g!/<Keywords name=/d
" Convert the lines (fairly poor XML parsing here!)
:%s/\s*<Keywords name="\([^"]\+\)">\([[:alpha:]_ ]\{-}\)<\/Keywords>/syn keyword \1 \2/
This generates lots of lines that look like:
syn keyword Words1 case then do while
You'll have to tweak the syntax class (Words1 in this case) to be something that will be highlighted in Vim (or syn-link it to something that will be highlighted in Vim).
You could probably then deal with the symbols with a regexp, but it might be easier to just do them by hand, so convert:
<Keywords name="Operators">- ! " # $ & * , . ; ? # \ ^ { | } ~ + < = ></Keywords>
into:
syn match Operators /\<[-!"#$&*,.;?#\\^{|}~+<=>]/
(this is \< to mark a word boundary, followed by a character class [..] with all the symbols in it).
You would then just need to add:
if exists("b:current_syntax")
finish
endif
at the start and:
let b:current_syntax = "q"
at the end.
Of course, this doesn't get you all the way, but hopefully it will give you a lot of what you need to get the syntax file that you want. There is plenty of help available in:
:help syntax
and by looking at the examples in the syntax directory of the runtime folder.
Good luck!

Resources