How to tab without losing block - vim

I have been using vim for about 3 weeks now and have been having problem with tabs.
What I usually do is do gg to go to the top, do a ctrl+v for visual block, do a G to select everything to below(one column), do a $ to select to the right, then press < or > to tab.
However having to do all this, I lose the selection and I have to do all those commands to do another tab.
How do I not lose selection? Or is there a better way?
NOTE: I sometimes don't need to select everything sometimes just a portion of the file.

To reselect a visual selection use the gv command followed by your command. Although this is not the best way.
Instead select the whole buffer with ggVG then indent with >. This will indent the selection. To repeat the command again just press .. The . command will repeat the last normal command, in this case the > command. If you have indent a few times to many just use the undo command, u, as many times as necessary. This vimcast is a great screencast describing this technique and this one describe more indention techniques.
Others prefer the following mappings:
xnoremap <Tab> >gv
xnoremap <S-Tab> <gv

I am not sure what is important here: being able to do multiple indents in a single go or keeping the visual block. Assuming you want to do multiple indents, just prefix the > with a number, e.g. 3> will indent the selected block three times.
Also, you don't need to select the entire line to indent it (i.e. the $ is not needed).

Related

How to execute specific regex substitution on selected lines in visual mode in vim

I want to replicate the VS code feature of 'highlight and comment out code' (usually bound to keys SHIFT + /) in vim.
I can run :g//s/^/\/\/ / in normal mode to prepend // at the start of every line. I just want to put a constraint on this so it only applies the substitution to lines highlighted in visual mode.
Visually select all the lines (using V), then hit :.
This will give you :'<,'> which is the range of your visual selection.
Then you can add your vim command to it.
I would recommend the following method if you wish to not use plugins.
:'<,'>normal I//
Which is not a substitution.
If you want a really nice vim plugin that does this task in a vim manner, check out tpope's vim-commentary which is an essential in my opinion.
I can run :g//s/^/\/\/ / in normal mode to prepend // at the start of every line.
Well, that would be an unnecessarily complicated way to do it and your command wouldn't really work anyway.
:g// either matches nothing or it matches the previous search. What you want, here, is probably something like :g/^/ or :g/$/.
A simple substitution on the whole buffer would be much simpler and much faster:
:%s/^/\/\/ /
Using :help :global in this context provides no value (you want to operate on every line anyway) and is considerably slower (we are talking thousands of times slower)
You can use alternative separators to avoid all that backslashing:
:%s#^#// #
The last separator is not even needed:
:%s#^#// <-- there is a space, here
And the kicker: you can enter command-line mode from visual mode like you would do from normal mode, by pressing :. So you can simply make your visual selection, press :, and run your substitution:
v " enter visual mode
<motion> " expand the selection
: " press :
:'<,'> " Vim inserts the range covering the visual selection for you
:'<,'>s#^#// <CR> " perform your substitution

Vim function to find pattern, replace, and visual mode

So I use Vim to write reports at work, reports are basically a bunch of "common issues" that we write over and over, so they are templated. These templates have placeholder blocks {==BLOCK==} to ensure people modify things as/when needed, so this is an example:
The test revealed that it was possible to access {==sensitive data==},
as shown in the examples below...
That block may need to be modified, or not. So the idea is, I am editing the common issue, and I see there are 3 or 4 blocks like the one in the example, I'd like to press let's say [leader]b and then end up having the template text for the first block selected in visual mode without the {== and ==} that are around it.
I have tried a few things but I didn't get too far, any suggestions?
Thanks!
You could define the following function:
function! VisualSelect()
call search("==}")
norm hvT=
endfunction
nnoremap <leader>b :call VisualSelect()<cr>
vnoremap <leader>b Ol<esc>:call VisualSelect()<cr>
This will visually select the contents between {== and ==}. Typing <leader>b repeatedly will select the next occurrence.
Most template/snippet expand plugins support this.
With my lh-brackets plugin, you can execute
:SetMarkers {== ==}
and then jump from one placeholder to the next with CTRL+J with vim, or META-DEL with gvim. lh-brackets doesn't take care of loading/expanding templates. mu-template will add this layer.
If instead you choose to use one of the more popular snippet plugin, there will certainly be an option to change the syntax of the placeholders, but I don't know it.
The poor man's solution would look like:
nnoremap <c-j> <c-\><c-n>/{==.*==}<cr>v/==}/e<cr><c-g>
snoremap <c-j> <c-\><c-n>/{==.*==}<cr>v/==}/e<cr><c-g>
but it won't take care of restoring the search pattern, of the cases where the cursor is already within a placeholder, and so on...
EDIT: the version that automatically deletes the placeholder marks is
nnoremap <c-j> <c-\><c-n>/{==.*==}<cr>v/==}/e<cr>s<c-r>=matchstr(#", '{==\zs.*\ze==}')<cr><esc>gv6h<c-g>
the same in snoremap
In short:
nnoremap <leader>b /{==.*==}<cr>xxxvt=<esc>/==}<cr>xxxgv
What it does:
1.) find the pattern
/{==.*==}<cr>
2.) Remove the first "{=="
xxx
3.) Visual select your text until the first = (maybe this could be also optimized for using a regex instead of simple searching for the next =)
vt=
4.) Go to the end sequence
/==}<cr>
5.) Remove it
xxx
6.) Select again your last selection
gv
I have figured out a way based on what #snap said, I ended up adding the code to a Python plugin to run it through it, as that fits better with what I am trying to do, snippet below:
#neovim.command('VimisEditTemplateBlock')
def urlify(self):
"""Search next codify block and prepare for editing"""
[...]
self.nvim.command('call search("{==")') # Find beginning of codify block
self.nvim.command('norm xxx') # Delete {==
self.nvim.command('norm vf=') # Select the inner text
self.nvim.command('norm v')
self.nvim.command('norm xxxgvh') #Delete ==} and leave the inner text selected in Visual Mode

