vim syntax performance with very long lines - vim

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.

Related

How to script in Vim to yank only lines from a visual selection (or fold) that match a certain pattern?

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.

Allowing syntax highlighting of kramdown footnotes while preventing highlighting in code blocks in vim

vim's default syntax highlighting for markdown is based on vanilla markdown, which considers every tab or four-space indented line to be the beginning of a code block. From markdown.vim:
syn region markdownCodeBlock start=" \|\t" end="$" contained
However, I use kramdown, which allows for footnotes (as do some others, such as Pandoc, Markdown Extra, and MultiMarkdown). I've come up with this rule modification to allow for syntax highlighting and spell checking within footnotes but not code blocks:
syn region markdownCodeBlock start="\(\[\^.*\]:\n\)\#<! \|\t" end="$" contained
It's less than perfect, however, because it doesn't allow footnotes to start on the same line as their instantiation, doesn't allow for code blocks inside footnotes, and doesn't allow for multi-paragraph footnotes. Any suggestions for how to do this better?
You can use vim-pandoc. It doesn't correctly highlight code inside footnotes, but addresses the rest of those issues. Unfortunately, it doesn't work great with some other less common parts of kramdown syntax (such as tables), so it's not a perfect fix.
Its default setting uses vim's conceal feature extensively; if you don't like this, you can turn it off:
:set cole=0

Vim smart tabs inside an if statement

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.

VIM: Respect only current code block

I have started working on a huge PHP application that has thousands of lines of code in each file, with lots of huge if blocks, classes, and functions all existing in the same file. I'm not the only dev working on it, so I cannot refactor!
I have tried using the Tags List plugin but it does not really help. Is there any way to have VIM respect only a particular code block, and ignore the rest of the file? I am hoping for some or all of these features:
Enable line numbering only for the current code block, starting from 1 at the line containing the opening {, and showing no numbering for lines preceding it or after the closing }.
Searching with / would be restricted only to the block in question.
I am thinking along the lines of selecting the current block and editing it in a new buffer when enabling the mode, then replacing the existing block with the edited block when exiting the mode. However, I am having trouble actually implementing this feature. My current version is this:
map <F7> <Esc>mO<C-V>aBy:new<Return>p:set nu<Return>:set ft=php<Return>ggi<?php<Return><Esc>
map <F8> <Esc>ggdd<C-V>aBx:bp<Return>`O<C-V>aBp
However, this has several issues, such as the inability to perform incremental saves.
I would be very surprised if Vim allows the kind of line numbering you ask for.
This plugin (and 1 or 2 similar ones IIRC) allows you to visually select a region of your current file, work on it in another buffer and put everything back in its place in the original file on :w.
Even if it's not the solution you are wanting, I think the following can help you to solve your problem.
You can use phpfolding plugin, which folds by PHP syntax (functions, classes, methods, PhpDoc...)
You can then select a fold by pressing v$ over the closed fold and execute whatever you want with :whatever. For example, :s/this/self/g to substitute all this for self in the fold. When you press :, vim will automatically add '<,'> to denote following command it's only for the visually selected text.

Using an external syntax highlighter in 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

Resources