Using an external syntax highlighter in vim - vim

I have access to a syntax highlighting program for an internal-only language. Is there any way in which I could get vim to call this program to perform syntax highlighting? I figure that it's worth seeing if this is possible before I write my own syntax file, since it's quite complex (not to mention prone to change). The program in question could be quite easily customized to output in a new intermediate format (it's only currently outputting HTML), if that would make things easier.

I would suggest to write a quick throwaway script in the language of
your choice to convert the output of the program in question to the Vim
highlighting syntax. You mentioned the program is prone to change, but
its output format can be easily customized: using your own conversion
script (which parses the programs output format) you could easily stay
up-to-date with the latest changes (just run your script again). And as
others have mentioned: creating a new syntax file is really easy in Vim,
so it's up to the complexity of the programs output how hard this actually is.

Yes, you can use vim job/channels to communicate with external process and highlight text using textprops.
Type :help channel and :help textprop in vim to get more info.
This method is used to implement treesitter highlighting in vim-treesitter plugin

Related

Give vimdiff some hints

I've got two c++ files that I want to diff with vimdiff. One of them has a lot more function definitions at the start, before both have a common function that I'm actually interested in. However, vimdiff seems incapable to ignore all the function defs before the common one (perhaps because of different arguments).
Is there any way I can give a hint to vimdiff that, say, line xxx in file1.cxx is equals to line yyy in file2.cxx?
I'm open for alternative solutions without vimdiff, but they must be on linux and very preferably command line, since I'm ssh-ing and any graphical interface is a bit uncomfortable.
Vim just delegates the actual work of comparing the files to the external diff utility, cp. :help diff-diffexpr. The help page also shows how a different utility can be used. Unfortunately, I'm not aware of any more "intelligent" or configurable diff tool that would help in your situation.
A workaround might be (temporarily) removing the excess functions that you're not interested in, anyway. With the BlockDiff plugin, you don't actually need to modify the files. Just select the interesting lines in both windows and execute :[range]BlockDiff on them. Only those sections will then be diffed in a separate tab page. (The plugin mentions this requires a GUI, but Vim in a terminal supports tab pages just as well.)

vim syntax performance with very long lines

I'm using vim to edit markdown files that contain some very long lines (100000
characters). Vim is very slow with this kind of input. If I turn off syntax
highlighting (:syntax off), Vim is not slow anymore.
The reason for the length is that some of the code blocks contain json that
contain images encoded in base64. (Actually, I'm trying to edit a markdown
version of an ipython notebook).
Here is what the offending text looks like:
```{.json .output n=41}
[
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAtAAAAFxCAYAAAB....long...long....line...."
}
]
```
What I'd like is for Vim to not be slow.
Possible solutions that I've thought of:
set synmaxcol=250 - no, breaks syntax highlighting after a long line
Disable syntax highlighting selectively for long lines (not sure how to do
this)
Disable syntax highlighting for code blocks that begin with {.json (don't
know how)
I'm using the vim-pandoc
syntax highlighter. This gives code blocks the syntax group
pandocDelimitedCodeBlock or e.g. pandocDelimitedCodeBlock_json if you turn
on language detection.
This also means that I'm folding on syntax groups (foldmethod=syntax) which
is a possible source of slowness (see stackoverflow, github and superuser).
However, :set foldmethod=manual does not solve the problem.
vim-pandoc makes extensive use of syntax folding and I'm pretty sure that is the issue. Disabling vim-pandoc-syntax and turning off folding (let g:pandoc#modules#disables = ['folding']) makes vim fast again.
For syntax highlightin I've used my fork of tpope's vim-markdown. I've forked it because the original does not syntax highlight code blocks with pandoc style attributes (pull request here).
For folding on headers and fenced code blocks using a foldexpr I've used my fork of vim-markdown-folding. Forked because the original does not fold on code blocks (pull request here).
Whilst this doesn't really answer my question (which I agree isn't well defined), it does fix my problem.

Vim - guess programming language based on input?

