styles.vim 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. " vim: set fdm=marker et ts=4 sw=4 sts=4:
  2. function! pandoc#keyboard#styles#Init() abort "{{{1
  3. for style in ['emphasis', 'strong', 'verbatim', 'strikeout', 'superscript', 'subscript']
  4. let u_style = substitute(style, '\<.', '\u&', '') " capitalize first char: emphasis -> Emphasis
  5. exe 'noremap <buffer> <silent> <Plug>(pandoc-keyboard-toggle-'.style.') :set opfunc=pandoc#keyboard#styles#Toggle'.u_style.'<cr>g@'
  6. exe 'vnoremap <buffer> <silent> <Plug>(pandoc-keyboard-toggle-'.style.') :<C-U>call pandoc#keyboard#styles#Toggle'.u_style.'(visualmode())<CR>'
  7. exe 'vnoremap <buffer> <silent> <Plug>(pandoc-keyboard-select-'.style.'-inclusive) :<C-U>call pandoc#keyboard#styles#Select'.u_style.'("inclusive")<cr>'
  8. exe 'vnoremap <buffer> <silent> <Plug>(pandoc-keyboard-select-'.style.'-exclusive) :<C-U>call pandoc#keyboard#styles#Select'.u_style.'("exclusive")<cr>'
  9. endfor
  10. if g:pandoc#keyboard#use_default_mappings == 1 && index(g:pandoc#keyboard#blacklist_submodule_mappings, 'styles') == -1
  11. nmap <buffer> <localleader>i <Plug>(pandoc-keyboard-toggle-emphasis)
  12. vmap <buffer> <localleader>i <Plug>(pandoc-keyboard-toggle-emphasis)
  13. nmap <buffer> <localleader>b <Plug>(pandoc-keyboard-toggle-strong)
  14. vmap <buffer> <localleader>b <Plug>(pandoc-keyboard-toggle-strong)
  15. nmap <buffer> <localleader>' <Plug>(pandoc-keyboard-toggle-verbatim)
  16. vmap <buffer> <localleader>' <Plug>(pandoc-keyboard-toggle-verbatim)
  17. nmap <buffer> <localleader>~~ <Plug>(pandoc-keyboard-toggle-strikeout)
  18. vmap <buffer> <localleader>~~ <Plug>(pandoc-keyboard-toggle-strikeout)
  19. nmap <buffer> <localleader>^ <Plug>(pandoc-keyboard-toggle-superscript)
  20. vmap <buffer> <localleader>^ <Plug>(pandoc-keyboard-toggle-superscript)
  21. nmap <buffer> <localleader>_ <Plug>(pandoc-keyboard-toggle-subscript)
  22. vmap <buffer> <localleader>_ <Plug>(pandoc-keyboard-toggle-subscript)
  23. vmap <buffer> <silent> aPe <Plug>(pandoc-keyboard-select-emphasis-inclusive)
  24. vmap <buffer> <silent> iPe <Plug>(pandoc-keyboard-select-emphasis-exclusive)
  25. omap <buffer> aPe :normal vaPe<cr>
  26. omap <buffer> iPe :normal viPe<cr>
  27. vmap <buffer> <silent> aPs <Plug>(pandoc-keyboard-select-strong-inclusive)
  28. vmap <buffer> <silent> iPs <Plug>(pandoc-keyboard-select-strong-exclusive)
  29. omap <buffer> aPs :normal vaPs<cr>
  30. omap <buffer> iPs :normal viPs<cr>
  31. vmap <buffer> <silent> aPv <Plug>(pandoc-keyboard-select-verbatim-inclusive)
  32. vmap <buffer> <silent> iPv <Plug>(pandoc-keyboard-select-verbatim-exclusive)
  33. omap <buffer> aPv :normal vaPv<cr>
  34. omap <buffer> iPv :normal viPv<cr>
  35. vmap <buffer> <silent> aPk <Plug>(pandoc-keyboard-select-strikeout-inclusive)
  36. vmap <buffer> <silent> iPk <Plug>(pandoc-keyboard-select-strikeout-exclusive)
  37. omap <buffer> aPk :normal vaPk<cr>
  38. omap <buffer> iPk :normal viPk<cr>
  39. vmap <buffer> <silent> aPu <Plug>(pandoc-keyboard-select-superscript-inclusive)
  40. vmap <buffer> <silent> iPu <Plug>(pandoc-keyboard-select-superscript-exclusive)
  41. omap <buffer> aPu :normal vaPu<cr>
  42. omap <buffer> iPu :normal viPu<cr>
  43. vmap <buffer> <silent> aPt <Plug>(pandoc-keyboard-select-subscript-inclusive)
  44. vmap <buffer> <silent> iPt <Plug>(pandoc-keyboard-select-subscript-exclusive)
  45. omap <buffer> aPt :normal vaPl<cr>
  46. omap <buffer> iPt :normal viPl<cr>
  47. endif
  48. endfunction
  49. " Functions: {{{1
  50. " Auxiliary: {{{2
  51. function! s:EscapeEnds(ends) abort
  52. return escape(a:ends, '*^~')
  53. endfunction
  54. function! s:IsCursorAtEndofNonEmptyLine() abort
  55. return (col('.')+1) == col('$') && col('.') != 1
  56. endfunction
  57. " Base: {{{2
  58. " Toggle Operators, WYSIWYG-style {{{3
  59. function! pandoc#keyboard#styles#ToggleOperator(type, ends) abort
  60. let sel_save = &selection
  61. let &selection = 'old'
  62. let reg = 'p'
  63. let reg_save = getreg(reg)
  64. if a:type ==# 'v'
  65. execute 'normal! `<'.a:type.'`>'.'"'.reg.'x'
  66. elseif a:type ==# 'char'
  67. let cline = getline('.')
  68. let ccol = getpos('.')[2]
  69. let nchar = cline[ccol]
  70. let pchar = cline[ccol-2]
  71. if cline[ccol] ==# ''
  72. " at end
  73. execute 'normal! `[Bv`]BE'.'"'.reg.'x'
  74. elseif match(pchar, '[[:blank:]]') > -1
  75. if match(nchar, '[[:blank:]]') > -1
  76. " single char
  77. execute 'normal! `[v`]ege'.'"'.reg.'x'
  78. else
  79. " after space
  80. execute 'normal! `[v`]BE'.'"'.reg.'x'
  81. endif
  82. elseif match(nchar, '[[:blank:]]') > -1
  83. " before space
  84. execute 'normal! `[Bv`]BE'.'"'.reg.'x'
  85. else
  86. " inside a word
  87. execute 'normal! `[EBv`]BE'.'"'.reg.'x'
  88. endif
  89. else
  90. return
  91. endif
  92. let match_data = matchlist(getreg(reg), '\('.s:EscapeEnds(a:ends).'\)\(.*\)\('.s:EscapeEnds(a:ends).'\)')
  93. if len(match_data) == 0
  94. call setreg(reg, a:ends.getreg(reg).a:ends)
  95. if s:IsCursorAtEndofNonEmptyLine()
  96. execute 'normal "'.reg.'p'
  97. else
  98. execute 'normal "'.reg.'P'
  99. endif
  100. else
  101. call setreg(reg, match_data[2])
  102. if s:IsCursorAtEndofNonEmptyLine()
  103. execute 'normal "'.reg.'p'
  104. else
  105. execute 'normal "'.reg.'P'
  106. endif
  107. endif
  108. call setreg(reg, reg_save)
  109. let &selection = sel_save
  110. endfunction "}}}3
  111. " Apply style {{{3
  112. function! pandoc#keyboard#styles#Apply(type, ends) abort
  113. let sel_save = &selection
  114. let &selection = 'old'
  115. let reg = 'p'
  116. let reg_save = getreg(reg)
  117. if a:type ==# 'v'
  118. execute 'normal! `<'.a:type.'`>'.'"'.reg.'x'
  119. elseif a:type ==# 'char'
  120. execute 'normal! `[v`]'.'"'.reg.'x'
  121. else
  122. return
  123. endif
  124. call setreg(reg, a:ends.getreg(reg).a:ends)
  125. execute 'normal "'.reg.'P'
  126. call setreg(reg, reg_save)
  127. let &selection = sel_save
  128. endfunction
  129. "}}}3
  130. "}}}2
  131. " Emphasis: {{{2
  132. " Apply emphasis, straight {{{3
  133. function! pandoc#keyboard#styles#Emph(type) abort
  134. return pandoc#keyboard#styles#Apply(a:type, '*')
  135. endfunction
  136. " }}}3
  137. " WYSIWYG-style toggle {{{3
  138. "
  139. function! pandoc#keyboard#styles#ToggleEmphasis(type) abort
  140. return pandoc#keyboard#styles#ToggleOperator(a:type, '*')
  141. endfunction
  142. " }}}3
  143. "}}}2
  144. " Strong: {{{2
  145. function! pandoc#keyboard#styles#Strong(type) abort
  146. return pandoc#keyboard#styles#Apply(a:type, '**')
  147. endfunction
  148. function! pandoc#keyboard#styles#ToggleStrong(type) abort
  149. return pandoc#keyboard#styles#ToggleOperator(a:type, '**')
  150. endfunction
  151. "}}}2
  152. " Verbatim: {{{2
  153. function! pandoc#keyboard#styles#Verbatim(type) abort
  154. return pandoc#keyboard#styles#Apply(a:type, '`')
  155. endfunction
  156. function! pandoc#keyboard#styles#ToggleVerbatim(type) abort
  157. return pandoc#keyboard#styles#ToggleOperator(a:type, '`')
  158. endfunction
  159. " }}}2
  160. " Strikeout: {{{2
  161. function! pandoc#keyboard#styles#Strikeout(type) abort
  162. return pandoc#keyboard#styles#Apply(a:type, '~~')
  163. endfunction
  164. function! pandoc#keyboard#styles#ToggleStrikeout(type) abort
  165. return pandoc#keyboard#styles#ToggleOperator(a:type, '~~')
  166. endfunction
  167. " }}}2
  168. " Superscript: {{{2
  169. function! pandoc#keyboard#styles#Superscript(type) abort
  170. return pandoc#keyboard#styles#Apply(a:type, '^')
  171. endfunction
  172. function! pandoc#keyboard#styles#ToggleSuperscript(type) abort
  173. return pandoc#keyboard#styles#ToggleOperator(a:type, '^')
  174. endfunction
  175. " }}}2
  176. " Subscript: {{{2
  177. function! pandoc#keyboard#styles#Subscript(type) abort
  178. return pandoc#keyboard#styles#Apply(a:type, '~')
  179. endfunction
  180. function! pandoc#keyboard#styles#ToggleSubscript(type) abort
  181. return pandoc#keyboard#styles#ToggleOperator(a:type, '~')
  182. endfunction
  183. " }}}2
  184. " Objects: {{{2
  185. function! pandoc#keyboard#styles#SelectSpan(mode, char) abort
  186. let [start_l, start_c] = searchpos(a:char, 'bn')
  187. let [end_l, end_c] = searchpos(a:char, 'n')
  188. let offset = len(substitute(a:char, '\\', '', 'g')) - 1
  189. if a:mode ==# 'inclusive'
  190. let start_c = start_c - 1
  191. let end_c = end_c + offset - 1
  192. elseif a:mode ==# 'exclusive'
  193. let start_c = start_c + offset
  194. let end_c = end_c - 2
  195. endif
  196. exe 'normal! '.start_l. 'G'. start_c. 'lv'. end_l . 'G'. end_c .'l'
  197. endfunction
  198. function! pandoc#keyboard#styles#SelectEmphasis(mode) abort
  199. if synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'pandocEmphasis'
  200. call pandoc#keyboard#styles#SelectSpan(a:mode, '\*')
  201. endif
  202. endfunction
  203. function! pandoc#keyboard#styles#SelectStrong(mode) abort
  204. if synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'pandocStrong'
  205. call pandoc#keyboard#styles#SelectSpan(a:mode, '\*\*')
  206. endif
  207. endfunction
  208. function! pandoc#keyboard#styles#SelectVerbatim(mode) abort
  209. if synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'pandocNoFormatted'
  210. call pandoc#keyboard#styles#SelectSpan(a:mode, '\`')
  211. endif
  212. endfunction
  213. function! pandoc#keyboard#styles#SelectStrikeout(mode) abort
  214. if synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'pandocStrikeout'
  215. call pandoc#keyboard#styles#SelectSpan(a:mode, '\~\~')
  216. endif
  217. endfunction
  218. function! pandoc#keyboard#styles#SelectSuperscript(mode) abort
  219. if synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'pandocSuperscript'
  220. call pandoc#keyboard#styles#SelectSpan(a:mode, '\^')
  221. endif
  222. endfunction
  223. function! pandoc#keyboard#styles#SelectSubscript(mode) abort
  224. if synIDattr(synID(line('.'), col('.'), 1), 'name') ==# 'pandocSubscript'
  225. call pandoc#keyboard#styles#SelectSpan(a:mode, '\~')
  226. endif
  227. endfunction
  228. " }}}2
  229. "
  230. "}}}1