Moving codefolds in Vim - vim

I have the following two code folds:
How would I move the bottom code fold above the top one? Is there a shortcut for that?

You can operate on a fold as a whole as if you're operating on a single line. So simply using dd here will cut the whole folded block.
See :help fold-behavior:
[...] When using an operator, a closed fold is included as a whole. Thus dl deletes the whole closed fold under the cursor.

Related

Turning upside-down two lines using vim [duplicate]

This question already has answers here:
Move entire line up and down in Vim
(21 answers)
Closed 9 years ago.
I was wondering which was the shortest way to turn upside down two adjacent lines in vim, for example:
Hi
How are you?
in
How are you?
Hi
Are there some special shortcuts or should I consider to write a macro for this?
Use ddp when your cursor is on the first line.
dd deletes the current line.
p pastes the deleted line under the current one.
What you need is a mapping: what that mapping does, even if it's 20 commands chained, doesn't really matter.
nnoremap <F6> :m-2<CR>==
and
nnoremap <F6> ddp
both do exactly what you want in slightly different ways. One command is complex and relatively smart while the other is simple and relatively dumb but they are equivalent in the way that they are both done with a single keystroke.
Of course you can use somerhing else than F6.

How can I delete empty lines in motion in Vim

I know how to delete blank lines with commands.
We may visually select the text block first, and then run commands like
s/^$/d to delete all blank lines or %s/^\(\s*\n\)\+/\r to keep only one blank lines.
Can I perform the above using motion, so that I can just press some keys to perform the "delete-motion" without having to enter command-line mode?
Creating a new operator for this is a good idea, but it can be tough to get right.
The operator-user plugin makes that task easy.
Once you have installed operator-user, all you need to do is add two lines to your vimrc, one to define the operator, and one to define your personal mapping to it:
call operator#user#define_ex_command('delete-blanks', 'g/^$/d')
map _ <Plug>(operator-delete-blanks)
This creates a new operator _. Change it to whatever you like best.
Now you can do _3} or _G or _23k to delete the blank lines contained in the motion. Text objects _a}, doubling of the operator 4__, and Visual mode V7j_ are all also supported, as befits a proper operator.
You could use operatorfunc. For example:
Define a function like this in your .vimrc:
function! DeleteEmptyLines(type)
if a:type == 'line'
silent execute ".,'\"g/^$/d"
endif
endfunction
And a mapping:
nnoremap <silent> ,d :set operatorfunc=DeleteEmptyLines<CR>m"g#
,d performs now just like an operator and accepts a (line-based) motion. You can, for example, insert ,d5j or ,dG in normal mode to delete empty lines in the next 5 lines or to the end of file.
You can find more information on how to extend this functionality here:
http://learnvimscriptthehardway.stevelosh.com/chapters/33.html
and of course::h operatorfunc and :h map-operator.
From :h map-operator:
"An operator is used before a {motion} command. To define your own operator
you must create mapping that first sets the operatorfunc option and then
invoke the g# operator. After the user types the {motion} command the
specified function will be called."
well, using motions I don't think you can only delete blank lines.
But you can do it using a mapping:
:nmap <Leader>db :g/^$/d<CR>
The motions help you move one word, one paragraph away... And before the motion you use an operator (d, c...).
So what you'd want is to create a new operator that deletes blank lines within the given motion (or selection). What I gave you is close to that, but you'd have to invent a new operator (and I don't think there's many unbound keys left).
Other vimmers may correct me, but I think the easiest way to create such operators would be to define a map for each motion and bind it to a function.
There isn't a motion that can combine with a delete such that it only deletes blank lines. A motion denotes all the text between the initial and final position, without any gaps. That includes motions which search using regular expressions.

Display some special character as a linebreak in Vim