autoindent in vim for selected text

1) Is there anyway to autoindent/retab on a set of lines, rather than the entire file?
set shiftwidth=4
set expandtab
set tabstop=4
has been defined in my .vimrc.
What I want is to select a bunch of lines and apply indentation only on them. This is because the file is large and I just want to clean my line of codes. By doing :retab, I would have to force the whole file to be reindented.
For example select the following code and reindent automatically
def hello(self):
line1
line2
to
def hello(self)
line1
line2
2) Is there any way that I can reverse tab? Something like Shift-Tab in Eclipse. It goes back 4 spaces.
You can try this one...
Shift + V to enter in Visual mode
Then press j until you reach the text you want to be ident.
Finally press
=, it will ident automatically your selected code.
If you want to ident the whole code just type gg=G.
What I want is to select a bunch of lines and apply indentation only on them
You can apply indentation to certain lines in Visual mode. To do this follow these steps:
Position your cursor in the first line to be indented
Enter visual mode by typing shift + v
Move down, typing j until you reach the last line to be indented (alternately you can type line # + G if you know the line number of the last line to be indented).
Type >
Another solution is to do this with a regex in command-line mode:
2,5s/\v(.*)/\t\1/g
Here the line range is specified in the first two numbers of the regex (in this case from line 2 to 5).
To answer both of your questions at the same time, you can use the > and < operators. Since they are operators, they behave just like y, d, c, and all the other operators do, so you must supply them with a motion. For example, >> will indent the current line (with 4 spaces), and >j will indent the current line and the line below. >G will indent everything to the end of the buffer, etc.
Similarly, < will unindent whatever you specify.
In your specific example, there are two different approaches I would recommend.
Use normal mode. This one kinda depends on how large your function is. If it's just the two lines, you could put your cursor on line1, and type <j>,. (Of course, if your function has more than 2 lines, you'll need to adjust). Unfortunately you need to unindent before reindenting because otherwise you'll end up with 5 spaces, which I assume you don't want.
Use visual mode. This one is slightly less convenient unless you modify your .vimrc because calling > or < in visual mode will drop your visual selection. That's why I have the following in my .vimrc:
"Make it easier to indent a visual selection several times.
xnoremap > >gv
xnoremap < <gv
With this setup, you can visually select the lines you would like to reindent, and then do <>. IMO, this is the best solution, and I frequently use this kind of workflow.
Most (if not all) Ex commands take a range so you could just visually select the lines and do :'<,'>retab.
Or :12,16retab.
Or :.,+9retab.
And so on.
See :help :retab and :help :range.

Opposite of newline in vim

