2

I have a hotkey in Vim that takes me into command mode and calls a Bash script. The Bash script attempts the following steps:

  1. Select text between two tokens
  2. Send selected text block to a .py file
  3. Load the .py file into IPython

The script works if I type everything in by hand, but if I run the script, the text block is not saved as a file until after the script is finished, causing an error when IPython tries to load the file later in the script.

Here are the steps I've tried:

  1. In the event my file is being held in the buffer, I tried syncing and flushing
  2. In case the file needed more time to be written, I tried sleep and wait
  3. I also tried asynchronous shell commands to see if the Bash script was getting priority over Vim writing the file.
#!/bin/bash

# Text to be written has been selected in Vim
tmux send-keys ':w jtemp.py'
tmux send-keys 'Enter'

# Load code selection in IPython
tmux select-pane -t 1
tmux send-keys '%load jtemp.py'
tmux send-keys 'Enter'
tmux send-keys 'Enter'

How can I get the file to be saved to disk while the Bash script is still in process?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Keith Lyons
  • 564
  • 7
  • 14

2 Answers2

2

The problem is most likely (I don't know this for certain however) that Vim is blocking and not processing the key presses until the script finishes. I don't know if it is possible to make Vim run the script in the background, but you could if you bind the hotkey in tmux instead using run-shell -b, something like:

bind F1 run -b "bash /path/to/my/script"

In fact, if doing it in tmux you probably won't need the script to run in the background, because the two affected applications (Vim and IPython) will not block and it doesn't matter if tmux does. So you could just leave the -b out.

You will still almost certainly need a sleep of a second or half a second ("sleep 1" or "sleep 0.5", experiment) between the Enter and the select-pane or there will be a race between Vim writing the file and IPython reading it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nicholas Marriott
  • 3,148
  • 9
  • 12
  • Thanks, this worked. I can confirm that the -b parameter can be omitted in this case. – Keith Lyons Apr 15 '19 at 12:27
  • Using the BASH command `while [ ! -f jtemp.py ]; do sleep .1` allowed me to run the script without manually adjusting the sleep time. It checks to see if the file exists every .1 seconds, else continues sleeping. – Keith Lyons Apr 15 '19 at 12:30
  • For anyone unfamiliar, the hotkey binding in tmux goes in the ~/.tmux.conf directory. You can create it if it doesn't already exist. – Keith Lyons Apr 15 '19 at 12:32
1

I am not sure of the overhead of calling tmux in a shell script, but I would recommend you script your workflow process without it—you can use sed to parse for text between two tokens in a file, pipe that to a new .py file, and then load that .py file into IPython.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rbecca
  • 53
  • 2
  • 6