-
-
Save jebaum/9f09cb46a3df3988b597 to your computer and use it in GitHub Desktop.
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
function! DetectIfInVimFunction(...) | |
" search upward from the current line for the command 'function' to see if we're currently in a function | |
" if we find 'endfunction' command before we find 'function', we aren't in a function | |
" if we find 'function' first, then search downward for the corresponding 'endfunction' | |
" return list of function start and end line numbers if successful, list of -1 if not | |
" TODO use search() ? `call search('function!', 'b')' | |
let startline = line('.') | |
let currentline = line('.') | |
if a:0 != 0 | |
let iterlimit = a:1 | |
else | |
let iterlimit = 250 | |
endif | |
let i = 0 | |
while i < iterlimit | |
" see if the text 'function' or 'endfunction' is on the current line | |
let funmatchpos = match(getline(currentline), "function!") | |
let endfunmatchpos = match(getline(currentline), "endfunction") | |
if funmatchpos != -1 " we found the text 'function' | |
let funsynlist = map(synstack(currentline, funmatchpos + 1),'synIDattr(v:val,"name")') | |
if index(funsynlist, 'vimFuncKey') >= 0 " function start markers are in the VimFuncKey syntax group | |
" save the line number of the first line of the function, and reset the search position | |
let startfunline = currentline | |
let currentline = startline | |
endif | |
endif | |
if endfunmatchpos != -1 " we found the text 'endfunction' | |
let endfunsynlist = map(synstack(currentline, endfunmatchpos + 1),'synIDattr(v:val,"name")') | |
if index(endfunsynlist, 'vimCommand') >= 0 " endfunction markers are in the VimCommand syntax group | |
if currentline == startline || exists('startfunline') | |
" if we started out with the cursor on endfunction, or we've already found a function start | |
let endfunline = currentline | |
else " we found an endfunction before finding a function start, so we aren't currently in a function | |
break | |
endif | |
endif | |
endif | |
let i += 1 | |
if exists('startfunline') && exists('endfunline') | |
return [startfunline, endfunline] | |
elseif exists('startfunline') | |
" we found the function start, so now we want to search downward | |
let currentline += 1 | |
else | |
let currentline -= 1 | |
endif | |
endwhile | |
return [-1, -1] | |
endfunction | |
function! SourcePart(line1, line2) | |
let tmp = @z | |
silent exec a:line1.",".a:line2."yank z" | |
let @z = substitute(@z, '\n\s*\\', '', 'g') | |
@z | |
let @z = tmp | |
endfunction | |
function! SourceCurrentFunction() | |
let [startfunline, endfunline] = DetectIfInVimFunction() | |
if startfunline != -1 | |
call SourcePart(startfunline, endfunline) | |
echo 'sourced ' . strpart(getline(startfunline), strlen('function! ')) | |
else | |
echo 'cursor is not in a function' | |
endif | |
endfunction | |
" if some argument is given, this command calls built-in command :source with | |
" given arguments; otherwise calls function SourcePart() which sources | |
" visually selected lines of the buffer. | |
command! -nargs=? -bar -range Source if empty("<args>") | call SourcePart(<line1>, <line2>) | else | exec "so <args>" | endif | |
nnoremap <leader>sf :call SourceCurrentFunction()<CR> | |
vnoremap <leader>sv :Source<CR> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment