easy_align.vim 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. " Copyright (c) 2014 Junegunn Choi
  2. "
  3. " MIT License
  4. "
  5. " Permission is hereby granted, free of charge, to any person obtaining
  6. " a copy of this software and associated documentation files (the
  7. " "Software"), to deal in the Software without restriction, including
  8. " without limitation the rights to use, copy, modify, merge, publish,
  9. " distribute, sublicense, and/or sell copies of the Software, and to
  10. " permit persons to whom the Software is furnished to do so, subject to
  11. " the following conditions:
  12. "
  13. " The above copyright notice and this permission notice shall be
  14. " included in all copies or substantial portions of the Software.
  15. "
  16. " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. " NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  20. " LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  21. " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22. " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. if exists("g:loaded_easy_align_plugin")
  24. finish
  25. endif
  26. let g:loaded_easy_align_plugin = 1
  27. command! -nargs=* -range -bang EasyAlign <line1>,<line2>call easy_align#align(<bang>0, 0, 'command', <q-args>)
  28. command! -nargs=* -range -bang LiveEasyAlign <line1>,<line2>call easy_align#align(<bang>0, 1, 'command', <q-args>)
  29. let s:last_command = 'EasyAlign'
  30. function! s:abs(v)
  31. return a:v >= 0 ? a:v : - a:v
  32. endfunction
  33. function! s:remember_visual(mode)
  34. let s:last_visual = [a:mode, s:abs(line("'>") - line("'<")), s:abs(col("'>") - col("'<"))]
  35. endfunction
  36. function! s:repeat_visual()
  37. let [mode, ldiff, cdiff] = s:last_visual
  38. let cmd = 'normal! '.mode
  39. if ldiff > 0
  40. let cmd .= ldiff . 'j'
  41. endif
  42. let ve_save = &virtualedit
  43. try
  44. if mode == "\<C-V>"
  45. if cdiff > 0
  46. let cmd .= cdiff . 'l'
  47. endif
  48. set virtualedit+=block
  49. endif
  50. execute cmd.":\<C-r>=g:easy_align_last_command\<Enter>\<Enter>"
  51. call s:set_repeat()
  52. finally
  53. if ve_save != &virtualedit
  54. let &virtualedit = ve_save
  55. endif
  56. endtry
  57. endfunction
  58. function! s:repeat_in_visual()
  59. if exists('g:easy_align_last_command')
  60. call s:remember_visual(visualmode())
  61. call s:repeat_visual()
  62. endif
  63. endfunction
  64. function! s:set_repeat()
  65. silent! call repeat#set("\<Plug>(EasyAlignRepeat)")
  66. endfunction
  67. function! s:generic_easy_align_op(type, vmode, live)
  68. if !&modifiable
  69. if a:vmode
  70. normal! gv
  71. endif
  72. return
  73. endif
  74. let sel_save = &selection
  75. let &selection = "inclusive"
  76. if a:vmode
  77. let vmode = a:type
  78. let [l1, l2] = ["'<", "'>"]
  79. call s:remember_visual(vmode)
  80. else
  81. let vmode = ''
  82. let [l1, l2] = [line("'["), line("']")]
  83. unlet! s:last_visual
  84. endif
  85. try
  86. let range = l1.','.l2
  87. if get(g:, 'easy_align_need_repeat', 0)
  88. execute range . g:easy_align_last_command
  89. else
  90. execute range . "call easy_align#align(0, a:live, vmode, '')"
  91. end
  92. call s:set_repeat()
  93. finally
  94. let &selection = sel_save
  95. endtry
  96. endfunction
  97. function! s:easy_align_op(type, ...)
  98. call s:generic_easy_align_op(a:type, a:0, 0)
  99. endfunction
  100. function! s:live_easy_align_op(type, ...)
  101. call s:generic_easy_align_op(a:type, a:0, 1)
  102. endfunction
  103. function! s:easy_align_repeat()
  104. if exists('s:last_visual')
  105. call s:repeat_visual()
  106. else
  107. try
  108. let g:easy_align_need_repeat = 1
  109. normal! .
  110. finally
  111. unlet! g:easy_align_need_repeat
  112. endtry
  113. endif
  114. endfunction
  115. nnoremap <silent> <Plug>(EasyAlign) :set opfunc=<SID>easy_align_op<Enter>g@
  116. vnoremap <silent> <Plug>(EasyAlign) :<C-U>call <SID>easy_align_op(visualmode(), 1)<Enter>
  117. nnoremap <silent> <Plug>(LiveEasyAlign) :set opfunc=<SID>live_easy_align_op<Enter>g@
  118. vnoremap <silent> <Plug>(LiveEasyAlign) :<C-U>call <SID>live_easy_align_op(visualmode(), 1)<Enter>
  119. " vim-repeat support
  120. nnoremap <silent> <Plug>(EasyAlignRepeat) :call <SID>easy_align_repeat()<Enter>
  121. vnoremap <silent> <Plug>(EasyAlignRepeat) :<C-U>call <SID>repeat_in_visual()<Enter>
  122. " Backward-compatibility (deprecated)
  123. nnoremap <silent> <Plug>(EasyAlignOperator) :set opfunc=<SID>easy_align_op<Enter>g@
  124. " vim: set et sw=2 :