In vim, is there a command to delete the newline, and all empty space behind the cursor?
Say I stand in the middle of a text in insert mode and press Enter, what command would the reverse what I just did?
A) An example:
"some code{ in here }"
B) After pressing Enter:
"some code{
in here }"
Now pressing backspace will delete one space of the indentation. I would rather have it delete all indentation, and jump back to A.
Can this be done in a command or by doing some remapping to the backspace key?
It's tragic how unknown the J command is. It joins lines in normal mode.
In insert mode, you can press <C-U> twice; first, it'll delete the indent before the cursor, then it'll join with the previous line. Note that this requires
:set backspace=indent,eol,start
did you try J (uppercase) ? it will give exactly what you want.
"some code{ cursor on this line, pressJ
in here }"
You can do ᴇꜱᴄ, K, Shift+J.
K jumps up to the previous line and Shift+J joins the two lines.
However, with properly configured indentation and syntax, a backspace doesn’t just delete a space, it deletes the full previous indentation block.
One easy way is up one line, to end of that line and just delete. As long as you still are in insert mode it will do the same thing as J when deleting at the last position - like most other editors. For me that is the quickest alternative because I'm used to it from other editors.
That is: ↑, End, Delete (when still in insert mode)
One quick alternative (the VIM-way) is (when still in insert mode):
↑, Ctrl+o, J (when still in insert mode)
(Ctrl+o is used in insert mode to enter one normal mode command.)
It's also possible to use a remapping of the backspace key:
inoremap <expr> <bs> getline('.')[:col('.')-2]=~'^\s\+$' ? "<c-u><c-u>" : "<bs>"
Note that this mapping completely overrides the normal behavior the backspace key. This will only be useful when you don't intend to use its normal behavior. This is not recommended if you can easily access the other options (c-u or J)
However, (as far as I know) there's no way to distinguish between manually added leading white spaces and auto indent. If you use noexpandtab, you can edit the regex to only match tabs.
This also does not work in some modes of auto-indent (for example, in block comment in C, vim automatically start a new line starts with *)

Vim / vi Survival Guide

