Commit 167be974 by HiPhish

Add a spawning function to the API

parent 525d78e4
......@@ -27,7 +27,7 @@
" Guess the file type based on a file type string.
"
" Arguments:
" a:ft File type string, such as 'python' or 'scheme.guile'
" ft File type string, such as 'python' or 'scheme.guile'
"
" Returns:
" The guessed type
......@@ -62,9 +62,12 @@ endfunction
" Define a new REPL for a given type.
"
" Arguments:
" a:type Type of the REPL to define
" a:repl Dictionary containing the repl information
" a:force Either "keep", "force" or "error"; see third arg of extend()
" type Type of the REPL to define
" repl Dictionary containing the repl information
" force Either "keep", "force" or "error"; see third arg of extend()
"
" Returns:
" Handle to the REPL buffer
"
" If the REPL does not exist it is added as a new REPL. If it does exists its
" settings are merged with the new one according to 'a:force'.
......@@ -77,3 +80,39 @@ function! repl#define_repl(type, repl, force)
call extend(g:repl[a:type], a:repl, a:force)
endf
" ----------------------------------------------------------------------------
" Open a new REPL buffer with the given options
"
" Arguments:
" mods Modifiers like `:vert`
" repl Dictionary of REPL settings
" type Type of the REPL
"
" Returns:
" Handle to the REPL buffer
"
" This function is responsible for opening a new buffer, launching the REPL
" process and setting it up. It does not depend on state, but the opening of a
" new buffer is a side effect. It does not mutate the value of `g:repl`.
" ----------------------------------------------------------------------------
function! repl#spawn(mods, repl, type)
" Open a new buffer and launch the terminal
silent execute a:mods 'new'
silent execute 'terminal' a:repl.bin join(a:repl.args, ' ')
silent execute 'set syntax='.a:repl.syntax
silent let b:term_title = a:repl.title
let b:repl = {
\ '-': {
\ 'type' : a:type,
\ 'bin' : a:repl.bin,
\ 'args' : a:repl.args,
\ 'job_id' : b:terminal_job_id,
\ 'buffer' : nvim_get_current_buf()
\ }
\ }
return b:repl['-']
endfunction
......@@ -31,6 +31,8 @@ Part I - User manual~
Part II - API reference~
guess_type ........................................... |repl#guess_type()|
define_repl .......................................... |repl#define_repl()|
spawn ................................................ |repl#spawn()|
==============================================================================
INTRODUCTION *repl.nvim-introduction*
......@@ -365,6 +367,25 @@ overriding existing options:
<
This will change the binary, but leave other options as they are.
------------------------------------------------------------------------------
repl#spawn({mods}, {repl}, {type}) *repl#spawn()*
Open a new REPL buffer with the given options. This is the default function to
be called when a REPL is instantiated.
Arguments:~
{mods} Modifiers like `:vert`
{repl} Dictionary of REPL settings
{type} Type of the REPL
Returns:~
{Handle} to the REPL buffer
This function is responsible for opening a new buffer, launching the REPL
process and setting it up. It does not depend on state, but the opening of a
new buffer is a side effect. It does not mutate the value of `g:repl`.
------------------------------------------------------------------------------
......
......@@ -108,42 +108,47 @@ function! s:repl(mods, bang, ...)
" first argument, that is the file type)
let l:repl.args = l:repl.args + a:000[1:]
" Open a new buffer and launch the terminal
silent execute a:mods 'new'
silent execute 'terminal' l:repl.bin join(l:repl.args, ' ')
silent execute 'set syntax='.l:repl.syntax
silent let b:term_title = l:repl.title
" Collect information about this REPL instance
let b:repl = {
\ '-': {
\ 'type' : l:type,
\ 'bin' : l:repl.bin,
\ 'args' : l:repl.args,
\ 'job_id' : b:terminal_job_id,
\ 'buffer' : bufnr('%')
\ }
\ }
let l:instance = repl#spawn(a:mods, l:repl, l:type)
call s:register_instance(l:instance)
endfunction
" ============================================================================
" API CANDIDATES: These functions might in the future be promoted to actual
" API functions, that is why they have been factored into standalone functions
" even though they are used only once.
" ============================================================================
" ----------------------------------------------------------------------------
" Registers a REPL instance on the stack of instances
"
" Arguments:
" instance Dictionary containing information about the instance
" ----------------------------------------------------------------------------
function! s:register_instance(instance)
" Add This instance to the top of the list of instances
if has_key(g:repl[l:type], 'instances')
call insert(g:repl[l:type].instances, b:repl['-'])
if has_key(g:repl[a:instance.type], 'instances')
call insert(g:repl[a:instance.type].instances, a:instance)
else
let g:repl[l:type].instances = [b:repl['-']]
let g:repl[a:instance.type].instances = [a:instance]
endif
" Hook up autocommand to clean up after the REPL terminates; the
" autocommand is not guaranteed to have access to the b:repl variable,
" autocommand is not guaranteed to have access to the instance variable,
" that's why we instead use the literal job-id to identify this instance.
silent execute 'au BufDelete <buffer> call <SID>remove_instance('. b:repl['-'].job_id .', "'.l:type.'")'
let l:type = a:instance.type
let l:job = a:instance.job_id
silent execute 'au BufDelete <buffer> call <SID>remove_instance('.job.', "'.type.'")'
endfunction
" ----------------------------------------------------------------------------
" Remove an instance from the global list of instances
"
" - a:job_id Job ID of the REPL process, used to find the REPL instance
" - a:type The type of REPL
" Arguments:
" job_id Job ID of the REPL process, used to find the REPL instance
" type The type of REPL
" ----------------------------------------------------------------------------
function! s:remove_instance(job_id, type)
for i in range(len(g:repl[a:type].instances))
......
......@@ -62,3 +62,16 @@ Execute (Throwing an error when re-defining a REPL):
Then (The settings are unchanged):
AssertThrows call repl#define_repl('foo', {'bin', ''}, 'error')
#-- repl#spawn ---------------------------------------------------------------
Execute (Spawning a new buffer with settings):
let foo = {'bin': '', 'args': [], 'syntax': '', 'title': ''}
let instance = repl#spawn('', foo, 'foo')
Then (The instance has the right entries):
let buffer = nvim_get_current_buf()
let job = b:terminal_job_id
let expect = {'type': 'foo', 'bin': '', 'args': [], 'job_id': job, 'buffer': buffer}
AssertEqual expect, instance
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment