I want to craft a custom operator-pending motion if
for functions in R language that look like this:
doSomething <- function(arg1, arg2, ...) {
doStuff(...)
}
The idea is to be able to press yif
while on the function body to copy it's contents doStuff(...)
in this case. I have something that works:
onoremap if :<c-u>execute "normal! $?<-\\s*function\\s*(\r^/{\r%``j^v``kg_"<cr>
This does the following: searches for the <- function
pattern backwards, then finds the first {
, jumps to it's match with %
, then goes back to the beginning, goes down one line, enters visual mode, jump to the end, goes up one line and finishes.
This works for me with one downside: it finds functions even when I am outside (below) the function body.
My question is: how to make it fail when the cursor is not on a function?
Any other help/tips are appreciated as well.
Update
Following advice from @Luc I wrote a simple function to check if the given line is inside the function:
function! IsInsideRFunction(lnum)
let currentline = a:lnum
let savedpos = getpos(".")
execute "silent! normal! $" . '?<-\s*function\s*(' . "\<cr>"
execute "silent! normal! " . '/{' . "\<cr>"
let startline = line(".")
execute "silent! normal! %"
let endline = line(".")
if currentline >=# startline && currentline <=# endline
call setpos(".", savedpos)
return 1
endif
call setpos(".", savedpos)
endfunction
The function works. However when I put it inside the expression map:
onoremap <expr> aF IsInsideRFunction(line(".")) ? ":echom 'yes'<cr>" : ":echom 'no'<cr>"
it stops working. More precisely - it always returns "1".
What am I doing wrong?