Skip to content

Instantly share code, notes, and snippets.

@rsepassi
Last active August 30, 2024 19:05
Show Gist options
  • Select an option

  • Save rsepassi/a6be1861dfaf14ea1cf6518f095134ec to your computer and use it in GitHub Desktop.

Select an option

Save rsepassi/a6be1861dfaf14ea1cf6518f095134ec to your computer and use it in GitHub Desktop.
function! ExecuteCurrentLine()
let l:line = getline('.')
if l:line[0] != '#'
echoerr "Current line must start with #"
return
endif
let l:replace_result = ReplaceInputBlock(l:line[1:])
let l:replaced = l:replace_result[0]
let l:command = l:replace_result[1]
if l:replaced
let l:end_line = search('@@end', 'W')
if l:end_line != 0
call setline(l:end_line + 1, '@@output')
endif
else
call append(line('.'), '@@output')
endif
call RunCommand(l:command)
endfunction
function! RunCommand(command)
let l:current_line = line('.')
let l:job = job_start(a:command, {
\ 'callback': function('HandleOutput', [l:current_line]),
\ 'exit_cb': function('HandleExit', [l:current_line]),
\ 'in_io': 'null'
\ })
endfunction
function! HandleOutput(start_line, channel, msg)
let l:next_line = a:start_line + 1
while l:next_line <= line('$') && getline(l:next_line) != '@@output'
let l:next_line += 1
endwhile
call append(l:next_line - 1, a:msg)
endfunction
function! HandleExit(start_line, job, status)
let l:current_line = a:start_line
while l:current_line <= line('$') && getline(l:current_line) != '@@output'
let l:current_line += 1
endwhile
if l:current_line <= line('$') && getline(l:current_line) == '@@output'
execute l:current_line . 'delete'
endif
endfunction
function! ReplaceInputBlock(input_s)
let new_foo = ""
let i = 0
while i < strlen(a:input_s)
let l:test_s = a:input_s[i:i+6]
if l:test_s == "@@input"
let new_foo = a:input_s[0:i-1]
let new_foo .= GetDelimitedBlock()
let new_foo .= a:input_s[i+7:]
return [1, new_foo]
endif
let i += 1
endwhile
return [0, a:input_s]
endfunction
function! GetDelimitedBlock()
" Save the current cursor position
let l:save_cursor = getcurpos()
let l:start_line = line('.')
" Search for the end delimiter
let l:end_line = search('@@end', 'W')
if l:end_line == 0
echoerr "End delimiter @@end not found"
call setpos('.', l:save_cursor)
return ''
endif
" Extract the content between the delimiters
let l:content = getline(l:start_line + 1, l:end_line - 1)
" Restore the cursor position
call setpos('.', l:save_cursor)
return join(l:content, "\n")
endfunction
nnoremap <leader>x :call ExecuteCurrentLine()<CR>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment