From b0ce83d7b23d206ccd0475c5c88a1c4652203d19 Mon Sep 17 00:00:00 2001 From: Hugo Musso Gualandi Date: Mon, 22 Jun 2020 00:11:02 -0300 Subject: [PATCH 1/4] Use v:count1 instead of (v:count ? v:count : 1) It is a more succinct way to specify that the count defaults to 1. --- plugin/move.vim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugin/move.vim b/plugin/move.vim index b09e8df..110ae94 100644 --- a/plugin/move.vim +++ b/plugin/move.vim @@ -50,7 +50,7 @@ function! s:MoveBlockDown(start, end, nlines) return endif - let l:distance = a:nlines * (v:count ? v:count : 1) + let l:distance = a:nlines * v:count1 let l:next_line = a:end + l:distance if l:next_line > line('$') @@ -71,7 +71,7 @@ function! s:MoveBlockUp(start, end, nlines) return endif - let l:distance = a:nlines * (v:count ? v:count : 1) + let l:distance = a:nlines * v:count1 let l:prev_line = a:start - l:distance - 1 if l:prev_line < 0 @@ -89,7 +89,7 @@ endfunction function! s:MoveBlockLeft() range let l:min_col = min([virtcol("'<"), virtcol("'>")]) - let l:distance = min([l:min_col - 1, v:count ? v:count : 1]) + let l:distance = min([l:min_col - 1, v:count1]) if !&modifiable || virtcol("$") == 1 || l:distance <= 0 || visualmode() ==# "V" normal! gv @@ -128,7 +128,7 @@ endfunction function! s:MoveBlockRight() range let l:max_col = max([virtcol("'<"), virtcol("'>")]) - let l:distance = v:count ? v:count : 1 + let l:distance = v:count1 if !g:move_past_end_of_line let l:shorter_line_len = min(map(getline(a:firstline, a:lastline), 'strwidth(v:val)')) @@ -187,7 +187,7 @@ function! s:MoveLineUp(nlines) range return endif - let l:distance = a:nlines * (v:count ? v:count : 1) + let l:distance = a:nlines * v:count1 let l:relative_cursor_col = s:GetRelativeCursorVirtCol() if (line('.') - l:distance) < 0 @@ -213,7 +213,7 @@ function! s:MoveLineDown(nlines) range return endif - let l:distance = a:nlines * (v:count ? v:count : 1) + let l:distance = a:nlines * v:count1 let l:relative_cursor_col = s:GetRelativeCursorVirtCol() if (line('.') + l:distance) > line('$') @@ -240,7 +240,7 @@ function! s:MoveCharLeft() return endif - let l:distance = v:count ? v:count : 1 + let l:distance = v:count1 call s:SaveDefaultRegister() @@ -260,7 +260,7 @@ function! s:MoveCharRight() return endif - let l:distance = v:count ? v:count : 1 + let l:distance = v:count1 call s:SaveDefaultRegister() if !g:move_past_end_of_line && (virtcol('.') + l:distance >= virtcol('$') - 1) From a375b69e358b3129da9e93c5d612e87eaf611998 Mon Sep 17 00:00:00 2001 From: Hugo Musso Gualandi Date: Mon, 22 Jun 2020 00:19:36 -0300 Subject: [PATCH 2/4] Read v:count before we call our functions. Instead of having our functions read v:count, have them receive it as a parameter. This will help us to avoid repeating the mistake from #42 in the future. --- plugin/move.vim | 95 +++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/plugin/move.vim b/plugin/move.vim index 110ae94..72f54dc 100644 --- a/plugin/move.vim +++ b/plugin/move.vim @@ -45,13 +45,12 @@ function! s:GetRelativeCursorVirtCol() return l:cursor_col - virtcol('.') + 1 endfunction -function! s:MoveBlockDown(start, end, nlines) +function! s:MoveBlockDown(start, end, distance) if !&modifiable return endif - let l:distance = a:nlines * v:count1 - let l:next_line = a:end + l:distance + let l:next_line = a:end + a:distance if l:next_line > line('$') call s:ResetCursor() @@ -66,13 +65,12 @@ function! s:MoveBlockDown(start, end, nlines) endif endfunction -function! s:MoveBlockUp(start, end, nlines) +function! s:MoveBlockUp(start, end, distance) if !&modifiable return endif - let l:distance = a:nlines * v:count1 - let l:prev_line = a:start - l:distance - 1 + let l:prev_line = a:start - a:distance - 1 if l:prev_line < 0 call s:ResetCursor() @@ -87,9 +85,9 @@ function! s:MoveBlockUp(start, end, nlines) endif endfunction -function! s:MoveBlockLeft() range +function! s:MoveBlockLeft(distance) range let l:min_col = min([virtcol("'<"), virtcol("'>")]) - let l:distance = min([l:min_col - 1, v:count1]) + let l:distance = min([a:distance, l:min_col - 1]) if !&modifiable || virtcol("$") == 1 || l:distance <= 0 || visualmode() ==# "V" normal! gv @@ -126,10 +124,10 @@ function! s:MoveBlockLeft() range let &virtualedit = l:old_virtualedit endfunction -function! s:MoveBlockRight() range +function! s:MoveBlockRight(distance) range let l:max_col = max([virtcol("'<"), virtcol("'>")]) - let l:distance = v:count1 + let l:distance = a:distance if !g:move_past_end_of_line let l:shorter_line_len = min(map(getline(a:firstline, a:lastline), 'strwidth(v:val)')) let l:distance = min([l:shorter_line_len - l:max_col, l:distance]) @@ -182,15 +180,14 @@ function! s:MoveBlockRight() range let &virtualedit = l:old_virtualedit endfunction -function! s:MoveLineUp(nlines) range +function! s:MoveLineUp(distance) range if !&modifiable || line('.') == 1 return endif - let l:distance = a:nlines * v:count1 let l:relative_cursor_col = s:GetRelativeCursorVirtCol() - if (line('.') - l:distance) < 0 + if (line('.') - a:distance) < 0 execute 'silent move 0' if (g:move_auto_indent == 1) normal! == @@ -198,7 +195,7 @@ function! s:MoveLineUp(nlines) range return endif - execute 'silent m-' . (l:distance + 1) + execute 'silent m-' . (a:distance + 1) if (g:move_auto_indent == 1) normal! == @@ -208,15 +205,14 @@ function! s:MoveLineUp(nlines) range execute 'silent normal!' . max([1, (virtcol('.') + l:relative_cursor_col - 1)]) . '|' endfunction -function! s:MoveLineDown(nlines) range +function! s:MoveLineDown(distance) range if !&modifiable || line('.') == line('$') return endif - let l:distance = a:nlines * v:count1 let l:relative_cursor_col = s:GetRelativeCursorVirtCol() - if (line('.') + l:distance) > line('$') + if (line('.') + a:distance) > line('$') silent move $ if (g:move_auto_indent == 1) normal! == @@ -224,7 +220,7 @@ function! s:MoveLineDown(nlines) range return endif - execute 'silent m+' . l:distance + execute 'silent m+' . a:distance if (g:move_auto_indent == 1) normal! == endif @@ -235,70 +231,67 @@ endfunction " Using range here fucks the col() function (because col() always returns 1 in " range functions), so use normal function and clear the range with later -function! s:MoveCharLeft() +function! s:MoveCharLeft(distance) if !&modifiable || virtcol("$") == 1 || virtcol(".") == 1 return endif - let l:distance = v:count1 - call s:SaveDefaultRegister() - if (virtcol('.') - l:distance <= 0) + if (virtcol('.') - a:distance <= 0) silent normal! x0P else let [l:old_virtualedit, &virtualedit] = [&virtualedit, 'onemore'] - execute 'silent normal! x' . l:distance . 'hP' + execute 'silent normal! x' . a:distance . 'hP' let &virtualedit = l:old_virtualedit endif call s:RestoreDefaultRegister() endfunction -function! s:MoveCharRight() +function! s:MoveCharRight(distance) if !&modifiable || virtcol("$") == 1 return endif - let l:distance = v:count1 call s:SaveDefaultRegister() - if !g:move_past_end_of_line && (virtcol('.') + l:distance >= virtcol('$') - 1) + if !g:move_past_end_of_line && (virtcol('.') + a:distance >= virtcol('$') - 1) silent normal! x$p else let [l:old_virtualedit, &virtualedit] = [&virtualedit, 'all'] - execute 'silent normal! x' . l:distance . 'lP' + execute 'silent normal! x' . a:distance . 'lP' let &virtualedit = l:old_virtualedit endif call s:RestoreDefaultRegister() endfunction -function! s:MoveBlockOneLineUp() range - call s:MoveBlockUp(a:firstline, a:lastline, 1) +function! s:MoveBlockOneLineUp(count) range + call s:MoveBlockUp(a:firstline, a:lastline, a:count) endfunction -function! s:MoveBlockOneLineDown() range - call s:MoveBlockDown(a:firstline, a:lastline, 1) +function! s:MoveBlockOneLineDown(count) range + call s:MoveBlockDown(a:firstline, a:lastline, a:count) endfunction -function! s:MoveBlockHalfPageUp() range - let l:distance = winheight('.') / 2 +function! s:MoveBlockHalfPageUp(count) range + let l:distance = a:count * (winheight('.') / 2) call s:MoveBlockUp(a:firstline, a:lastline, l:distance) endfunction -function! s:MoveBlockHalfPageDown() range - let l:distance = winheight('.') / 2 +function! s:MoveBlockHalfPageDown(count) range + let l:distance = a:count * (winheight('.') / 2) call s:MoveBlockDown(a:firstline, a:lastline, l:distance) endfunction -function! s:MoveLineHalfPageUp() range - let l:distance = winheight('.') / 2 +function! s:MoveLineHalfPageUp(count) range + let l:distance = a:count * (winheight('.') / 2) call s:MoveLineUp(l:distance) endfunction -function! s:MoveLineHalfPageDown() range - let l:distance = winheight('.') / 2 +function! s:MoveLineHalfPageDown(count) range + let l:distance = a:count * (winheight('.') / 2) call s:MoveLineDown(l:distance) endfunction @@ -307,19 +300,19 @@ function! s:MoveKey(key) endfunction -vnoremap MoveBlockDown :call MoveBlockOneLineDown() -vnoremap MoveBlockUp :call MoveBlockOneLineUp() -vnoremap MoveBlockHalfPageDown :call MoveBlockHalfPageDown() -vnoremap MoveBlockHalfPageUp :call MoveBlockHalfPageUp() -vnoremap MoveBlockLeft :call MoveBlockLeft() -vnoremap MoveBlockRight :call MoveBlockRight() +vnoremap MoveBlockDown :call MoveBlockOneLineDown(v:count1) +vnoremap MoveBlockUp :call MoveBlockOneLineUp(v:count1) +vnoremap MoveBlockHalfPageDown :call MoveBlockHalfPageDown(v:count1) +vnoremap MoveBlockHalfPageUp :call MoveBlockHalfPageUp(v:count1) +vnoremap MoveBlockLeft :call MoveBlockLeft(v:count1) +vnoremap MoveBlockRight :call MoveBlockRight(v:count1) -nnoremap MoveLineDown :call MoveLineDown(1) -nnoremap MoveLineUp :call MoveLineUp(1) -nnoremap MoveLineHalfPageDown :call MoveLineHalfPageDown() -nnoremap MoveLineHalfPageUp :call MoveLineHalfPageUp() -nnoremap MoveCharLeft :call MoveCharLeft() -nnoremap MoveCharRight :call MoveCharRight() +nnoremap MoveLineDown :call MoveLineDown(v:count1) +nnoremap MoveLineUp :call MoveLineUp(v:count1) +nnoremap MoveLineHalfPageDown :call MoveLineHalfPageDown(v:count1) +nnoremap MoveLineHalfPageUp :call MoveLineHalfPageUp(v:count1) +nnoremap MoveCharLeft :call MoveCharLeft(v:count1) +nnoremap MoveCharRight :call MoveCharRight(v:count1) if g:move_map_keys From a3a0e7b97bbba2c068aa903b3c58bcb996ee0adc Mon Sep 17 00:00:00 2001 From: Hugo Musso Gualandi Date: Mon, 22 Jun 2020 00:27:26 -0300 Subject: [PATCH 3/4] Large vertical block moves now move until the edge If we vertically move a block using a large step when we are close to the start or the end of the file, move as much as possible (that is, until the first or the last line). This should make the behavior of block moves work the same as line moves. Previously, a block move that attempted to move out of bounds would not move at all. --- plugin/move.vim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/move.vim b/plugin/move.vim index 72f54dc..7983cc8 100644 --- a/plugin/move.vim +++ b/plugin/move.vim @@ -50,7 +50,7 @@ function! s:MoveBlockDown(start, end, distance) return endif - let l:next_line = a:end + a:distance + let l:next_line = min([a:end + a:distance, line('$')]) if l:next_line > line('$') call s:ResetCursor() @@ -70,14 +70,14 @@ function! s:MoveBlockUp(start, end, distance) return endif - let l:prev_line = a:start - a:distance - 1 + let l:prev_line = max([a:start - a:distance, 1]) if l:prev_line < 0 call s:ResetCursor() return endif - execute 'silent' a:start ',' a:end 'move ' l:prev_line + execute 'silent' a:start ',' a:end 'move ' (l:prev_line - 1) if (g:move_auto_indent == 1) call s:ResetCursor() else From 17a2d98c896a412571181d880b5ed4ce1aefd57b Mon Sep 17 00:00:00 2001 From: Hugo Musso Gualandi Date: Mon, 22 Jun 2020 00:58:40 -0300 Subject: [PATCH 4/4] Don't use range functions for vertical line moves Previously, if we attempted to make a large line move that would put the line out of bounds it would usually give error E16 (Invalid Address). It would only work if out out of bounds destination was only a single line out before/after the start/end of the file. Now, moving a line vertically by a large step does not produce an error. If the step is too large then the movement is clipped to the start or end of the file. --- plugin/move.vim | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/plugin/move.vim b/plugin/move.vim index 7983cc8..5089562 100644 --- a/plugin/move.vim +++ b/plugin/move.vim @@ -180,7 +180,7 @@ function! s:MoveBlockRight(distance) range let &virtualedit = l:old_virtualedit endfunction -function! s:MoveLineUp(distance) range +function! s:MoveLineUp(distance) if !&modifiable || line('.') == 1 return endif @@ -205,7 +205,7 @@ function! s:MoveLineUp(distance) range execute 'silent normal!' . max([1, (virtcol('.') + l:relative_cursor_col - 1)]) . '|' endfunction -function! s:MoveLineDown(distance) range +function! s:MoveLineDown(distance) if !&modifiable || line('.') == line('$') return endif @@ -229,8 +229,6 @@ function! s:MoveLineDown(distance) range execute 'silent normal!' . max([1, (virtcol('.') + l:relative_cursor_col - 1)]) . '|' endfunction -" Using range here fucks the col() function (because col() always returns 1 in -" range functions), so use normal function and clear the range with later function! s:MoveCharLeft(distance) if !&modifiable || virtcol("$") == 1 || virtcol(".") == 1 return @@ -285,12 +283,12 @@ function! s:MoveBlockHalfPageDown(count) range call s:MoveBlockDown(a:firstline, a:lastline, l:distance) endfunction -function! s:MoveLineHalfPageUp(count) range +function! s:MoveLineHalfPageUp(count) let l:distance = a:count * (winheight('.') / 2) call s:MoveLineUp(l:distance) endfunction -function! s:MoveLineHalfPageDown(count) range +function! s:MoveLineHalfPageDown(count) let l:distance = a:count * (winheight('.') / 2) call s:MoveLineDown(l:distance) endfunction @@ -307,12 +305,16 @@ vnoremap MoveBlockHalfPageUp :call MoveBlockHalfPageUp(v vnoremap MoveBlockLeft :call MoveBlockLeft(v:count1) vnoremap MoveBlockRight :call MoveBlockRight(v:count1) -nnoremap MoveLineDown :call MoveLineDown(v:count1) -nnoremap MoveLineUp :call MoveLineUp(v:count1) -nnoremap MoveLineHalfPageDown :call MoveLineHalfPageDown(v:count1) -nnoremap MoveLineHalfPageUp :call MoveLineHalfPageUp(v:count1) -nnoremap MoveCharLeft :call MoveCharLeft(v:count1) -nnoremap MoveCharRight :call MoveCharRight(v:count1) +" We can't use functions defined with the 'range' attribute for moving lines +" or characters. In the case of lines, it causes vim to complain with E16 +" (Invalid adress) if we try to move out of bounds. In the case of characters, +" it messes up the result of calling col(). +nnoremap MoveLineDown : call MoveLineDown(v:count1) +nnoremap MoveLineUp : call MoveLineUp(v:count1) +nnoremap MoveLineHalfPageDown : call MoveLineHalfPageDown(v:count1) +nnoremap MoveLineHalfPageUp : call MoveLineHalfPageUp(v:count1) +nnoremap MoveCharLeft : call MoveCharLeft(v:count1) +nnoremap MoveCharRight : call MoveCharRight(v:count1) if g:move_map_keys