Does anyone know of a way to get vim to guess the programming language of a new file based on your input and use the appropriate syntax highlighting? So far the syntax highlighting only works when it knows the file extension (after I have saved it), which is good, but sometimes I am lazy and want to make a new file without saving it until later.
e.g. if I were to start a new file and type:
#include <stdlib.h>
I would like it to automatically start using C syntax highlighting, say after I hit enter, and the same goes for other languages like Python.
I am a bit of a noob with vim and don't know vimscript, so don't make it too complicated please. Any help is appreciated.
Thanks, Simon
Vim uses both file path / name / extension and certain characteristic file contents to detect the filetype; what is used depends on the particular type.
You can re-trigger the detection via
:filetype detect
For C / C++, the detection is based on file extensions. To add a contents-based detection, you'd have to write this yourself; see :help new-filetype-scripts for details. In practice, I'd recommend to just manually :setf c when the need arises.
This could be arranged, but performance could be a slight problem (depending on how clever you want to be) and it is much easier to just set the syntax manually:
:setf c
You could also set the buffer filename; this will set the syntax accordingly, normally:
:file x.c
(This does not save the file.)
If you really do want automatic guessing, you'd be using an autocmd to trigger it, and could then guess the filetype if &ft is empty (i.e. if it hasn't already done so).

Use Vim to "colourize" files or input streams

This may be an odd question, but still. I use cat to display a file in bash (KDE Konsole),
cat foobar.rb
Now, I would like to use Vim to colourize that foobar.rb file according to what you would get when you start foobar.rb in Vim. Edit: But only for display purpose, on the terminal.
I am not sure this is possible, but I thought it would be neat if I could use Vim for that.
I really just want colourized keywords, and Vim has the perfect colour definitions.
So I thought combining this would be great.
Is this possible in Vim out of the box though?
One approach would be to use a library such as Pygments, which is a general purpose syntax highlighter. You could write a wrapper called ccat or something that would apply syntax highlighting to an input file and write to stdout.
If you want to page up and down in a highlighted file, you can use less with the -R switch, which passes control characters through to the terminal directly, preserving colours. So:
ccat file.rb | less -R
But at that point, you're pretty much at the capabilities of view.
I'm not sure if I understand your question correctly, but if you are only looking for a command that will give you a read-only view of the input file (like cat) but with coloured keywords, use view. view is an alternative way to start vim in read-only mode, so you have all syntax highlighting possibilities. From the vim man page:
view Start in read-only mode. You will be protected from writing
the files. Can also be done with the "-R" argument.
gvim gview
The GUI version. Starts a new window. Can also be done with
the "-g" argument.
evim eview
The GUI version in easy mode. Starts a new window. Can also
be done with the "-y" argument.
rvim rview rgvim rgview
Like the above, but with restrictions. It will not be possi-
ble to start shell commands, or suspend Vim. Can also be
done with the "-Z" argument.
I have always seen view on systems that have vim installed.
Closest is the less script that comes with vim:
cat myfile | vim -u /usr/share/vim/vim72/macros/less.vim -
Note the - argument to vim. You may need to change the vim72 to your version (and the whole path if you have it installed elsewhere)
Now, this isn't exactly what you want, because its behaviour is less-like, in that you have to press keys to make it scroll down or complete. However, they are briefer than usual vim. For example, space to scroll down; and q to quit (not :q).
You want a cat-like version; me too. But there doesn't seem to be one.
EDIT uh, there's also a vimpager project, that includes vimcat - exactly what you want. But it doesn't come with vim, and I haven't tried it yet.
vim.org: http://www.vim.org/scripts/script.php?script_id=1723
github: https://github.com/rkitover/vimpager

Is it possible to format C++ code with VIM?

