"=============================================================================
" FILE: int_mappings.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be included
" in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
" }}}
"=============================================================================
function! vimshell#int_mappings#define_default_mappings() abort "{{{
" Plugin key-mappings. "{{{
nnoremap <buffer><silent> <Plug>(vimshell_int_previous_prompt)
\ :<C-u>call <SID>previous_prompt()<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_next_prompt)
\ :<C-u>call <SID>next_prompt()<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_execute_line)
\ :<C-u>call vimshell#execute_current_line(0)<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_paste_prompt)
\ :<C-u>call vimshell#int_mappings#_paste_prompt()<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_hangup)
\ :<C-u>call vimshell#interactive#hang_up(bufname('%'))<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_exit)
\ :<C-u>call vimshell#interactive#quit_buffer()<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_restart_command)
\ :<C-u>call <SID>restart_command()<CR>
nnoremap <buffer><expr> <Plug>(vimshell_int_change_line)
\ (vimshell#interactive#get_prompt() == '') ? 'ddO' :
\ printf('0%dlc$', vimshell#util#strchars(
\ vimshell#interactive#get_prompt()))
nmap <buffer> <Plug>(vimshell_int_delete_line)
\ <Plug>(vimshell_int_change_line)<ESC>
nnoremap <silent><buffer> <Plug>(vimshell_int_insert_enter)
\ :<C-u>call <SID>insert_enter()<CR>
nnoremap <silent><buffer> <Plug>(vimshell_int_insert_head)
\ :<C-u>call <SID>insert_head()<CR>
nnoremap <silent><buffer> <Plug>(vimshell_int_append_enter)
\ :<C-u>call <SID>append_enter()<CR>
nnoremap <silent><buffer> <Plug>(vimshell_int_append_end)
\ :<C-u>call <SID>append_end()<CR>
nnoremap <silent><buffer> <Plug>(vimshell_int_clear)
\ :<C-u>call vimshell#int_mappings#clear()<CR>
nnoremap <buffer><silent> <Plug>(vimshell_int_interrupt)
\ :<C-u>call vimshell#interactive#send_char(3)<CR>
inoremap <buffer><silent> <Plug>(vimshell_int_move_head)
\ <ESC>:<C-u>call <SID>move_head()<CR>
inoremap <buffer><expr> <Plug>(vimshell_int_delete_backward_line)
\ <SID>delete_backward_line()
inoremap <buffer><expr> <Plug>(vimshell_int_delete_backward_word)
\ vimshell#interactive#get_cur_text() == '' ? '' : "\<C-w>"
inoremap <buffer><silent> <Plug>(vimshell_int_execute_line)
\ <C-g>u<C-o>:call vimshell#execute_current_line(1)<CR>
" \ <C-g>u<ESC>:<C-u>call vimshell#execute_current_line(1)<CR>
inoremap <buffer><expr> <Plug>(vimshell_int_delete_backward_char)
\ <SID>delete_backward_char(0)
" 3 == char2nr("\<C-c>")
inoremap <buffer><silent> <Plug>(vimshell_int_interrupt)
\ <C-o>:call vimshell#interactive#send_char(3)<CR>
inoremap <buffer><expr> <Plug>(vimshell_int_another_delete_backward_char)
\ <SID>delete_backward_char(1)
inoremap <buffer><silent> <Plug>(vimshell_int_send_input)
\ <C-o>:call vimshell#interactive#send_input()<CR>
inoremap <buffer><expr> <SID>(bs-ctrl-])
\ getline('.')[col('.') - 2] ==# "\<C-]>" ? "\<BS>" : ''
inoremap <buffer><silent> <Plug>(vimshell_int_command_complete)
\ <C-o>:call vimshell#int_mappings#command_complete()<CR>
inoremap <buffer><expr> <Plug>(vimshell_int_delete_forward_line)
\ col('.') == col('$') ? "" : "\<ESC>lDa"
inoremap <buffer><expr><silent>
\ <Plug>(vimshell_int_history_unite)
\ unite#sources#vimshell_history#start_complete(!0)
"}}}
if get(g:, 'vimshell_no_default_keymappings', 0)
return
endif
" Normal mode key-mappings.
nmap <buffer> <C-p> <Plug>(vimshell_int_previous_prompt)
nmap <buffer> <C-n> <Plug>(vimshell_int_next_prompt)
nmap <buffer> <CR> <Plug>(vimshell_int_execute_line)
nmap <buffer> <C-y> <Plug>(vimshell_int_paste_prompt)
nmap <buffer> <C-z> <Plug>(vimshell_int_restart_command)
nmap <buffer> <C-c> <Plug>(vimshell_int_interrupt)
nmap <buffer> q <Plug>(vimshell_int_exit)
nmap <buffer> cc <Plug>(vimshell_int_change_line)
nmap <buffer> dd <Plug>(vimshell_int_delete_line)
nmap <buffer> I <Plug>(vimshell_int_insert_head)
nmap <buffer> A <Plug>(vimshell_int_append_end)
nmap <buffer> i <Plug>(vimshell_int_insert_enter)
nmap <buffer> a <Plug>(vimshell_int_append_enter)
nmap <buffer> <C-l> <Plug>(vimshell_int_clear)
" Insert mode key-mappings.
imap <buffer> <C-h> <Plug>(vimshell_int_delete_backward_char)
imap <buffer> <BS> <Plug>(vimshell_int_delete_backward_char)
imap <buffer> <C-a> <Plug>(vimshell_int_move_head)
imap <buffer> <C-u> <Plug>(vimshell_int_delete_backward_line)
imap <buffer> <C-w> <Plug>(vimshell_int_delete_backward_word)
imap <buffer> <C-k> <Plug>(vimshell_int_delete_forward_line)
imap <buffer> <C-]> <C-]><SID>(bs-ctrl-])
imap <buffer> <CR> <C-]><Plug>(vimshell_int_execute_line)
imap <buffer> <C-c> <Plug>(vimshell_int_interrupt)
imap <buffer> <C-l> <Plug>(vimshell_int_history_unite)
imap <buffer> <C-v> <Plug>(vimshell_int_send_input)
inoremap <buffer> <C-n> <C-n>
imap <buffer><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ "\<Plug>(vimshell_int_command_complete)"
endfunction"}}}
" vimshell interactive key-mappings functions.
function! s:delete_backward_char(is_auto_select) abort "{{{
if !pumvisible()
let prefix = ''
elseif a:is_auto_select ||
\ vimshell#util#is_auto_select()
let prefix = "\<C-e>"
else
let prefix = "\<C-y>"
endif
" Prevent backspace over prompt
let cur_text = vimshell#get_cur_line()
if !has_key(b:interactive.prompt_history, line('.'))
\ || cur_text !=# b:interactive.prompt_history[line('.')]
return prefix . "\<BS>"
else
return prefix
endif
endfunction"}}}
function! s:previous_prompt() abort "{{{
let prompts = sort(filter(map(keys(b:interactive.prompt_history), 'str2nr(v:val)'),
\ 'v:val < line(".")'))
if !empty(prompts)
call cursor(prompts[-1], len(vimshell#interactive#get_prompt()) + 1)
endif
endfunction"}}}
function! s:next_prompt() abort "{{{
let prompts = sort(filter(map(keys(b:interactive.prompt_history),
\ 'str2nr(v:val)'), 'v:val > line(".")'))
if !empty(prompts)
call cursor(prompts[0], len(vimshell#interactive#get_prompt()) + 1)
endif
endfunction"}}}
function! s:move_head() abort "{{{
call vimshell#int_mappings#_insert_head()
endfunction"}}}
function! s:delete_backward_line() abort "{{{
if !pumvisible()
let prefix = ''
elseif vimshell#util#is_auto_select()
let prefix = "\<C-e>"
else
let prefix = "\<C-y>"
endif
let len = !has_key(b:interactive.prompt_history, line('.')) ?
\ len(getline('.')) :
\ len(substitute(vimshell#interactive#get_cur_text(), '.', 'x', 'g'))
return prefix . repeat("\<BS>", len)
endfunction"}}}
function! vimshell#int_mappings#execute_line(is_insert) abort "{{{
call vimshell#util#disable_auto_complete()
if !has_key(b:interactive.prompt_history, line('.'))
" Do update.
call vimshell#interactive#execute_process_out(a:is_insert)
endif
if line('.') != line('$')
call vimshell#int_mappings#_paste_prompt()
endif
call cursor(line('$'), 0)
call cursor(0, col('$'))
call vimshell#interactive#execute_pty_inout(a:is_insert)
call vimshell#helpers#imdisable()
endfunction"}}}
function! vimshell#int_mappings#_paste_prompt() abort "{{{
if !has_key(b:interactive.prompt_history, line('.'))
return
endif
" Set prompt line.
let cur_text = vimshell#interactive#get_cur_line(line('.'))
call setline(line('$'), vimshell#interactive#get_prompt(line('$')) . cur_text)
call cursor(line('$'), 0)
call cursor(0, col('$'))
endfunction"}}}
function! s:restart_command() abort "{{{
if exists('b:interactive') && !empty(b:interactive.process) && b:interactive.process.is_valid
" Delete zombie process.
call vimshell#interactive#force_exit()
endif
set modifiable
" Clean up the screen.
% delete _
call vimshell#terminal#clear_highlight()
" Initialize.
let sub = vimproc#ptyopen(b:interactive.args)
call s:default_settings()
" Set variables.
call extend(b:interactive, {
\ 'process' : sub,
\ 'is_secret': 0,
\ 'prompt_history' : {},
\ 'echoback_linenr' : 0
\}, 'force')
call vimshell#interactive#execute_process_out(1)
call vimshell#view#_start_insert()
endfunction"}}}
function! vimshell#int_mappings#command_complete() abort "{{{
let prompt = vimshell#interactive#get_prompt()
let cur_text = vimshell#interactive#get_cur_text()
call setline('.', prompt)
let prompt_linenr = line('.')
call vimshell#interactive#iexe_send_string(cur_text .
\ (b:interactive.is_pty ? "\<TAB>" : "\<TAB>\<TAB>"), !0, 0)
" if !vimshell#util#head_match(getline(prompt_linenr), prompt)
" " Restore prompt.
" call setline(prompt_linenr, prompt . cur_text .
" \ getline(prompt_linenr))
" startinsert!
" endif
let b:interactive.prompt_history[prompt_linenr] =
\ getline(prompt_linenr)
endfunction "}}}
function! s:insert_enter() abort "{{{
if !has_key(b:interactive.prompt_history, line('.')) && line('.') != line('$')
startinsert
return
endif
if col('.') <= len(vimshell#interactive#get_prompt())
if len(vimshell#interactive#get_prompt()) + 1 >= col('$')
startinsert!
return
else
call cursor(0, len(vimshell#interactive#get_prompt()) + 1)
endif
endif
startinsert
endfunction"}}}
function! vimshell#int_mappings#_insert_head() abort "{{{
call cursor(0, 1)
call s:insert_enter()
endfunction"}}}
function! s:append_enter() abort "{{{
if vimshell#helpers#check_cursor_is_end()
call s:append_end()
else
call cursor(0, col('.') + 1)
call s:insert_enter()
endif
endfunction"}}}
function! s:append_end() abort "{{{
call s:insert_enter()
startinsert!
endfunction"}}}
function! s:send_intrrupt() abort "{{{
endfunction"}}}
function! vimshell#int_mappings#clear() abort "{{{
set modifiable
" Clean up the screen.
if line('$') != 1
if has_key(b:interactive.prompt_history, line('$'))
let current_history = b:interactive.prompt_history[line('$')]
let b:interactive.prompt_history = {}
" Restore history.
let b:interactive.prompt_history[1] = current_history
else
let b:interactive.prompt_history = {}
endif
1,$-1 delete _
else
" Clear prompt history.
let b:interactive.prompt_history = {}
% delete _
endif
let b:interactive.echoback_linenr = 0
" Clear.
call vimshell#terminal#clear_highlight()
call vimshell#terminal#init()
call vimshell#interactive#execute_process_out(1)
call vimshell#view#_start_insert()
endfunction"}}}
" vim: foldmethod=marker