5 changed files with 387 additions and 0 deletions
@ -0,0 +1,41 @@ |
|||||||
|
vim-peekaboo |
||||||
|
============ |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
Peekaboo extends `"` and `@` in normal mode and `<CTRL-R>` in insert mode so |
||||||
|
you can see the contents of the registers. |
||||||
|
|
||||||
|
Installation |
||||||
|
------------ |
||||||
|
|
||||||
|
Using [vim-plug](https://github.com/junegunn/vim-plug): |
||||||
|
|
||||||
|
```vim |
||||||
|
Plug 'junegunn/vim-peekaboo' |
||||||
|
``` |
||||||
|
|
||||||
|
Usage |
||||||
|
----- |
||||||
|
|
||||||
|
Peekaboo will show you the contents of the registers on the sidebar when you |
||||||
|
hit `"` or `@` in normal mode or `<CTRL-R>` in insert mode. The sidebar is |
||||||
|
automatically closed on subsequent key strokes. |
||||||
|
|
||||||
|
You can toggle fullscreen mode by pressing spacebar. |
||||||
|
|
||||||
|
Customization |
||||||
|
------------- |
||||||
|
|
||||||
|
| Config | Default | Description | |
||||||
|
| ------ | ------- | ----------- | |
||||||
|
| `g:peekaboo_window` | `vert bo 30new` | Command for creating Peekaboo window | |
||||||
|
| `g:peekaboo_delay` | 0 (ms) | Delay opening of Peekaboo window | |
||||||
|
| `g:peekaboo_compact` | 0 (boolean) | Compact display | |
||||||
|
| `g:peekaboo_prefix` | Empty (string) | Prefix for key mapping (e.g. `<leader>`) | |
||||||
|
| `g:peekaboo_ins_prefix` | Empty (string) | Prefix for insert mode key mapping (e.g. `<c-x>`) | |
||||||
|
|
||||||
|
License |
||||||
|
------- |
||||||
|
|
||||||
|
MIT |
@ -0,0 +1,246 @@ |
|||||||
|
" The MIT License (MIT) |
||||||
|
" |
||||||
|
" Copyright (c) 2017 Junegunn Choi |
||||||
|
" |
||||||
|
" 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. |
||||||
|
|
||||||
|
let s:cpo_save = &cpo |
||||||
|
set cpo&vim |
||||||
|
|
||||||
|
" Default options |
||||||
|
let s:default_delay = 0 |
||||||
|
let s:default_window = 'vertical botright 30new' |
||||||
|
let s:default_compact = 0 |
||||||
|
|
||||||
|
let s:QUOTE = '"' |
||||||
|
let s:REPLAY = '@' |
||||||
|
let s:CTRL_R = "\<c-r>" |
||||||
|
|
||||||
|
let s:buf_peekaboo = 0 |
||||||
|
|
||||||
|
" Returns true if timed out |
||||||
|
function! s:wait_with_timeout(timeout) |
||||||
|
let timeout = a:timeout |
||||||
|
while timeout >= 0 |
||||||
|
if getchar(1) |
||||||
|
return 0 |
||||||
|
endif |
||||||
|
if timeout > 0 |
||||||
|
sleep 20m |
||||||
|
endif |
||||||
|
let timeout -= 20 |
||||||
|
endwhile |
||||||
|
return 1 |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Checks if Peekaboo buffer is open |
||||||
|
function! s:is_open() |
||||||
|
return s:buf_peekaboo |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Closes peekaboo buffer |
||||||
|
function! s:close() |
||||||
|
silent! execute 'bd' s:buf_peekaboo |
||||||
|
let s:buf_peekaboo = 0 |
||||||
|
execute s:winrestcmd |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Appends macro list for the specified group to Peekaboo window |
||||||
|
function! s:append_group(title, regs) |
||||||
|
let compact = get(g:, 'peekaboo_compact', s:default_compact) |
||||||
|
if !compact | call append(line('$'), a:title.':') | endif |
||||||
|
for r in a:regs |
||||||
|
try |
||||||
|
if r == '%' | let val = s:buf_current |
||||||
|
elseif r == '#' | let val = s:buf_alternate |
||||||
|
else | let val = eval('@'.r)[:&columns] |
||||||
|
endif |
||||||
|
if empty(val) |
||||||
|
continue |
||||||
|
endif |
||||||
|
let s:regs[printf('%s', r)] = line('$') |
||||||
|
call append(line('$'), printf(' %s: %s', r, substitute(val, '^\s*', '', ''))) |
||||||
|
catch |
||||||
|
endtry |
||||||
|
endfor |
||||||
|
if !compact | call append(line('$'), '') | endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Opens peekaboo window |
||||||
|
function! s:open(mode) |
||||||
|
let [s:buf_current, s:buf_alternate, s:winrestcmd] = [@%, @#, winrestcmd()] |
||||||
|
execute get(g:, 'peekaboo_window', s:default_window) |
||||||
|
let s:buf_peekaboo = bufnr('') |
||||||
|
setlocal nonumber buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap |
||||||
|
\ modifiable statusline=>\ Registers nocursorline nofoldenable |
||||||
|
if exists('&relativenumber') |
||||||
|
setlocal norelativenumber |
||||||
|
endif |
||||||
|
|
||||||
|
setfiletype peekaboo |
||||||
|
augroup peekaboo |
||||||
|
autocmd! |
||||||
|
autocmd CursorMoved <buffer> bd |
||||||
|
augroup END |
||||||
|
|
||||||
|
let s:regs = {} |
||||||
|
call s:append_group('Special', ['"', '*', '+', '-']) |
||||||
|
call s:append_group('Read-only', a:mode ==# s:REPLAY ? ['.', ':'] : ['.', '%', '#', '/', ':']) |
||||||
|
call s:append_group('Numbered', map(range(0, 9), 'string(v:val)')) |
||||||
|
call s:append_group('Named', map(range(97, 97 + 25), 'nr2char(v:val)')) |
||||||
|
normal! "_dd |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Checks if the buffer for the position is visible on screen |
||||||
|
function! s:is_visible(pos) |
||||||
|
return a:pos.tab == tabpagenr() && bufwinnr(a:pos.buf) != -1 |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Triggers gv to keep visual highlight on |
||||||
|
function! s:gv(visualmode, visible) |
||||||
|
if a:visualmode && a:visible |
||||||
|
noautocmd wincmd p |
||||||
|
normal! gv |
||||||
|
redraw |
||||||
|
noautocmd wincmd p |
||||||
|
else |
||||||
|
redraw |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Feeds the final key sequence |
||||||
|
function! s:feed(count, mode, reg, rest) |
||||||
|
call feedkeys(a:count > 1 ? a:count : '', 'n') |
||||||
|
if a:mode ==# s:QUOTE |
||||||
|
call feedkeys('"'.a:reg, 'n') |
||||||
|
call feedkeys(a:rest) |
||||||
|
elseif a:mode ==# s:CTRL_R |
||||||
|
call feedkeys("\<c-r>".a:reg, 'n') |
||||||
|
else |
||||||
|
call feedkeys('@'.a:reg, 'n') |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
let s:scroll = { |
||||||
|
\ "\<up>": "\<c-y>", "\<down>": "\<c-e>", |
||||||
|
\ "\<c-y>": "\<c-y>", "\<c-e>": "\<c-e>", |
||||||
|
\ "\<c-u>": "\<c-u>", "\<c-d>": "\<c-d>", |
||||||
|
\ "\<c-b>": "\<c-b>", "\<c-f>": "\<c-f>", |
||||||
|
\ "\<pageup>": "\<c-b>", "\<pagedown>": "\<c-f>" |
||||||
|
\ } |
||||||
|
|
||||||
|
" Returns the position of the current buffer as a dictionary |
||||||
|
function! s:getpos() |
||||||
|
return {'tab': tabpagenr(), 'buf': bufnr(''), 'win': winnr(), 'cnt': winnr('$')} |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! peekaboo#peek(count, mode, visualmode) |
||||||
|
" First check if we should start peekaboo, if not just return the mode key |
||||||
|
let timeout = get(g:, 'peekaboo_delay', s:default_delay) |
||||||
|
if !s:wait_with_timeout(timeout) |
||||||
|
return a:mode |
||||||
|
endif |
||||||
|
|
||||||
|
let s:args = [a:count, a:mode, a:visualmode] |
||||||
|
return "\<Plug>(peekaboo)" |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! peekaboo#aboo() |
||||||
|
let [cnt, mode, visualmode] = s:args |
||||||
|
|
||||||
|
if s:is_open() |
||||||
|
call s:close() |
||||||
|
endif |
||||||
|
|
||||||
|
let positions = { 'current': s:getpos() } |
||||||
|
call s:open(mode) |
||||||
|
let positions.peekaboo = s:getpos() |
||||||
|
|
||||||
|
let inplace = positions.current.tab == positions.peekaboo.tab && |
||||||
|
\ positions.current.win == positions.peekaboo.win && |
||||||
|
\ positions.current.cnt == positions.peekaboo.cnt |
||||||
|
let visible = !inplace && s:is_visible(positions.current) |
||||||
|
|
||||||
|
call s:gv(visualmode, visible) |
||||||
|
|
||||||
|
let [stl, lst] = [&showtabline, &laststatus] |
||||||
|
let zoom = 0 |
||||||
|
try |
||||||
|
while 1 |
||||||
|
let ch = getchar() |
||||||
|
let reg = nr2char(ch) |
||||||
|
let key = get(s:scroll, ch, get(s:scroll, reg, '')) |
||||||
|
if !empty(key) |
||||||
|
execute 'normal!' key |
||||||
|
call s:gv(visualmode, visible) |
||||||
|
continue |
||||||
|
endif |
||||||
|
|
||||||
|
if zoom |
||||||
|
tab close |
||||||
|
let [&showtabline, &laststatus] = [stl, lst] |
||||||
|
call s:gv(visualmode, visible) |
||||||
|
endif |
||||||
|
if reg != ' ' |
||||||
|
break |
||||||
|
endif |
||||||
|
if !zoom |
||||||
|
tab split |
||||||
|
set showtabline=0 laststatus=0 |
||||||
|
endif |
||||||
|
let zoom = !zoom |
||||||
|
redraw |
||||||
|
endwhile |
||||||
|
|
||||||
|
let rest = '' |
||||||
|
if mode ==# s:QUOTE && has_key(s:regs, tolower(reg)) |
||||||
|
let line = s:regs[tolower(reg)] |
||||||
|
execute line |
||||||
|
execute 'syntax region peekabooSelected start=/\%'.line.'l\%5c/ end=/$/' |
||||||
|
setlocal cursorline |
||||||
|
call setline(line('.'), substitute(getline('.'), ' .', ' '.reg, '')) |
||||||
|
call s:gv(visualmode, visible) |
||||||
|
let rest = nr2char(getchar()) |
||||||
|
endif |
||||||
|
|
||||||
|
" - Make sure that we're back to the original tab/window/buffer |
||||||
|
" - e.g. g:peekaboo_window = 'tabnew' / 'enew' |
||||||
|
if inplace |
||||||
|
noautocmd execute positions.current.win.'wincmd w' |
||||||
|
noautocmd execute 'buf' positions.current.buf |
||||||
|
else |
||||||
|
noautocmd execute 'tabnext' positions.current.tab |
||||||
|
call s:close() |
||||||
|
noautocmd execute positions.current.win.'wincmd w' |
||||||
|
endif |
||||||
|
if visualmode |
||||||
|
normal! gv |
||||||
|
endif |
||||||
|
call s:feed(cnt, mode, reg, rest) |
||||||
|
catch /^Vim:Interrupt$/ |
||||||
|
return |
||||||
|
finally |
||||||
|
let [&showtabline, &laststatus] = [stl, lst] |
||||||
|
call s:close() |
||||||
|
redraw |
||||||
|
endtry |
||||||
|
endfunction |
||||||
|
|
||||||
|
let &cpo = s:cpo_save |
||||||
|
unlet s:cpo_save |
@ -0,0 +1,60 @@ |
|||||||
|
" The MIT License (MIT) |
||||||
|
" |
||||||
|
" Copyright (c) 2017 Junegunn Choi |
||||||
|
" |
||||||
|
" 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. |
||||||
|
|
||||||
|
nnoremap <silent> <Plug>(peekaboo) :<c-u>call peekaboo#aboo()<cr> |
||||||
|
xnoremap <silent> <Plug>(peekaboo) :<c-u>call peekaboo#aboo()<cr> |
||||||
|
inoremap <silent> <Plug>(peekaboo) <c-\><c-o>:<c-u>call peekaboo#aboo()<cr> |
||||||
|
|
||||||
|
function! peekaboo#on() |
||||||
|
if get(b:, 'peekaboo_on', 0) |
||||||
|
return |
||||||
|
endif |
||||||
|
|
||||||
|
let prefix = get(g:, 'peekaboo_prefix', '') |
||||||
|
let ins_prefix = get(g:, 'peekaboo_ins_prefix', '') |
||||||
|
execute 'nmap <buffer> <expr> '.prefix. '" peekaboo#peek(v:count1, ''"'', 0)' |
||||||
|
execute 'xmap <buffer> <expr> '.prefix. '" peekaboo#peek(v:count1, ''"'', 1)' |
||||||
|
execute 'nmap <buffer> <expr> '.prefix. '@ peekaboo#peek(v:count1, ''@'', 0)' |
||||||
|
execute 'imap <buffer> <expr> '.ins_prefix.'<c-r> peekaboo#peek(1, "\<c-r>", 0)' |
||||||
|
let b:peekaboo_on = 1 |
||||||
|
return '' |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! peekaboo#off() |
||||||
|
if !get(b:, 'peekaboo_on', 0) |
||||||
|
return |
||||||
|
endif |
||||||
|
|
||||||
|
let prefix = get(g:, 'peekaboo_prefix', '') |
||||||
|
let ins_prefix = get(g:, 'peekaboo_ins_prefix', '') |
||||||
|
execute 'nunmap <buffer> '.prefix.'"' |
||||||
|
execute 'xunmap <buffer> '.prefix.'"' |
||||||
|
execute 'nunmap <buffer> '.prefix.'@' |
||||||
|
execute 'iunmap <buffer> '.ins_prefix.'<c-r>' |
||||||
|
let b:peekaboo_on = 0 |
||||||
|
endfunction |
||||||
|
|
||||||
|
augroup peekaboo_init |
||||||
|
autocmd! |
||||||
|
autocmd BufEnter * if !exists('*getcmdwintype') || empty(getcmdwintype()) | call peekaboo#on() | endif |
||||||
|
augroup END |
||||||
|
|
@ -0,0 +1,33 @@ |
|||||||
|
" The MIT License (MIT) |
||||||
|
" |
||||||
|
" Copyright (c) 2015 Junegunn Choi |
||||||
|
" |
||||||
|
" 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. |
||||||
|
|
||||||
|
syntax clear |
||||||
|
syntax match peekabooTitle /^[A-Za-z-]*/ contained |
||||||
|
syntax match peekabooTitleColon /^[A-Za-z-]*:/ contains=peekabooTitle |
||||||
|
syntax match peekabooReg /^ ./ contained |
||||||
|
syntax match peekabooRegColon /^ .:/ contains=peekabooReg |
||||||
|
highlight default link peekabooTitle Title |
||||||
|
highlight default link peekabooTitleColon NonText |
||||||
|
highlight default link peekabooReg Label |
||||||
|
highlight default link peekabooRegColon NonText |
||||||
|
highlight default link peekabooSelected Todo |
||||||
|
|
Loading…
Reference in new issue