Skip to content

Instantly share code, notes, and snippets.

@jebaum

jebaum/vimrc Secret

Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jebaum/9f09cb46a3df3988b597 to your computer and use it in GitHub Desktop.
Save jebaum/9f09cb46a3df3988b597 to your computer and use it in GitHub Desktop.
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