This is controlled with the formatoptions setting; from :help fo-table:
You can use the 'formatoptions' option to influence how Vim formats text.
'formatoptions' is a string that can contain any of the letters below. The
default setting is tcq. You can separate the option letters with commas for
Note that the statement ...
Or you can install jq which is faster (written in C) from your package manager (e.g. sudo apt install jq in Ubuntu/Debian, sudo dnf install jq on Fedora/RHEL/CentOS) or from source and then in vim, type:
The 'formatexpr' option
You can achieve this using the 'formatexpr' option. From the help:
Expression which is evaluated to format a range of lines for the gq operator or automatic formatting (see 'formatoptions'). When this option is empty 'formatprg' is used.
Setting your 'formatexpr' correctly will work both when using gq and while inserting text.
The problem is that you have set smartindent in your ~/.vimrc. The smartindent options causes Vim to assume that your text is some C-like programming language when indenting. Among other things, it treats for like a keyword and gives an extra level of indentation to the line following. See
Really good solution would probably require some more work, but "not bad" is
not very hard to achieve.
All we need is to move one line down after each character, so let's do just
that via InsertCharPre auto-command!
Put it into .vimrc or better yet to some file under plugin/ directory.
" enters insert mode to write vertically
I found a solution. Setting nomodifiable prevents the file being edited (as used in help windows). I created a simple function to set or unset modifiable depending on if readonly is set and attached it to an autocmd.
" Don't allow editing of read only files
autocmd BufRead * call RONoEdit()
if &readonly == 1
Here is another alternative:
First copy the lines which are 4 lines below to the after the current line (:h :t) then delete the consecutive b lines (:h :d)
Even better is this command:
Which means, for each line starting with a find the next line starting with 'b' and move it to below the current line.
If you don't want to use systemlist for whatever reason, you can explicitly remove the newline and/or whitespace. Since vim 8.0.1630 (very recent), there is a trim() function which removes whitespace, including newline, from the front and the back of a string.
A common way, if you know there will always be a trailing newline is:
There is no dedicated way to do that (as far as I know), but yeah, it can be done with a few commands:
function! Interleave(start, end, where)
if a:start < a:where
for i in range(0, a:end - a:start)
execute a:start . 'm' . (a:where + i)
for i in range(a:end - a:start, 0, -1)
If you want to do that in vim you can use the following macro:
Which can be decomposed like this:
qa Record the macro in the register a
^V Enter visual block mode (use ctrl-v)
3j$ Select the lines you want to put in a column
d Delete them
"_4dd Delete the lines which ...
Since you don't have wrapping for comments enabled, the workaround in this Stack Overflow post can be used:
This adds # as a comment marker (allowing nesting, so that ##, ###, etc. also count).
I'd suggest leaving a space after # and using nb:# - some Markdown parsers require a space after #. The CommonMark spec also supports ...
You can hack around with some custom syntax and the use of the conceal:
syntax region FunctionArguments start=+(+hs=e+1 end=+)+he=e-1 conceal cchar=…
function (a, b, c, d, e)
Careful though, with this basic example, all () will be concealed, so a little more work must be done here, but it should be a good opportunity ...
Note 1 As I said in the comment this kind of box is not a good thing: it distract the eye from the important part of your file (the comment itself or the actual code). There are better way to create headers. Now this is only my opinion and this site is not here to argue about this so here is a solution.
Note 2 I give here a solution with the plugins I know ...
When vim starts, it runs $VIMRUNTIME/ftdetect.vim to find out what type of file you're editing; then, if you have 'ftplugin' set, it sources $VIMRUNTIME/ftplugin.vim which sources $VIMRUNTIME/ftplugin/&filetype.vim (see :help startup for more detail).
You can alter or override $VIMRUNTIME/ftplugin.vim or $VIMRUNTIME/ftplugin/&filetype.vim. Create a ...
This should almost work, it aligns the attributes slightly different than your example, but it's probably "close enough":
autocmd FileType xml let g:formatprg_args_expr_xml .= '." --indent-attributes 1"'
Which will format it like as:
:help 'formatlistpat' says:
A pattern that is used to recognize a list header. This is used for the "n" flag in 'formatoptions'.
And :help 'formatoptions' says:
Vim default: "tcq"
:help fo-table describes the meaning of the n flag:
n When formatting text, recognize numbered lists. This actually uses the ...
An easy way to achieve this using no vimscript is the following:
nnoremap <leader>o yyp^v$r A
This assumes you want to start the mapping in normal mode (otherwise just add <Esc> to the beginning of your insert mode mapping).
It copies the current line with yy, pastes it on the line below (p), selects the pasted text in visual mode (^v$), ...
I actually wrote a blog post about this:
tl;dr use a Vim Macro
Macro used for the image below
You could probably do something similar
It is important to realize that this "default" only applies to the gq and gw commands and auto-format as described in that section. The default textwidth is 0. Furthermore, :right and :center default to 80, not 79.
As for why 79 was chosen, it cannot be a direct hold-over from vi since gq, gw, and auto-format do not exist in vi. This is mostly ...
I don't have any evidence that this is why 79 was originally chosen, but one good reason to leave it at that value is because if you use 'list' with a value included for eol in 'listchars' then the display of the listchar will cause an 80-character-length line to wrap onto the next line in an 80-character-wide terminal.
If the line is only 79-characters ...
Even simpler: the a flag for 'formatoptions' enables automatic formatting of paragraphs whenever text is inserted or deleted. See :help fo-table for details on 'formatoptions' flags and :help autoformat.
gq and gw will format the lines that the following motion moves over.
Formatting is done with one of three methods:
Put this in your .vimrc file:
autocmd BufRead,BufNewFile *.htm,*.html setlocal tabstop=2 shiftwidth=2 softtabstop=2
Briefly, autocmds get processed when the specified events occur for the specified file name patterns. Here we just set the tab values for the current buffer to the desired value in the event of reading or creating a file with .htm or .html ...
You can add the following to your .vimrc
1. function FormatBuffer()
2. if &modified && !empty(findfile('.clang-format', expand('%:p:h') . ';'))
3. let cursor_pos = getpos('.')
5. call setpos('.', cursor_pos)
9. autocmd BufWritePre *.h,*.hpp,*.c,*.cpp,*.vert,*.frag :call FormatBuffer()...
If this is a regular occurrence, you'd be best off looking for a plugin or using @Sukima 's function. If I were doing this on the fly however, here's what I'd probably do:
Add a newline after the opening paren and before the closing paren so that strings are on separate lines.
"Some string parameter that goes on and on and on ...
Oh that's a tough one. I think the best approach is possibly a macro but more likely a plugin. Here is an example I whipped up (I need a better hobby). It seemed to work for me but would need the python indenting plugin to indent properly. Try it out.
let brx = '^\s*"'
let erx = '"\s*$'
let fullrx = brx . '\(.\+\)' . erx
The configuration of C indenting in Vim is controlled by the cinoptions option. That particular aspect of indenting is controlled by the l (lower-case L) flag. When set to any value other than 1, it will "align with a case label instead of the statement after it in the same line."
So, you can get the indenting style you want by putting this in your ~/.vimrc ...