Skip to content

Commit be2c01c

Browse files
author
Bruno Sutic
committed
Add g!
1 parent a169e46 commit be2c01c

File tree

4 files changed

+108
-6
lines changed

4 files changed

+108
-6
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
### master
4+
- add `g!`
5+
36
### v2.2.0, 2014-11-16
47
- `K` mapping now uses `:Man tmux` and jumps to the exact section in the
58
manpage.

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ When you edit `.tmux.conf` you get:
1010
* `commentstring` - so that plugins like
1111
[vim-commentary](https://github.com/tpope/vim-commentary) work as intended
1212
* `K` - jumps to the \*exact* place in `man tmux` where the word under cursor is
13-
explained (a helluva time saver).
13+
explained (a helluva time saver). This should work correctly on practically
14+
anything in `.tmux.conf`.
1415
* [:make](http://vimdoc.sourceforge.net/htmldoc/quickfix.html#:make) - invokes
1516
tmux source `.tmux.conf` and places all the errors (if any) in quicklist
17+
* `g!` - executes lines as tmux commands. Works on visual selection or as a
18+
motion. `g!!` executes just the current line.
1619

1720
### Installation
1821

autoload/tmux.vim

+95-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
" keyword based jump dictionary maps {{{1
1+
" K {{{1
2+
" keyword based jump dictionary maps {{{2
3+
24
" Mapping short keywords to their longer version so they can be found
35
" in man page with 'K'
46
" '\[' at the end of the keyword ensures the match jumps to the correct
@@ -105,7 +107,8 @@ let s:highlight_group_manpage_section = {
105107
\ 'tmuxMiscCmds': 'MISCELLANEOUS'
106108
\ }
107109

108-
" keyword based jump {{{1
110+
" keyword based jump {{{2
111+
109112
function! s:get_search_keyword(keyword)
110113
if has_key(s:keyword_mappings, a:keyword)
111114
return s:keyword_mappings[a:keyword]
@@ -147,7 +150,8 @@ function! s:keyword_based_jump(highlight_group, keyword)
147150
end
148151
endfunction
149152

150-
" highlight group based jump {{{1
153+
" highlight group based jump {{{2
154+
151155
let s:highlight_group_to_match_mapping = {
152156
\ 'tmuxKeyTable': ['KEY BINDINGS', '^\s\+\zslist-keys', ''],
153157
\ 'tmuxLayoutOptionValue': ['WINDOWS AND PANES', '^\s\+\zs{}', '^\s\+\zsThe following layouts are supported'],
@@ -189,7 +193,8 @@ function! s:highlight_group_based_jump(highlight_group, keyword)
189193
echohl ErrorMsg | echo "Sorry, couldn't find the exact description" | echohl None
190194
end
191195
endfunction
192-
" just open manpage {{{1
196+
" just open manpage {{{2
197+
193198
function! s:just_open_manpage(highlight_group)
194199
let hg = a:highlight_group
195200
let char_under_cursor = getline('.')[col('.')-1]
@@ -207,7 +212,8 @@ function! s:just_open_manpage(highlight_group)
207212
endif
208213
endfunction
209214

210-
" 'public' function {{{1
215+
" 'public' function {{{2
216+
211217
function! tmux#man(...)
212218
if !exists(":Man")
213219
runtime! ftplugin/man.vim
@@ -223,3 +229,87 @@ function! tmux#man(...)
223229
return s:keyword_based_jump(highlight_group, keyword)
224230
endif
225231
endfunction
232+
233+
" g! {{{1
234+
" g! is inspired and in good part copied from https://github.com/tpope/vim-scriptease
235+
236+
function! s:opfunc(type) abort
237+
let sel_save = &selection
238+
let cb_save = &clipboard
239+
let reg_save = @@
240+
try
241+
set selection=inclusive clipboard-=unnamed clipboard-=unnamedplus
242+
if a:type =~ '^\d\+$'
243+
silent exe 'normal! ^v'.a:type.'$hy'
244+
elseif a:type =~# '^.$'
245+
silent exe "normal! `<" . a:type . "`>y"
246+
elseif a:type ==# 'line'
247+
silent exe "normal! '[V']y"
248+
elseif a:type ==# 'block'
249+
silent exe "normal! `[\<C-V>`]y"
250+
else
251+
silent exe "normal! `[v`]y"
252+
endif
253+
redraw
254+
return @@
255+
finally
256+
let @@ = reg_save
257+
let &selection = sel_save
258+
let &clipboard = cb_save
259+
endtry
260+
endfunction
261+
262+
function! tmux#filterop(type) abort
263+
let reg_save = @@
264+
try
265+
let expr = s:opfunc(a:type)
266+
let lines = split(expr, "\n")
267+
let all_output = ""
268+
let index = 0
269+
while index < len(lines)
270+
let line = lines[index]
271+
272+
" if line is a part of multi-line string (those have '\' at the end)
273+
" and not last line, perform " concatenation
274+
while line =~# '\\\s*$' && index !=# len(lines)-1
275+
let index += 1
276+
" remove '\' from line end
277+
let line = substitute(line, '\\\s*$', '', '')
278+
" append next line
279+
let line .= lines[index]
280+
endwhile
281+
282+
" skip empty line and comments
283+
if line =~# '^\s*#' ||
284+
\ line =~# '^\s*$'
285+
continue
286+
endif
287+
288+
let command = "tmux ".line
289+
if all_output =~# '\S'
290+
let all_output .= "\n".command
291+
else " empty var, do not include newline first
292+
let all_output = command
293+
endif
294+
295+
let output = system(command)
296+
if v:shell_error
297+
throw output
298+
elseif output =~# '\S'
299+
let all_output .= "\n> ".output[0:-2]
300+
endif
301+
302+
let index += 1
303+
endwhile
304+
305+
if all_output =~# '\S'
306+
redraw
307+
echo all_output
308+
endif
309+
catch /^.*/
310+
redraw
311+
echo all_output | echohl ErrorMSG | echo v:exception | echohl NONE
312+
finally
313+
let @@ = reg_save
314+
endtry
315+
endfunction

ftplugin/tmux.vim

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ setlocal commentstring=#\ %s
1111

1212
nnoremap <silent><buffer> K :call tmux#man()<CR>
1313
14+
nnoremap <silent> <Plug>TmuxExec :<C-U>set opfunc=tmux#filterop<CR>g@
15+
xnoremap <silent> <Plug>TmuxExec :<C-U>call tmux#filterop(visualmode())<CR>
16+
nmap <buffer> g! <Plug>TmuxExec
17+
nmap <buffer> g!! <Plug>TmuxExec_
18+
xmap <buffer> g! <Plug>TmuxExec
19+
1420
let &cpo = s:cpo_save
1521
unlet s:cpo_save
1622

0 commit comments

Comments
 (0)