From e00abb7772d53f118ca8662a0fcca03e2423c25d Mon Sep 17 00:00:00 2001 From: Thomas Buckley-Houston Date: Tue, 25 Jul 2017 16:48:43 +0700 Subject: Better non-wrapped HOME/END. Use system clipboard. --- autoload/novim_mode.vim | 78 ++++++++++++++++++++++++++++++---------------- spec/novim_mode_spec.rb | 82 +++++++++++++++++++++++++++++++++++++++++++------ spec/spec_helper.rb | 31 ++++++++++++++++--- 3 files changed, 150 insertions(+), 41 deletions(-) diff --git a/autoload/novim_mode.vim b/autoload/novim_mode.vim index 90aecc5..f992b3f 100644 --- a/autoload/novim_mode.vim +++ b/autoload/novim_mode.vim @@ -109,18 +109,11 @@ function! g:SetNoVimModeShortcuts() " General fixes to editor behaviour if g:novim_mode_use_editor_fixes == 1 - " All thee `g`s here make these also work for wrapped lines. - " Fix HOME to go back to the first non-whitespace character of the line. - inoremap g^ - " Native End would work anyway but it needs the `g` for wrapped lines - inoremap g$ - - " For selection behaviour - inoremap g^ - snoremap g^ - inoremap g$ - snoremap g$ + inoremap ^ + " The same but for selection behaviour + inoremap ^ + snoremap ^ " Tweaks PageUp behaviour to get cursor to first line on top page inoremap :call novim_mode#PageUp() @@ -155,14 +148,14 @@ function! g:SetNoVimModeShortcuts() " One of those curious features of Vim: without `onemore` when pasting " at the end of a line, pasted text gets put *before* the cursor. set virtualedit=onemore - " NB. All these use the named 'p' register. - inoremap "pP - snoremap "pP - cnoremap "p - snoremap "pygv - inoremap "pY - snoremap "pxi - inoremap "pdd + " NB. All these use the system clipboard. + inoremap "+P + snoremap "+P + cnoremap "+ + snoremap "+ygv + inoremap "+Y + snoremap "+xi + inoremap "+dd " Select word under cursor inoremap viw " Select current line @@ -239,26 +232,57 @@ endfunction " By default Vim treats wrapped text as a single line even though it may " appear as many lines on screen. So here we try to make wrapped text behave -" more conventionally. +" more conventionally. Please add any new types you might come across. function! s:SetWrappedTextNavigation() + autocmd BufNewFile,BufRead *.{ + \md, + \mdown, + \markdown, + \txt, + \textile, + \rdoc, + \org, + \creole, + \mediawiki + \} setlocal filetype=txt + autocmd FileType \ + \rst, + \asciidoc, + \pod, + \txt + \ call s:WrappedTextBehaviour() +endfunction + +function! s:WrappedTextBehaviour() " Allow text to wrap in text files - au BufNewFile,BufRead *.txt,*.md,*.markdown setlocal linebreak spell wrap + setlocal linebreak wrap " Make arrow keys move through wrapped lines " TODO: - " * Scroll window 1 wrapped soft line at a time rather than entire block of wrapped - " lines. - au BufNewFile,BufRead *.txt,*.md,*.markdown inoremap gk - au BufNewFile,BufRead *.txt,*.md,*.markdown inoremap gj + " * Scroll window 1 wrapped soft line at a time rather than entire block + " of wrapped lines -- I'm as good as certain this will need a patch to + " (n)vim's internals. + inoremap gk + inoremap gj + " For selection behaviour + snoremap gk + snoremap gj + " HOME/END for *visible* lines, not literal lines + inoremap g^ + inoremap g$ " For selection behaviour - au BufNewFile,BufRead *.txt,*.md,*.markdown snoremap gk - au BufNewFile,BufRead *.txt,*.md,*.markdown snoremap gj + inoremap g^ + snoremap g^ + inoremap g$ + snoremap g$ endfunction " Try to intuitively and intelligently close things like buffers, splits, " panes, quicklist, etc, basically anything that looks like a pane. function! novim_mode#ClosePane() if s:IsEditableBuffer() == 1 + " TODO: These aren't actually formally associated with a buffer, although + " conceptually they often are (eg; linting errors, file search). " Close any location lists on screen. exe "lclose" " Close any quickfix lists on screen. diff --git a/spec/novim_mode_spec.rb b/spec/novim_mode_spec.rb index a3d603c..965fbb0 100644 --- a/spec/novim_mode_spec.rb +++ b/spec/novim_mode_spec.rb @@ -2,15 +2,6 @@ # of testing Vim. require 'spec_helper' -def initial(string) - @vim_options.each { |x| vim.command(x) } if @vim_options - write_file_content(string) -end - -def final(string) - expect(load_file_content).to eq normalize_string_indent(string) -end - describe 'Basic editing' do specify 'writing simple text' do initial <<-EOF @@ -48,6 +39,18 @@ describe 'Basic editing' do copy me copy me EOF end + + specify 'CTRL+ARROW jumps by word' do + initial <<-EOF + one two three four + EOF + + type 'XYZ' + + final <<-EOF + one Xtwo ZYthree four + EOF + end end describe 'Selecting' do @@ -106,6 +109,66 @@ describe 'Selecting' do !of text EOF end + + specify 'CTRL+D selects the word under the cursor' do + initial <<-EOF + a line of text + EOF + + 4.times { type '' } + type 'X' + + final <<-EOF + a X of text + EOF + end +end + +describe 'Home/End behaviour for long, non-wrapped code lines' do + before(:each) do + # We need a small screen so that lines go off the edge of it. + @vim_options = [ + # A single buffer can't be resized, so create a split of the buffer + 'vsplit', + 'vertical resize 6' + ] + end + + specify 'HOME/END move to start/end of line off-screen' do + initial <<-EOF + line line line line + EOF + + type 'XY' + + final <<-EOF + Yline line line lineX + EOF + end + + specify 'SHIFT+END selects line, even if off-screen' do + initial <<-EOF + line line line line! + EOF + + type 'x' + + final <<-EOF + x! + EOF + end + + specify 'SHIFT+HOME selects line, even if off-screen' do + initial <<-EOF + !line line line line + EOF + + type 'x' + + final <<-EOF + !x + EOF + end end describe 'Wrapped text' do @@ -115,6 +178,7 @@ describe 'Wrapped text' do 'vsplit', 'vertical resize 6' ] + use_extension 'txt' end specify 'move up/down one wrapped line' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5b3e0ea..cfe5a51 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -20,17 +20,24 @@ Vimrunner::RSpec.configure do |config| end end -TEST_FILE = 'test_file.txt'.freeze +RSpec.configure do |config| + config.before :each do + # Default to setting the filetype to shell to enable + # code-like behaviour. + @ext = 'sh' + end +end -def write_file_content(string) +def write_file_content(string, ext = 'sh') + @file = "file.#{ext}" string = normalize_string_indent(string) - File.open(TEST_FILE, 'w') { |f| f.write(string) } - vim.edit TEST_FILE + File.open(@file, 'w') { |f| f.write(string) } + vim.edit @file end def load_file_content vim.write - IO.read(TEST_FILE).strip + IO.read(@file).strip end def type(string) @@ -42,3 +49,17 @@ def type(string) end end end + +def initial(string) + @vim_options.each { |x| vim.command(x) } if @vim_options + write_file_content(string, @ext) +end + +def final(string) + expected = normalize_string_indent(string) + expect(load_file_content).to eq expected +end + +def use_extension(ext) + @ext = ext +end -- cgit v1.2.3-70-g09d2