keyify.vim 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. function! go#keyify#Keyify()
  2. let bin_path = go#path#CheckBinPath("keyify")
  3. let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
  4. if empty(bin_path) || !exists('*json_decode')
  5. return
  6. endif
  7. " Get result of command as json, that contains `start`, `end` and `replacement`
  8. let command = printf("%s -json %s:#%s", go#util#Shellescape(bin_path),
  9. \ go#util#Shellescape(fname), go#util#OffsetCursor())
  10. let output = go#util#System(command)
  11. silent! let result = json_decode(output)
  12. " We want to output the error message in case the result isn't a JSON
  13. if type(result) != type({})
  14. call go#util#EchoError(s:chomp(output))
  15. return
  16. endif
  17. " Because keyify returns the byte before the region we want, we goto the
  18. " byte after that
  19. execute "goto" result.start + 1
  20. let start = getpos('.')
  21. execute "goto" result.end
  22. let end = getpos('.')
  23. let vis_start = getpos("'<")
  24. let vis_end = getpos("'>")
  25. " Replace contents between start and end with `replacement`
  26. call setpos("'<", start)
  27. call setpos("'>", end)
  28. let select = 'gv'
  29. " Make sure the visual mode is 'v', to avoid some bugs
  30. normal! gv
  31. if mode() !=# 'v'
  32. let select .= 'v'
  33. endif
  34. silent! execute "normal!" select."\"=result.replacement\<cr>p"
  35. " Replacement text isn't aligned, so it needs fix
  36. normal! '<v'>=
  37. call setpos("'<", vis_start)
  38. call setpos("'>", vis_end)
  39. endfunction
  40. function! s:chomp(string)
  41. return substitute(a:string, '\n\+$', '', '')
  42. endfunction
  43. " vim: sw=2 ts=2 et