vimwiki

Personal wiki for vim
git clone https://github.com/vimwiki/vimwiki.git
Log | Files | Refs | README | LICENSE

commit ac38bb2f09f49b287ed8f59e0518b56dceadd6cc
parent edf562fab015c4e2b5322339f0c63f3c23cb0977
Author: Tinmarino <tinmarino@gmail.com>
Date:   Fri, 24 Jul 2020 17:59:54 -0400

Refactor: normalize_link_v, creating u#get_selection (Fix #382)

* Less hacky selection handling: nomal command hack -> vimscript code
* Some prettifying, antipattern removal

Diffstat:
Mautoload/vimwiki/base.vim | 73+++++++++++++++++++++++++++++++++++++++----------------------------------
Mautoload/vimwiki/markdown_base.vim | 54+++---------------------------------------------------
Mautoload/vimwiki/u.vim | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mtest/link_creation.vader | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 184 insertions(+), 93 deletions(-)

diff --git a/autoload/vimwiki/base.vim b/autoload/vimwiki/base.vim @@ -2380,50 +2380,55 @@ endfunction " TODO mutualize most code with syntax_n " Normalize link in visual mode Enter keypress function! s:normalize_link_syntax_v() abort - let sel_save = &selection - let &selection = 'old' - let default_register_save = @" - let registertype_save = getregtype('"') + " Get selection content + let visual_selection = vimwiki#u#get_selection() - try - " Save selected text to register " - normal! gv""y - - " Set substitution - " Replace Url - if vimwiki#base#is_diary_file(expand('%:p')) - let sub = vimwiki#base#normalize_link_in_diary(@") + " Embed link in template + " In case of a diary link, wiki or markdown link + if vimwiki#base#is_diary_file(expand('%:p')) + let link = vimwiki#base#normalize_link_in_diary(visual_selection) + else + " Warning nested syntax discrimination + if vimwiki#vars#get_wikilocal('syntax') ==# 'markdown' + let template = vimwiki#vars#get_syntaxlocal('Weblink1Template') else - let sub = s:safesubstitute(vimwiki#vars#get_global('WikiLinkTemplate1'), - \ '__LinkUrl__', @", '') + let template = vimwiki#vars#get_global('WikiLinkTemplate1') endif - " Replace file extension - let file_extension = vimwiki#vars#get_wikilocal('ext', vimwiki#vars#get_bufferlocal('wiki_nr')) - let sub = s:safesubstitute(sub, '__FileExtension__', file_extension , '') + let link = s:safesubstitute(template, '__LinkUrl__', visual_selection, '') + endif - " Put substitution in register " and change text - let sc = vimwiki#vars#get_wikilocal('links_space_char') - call setreg('"', substitute(substitute(sub, '\n', '', ''), '\s', sc, 'g'), visualmode()) - normal! `>""pgvd - finally - call setreg('"', default_register_save, registertype_save) - let &selection = sel_save - endtry + " Transform link: + " Replace description (used for markdown) + let link = s:safesubstitute(link, '__LinkDescription__', visual_selection, '') + " Replace file extension + let file_extension = vimwiki#vars#get_wikilocal('ext', vimwiki#vars#get_bufferlocal('wiki_nr')) + let link = s:safesubstitute(link, '__FileExtension__', file_extension , '') + " Replace space characters + let sc = vimwiki#vars#get_wikilocal('links_space_char') + let link = substitute(link, '\s', sc, 'g') + " Remove newlines + let link = substitute(link, '\n', '', '') + + " Paste result + call vimwiki#u#get_selection(link) endfunction " Normalize link function! vimwiki#base#normalize_link(is_visual_mode) abort - if exists('*vimwiki#'.vimwiki#vars#get_wikilocal('syntax').'_base#normalize_link') - " Syntax-specific links - call vimwiki#{vimwiki#vars#get_wikilocal('syntax')}_base#normalize_link(a:is_visual_mode) + " Switch implementation + " If visual mode + " TODO elseif line("'<") == line("'>") + if a:is_visual_mode + return s:normalize_link_syntax_v() + + " If Syntax-specific normalizer exists: call it + elseif exists('*vimwiki#'.vimwiki#vars#get_wikilocal('syntax').'_base#normalize_link') + return vimwiki#{vimwiki#vars#get_wikilocal('syntax')}_base#normalize_link() + + " Normal mode default else - if !a:is_visual_mode - call s:normalize_link_syntax_n() - elseif line("'<") == line("'>") - " action undefined for multi-line visual mode selections - call s:normalize_link_syntax_v() - endif + return s:normalize_link_syntax_n() endif endfunction diff --git a/autoload/vimwiki/markdown_base.vim b/autoload/vimwiki/markdown_base.vim @@ -111,55 +111,7 @@ function! s:normalize_link_syntax_n() abort endfunction -function! s:normalize_link_syntax_v() abort - let lnum = line('.') - let sel_save = &selection - let &selection = 'old' - let rv = @" - let rt = getregtype('"') - let done = 0 - - try - norm! gvy - let visual_selection = @" - - if vimwiki#base#is_diary_file(expand('%:p')) - let link = vimwiki#base#normalize_link_in_diary(visual_selection) - else - let link = s:safesubstitute(vimwiki#vars#get_syntaxlocal('Weblink1Template'), - \ '__LinkUrl__', visual_selection, '') - endif - - " Replace spaces with new character if option is set - let link = substitute(link, '\s', vimwiki#vars#get_wikilocal('links_space_char'), 'g') - - " Replace description - let link = s:safesubstitute(link, '__LinkDescription__', visual_selection, '') - - " Replace file extension - let file_extension = vimwiki#vars#get_wikilocal('ext', vimwiki#vars#get_bufferlocal('wiki_nr')) - let link = s:safesubstitute(link, '__FileExtension__', file_extension , '') - - call setreg('"', substitute(link, '\n', '', ''), visualmode()) - - " paste result - norm! `>""pgvd - - finally - call setreg('"', rv, rt) - let &selection = sel_save - endtry - -endfunction - - -function! vimwiki#markdown_base#normalize_link(is_visual_mode) abort - - if !a:is_visual_mode - call s:normalize_link_syntax_n() - elseif line("'<") == line("'>") - " action undefined for multi-line visual mode selections - call s:normalize_link_syntax_v() - endif +function! vimwiki#markdown_base#normalize_link() abort + " TODO mutualize with base + call s:normalize_link_syntax_n() endfunction - diff --git a/autoload/vimwiki/u.vim b/autoload/vimwiki/u.vim @@ -4,6 +4,55 @@ " Home: https://github.com/vimwiki/vimwiki/ +" Get visual selection text content, optionaly replace its content +" :param: Text to replace selection +function! vimwiki#u#get_selection(...) abort + " Copyed from DarkWiiPlayer at stackoverflow + " https://stackoverflow.com/a/47051271/2544873 + " Get selection extremity position, + " Discriminate selection mode + if mode() ==? 'v' + let [line_start, column_start] = getpos('v')[1:2] + let [line_end, column_end] = getpos('.')[1:2] + else + let [line_start, column_start] = getpos("'<")[1:2] + let [line_end, column_end] = getpos("'>")[1:2] + end + + " Guard + if (line2byte(line_start)+column_start) > (line2byte(line_end)+column_end) + let [line_start, column_start, line_end, column_end] = + \ [line_end, column_end, line_start, column_start] + end + let lines = getline(line_start, line_end) + if len(lines) == 0 + return '' + endif + + " If want to modify selection + if a:0 > 0 + " Grab new content + let line_link = a:1 + + " Grab the content of line around the link: pre and post + let start_link = max([column_start - 2, 0]) + let line_pre = '' + if start_link > 0 + let line_pre .= lines[0][ : start_link] + endif + let line_post = lines[0][column_end - (&selection ==# 'inclusive' ? 0 : 1) : ] + + " Set the only single selected line + call setline(line_start, line_pre . line_link . line_post) + endif + + " Get selection extremity position, take into account selection option + let lines[-1] = lines[-1][: column_end - (&selection ==# 'inclusive' ? 1 : 2)] + let lines[0] = lines[0][column_start - 1:] + return join(lines, "\n") +endfunction + + " Execute: string v:count times function! vimwiki#u#count_exe(cmd) abort for i in range( max([1, v:count]) ) @@ -12,6 +61,7 @@ function! vimwiki#u#count_exe(cmd) abort endfunction +" Trim spaces: leading and trailing function! vimwiki#u#trim(string, ...) abort let chars = '' if a:0 > 0 @@ -42,11 +92,13 @@ function! vimwiki#u#os_name() abort endfunction +" Check if OS is windows function! vimwiki#u#is_windows() abort return has('win32') || has('win64') || has('win95') || has('win16') endfunction +" Check if OS is mac function! vimwiki#u#is_macos() abort if has('mac') || has('macunix') || has('gui_mac') return 1 @@ -81,15 +133,13 @@ endfunction " Backward compatible version of the built-in function shiftwidth() -if exists('*shiftwidth') - function! vimwiki#u#sw() abort +function! vimwiki#u#sw() abort + if exists('*shiftwidth') return shiftwidth() - endfunc -else - function! vimwiki#u#sw() abort + else return &shiftwidth - endfunc -endif + endif +endfunc " a:mode single character indicating the mode as defined by :h maparg " a:key the key sequence to map @@ -116,7 +166,7 @@ function! vimwiki#u#map_key(mode, key, plug, ...) abort endfunction -" returns 1 if line is a code block or math block +" Returns: 1 if line is a code block or math block " " The last two conditions are needed for this to correctly " detect nested syntaxes within code blocks diff --git a/test/link_creation.vader b/test/link_creation.vader @@ -1,5 +1,89 @@ Include: vader_includes/vader_setup.vader +# Visual Creatin {{{1 +# Issues: #382 +#################### + +Execute (Log): + Log 'Visual Creation' + +# For markdown {{{2 +# ------------------ + +Given vimwiki (abc def ghi jkl): + abc def ghi jkl + +Execute (Set filename wiki_test.md): + Log '>> Visual creation, markdown syntax' + file wiki_test.md + call SetSyntax('markdown') + AssertEqual vimwiki#vars#get_wikilocal('syntax'), 'markdown' + +Do (v3e): + v3e\<Cr> + +Expect (3 Words []()): + [abc def ghi](abc def ghi) jkl + +Do (v3e): + wv2e\<Cr> + +Expect (2 Words []()): + abc [def ghi](def ghi) jkl + +Do (selection=exclusive v3e): + :set selection=exclusive\<Cr> + wv2e\<Cr> + +Expect (2 Words []()): + abc [def ghi](def ghi) jkl + +Do (selection=exclusive wv$): + :set selection=exclusive\<Cr> + wv$\<Cr> + +Expect (3 Words []()): + abc [def ghi jkl](def ghi jkl) + + +# For Wiki {{{2 +# ------------------ + +Given vimwiki (abc def ghi jkl): + abc def ghi jkl + +Execute (Set filename wiki_test.md): + Log '>> Visual creation, wiki syntax' + file wiki_test.wiki + call SetSyntax('default') + +Do (v3e): + v3e\<Cr> + +Expect (3 Words []()): + [[abc def ghi]] jkl + +Do (v3e): + wv2e\<Cr> + +Expect (2 Words []()): + abc [[def ghi]] jkl + +Do (selection=exclusive v3e): + :set selection=exclusive\<Cr> + wv2e\<Cr> + +Expect (2 Words []()): + abc [[def ghi]] jkl + +Do (selection=exclusive wv$): + :set selection=exclusive\<Cr> + wv$\<Cr> + +Expect (3 Words []()): + abc [[def ghi jkl]] + + # Absolute links {{{1 ####################