Latex precompiling with Vim - 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.

Related

Vim generate text expansion from shortcut

The codebase I'm working on requires standard comments around any modifications that we make:
// -----------ABCD---------------
and then
// ----------\ABCD---------------
What's the best way to map a short combination of keys like -abcd and \abcd to generate these longer strings?
The simplest, built-in :help abbreviations:
inoreab abcd // -----------ABCD---------------
inoreab abcD // ----------\ABCD---------------
Why did I choose different triggers? There are some rules (documented as "three types of abbreviations" under the above help link) for the allowed keys; the easiest is that it's all keyword characters.
If you insist on those exact triggers, you'd have to fiddle with the 'iskeyword' option (which can affect syntax highlighting and motions!), or switch to :inoremap. The downside of that is that you won't see the typed characters until any ambiguity has been resolved (try it; you'll see what I mean).
ABCD is just a dummy; I need dynamic text here
If multiple abbreviations won't do, you'll need snippets.
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 and this comparison by Mark Weber.
A snippet would look like this (snipMate syntax):
snippet abcd
// -----------${1:ABCD}---------------
${2:content}
// ----------\$1---------------
${3}

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.

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.

Is it possible to use multiple foldmarkers in vim?

I'm coding C# in Vim and I want to be able to fold both
+---- 3 lines: void SomeFunction()-----------------------------------------------
As well as
+---- 42 lines: #region The Answer To Life---------------------------------------
However, foldmarker must be a literal string. I've been led to the idea of foldmethod=syntax, but this doesn't work out of the box in Vim 7.3.
Other than setting the fold method to manual and writing a script, how can I achieve this?
My Vim 7.3 runtime has a syntax/cs.vim file (from 14-Aug-2009) that supports syntax folding for #region. Syntax folding is nice; I'd advise against another foldmethod. I would contact the author of the syntax file and suggest the missing folding of functions as an enhancement; many other filetypes have this, and it seems to be common and helpful. (This can be made configurable for those who don't want one or the other.)
In the meantime, you can add the following to ~/.vim/after/syntax/cs.vim to enable folding of any curly braces blocks:
syn region csFold start="{" end="}" transparent fold

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