Vim: Hide all code around selected code - vim

I want to be able to hide all code around the specific section of code that I am working with. Now I am wondering if this is possible in Vim somehow. I have experimented with it a bit already and have been successful at hiding lines above and below my selection by using highlight group Igore. This enables me to only see the lines that I want to focus on but the problem is when I begin to edit the code and add or remove lines. When I add a line or remove a line the already set highlight group Ignore is still maintaining the set line numbers so I either get to see some of the hidden code or some of the code that I want to see gets long and extends into the hidden line numbers. So I am wondering if there is some way to fix this or any other way to accomplish what I want in Vim?
Appreciate any suggestions!

Hiding or shading parts of the buffer is not the Vim way. Folding is the built-in feature that comes closest. With :set foldmethod=manual, you can then use zf or :fold to hide the parts above and below.
For a plugin solution, have a look at NrrwRgn - A Narrow Region Plugin. It allows you to edit parts of a buffer in a separate scratch buffer, with automatic syncing back.

To hide a range of lines (let's say from 1 to 10 and 20 to end, you can type :1,10fo|20,$fo
From there, you can create a function based on the current cursor position -10/+10
Note you have first to :set foldmethod=manual to make this works.
EDIT: a simple solution : :1,.-10fo|.+10,$fo

Related

How to remove tabs on multiple rows at once

This is not a programming question but an inconvenience in the android-studio editor.
If you have an unwanted tab before all your lines, how can you remove them all at once? Now I have to manually go over 50 lines to remove all the tabs to make my code look clean.
If you want to add multiple tabs at once you just select all your code and press the tab button. So I'm looking for the reverse of that.
If I understood you right, you want to beautify the code itself. Fortunately, you don't have to do that manually - at all.
There's a keybinding for it, which may vary by your OS and which layout you use by default. Go to file -> settings -> Keymap and search for auto-indent. Here's what I get on Windows 10 with the default keymap:
Again, which you have may depend on OS (I'm assuming that mainly applies to Mac though) and your keymap, but you can automatically indent your code as per language standards using Ctrl+Alt+I.
Note that this mainly does indentation. If you chose to golf code and want to ungolf it, this will not work. At least it doesn't for Java.
However: This only works with code files the IDE or plugins support. This won't work for i.e. a .txt file out of the box.
If I misunderstood you and you only want to remove tabs without doing the auto-indent, there's at least two other options.
The first option is using multiple cursors. You can add an additional cursor with shift+alt+a mouse click where you want the cursor, or holding the mouse wheel and moving the cursor with the mouse wheel held down. There might be other methods as well, but those are the two I know of.
Once you have multiple cursors, delete the tabs just like normal. But be careful! Doing so might delete the entire line itself. If it does, you can do 1 tab/n units per indent level to the left, and press delete instead.
There's (AFAIK) no limit to how many cursors you can have at once, but you can theoretically do it with 50 lines at once if you want to. But general advice - don't add more cursors than you can see at once. These do run in parallel and it's easy to lose track if you're not careful, and you might end up deleting stuff you didn't want to delete.
And finally, the regex solution:
Note: Be careful with this. If you use it incorrectly, you might get unwanted results.
If you only want to do this in a limited area, highlight it first. Then CTRL+R and you'll be presented with the regular replace menu. Make sure Regex and In Selection are selected.
A base regex to go off is ^([\s]{2,4}|\t). Explanation just for reference:
^ - At the start of the line
(
\s{4} - Match 4 spaces
|\t - Or a tab character
)
Replace with nothing and click "replace all" (or just use the regular "replace" button if you want to double-check before you do anything). This will replace one occurrence of 4 spaces or a single tab character. If you use indentation that isn't based on 4, change the number.
This is only useable and useful if you've found yourself with incorrect indentation that's the same across all the relevant lines - it will not fix indentation mistakes and/or inconsistencies such as 3-space indentation when you want 4, or random indetation for the same block. Use the first or alternatively second method for that instead.

Vim: Is it possible to have a filtered view of a file?

In a given text file, I would like to work on a "filtered view" (hiding lines with a pattern), but still to be able to edit visible lines : the filtering would only affect the visibility of some lines, and as soon as I would reset the filter, the hidden lines would appear again.
The feature I describe could be compared to the & key in the less command (except, of course, that less can't edit the file's content) :
&some_pattern <RETURN> starts a new filter,
& <RETURN> reset the filter.
Does such a feature exist in vim, natively or as a plugin?
This usually is done with folding; you can easily define a 'foldexpr' that filters lines based on a regular expression match; see Folding with Regular Expression for implementations.
However, a single fold line will remain for each condensed block. To do away with those, I can only think of the NrrwRgn plugin, which transfers selected lines into a separate scratch buffer. It's usually only for a single block, but :help NR-multi-example suggests this works on ranges, too:
For example before editing your config file, you decide to strip all comments
for making big changes but when you write your changes back, these comments
will stay in your file. You would do it like this: >
:v/^#/NRP
:NRMulti
It can be done with plain Vim, and it's named folding. Drew Neil has two screencasts about it that you might find informative.

Is there a way to show line numbers at end of the line in Vim

I am using
set relativenumber
set number
which let's me move easily around. However, it is often hard to know the exact the line number of the object where I would like to jump to because I first need to look to the left. I feel it would be easier if I could see the line numbers also on the right hand side right because my eyes have less space to follow (maybe?). I think the ideal setting would be to show the relative/absolute line number where the $ appears when whitespace characters are shown and to the left/right of the buffer. I.e.
1 Random text.$1 1
159 This is the line where the cursor is.$159 159
1 Some random text.$1 1
2 More random text. Another sentence. Maybe a third one? And so on.$2 2
3 Another line which might be quite long and my eyes focus somewhere here.$3 3
4 More random text containing more text and more words and stuff.$4 4
(In this example, I would like to do 3k but I may type 2k or 4k because I did not follow the correct line to the left.)
Is it possible to achieve this somehow?
Any suggestion on how to change my workflow are welcome, too.
Note: Using cursorline does not help as I do not seek the number of the current line.
No, there is no built-in support to your requirement. also I don't think this is easy to be done by plugin.
Maybe you could consider to change your habit/workflow. E.g. enable the cursorline option, to highlight your "current" line, it may let you easier to identify which line are you on right now.
To move cursor, if you don't want to count lines, you may want to try the EasyMotion plugin. It is very handy plugin. However it won't replace the hjkl ... motions.
No, that's not possible, unless you modify Vim's source code in a non-trivial way, or work around with kludges like a vertically split small scratch buffer at the side that is updated via autocmds.
Do you have :set cursorline? That helps (me) a lot to follow the current line, even with large window widths. Reducing those might help, too, though you have to deal with wrapping / scrolling of long lines then.

Don't wrap certain lines

I'm using conceal in a plugin to hide some data, but when the hidden line gets too long it makes a wrap which is still hidden and just looks weird.
how it looks:
<hidden metadata line that the user can't see......
which is wrapped and makes 2 empty looking lines when it gets long>
stuff
how it should look:
<a very long metadata line that is not wrapped>
stuff
How can I tell vim to not wrap certain lines (concealed ones)?
Wait, I figured out 1 way. Custom folding. A single line fold won't show as wrapped.
Now I just have to write a custom syntax folding part for my plugin and I'm golden.
It is not possible to do it on current version.
This is intentional. Without this cursor movements would be messed up,
as the screen line depends on how text is concealed, which requires
syntax parsing, which is slow.
For more information, see this discussion on vim_dev group.

VIM hide (not fold!) lines

Is there a way to totally hide certain lines? I do not want folding, I one them to not be visible at all.
Example: I program with php; functions and class variables have phpdocs, and I hate how much vertical space lines with nothing but /** and */ can take. Thus I would like to not show them (and most likely some other things). Though I have doubts that that is possible...
Note: I know about global commands and they don't do what I want. You can one of printing of what I want. But I want lines hidden in the editing area.
You can make comments invisible:
:hi! Comment guifg=bg ctermfg=white
Or
:hi! link Comment Ignore
I know this isn't really what you're asking for, but have you tried using folding with a blank foldtext? That way the lines a folded region appears like an empty line. To do this, set
set foldmethod=marker
set foldmarker=\/**,*\/
set foldtext='\ '
I prefer a foldtext which indicates that there's something there, possibly by making is look like a single commented line. In this case, replacing the first folded line with a single comment string // at the current indent level:
set foldtext=substitute(getline(v:foldstart),'\\/\\*\\*.*','\\/\\/','g'
I find this unobtrusive, while still reminding me that there is some hidden text.
Hope this helps.

Resources