thoughtbot / vim-rspec

Run Rspec specs from Vim
https://robots.thoughtbot.com
MIT License
656 stars 108 forks source link

Let user specify an option to redraw! after running specs for integration with vim-plumber #128

Closed pedroadame closed 7 years ago

pedroadame commented 7 years ago

Very useful to integrate this plugin with vim-plumber. In that plugin, you can send commands to a pipe that will execute them, useful for sending bundle exec rspec to it and execute tests in background in another terminal (or tmux pane ;) ).

Without my modifications, user can specify

#! /usr/bin/env bash
DEFAULT_PIPE_NAME=".plumber"
PIPE_NAME="${1:-$DEFAULT_PIPE_NAME}"

if [ ! -p $PIPE_NAME ]; then
  echo "Created pipe ${PIPE_NAME}..."
  mkfifo $PIPE_NAME
fi

echo "Waiting for commands!"

while :; do
  while read -r cmd; do
    echo "Running $cmd..."
    sh -c "$cmd"
  done <"$PIPE_NAME"
done

as their read_pipe.sh and let g:rspec_command = "silent ! echo \"rspec {spec}\" > .plumber &" in their vimrc to execute commands to pipe. The problem with this is that user needs to press Enter after doing this. If he specifies let g:redraw_after_specs = 1 in vimrc, vim-rspec will redraw so user will keep focused in writing code and running specs in background.

Practical example:

" Maps to run Rspec easily
nnoremap <leader>a :call RunAllSpecs()<CR>
nnoremap <leader>l :call RunLastSpec()<CR>
nnoremap <leader>; :call RunNearestSpec()<CR>
nnoremap <leader>' :call RunCurrentSpecFile()<CR>

" Integrate vim-rspec with vim-plumber. Comment this if you don't use
" vim-plumber
let g:rspec_command = "silent ! echo \"rspec {spec}\" > .plumber &"
let g:redraw_after_specs = 1
" Protip: This is my actual .vimrc configuration.

Then use <leader>; to execute vim-rspec function that will be read by vim-plumber and executed in background.

I know it's a very specific purpose but with allowing user to specify it he wants this behaviour I find it very useful.

gylaz commented 7 years ago

Wouldn't this be possible by providing a custom g:rspec_command?

pedroadame commented 7 years ago

Hi @gylaz, that's exactly what I tried at first, and could'nt get more than a blank screen that behaves strangely (it display rows of text as I navigate through them) with specs running in background. The other possibility was a "Press Enter to continue" blank screen with specs running in background. With redraw! this screen is in fact redrawn so the blank screen becomes the editor again correctly working and you don't need more than your specified keystroke to launch tests in background.

christoomey commented 7 years ago

Hi @pedroadame, could you instead wrap the vim-rspec functions in a function of your own, which does the normal vim-rspec call, and then does redraw!? This should give you the control you want, without needing to add any code to vim-rspec. Example:

function! RunAllSpecsAndRedraw()
  call RunAllSpecs()
  redraw!
end

nnoremap <leader>a :call RunAllSpecsAndRedraw()<CR>

If you wanted to map all of them, you could make it slightly cleaner by adding a generic CallAndRedraw function, and then only needing to update the mappings:

" Looks up the function with the given name and calls it
function! CallAndRedraw(function_name)
  call function(a:function_name)()
  redraw!
endfunction

nnoremap <leader>a :call CallAndRedraw('RunAllSpecs')<CR>
nnoremap <leader>l :call CallAndRedraw('RunLastSpec')<CR>
nnoremap <leader>; :call CallAndRedraw('RunNearestSpec')<CR>
nnoremap <leader>' :call CallAndRedraw('RunCurrentSpecFile')<CR>

Would that work for you?

pedroadame commented 7 years ago

Hi @christoomey Yes, it seems it would work nicely. Thanks!