This question already has answers here:
Vim: move around quickly inside of long line
(8 answers)
Closed 8 years ago.
I'm editing a text file with vim and I have wrap enabled using "set wrap". Suppose I have one very long line which has been wrapped to 10 lines. Lets say I'm on the 5th word(which is on the first line when wrapped) and I'd like to get to a word on the 7th line(when wrapped). Whats the fastest way I could get to that line. I'm not too keen on going w<a-number>l -- there is probably a better/easier way to do this, right?
gj to go to line below (same line, but wrapped)
gk to go to the above line.
I have a map in my .vimrc
map j gj
map k gk
There are several motions that specifically deal with :set wrap; mostly they are variants of the "normal" motions with g prefixed.
So there's gj and gk to move across screen lines, as well as g0, g^, g$, etc. Look them up with :help for more details.
When you know the word or see it. for example it's hello, you might search for it with /hello. That should jump there. If there is a hello before, you can use n to get to the next one.
As Paco says in his answer, you can navigate screen lines with gj and gk. If that is too much hassle, as it probably is, you can add these lines to your ~/.vimrc to have the normal arrow keys navigate in terms of screen lines instead of logical lines:
noremap <silent> <Up> gk
noremap <silent> <Down> gj
noremap <silent> <Home> g<Home>
noremap <silent> <End> g<End>
inoremap <silent> <Up> <C-o>gk
inoremap <silent> <Down> <C-o>gj
inoremap <silent> <Home> <C-o>g<Home>
inoremap <silent> <End> <C-o>g<End>
Related
Sometimes I want to swap current line with line up or below in vim. I can do it with commands :m+1 or :m-1. However it is too wordy. Is there shorter way doing the same?
give this a try:
ddp and ddkP
if it gives what you want. ;)
Both Tim Pope's unimpaired.vim - Pairs of handy bracket mappings and my own LineJuggler plugin provide (among others; my plugin has a focus on line moves and copies, whereas Tim's has a mixture of useful stuff) [e and ]e mappings to move the current line / selection above or below. These don't clobber the default register, as ddp et al. would do.
Give mappings a chance:
nnoremap <leader>k :move-2<CR>==
nnoremap <leader>j :move+<CR>==
xnoremap <leader>k :move-2<CR>gv=gv
xnoremap <leader>j :move'>+<CR>gv=gv
Vim has the :move command that allows you to move one line.
For instance, :m +1 will move the current line down.
I have these mappings in my .vimrc :
" move the lines of visual mode up or down
" JK to move and keep a correct indentation (with =)
" <up><down> to move keeping the correct indentation
vnoremap <silent> J :m '>+1<cr>gv=gv
vnoremap <silent> <down> :m '>+1<cr>gv
vnoremap <silent> K :m '<-2<cr>gv=gv
vnoremap <silent> <up> :m '<-2<cr>gv
With these lines, if you select a bunch of lines in visual mode, and then press <up> or <down> arrows, the lines will be moved up or down (and you will stay in the same visual selection thanks to the gv at the end).
J and K are almost the same, but they keep and autoindentation, using the = operator (gv= autoindents the last visual selection).
For sure, i encourage you to do modify the keys that are mapped to your own preferences. These are just mine. Also, copy-pasting without understanding is probably a bad idea. If you understand that mapping, you could check help pages for :m, gv and =.
I'm sorry if my question isn't very clear. I'm not sure how to phrase it.
I'd like to use VIM to write papers for some classes I'm in. The problem I'm having is with the formatting of lines in the editor. If I don't explicitly break the end of a line with the enter key, when I try to move the cursor through the text, it skips multiple lines if I have a sentence that spans more than one line. Is there any way to make it so that the cursor will be able to move through the text akin to the way it does in most word processors?
The problem with the often used
noremap j gj
noremap k gk
option is, that it breaks the <vcount> functionality, if you have lines in your text, which span across multiple lines.
Example: you want 10k (go UP 10 lines), because you use relative numbers in the sidebar, but theres a multiline with 4 lines height. Therefore you end up effectively at 6 lines (6k) above your desired line, which you read from your relative numbers. You'd have to calculate manually! Annoying... Especially if you have multiple multiline between your current position and your desired position - not Vim-istic!
I like my <vcount> function together with my :relativenumber, which is why I wrote the following functions & mapping to solve all problems related to this.
These functions let you use commands like 10j or 10k as expected, despite the presence of multilines with all the advantages of using gj and gk as your default movement mappings:
Edit:
I just found the following on reddit, which is so much better then my own solution. This is shortest possible version:
nnoremap <expr> j v:count ? 'j' : 'gj'
nnoremap <expr> k v:count ? 'k' : 'gk'
(If you use noremap instead of nnoremap, then this works in both visual and normal modes)
"Longer" version for better understanding and completeness:
nnoremap <expr> k (v:count == 0 ? 'gk' : 'k')
nnoremap <expr> j (v:count == 0 ? 'gj' : 'j')
source: http://www.reddit.com/r/vim/comments/2k4cbr/problem_with_gj_and_gk/
My old solution:
nnoremap <silent> j :<C-U>call Down(v:count)<CR>
vnoremap <silent> j gj
nnoremap <silent> k :<C-U>call Up(v:count)<CR>
vnoremap <silent> k gk
function! Down(vcount)
if a:vcount == 0
exe "normal! gj"
else
exe "normal! ". a:vcount ."j"
endif
endfunction
function! Up(vcount)
if a:vcount == 0
exe "normal! gk"
else
exe "normal! ". a:vcount ."k"
endif
endfunction
That's because the default j and k motions move across physical lines, not the visible, soft-wrapped screen lines (when you have :set wrap). You can use the gj and gk commands for that.
If you want to default to that behavior, you can remap the default keys by putting this into your ~/.vimrc:
noremap j gj
noremap k gk
Have you tried the following in vim command line:
:set nowrap
Solution that I found on internet that works with up and down arrow:
imap <silent> <Down> <C-o>gj
imap <silent> <Up> <C-o>gk
nmap <silent> <Down> gj
nmap <silent> <Up> gk
I have found another version of this solution that does more than moving through physical or virtual lines, it also adds jumps bigger than 5 lines to the jump list, allowing us to use Ctrl-o and Ctrl-i.
" source: https://www.vi-improved.org/vim-tips/
nnoremap <expr> j v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j' : 'gj'
nnoremap <expr> k v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k' : 'gk'
It uses a nested ternary operator to add the jump to the jump list
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm using vim on a very small screen device (7 inch); I use wrap and linebreak, and you can imagine that scrolling (by keyboard and mouse) is a nightmare since if you have a very long line, it can wrap below the visible screen.
I've looked through many posts and none offers a definitive solution other than gj and gk.
To clarify: just try to write a long line that goes below the visible window: ctrl-e or j k will go to the beginning of the next line and you will not see the last characters of the first line.
Is there something that I didn't find? It seems that there are really many persons interested in this, but not a single developer that wants to handle this :-(
thanks
http://vim.1045645.n5.nabble.com/Scrolling-screen-lines-I-knew-it-s-impossible-td3358342.html
gj and gk will scroll within a line, rather than moving to the next line. This might help you out. If it does, you might want to temporarily do:
:nmap j gj
:nmap k gk
the closest I could get is this, no mouse support anyway:
Traversing text in Insert mode
http://vim.wikia.com/wiki/Move_cursor_by_display_lines_when_wrapping
"use up and down to move by screen line
map <Up> gk
map <Down> gj
vmap <Up> gk
vmap <Down> gj
inoremap <Up> <C-o>gk
inoremap <Down> <C-o>gj
" make hjkl movements accessible from insert mode via the <Alt> modifier key
inoremap <A-h> <C-o>h
inoremap <A-j> <C-o>gj
inoremap <A-k> <C-o>gk
inoremap <A-l> <C-o>l
if some lines are too long, it will be forced to be newlined.
for example, normally a long line will looks like this
1 first line
2 this is the long second line of the file
3 third line.
but, if the window of a vim are too narrow, it will looks like this
1 first line
2 this is the long
second line of the file
3 third line
the problem arise from this.
let's assume the vim cursor are located at before 't' in 'third line'. if i type 'k', cursor will move to before 's' in 'second line of the file'. after that, if i type 'k' again, cursor will move to 'f' in 'first line'!, not 't' in 'this is the long'. what i want is that the cursor move to 't' in 'this is the long', it is more intuitive process for me. how can set my vim to works like this?
In Vim, the gj and gk commands move by line on the screen rather than by line in the file. This sounds like it probably matches your description.
You can modify your keys like this:
:map j gj
:map k gk
No, if some lines are too long and you have set wrap on they will be shown on "two lines", so to say, but there won't be a newline character between them. If you turn off wrap with set nowrap you'll see the effect.
Normally, k and j move you up and down. If you want to navigate wrapped lines use gk or gj, or just as some like it, map it to for example, the cursor keys.
nmap <up> gk
nmap <down> gj
To move in vim in a natural way is possible.
What I did was, and I suggest you, to modify (or create) your "~/.vimrc" and add these two lines:
map <C-Up> g<Up>
map <C-Down> g<Down>
This will map you control-up and control-down to the movements commands (this is coherent with control-right and control-left to move around long lines)
If you add these other two lines, you can use the same command to move in insertmode:
imap <C-Up> <C-[> g<Up> i
imap <C-Down> <C-[> g<Down> i
(VIM is great !)
Greg Ruo
This answer is derived from #mario-rossi 's answer (Kudo to him), with minor midification.
I use the normal UP and DOWN arrow key, rather than CTRL+up and CTRL+down. And somehow I need to remove one excess space in the INSERT mode mapping to avoid an off-by-one behavior.
Put the following into your ~/.vimrc:
" When a long line is wrapped, the "gk" and "gj" allow you to move up and down
" a visual line, while normal "k" and "j" move a physical line.
" The following settings map "gk" and "gj" to cursor <up> and <down>.
map <up> gk
map <down> gj
" And the following lines enables same <up> and <down> behavior in INSERT mode
imap <up> <C-[> <up>i
imap <down> <C-[> <down>i
Took this from vim.fandom.com:
There are several cases to remap up and down movements. First, you probably should remap both k/j and / arrows. Second, you should coose vim modes that requires remap. Basic modes are Normal (nmap), Insert (as after i command, imap) and Select (as after v command, vmap). To remap all three:
nnoremap j gj
nnoremap k gk
vnoremap j gj
vnoremap k gk
nnoremap <Down> gj
nnoremap <Up> gk
vnoremap <Down> gj
vnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
There's also one significant Operator mode (as in dj or, to say, y4k), remapping operator (omap) breaks vim experience/habits dramatically and not recommended.
Personally I prefer to remap Insert mode only, to keep my editorial habits intact.
I really like this vim trick to use the left and right arrows to flip between buffers:
"left/right arrows to switch buffers in normal mode
map <right> :bn<cr>
map <left> :bp<cr>
(Put that in ~/.vimrc)
But sometimes I'm munching on a sandwich or something when scrolling around a file and I really want the arrow keys to work normally.
I think what would make most sense is for the arrow keys to have the above buffer-flipping functionality only if there are actually multiple buffers open.
Is there a way to extend the above to accomplish that?
I'd rather have a completely different mapping because:
cursors are really useful, and not having them because you have a hidden buffer will annoy you a lot
some plugins use <left> and <right> because they are less obfuscated than l and h; those plugins are likely to break with such mappings
Anyway, you can try this:
nnoremap <expr> <right> (len(filter(range(0, bufnr('$')), 'buflisted(v:val)')) > 1 ? ":bn\<cr>" : "\<right>")
nnoremap <expr> <left> (len(filter(range(0, bufnr('$')), 'buflisted(v:val)')) > 1 ? ":bp\<cr>" : "\<left>")
To see documentation on the pieces above:
:h :map-<expr>
:h len()
:h filter()
:h range()
:h bufnr()
:h buflisted()
I use alt-direction to switch between buffers.
nmap <A-Left> :bp<CR>
nmap <A-Right> :bn<CR>
If you modifying hl's defaults, then the arrows would feel more useful. (Like changing whichwrap to allow hl to go past the end of line.)
I do something similar with jk to make them different from my arrows:
" work more logically with wrapped lines
set wrap
set linebreak
noremap j gj
noremap k gk
noremap gj j
noremap gk k
That will wrap long lines and jk will move to what looks like the line below. (If you have one long line, then you'll move to the part of that line below the cursor.) Great for editing prose or long comments.
See also
help showbreak
I map Tab and Shift+Tab to switch buffers when in normal mode (makes sense to my brain and the keys are not doing anything useful otherwise).
Add this to your .vimrc
" Use Tab and Shift-Tab to cycle through buffers
nnoremap <Tab> bnext<CR>
nnoremap <S-Tab> :bprevious<CR>