Refactor: normalize_link_v, creating u#get_selection (Fix #382)
* Less hacky selection handling: nomal command hack -> vimscript code * Some prettifying, antipattern removal
This commit is contained in:
		@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
function! vimwiki#markdown_base#normalize_link() abort
 | 
			
		||||
  " TODO mutualize with base
 | 
			
		||||
  call s:normalize_link_syntax_n()
 | 
			
		||||
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
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user