Is it possible to use multiple foldmarkers in vim? - 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

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}

Faster way to type control flow statements (in C and php etc)?

I am new to Vim and I need to speed up my typing for this kind of statements.
if (a == 'e') {
foo();
}
In other text editors, I usually type if() {} first and then insert the text in to the parenthesis and curly braces. If I do this in Vim, I need to switch back to normal, move cursor to middle of () then middle of {}... switch between i and esc ...
What is your suggestion on typing this kind of syntax for Vim beginner? I would be grateful if you can show me the commands for that example step by step.
This is a job for snippet expansion. Take a look at SnipMate or UltiSnips.
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.
There are two approaches that solves your goal:
abbreviations
and snippets engines
Abbreviations and the old way of doing things. You just type if and space, and tada! You'll find plenty examples around the web. Only a few will be context-sensitive (i.e. they won't expand within comment or string contexts), or able to take the current project spacing style into consideration. In lh-cpp, you'll find the usual control-statement abbreviations for C and C++, they'll need to be duplicated for similar languages (a runtime ftplugin/c/c_snippets.vim from a php ftplugin should do it in your case)-- in lh-misc I support a couple of others languages (for VimL and shell)
Snippet engines are the trendy way of doing the same thing. This time, you will be able to type i or if and then <tab> (or CTRL+SPACE, or ...). Control-statement snippets won't need to be aware of the current context as we need to explicitly require the expansion. Others have already given links to the trendy snippets engines. Snippets from lh-cpp (which relies on mu-template) take the project style into account when expanding control-statement snippets (i.e. some projects want ) and { on a same line, other want a newline in between, ...)
Here's my answer in case you want to go with vanilla Vim.
In the majority of the cases I guess there is no point in entering the parentheses first and filling in the condition later, just type it all in right away:
if (a == 'e')
Then you can either continue
by typing {}<ESC>:
if (a == 'e') {}
^ cursor is here
The cursor is already placed so you can continue with i<CR> and type the body (if properly configured, Vim should indent for you).
or by typing {<CR>}<ESC>:
if (a == 'e') {
}
^ cursor is here
Then you can enter the body by pressing O (open new line above cursor). Possibly Vim also automatically indents here (it doesn't in my configuration).
If you really want to fill in the condition after you have entered this:
if () {
}
^ cursor
you can do so by typing kf(a.
If anybody knows better ways to do this without plugins, suggestions are welcome.

How to color function call in Vim syntax highlighting

I'm new to Vim and curious how to highlight a function call after the function has been defined. As an example, in the SublimeText version, totalForArray is green when it is defined, as well as when it is called on line 12. This is what my Vim looks like imgur.com/q2WMQ4d, and I'm wondering how to make totalForArray highlighted when it's called.
An improvement on Vitor's regex matching.
This will highlight nested function calls while respecting highlighting for keywords like while, if, for, etc... and also allows for whitespace between function name and parenthesis
e.g. myFunction (int argc) { ... }
syn match dFunction "\zs\(\k\w*\)*\s*\ze("
hi link dFunction Function
Vim's syntax parsing usually only colors the function definition, because that one is easy to locate with a regular expression. For function calls, it would have to maintain a list of detected functions.
There are plugins that extend syntax highlighting with such a list, usually taken from the tags database. For example, the easytags.vim plugin performs automatic tags updates and can highlight those via the :HighlightTags command.
As a simpler alternative to what was proposed by #Ingo, you can also define a syntax to match any keyword that is directly followed by a parentheses:
syn match jsFunction "\<\k\+\ze("
hi link jsFunction Function
Searching in github I was also able to find the vim-javascript plugin, which appears to have various extensions to the default Javascript syntax included in Vim. In particular, it contains the following syntax definition:
syntax match jsFuncCall /\k\+\%(\s*(\)\#=/
This will implement the same syntax highlight I described before, but by using this plugin you might also benefit from other improvements that are included in it.

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 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.

Resources