What are the essential vim commands? What does a new-user need to know to keep themselves from getting into trouble? One command per comment, please.
What I find irreplaceable (because it works in vi also, unlike vim's visual mode) are marks. You can mark various spots with m (lower case) and then a letter of your choice (eg x). Then you go elsewhere, and can go back with ``x(backquote letter) to the exact spot, or with'x` (apostrophe letter) to go to the line.
These movements can be used as arguments to commands (yank, delete, etc). For example, you want to delete 10 lines; instead of counting and then moving to the topmost line and entering 10dd, you go to either the start or the end of the block, press mm (mark m), then go to the other end of the block, and press d'm (delete apostrophe m). If you use backquote instead of apostrophe in this example, then the deletion will work character-wise, not line-wise. Try marking in the middle of the line with "mark m", moving to the middle of another line, then entering "d backquote m" and you will see what I mean.
I was very happy the day I learned about using * or # to search, down or up respectively, for the word under the cursor. Make sure to :set incsearch and :set hlsearch first.
I like this QRC!
http://www.fsckin.com/wp-content/uploads/2007/10/vi-vim_cheat_sheet.gif
When you have some repetitive action to take Macros are usually faster than regex.
Just type
q[0-9a-z] in normal mode
Many people use
qq
because it's fast.
Press
q in normal mode
again to stop recording.
Then just type
#[0-9a-z] in normal mode
to repeat what you just recorded.
#q
for the example like above.
Edited to add: you can also repeat the macro. Let's say you programed a macro to jump to the head of a line, insert a tab, and then jump down one line. You then test your macro by typing "#q" to run it once. Then you can repeat the action nine more times by typing "9#q".
:q -> quit
:w -> save
:q! -> quit and don't save
:x -> save and quit
:[number] -> go to line number
G -> go to end of file
dd -> delete line
p -> "put" line
yy -> "copy" line
:s/[searchfor] -> search
I guess those are the basic one to start from
Use the 'J' (J for Join; upper-case) command to delete the newline at the end of a line. You'll find it tricky otherwise.
This recent Vim tutorial from IBM is pretty good
First of all you need to know how to close vi:
ctrl-c : q!
Rest can be found from vimtutor. Launch vimtutor by typing vimtutor at your command line
Although this is a matter of personal preference I've found that one of the essential things to do is to remap Esc to something else.
I find it very uncomfortable to reach for the Esc key to exit insert mode, but the beautiful thing about Vim is that allows key mappings.
I'm currently using the following mapping using Control + S:
inoremap <C-s> <Esc>:w<CR>
This has the advantage of being a key mapping I have already committed to memory and has the added value of saving my work every time I go to normal mode. Yeah, I know it is crazy but I would be hitting the save command that frequently anyway. It's like a bad habit, you know.
" ~/.vimrc
" Turn on line numbering
set nu
" Turn on syntax highlighting
syntax on
" Set 4 space expanding tabs
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
"turn off line wrapping
set nowrap
" Map CTRL-N to create a new tab
:map <C-n> <ESC>:tabnew<RETURN>
" Map Tab and CTRL-Tab to move between tabs
:map <Tab> <ESC>:tabn<RETURN>
:map <C-Tab> <ESC>:tabp<RETURN>
If you're using vim, the 'u' command (in command mode) will Undo the last command you typed. You can use this command repeatedly to undo mistakes you may have made before saving the file.
See http://www.rayninfo.co.uk/vimtips.html for a great collection of Vim tips, from the basic can't-live-without to very sophisticated stuff that you might never have thought of trying.
Lots of great commands are listed at the Vim Tips Wiki.
It's also good to run the vimtutor when learning these commands
alias vi nedit :)
all humor aside..
for vi WHEN NOT using nedit..
i (switch to insert mode)
a (append = move to end of line and switch to insert mode)
esc (exit insert mode)
dd delete a line
x delete a character
:wq (save and quit)
/ start a search
n find Next
? search backwards..
yy (yank) copy a line to the buffer
pp (paste) paste it here
r (replace a character)
<N> <command> this is a neat - but aggravating feature that lets you type digits and then a command so
5dd will delete 5 lines
but at this point you might as well
- man vi and refresh your memory
While there are LOTS more, I switched from Vi to nedit several years ago, which I find has more features I can use on a regular basis more easily. Tabbed editing, incremental search bar, column select, copy and paste. sort selected lines, search and destroy within selection, whole doc or all open docs..
tear-off drop down menus..
and it supports syntax highlighting for all the languages I use.. (with pattern files I've used a long time over the years. VIM many now be equivalent, but It has to introduce a feature that Nedit doesn't and an easy way to migrate my pattern files before I switch again.
I like the Vim 5.6 Reference Guide, by Bram Moolenaar and Oleg Raisky.
You can directly print it in booklet form, easy to read, I always have it laying around.
It's a tad old, but what are 8 years in Vi's lifespan ?
:set ignorecase smartcase
Makes searching case-insensitive, unless your search includes a capital letter. Not the most indispensable perhaps, but I find myself setting this option any time I'm editing in a new place. It's in any vimrc file I own.
:%!xxd
View the contents of a buffer in hexadecimal. To revert:
:%!xxd -r
My biggest tip: ctrl+q saves the day when you accidentally hit ctrl+s to save the file you are working on
I have this in my vimrc
set number
set relativenumber
This gives me a line numbering system which makes j, k keys really productive.
I use vi very lightly, and I only use the following commands:
a - switch to insert mode (after the cursor)
esc - return to command mode
:wq - save and quit
:q - quit (no save, only without modification)
:q! - force quit (no save, also with modification)
x - delete one character (in command mode)
dd - delete the whole line (in command mode)
I know there are many many more, but those are enough to get you by.
One of my favourite commands is %G which takes to directly to the end of a file. Especially useful in log-files.
How to switch between modes (i to enter insert mode (one of many ways), esc to exit insert mode, colon for command mode) and how to save and exit. (:wq)
Another useful command is to search something: /
e.g. /Mon will search (and in case of vim highlight) any occurences of Mon in your file.
As a couple of other people have already mentioned, vimtutor is the way to go. It will teach you everything you need to know in vim. The one piece of general advice I would give you is to stay out of insert mode as much as possible. There is enormous power in the other modes, it just takes a little bit of practice to get used to it.
i - insert mode (escape to exit)
dd - delete line
shift-y - 'Yank' (copy) line
p - 'Put' (paste) line(s)
shift-v - Visual mode used to select text (tryin 'yanking' this text and 'putting' it somewhere.
ctrl-w n - create new window (you can open a file or start new file here)
ctrl-w v - split existing window vertically
ctrl-n (in insert mode) - autocomplete (if supported)
:! to run a shell command, usually with standard in as the file or a selection (shift-V)
Useful plugins to look at:
* Buffer Explorer - use \be to view files in the buffer (and select to re-open)
NB vi is not vim! vim is rapidly turning into the emacs of the new century. nvi is probably the closest thing to the original vi. Here's a nice hint: "xp" will exchange two characters (try it).
replace 'foo' with 'bar' everywhere in the file
:%s/foo/bar/gc
The real power is in the searching. Here are the essential commands:
/Steve will find the first instance of "Steve" in the text.
n will find the next "Steve" in the text.
:%s//Stephen/g will replace all those instances of "Steve" you just searched for with "Stephen".
Not to promote myself, but I wrote a blog post on this subject. It focuses on the critical parts of Vim for a beginner.
My favorites:
% find matching bracket/brace
* and # next/previous match
gg top of page
G end of the page
<Ctrl-v> Change to visual mode and select column
<Ctrl-a> increase current number by 1
<Ctrl-x> decrease current number by 1
Running macros

Resources