# HG changeset patch # User Steve Losh # Date 1334265206 14400 # Node ID 429731def5a9771b8a9197966c17fbcdc44f5d47 # Parent 2b5144befdbb88a4606c62f891741d21656232b5 Big refactoring. diff -r 2b5144befdbb -r 429731def5a9 doc/clam.txt --- a/doc/clam.txt Tue Apr 03 18:49:11 2012 -0400 +++ b/doc/clam.txt Thu Apr 12 17:13:26 2012 -0400 @@ -35,10 +35,35 @@ When you close the buffer with :quit or something similar Clam will place your cursor back in the split you came from. -You might want to set up your own mapping to make Clam easier to use. The +The :Clam command can take a range. If given, the lines will be passed to the +command on standard input. For example, this will open a Clam output window +with the contents of the current buffer sorted: > + + :%Clam sort + +This will pipe the first ten lines of the file into the python command: > + + :1,10Clam python + +To pipe visually selected text you can use the :ClamVisual command: > + + :ClamVisual sort | uniq -c | sort -n + +When you've got some text visually selected and hit : to enter the command, +Vim will add the '<,'> range by default. You can backspace it out if you want +(or use ), but you don't have to: ClamVisual will work fine with or +without it. + +In other words, the following commands do the same thing: > + + :ClamVisual wc -c + :'<,'>ClamVisual wc -c + +You might want to set up your own mappings to make Clam easier to use. The author has something like this in his .vimrc: > nnoremap ! :Clam + vnoremap ! :ClamVisual That's Clam in a nutclamshell. @@ -110,6 +135,9 @@ ============================================================================== 7. Changelog *ClamChangelog* +v1.2.0 + * Added support for ranges in the :Clam command. + * Added the :ClamVisual command. v1.1.0 * Added the g:clam_autoreturn setting. v1.0.0 diff -r 2b5144befdbb -r 429731def5a9 plugin/clam.vim --- a/plugin/clam.vim Tue Apr 03 18:49:11 2012 -0400 +++ b/plugin/clam.vim Thu Apr 12 17:13:26 2012 -0400 @@ -1,6 +1,6 @@ " ============================================================================ " File: clam.vim -" Description: A simple little shell. +" Description: A simple little shell plugin. " Maintainer: Steve Losh " License: MIT/X11 " ============================================================================ @@ -14,41 +14,37 @@ let loaded_clam = 1 -if !exists('g:clam_autoreturn') "{{{ +if !exists('g:clam_autoreturn') " {{{ let g:clam_autoreturn = 1 endif " }}} "}}} -" Function {{{ +" Functions {{{ -function! s:Execlam(command) - " Build the actual command string to execute - let command = join(map(split(a:command), 'expand(v:val)')) +function! s:GoToClamBuffer(command) " {{{ + let buffer_name = fnameescape(a:command) " Find any already-open clam windows for this command. - let winnr = bufwinnr('^' . command . '$') + let winnr = bufwinnr('^' . buffer_name . '$') " Open the new window (or move to an existing one). if winnr < 0 - silent! execute 'botright vnew ' . fnameescape(command) + silent! execute 'botright vnew ' . buffer_name else silent! execute winnr . 'wincmd w' endif - +endfunction " }}} +function! s:ConfigureCurrentClamBuffer(command) " {{{ " Set some basic options for the output window. setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap nonumber - " Actually run the command, placing its output in the current window. - echo 'Executing: ' . command - silent! execute 'silent %!'. command - if g:clam_autoreturn " When closing this buffer in any way (like :quit), jump back to the original window. silent! execute 'au BufUnload execute bufwinnr(' . bufnr('#') . ') . ''wincmd w''' endif " Map r to "refresh" the command (call it again). - silent! execute 'nnoremap r :call Execlam(''' . command . ''')' + silent! execute 'nnoremap r :call Execlam(''' . a:command . ''')' " Map p to "pipe" the buffer into a new command. silent! execute 'nnoremap p ggVG!' @@ -57,15 +53,60 @@ if exists("g:loaded_AnsiEscPlugin") silent! execute 'AnsiEsc' endif +endfunction " }}} +function! s:ReplaceCurrentBuffer(contents) " {{{ + normal! ggdG + call append(0, split(a:contents, '\v\n')) +endfunction " }}} + +function! s:ExeclamVisual(command) range " {{{ + let old_z = @z + + normal! gv"zy + call s:Execlam(a:command, @z) + + let @z = old_z +endfunction " }}} +function! s:ExeclamNormal(ranged, l1, l2, command) " {{{ + if a:ranged + let lines = getline(a:l1, a:l2) + let stdin = join(lines, "\n") . "\n" + + call s:Execlam(a:command, stdin) + else + call s:Execlam(a:command) + endif +endfunction " }}} +function! s:Execlam(command, ...) " {{{ + " Build the actual command string to execute + let command = join(map(split(a:command), 'expand(v:val)')) + + " Run the command + echo 'Executing: ' . command + + if a:0 == 0 + let result = system(command) + elseif a:0 == 1 + let result = system(command, a:1) + else + echom "Invalid number of arguments passed to Execlam()!" + return + endif + + call s:GoToClamBuffer(command) + call s:ConfigureCurrentClamBuffer(command) + + call s:ReplaceCurrentBuffer(result) silent! redraw echo 'Shell command executed: ' . command -endfunction +endfunction " }}} " }}} " Command {{{ -command! -complete=shellcmd -nargs=+ Clam call s:Execlam() +command! -range=0 -complete=shellcmd -nargs=+ Clam call s:ExeclamNormal(, , , ) +command! -range=% -complete=shellcmd -nargs=+ ClamVisual call s:ExeclamVisual() " }}}