I am rather new to VIM. I got some source code and this is a mess. At a first sight I would like at least to get a clear and organised view of the code, so I like to get it rightly formatted, I mean indented depending on the depth of the functions and so.
I wonder if it can be done with VIM, and otherwise which other commandline tools for that can you recommend.
Thanks
While vim is a true Swiss-knife I still prefer external tools for some jobs. This approach is some times much more intuitive and easy to remember than using the built-in equivalent.
In the case of indenting, I filter the whole file buffer through astyle. The astyle parameters are much easier to grasp in a couple of minutes, especially if you are not a vim guru. Also astyle provides much more flexibility in fine-tuning the output.
First install astyle:# apt-get install astyle
Then inside vim:
:%!astyle (simple case - astyle default mode is C/C++)
or
:%!astyle --mode=c --style=ansi -s2 (ansi C++ style, use two spaces per indent level)
or
:1,40!astyle --mode=c --style=ansi (ansi C++ style, filter only lines 1-40)
you can do the following:
gg=G
I would highly recommend clang-format nowadays. It allows simple integration of clang-format into Vim, once you have clang-format installed:
http://clang.llvm.org/docs/ClangFormat.html#vim-integration
It is the only code beautifier that really understands your C++ code, and it is really intelligent to beautify the code more like a human being than a machine. E.g.:
void TestFunction(int argument1, int argument2,
int argument3);
void TestFunctionVeryLongName(int argument1,
int argument2,
int argument3);
void TestFunctionWithRidiculouslyLongName(
int argument1, int argument2, int argument3);
Vim will definitely do this, although the results may not be perfect:
First, select the entire file in visual mode: ggVG
Then hit = to reindent everything.
You can learn more about the equal command with: :help =
There is also a Vim plugin relying on clang-format: vim-clang-format
Then you can simply map the formatting command to whatever suits you.
There is a vim plugin that enables formatting on your code from within vim. It's called vim-autoformat and you can download it here:
https://github.com/vim-autoformat/vim-autoformat
It integrates external code-formatting programs into vim. For example, if you want to format C, C++, C# or Java code, you need to install the program astyle, and vim sets it as the format program automatically.
I don't write C++ code, but I write some Java code.
Instead, Vim supports the formatting of some common languages.
I have set up a short cut for me to format the whole code in the buffer.
It will return to the line I just edited :)
" format the file
map <leader>fm gg=G'.
A generic solution along the lines of m000's idea is to use UniversalIndentGUI as an external tool.
Just had to solve this exact problem, so I thought I'd contribute to save others some time.
You can use gg=G to indent your code. But things get hard to understand the moment you want to tweak how that auto-indenting happens. Therefore, if you only care that errant whitespace is removed and don't really care about formatting style, gg=G is the quickest way to go about it, because its built-in.
If you do want to control the style (for example, you're trying to make your code conform to a style guide), then you're going to need an external tool to process your file. You can invoke that tool from within vim with: :%!<toolname> <options>. This pipes the file through the tool and re-loads the processed result. (You can obviously use this for anything else you want to do to your file too)
So the next question is, what external tool should you choose? Regardless, the method is the same:
Install the tool of choice
Make sure its in your path
Add a line to your vimrc file that creates a shortcut key to use so you save time
Use it.
Now, which tool you use depends on the style you're trying to replicate. If you're trying to replicate a widely used style, then chances are astyle is all you need.
If you're trying to replicate a custom style, then you will need two things:
UniversalIndentGui - a front end that lets you play around with various options and live-preview their effect on the source file
A set of source code formatting tools installed and in your path
Between uncrustify and greatcode, you should be able to completely replicate the style you want.
Actually, I lied. There is another way and its called clang-format. However, you're going to want to read the documentation on it and its still in early stages so some options don't work very well. It is a beautiful tool though (definitely the smartest of the lot because constructs an AST of your code) and it is even available for Windows.
If you're going to take the time to read the manual, you also want to check out GNU Indent.
Of course, there is the last way, which is actually taking the time to learn vim's indent rules and writing one for your style. It will take time, but it will work with gg=G.
Some notes on astyle vs uncrustify vs greatcode:
Astyle is good for general formatting, but can't do things like align the declaration of variables and re-style comments very well.
Uncrustify can do a LOT of stuff that astyle can't, but be prepared to spend an hour playing around until you've found the correct combination of options you need. (Or if you feel like wasting a lot of time, use genetic algorithms to figure out the best combination of options for your style and when you do share the code and give me a link so I can use it too :) )
Note that you don't have to choose one tool. With vim, you can map one keystroke to execute several commands in succession, so theoretically you could use a combination of these tools to get exactly what you're looking for.
Last but not least, here's an excerpt from my .vimrc file, where I have mapped F12 to invoke astyle with some options:
"A2 = attached brackets
"-s8 indent 8 spaces
"-xc attached braces to class declarations
"-xj remove braces for single statement ifs and elses
"-c convert tabs to spaces in the non-indentation part of the line
map <F12> :%!astyle -A2 -s8 -xc -xj -c<CR>
Don't judge me on the style. Just use the tool to reproduce what you want.

Resources