I would like to display some (arbitrary) special character as linebreak <CR> in vim.
So far I tried misusing (certainly extreme misuse:) the non-breakable space typing
:set list listchars=nbsp:<CR>
which does not work, seemingly because the command does not accept the <CR>.
Is there anything which I can use here for <CR>? \r didn't work either.
Note that I don't want to edit the text file. The goal is to have blocks of lines (some related code) treated as a single line with respect to vim actions but displayed as multiple lines. The special character (to be defined) would be used only to save this block structure in the file replacing the linebreak \r in these cases.
Given the wider context of the problem that you have provided in a
later comment, I would suggest the following solution. Group dependent
lines of code in folds by indentation, language’s syntax, or markers.
All of these three methods are automatic and do not require manual
creation of folds. Which one to choose depends on the language you
use. See :help foldmethod, and feel free to comment this answer if
you need any help with folding.
Unless the syntax of the language you use has extensive support in
Vim, the most convenient methods would be using fold markers or
defining a custom expression to calculate fold level of each line.
The former method implies surrounding every group of lines to fold
with special text markers (which could be enclosed in a comment not
to break the syntax rules of the language). By default, those markers
are {{{ and }}}; see :help fold-marker and :help foldmarker
to find out how to change them. Use
:set foldmethod=marker
to enable this mode of folding.
Defining an expression to calculate fold level for every line is an
even more flexible method. It allows to use any logic (that can be
expressed in Vimscript) to determine the fold level. For example, to
fold groups of lines that start with a single space use the following
settings:
:set foldmethod=expr
:set foldexpr=getline(v:lnum)[0]=='\ '
See :help fold-expr for further details on customizing the fold
expression.
When the lines that depend on each other are grouped into folds, you
can easily pass the contents of any particular fold to a filter
program. Move the cursor to a line inside a target fold, then type
[zV]z to select the entire fold, followed by !, and enter the
command to run. To save typing, you can define the mapping
:nnoremap <leader>z [zV]z!
If the command is always the same, you can include it in the mapping:
:nnoremap <leader>z [zV]z!cat -n<cr>
Substitute the cat -n portion above—my example command—with the
appropriate command in your case.
I think you might want check out this vimcasts episode. May not be exactly what you want, but could get you there. Good luck!
My solution, in the end, was to insert non-breaking spaces and linebreaks in the respective places in the file. :set list listchars=nbsp:$ can then be used to display these 'special linebreaks'. Their presence allows interpreting code to identify the blocks of lines separated by this combination as related lines.
Of course this doesn't answer the question. The answer, according to my best knowledge now, is that neither :set list nor :wrap can be used to achieve this.

Vim: Fold top level folds only

I have a long code file with syntax folding in Vim.
I know how to open all folds (zR) or close all folds (zM), and I know how to increase or decrease the foldlevel (zm, zr).
However when I increase the foldlevel the inner most folds are closed; instead I want the outer most folds closed while the inner most are unfolded. It is possible to do this manually by opening all folds and the closing each top level fold by hand it's incredible tedious specially with long files that I open quickly to get an overview of the code.
Is there any key shortcut to do this? Or do I need to make some sort of Vim function to do this? And if so, how?
I think you want to add set foldnestmax=1 to your $MYVIMRC.
Yes, you can type
:%foldc
Which closes one level of folds (outside in).
As Karl says, the foldnestmax setting is probably what you want.
zO (i.e., capital-letter-o) opens all nested folds.
I also find zx and zv very helpful.
When I use foldmethod=expr with a custom fold expression, I'll often modify the expression so that it only folds what I want it to fold.

How do I preserve folds in VIM when cutting and pasting?

In vim, you can create a fold with zf, so if is %, you can neatly fold a delimited block.
is there a way to select some text in visual mode and automatically fold that?
I've noticed that if I select a closed fold and use dd to delete it, then go somewhere else and use P to paste it, the fold will disappear and the fold will be expanded. I want to cut the folded stuff and paste it and have it paste with the folds still intact and closed.
You can do the first if you use :set foldmethod=manual and then simply highlight the block you want and use zf to fold it.
I don't think you can do this (at least, not without a script)
Vim has several different fold strategies; I assume you are talking about manual folding.
Unfortunately, yanking and pasting does not keep the fold in-tact. You may be able to create a script that will re-fold pasted text, but it seems like it would be more annoying than useful in the end.

Resources