There is a way to move highlighted code up or down with arrow keys. Even the indentation would be correct on dropping the block.
For the life of me I do not remember how to do it.
Can someone please tell me how to do it.( suitably embarrassed asking this).
Here's the link that'll help you
link
You can move a line, or a block of lines, with the :m command. Examples:
:m 12 move current line to after line 12
To move a block of lines, use the same command but visually select the lines before entering the move command. You can also use arbitrary ranges with the move command. Examples:
:5,7m 21 move lines 5, 6 and 7 to after line 21
why not use d+p if you had chosen the block code
If you want to do it with arrow keys, you can try Tim Pope's vim-unimpaired plugin, which you can find on Github.
Then you can use mappings similar to these (except map them to whatever keys you like).
" ^U moves lines up, ^D moves lines down.
" Works in normal or visual select modes.
nmap <C-u> [e
nmap <C-d> ]e
vmap <C-u> [egv
vmap <C-d> ]egv
Cutting a block of text in visual mode and then pasting:
Go to command mode by pressing Esc if you're not already in it
Move to the start or end of where you want to go
Press V to switch to visual mode
Move with arrows or H,J,K,L to the other end of the block you want to move
Press D to cut it, it will switch back into command mode
Move to where you want to put it and press P to paste what you cut
It seems like a lot of steps but it's just a verbose explanation.
Here is my configurations, There is a nice configuration that I am using to map Ctrl+J to move a block of code up and Ctrl+K to move a block down. I am using currently NVIM but I think the same configuration setting is applicable for VIM as well.
Setting on NVIM
The location that I am using on macOS Catalina for the NVIM is located at:
.config/nvim/init.vim
nnoremap K :m .-2<CR>==
nnoremap J :m .+1<CR>==
vnoremap K :m '<-2<CR>gv==gv
vnoremap J :m '>+1<CR>gv=gv
for vim I think you can change the setting on
.vimrc located under the home directory.
Related
In VSCode you can copy and paste selected lines of text up or down using Alt+Shift + Up or Down.
I switched to vim a few months ago, and I really miss this feature.
I found out you can move selected lines in visual mode up or down using these visual mode bindings,
vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv
but it'd be great if you could copy and paste up and down as well without using yy and p because when you're done yanking, the cursor is placed at the initial position, exiting visual mode and reducing productivity.
Well, that, here, is the problem with copying and pasting random snippets from the internet without understanding what they do: they are little black boxes that one can't modify or extend at will by lack of knowledge.
Let's deconstruct the first mapping:
vnoremap J :m '>+1<CR>gv=gv
:[range]m {address} moves the lines covered by [range] to below line {address}. Here, the range is automatically injected by Vim: '<,'> which means "from the first line of the latest visual selection to its last line", and the address is '>+1, meaning "the last line of the latest visual selection + 1 line". So :'<,'>m '>+1<CR> effectively moves the selected lines below themselves,
gv reselects the latest visual selection,
= indents it,
gv reselects it again for further Js or Ks.
Now, we want a similar mapping but for copying the given lines. Maybe we can start with :help :m and scroll around?
Sure enough we find :help :copy right above :help :move, which we can try right away:
xnoremap <key> :co '>+1<CR>gv=gv
Hmm, it doesn't really work the way we want but that was rather predictable:
the address is one line below the last line of the selection,
the selection is reselected and indented, which is pointless.
We can fix the first issue by removing the +1:
xnoremap <key> :co '><CR>gv=gv
and fix the second one by selecting the copied lines instead of reselecting the latest selection:
xnoremap <key> :co '><CR>V'[=gv
See :help :copy and :help '[.
I have this:
pick 887b66f add 222 Dziewiecsil to flowers new title
pick dc331cb new name of beginning commit
And I want to get this:
pick dc331cb new name of beginning commit
pick 887b66f add 222 Dziewiecsil to flowers new title
Is there a way to do this in a quick way using keyboard shortcuts?
To swap the current line with the next one, type ddp while in command mode.
dd - delete line (actually called cut in other editors) and save it in register
p - paste line from register
dd deletes the current line, then you can paste the removed line using p. There's another way though using m. With m you can move lines around i.e.
:m 1 will move the current line after line 1
:m 0 will move the current line to top
:m $ will move the current line to bottom
In your example, place the cursor in the first line and type :m $
More info: http://vim.wikia.com/wiki/Moving_lines_up_or_down
Example:
1. one
> 2. two
with :m-2, switch (current line - 2)
> 2. two
1. one
with :m+1 switch (current line + 1)
1. one
> 2. two
You could map this if you want.
Despite the fact that question is quite old and marked as answered, I'd like to extend the answer by saying that you can use normal mode commands, which were provided by Sven Marnach with nnoremap like so:
:nnoremap <C-Up> <Up>ddp<Up>
:nnoremap <C-Down> ddp
This will allow you to move lines with Ctrl + Up and Ctrl + Down within your file. However this will overwrite #" register, which stores your last copied string/word/letter/etc. So by adding "(reg) before dd and p commands we can fix this:
:nnoremap <C-Up> <Up>"add"ap<Up>
:nnoremap <C-Down> "add"ap
Here we add "a before delete and paste commands to store our line in #a register, so your default copy register will not be overwritten. However it may overwrite contents of #a register (who knows, but you may use it for something important in your use-case, but this step bit paranoid, you can skip it if you want to), let's fix that too:
:nnoremap <silent><C-Up> :let save_a=#a<Cr><Up>"add"ap<Up>:let #a=save_a<Cr>
:nnoremap <silent><C-Down> :let save_a=#a<Cr>"add"ap:let #a=save_a<Cr>
(<silent> needed to prevent echoing our commands to message-line at the bottom.)
Now we have two mappings which allow us to move lines within the file with keyboard shortcuts. You can redefine buttons, I use Alt + j/k, which would be <A-j> and <A-k> for those commands. However not all terminal emulators support Alt key mappings AFAIK.
The mappings proposed in the Vim wikia page are actually the best way to map key combinations that emulate the way Sublime and other editors implement this feature.
This includes an indentation action after the move, which is also great (that's the double equal == signs, in case you don't want that).
It also supports visual and insert modes, so that you can move lines while editing or with fulblocks.
nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv
I personally mapped them to <D-J> and <D-K> on my Mac, instead of <A- which maps to the Alt key. That way I use Cmd + Shift + j/k, which feels more natural to my fingertips.
I have two buffers open in vim using a vertical split which are linked using :set scrollbind.
Is there a way to switch between the windows so that the cursor remains on the same (relative) row when I do switch between them using the ctrl+w commands?
A mapping will do what you need
Do this in the left window:
:nmap <right> :let linenum=getpos('.')[1]\|:wincmd l\|:call cursor(linenum,0)<cr>
and do this in the right window:
:nmap <left> :let linenum=getpos('.')[1]\|:wincmd h\|:call cursor(linenum,0)<cr>
Then you can use the left and right arrows to switch between the windows and the cursor will go to the same line in the other window.
Edit:
I didn't read your question carefully (shame on me!:).
Here's how to get exactly what you wanted:
On the left window:
:nnoremap <right> :let offset=winline()\|wincmd l\|exe 'normal ' . offset . 'H'<cr>
and on the right:
:nnoremap <left> :let offset=winline()\|wincmd h\|exe 'normal ' . offset . 'H'<cr>
Have fun!
Vim version 7.3 added a cursorbind option:
When this option is set, as the cursor in the current
window moves other cursorbound windows (windows that also have
this option set) move their cursors to the corresponding line and
column. This option is useful for viewing the
differences between two versions of a file (see 'diff'); in diff mode,
inserted and deleted lines (though not characters within a line) are
taken into account.
^W+r (switch buffers) followed by ^W^W (return cursor back)
Is there a vim command to directly select a block of text which has just been pasted?
ps. I know about gv to reselect a block after exiting visual mode. It doesn't apply to this case.
If you want to select it just after paste (before you change anything else), use
nnoremap <expr> gV "`[".getregtype(v:register)[0]."`]"
. [ and ] marks point to start and end of the last change, v:register is set to the last register used (which is register used for the paste command unless you, for example, yank something), [0] selects only first byte of register type (it is required because for blockwise register it returns <C-v>{width}) and register type is one byte which is just the same as the keystroke you should use in normal mode to invoke visual mode.
I saw this solution somewhere on SO, you may want to search for it in order to get some alternatives.
In my case I have this map:
:nnoremap gp `[v`]
After more research I think the better solution is:
" https://vim.fandom.com/wiki/Selecting_your_pasted_text
nnoremap <expr> gp '`[' . strpart(getregtype(), 0, 1) . '`]'
I have had the following maps in my vimrc forever:
nnoremap <leader>p `[V`]
nnoremap <leader>[ `[V`]<
nnoremap <leader>] `[V`]>
They do the following:
visually select the recently pasted block
de-indent the recently pasted block
indent the recently pasted block
I probably use the indent ones even more than the selection one.
I installed Ubuntu recently and fiddled around with profile preferences in terminal. Now when I edit in vim, the cursor doesn't go to the end of a line using navigation keys (In normal mode. '$' doesn't work either). However, it does show itself correctly in insert mode. This is merely a nuisance, but I'd rather be not having it. How to correct this?
Virtualedit permits the cursor to move past the end of line. Try :set ve+=all or :set ve+=onemore. For more information see:
:h ve. These settings can be made default by adding corresponding command without : to your ~/.vimrc file.
This is the correct behavior in vim. The cursor will only go to the last character unless in insert mode.
I added this to my vimrc and it seems to work.
set selection=exclusive
" allows cursor to go to the end of line with g$
set virtualedit+=onemore
noremap $ g$
" Remap VIM 1 to first non-blank character and 2 to the last non-blank character
nnoremap 1 ^
nnoremap 2 g$
" mapping for <End>
map <Esc>[4~ g$