Last active
June 6, 2019 11:25
-
-
Save tyru/d497fd496ca5e7061f233335bf724119 to your computer and use it in GitHub Desktop.
Searching declaration in PHP ftplugin (Fix [[, ]] mappings problems, added [], ][ mappings)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- php.vim.bak 2018-10-10 14:08:25.875669800 +0900 | |
+++ php.vim 2018-10-10 14:04:30.777334700 +0900 | |
@@ -61,15 +61,107 @@ | |
setlocal omnifunc=phpcomplete#CompletePHP | |
endif | |
-" Section jumping: [[ and ]] provided by Antony Scriven <adscriven at gmail dot com> | |
-let s:function = '\(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function' | |
-let s:class = '\(abstract\s\+\|final\s\+\)*class' | |
+" Section jumping: [[ and ]] provided by: | |
+" * Antony Scriven <adscriven at gmail dot com> | |
+" * Takuya Fujiwara <tyru dot exe at gmail dot com> | |
+" Operator-pending mappings are linewise (:help linewise) | |
+nnoremap <buffer><silent> [[ :<C-u>call <SID>searchSection('sbW')<CR> | |
+onoremap <buffer><silent> [[ V:<C-u>call <SID>searchSection('sbW')<CR> | |
+nnoremap <buffer><silent> ]] :<C-u>call <SID>searchSection('sW')<CR> | |
+onoremap <buffer><silent> ]] V:<C-u>call <SID>searchSection('sW')<CR> | |
+nnoremap <buffer><silent> [] :<C-u>call <SID>searchDeclEnd(1)<CR> | |
+onoremap <buffer><silent> [] V:<C-u>call <SID>searchDeclEnd(1)<CR> | |
+nnoremap <buffer><silent> ][ :<C-u>call <SID>searchDeclEnd(0)<CR> | |
+onoremap <buffer><silent> ][ V:<C-u>call <SID>searchDeclEnd(0)<CR> | |
+ | |
+let s:function = '\%(abstract\s\+\|final\s\+\|private\s\+\|protected\s\+\|public\s\+\|static\s\+\)*function' | |
+let s:class = '\%(abstract\s\+\|final\s\+\)*class' | |
let s:interface = 'interface' | |
-let s:section = '\(.*\%#\)\@!\_^\s*\zs\('.s:function.'\|'.s:class.'\|'.s:interface.'\)' | |
-exe 'nno <buffer> <silent> [[ ?' . escape(s:section, '|') . '?<CR>:nohls<CR>' | |
-exe 'nno <buffer> <silent> ]] /' . escape(s:section, '|') . '/<CR>:nohls<CR>' | |
-exe 'ono <buffer> <silent> [[ ?' . escape(s:section, '|') . '?<CR>:nohls<CR>' | |
-exe 'ono <buffer> <silent> ]] /' . escape(s:section, '|') . '/<CR>:nohls<CR>' | |
+let s:section = '\%(.*\%#\)\@!\_^\s*\zs\%('.s:function.'\|'.s:class.'\|'.s:interface.'\)' | |
+ | |
+function! s:searchSection(flags) abort | |
+ return search(s:section, a:flags) | |
+endfunction | |
+ | |
+function! s:searchDeclEnd(backward) abort | |
+ let prevpos = getcurpos() | |
+ let ok = 0 | |
+ try | |
+ if s:doSearchDeclEnd(a:backward) | |
+ let ok = 1 | |
+ endif | |
+ finally | |
+ " Save to jumplist | |
+ let nextpos = s:curpos() | |
+ call setpos('.', prevpos) | |
+ if ok | |
+ call s:move(nextpos) | |
+ endif | |
+ endtry | |
+endfunction | |
+ | |
+function! s:doSearchDeclEnd(backward) abort | |
+ let curpos = s:curpos() | |
+ let [begin, end] = s:searchBlock('bcW') | |
+ if a:backward | |
+ if s:between(begin, curpos, end) | |
+ return s:searchSection('bW') && s:searchSection('bW') && s:searchEndBlock() | |
+ else | |
+ return 1 | |
+ endif | |
+ else | |
+ if s:between(begin, curpos, end) && curpos[0] < end[0] | |
+ return 1 | |
+ else | |
+ return s:searchSection('W') && s:searchEndBlock() | |
+ endif | |
+ endif | |
+endfunction | |
+ | |
+function! s:searchBlock(flags) abort | |
+ if !s:searchSection(a:flags) | |
+ return [0, 0] | |
+ endif | |
+ let begin = s:curpos() | |
+ if !s:searchEndBlock() | |
+ return [0, 0] | |
+ endif | |
+ let end = s:curpos() | |
+ return [begin, end] | |
+endfunction | |
+ | |
+" NOTE: This function must be called on the declaration line | |
+function! s:searchEndBlock() abort | |
+ let pos = s:curpos() | |
+ " if '{' is after section, jump to matched '}' | |
+ keepjumps normal! f{ | |
+ if s:curpos() !=# pos | |
+ keepjumps normal! % | |
+ return 1 | |
+ endif | |
+ " Otherwise the next non-blank line should have '{' | |
+ normal! j | |
+ if search('\%' . nextnonblank('.') . 'l^\s*\zs{') | |
+ keepjumps normal! % | |
+ return 1 | |
+ endif | |
+ return 0 | |
+endfunction | |
+ | |
+function! s:curpos() abort | |
+ return getcurpos()[1:2] | |
+endfunction | |
+ | |
+function! s:between(begin, pos, end) abort | |
+ return a:begin[0] <=# a:pos[0] && a:pos[0] <=# a:end[0] | |
+endfunction | |
+ | |
+" This function also updates jumplist (setpos() and cursor() doesn't update it) | |
+function! s:move(pos) abort | |
+ let [lnum, col] = a:pos | |
+ let offset = line2byte(lnum) | |
+ execute printf('normal! %dgo', offset + col - 1) | |
+endfunction | |
setlocal commentstring=/*%s*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have sent an email to maintainers at 2018/09/26 (But no response 😭).