Running script in background - i.e. not blocking BBEdit

77 views
Skip to first unread message

Rainer Krug

unread,
Mar 22, 2022, 9:52:19 AM3/22/22
to BBEdit Talk
I have an using quarto to render technical documents (it is very nice!) and writing them in BBEdit.

Now I have a script which I want to start from BBEdit as I do with all scripts, but this script runs continuously and updates the preview. I would very much like to have this in BBEdit (in the Scripts Menu), but when I start this script, it blocks BBEdit.

Is there a way of having that dialog non-blocking? Or is there another way of running that script (at the moment I am running it from a different terminal)?

Thanks.

jj

unread,
Mar 22, 2022, 3:12:56 PM3/22/22
to BBEdit Talk
Hi Rainer,

I suspect that BBEdit's Script menu will always be blocking because as far as I know it uses an XPCService. (This should be checked with Bare Bones support though!)

I think of 2 other options that you could try:

Option 1. Use the menubar Script Menu.
 
  • Activate the menubar Script Menu in Script Editor > Preferences > General > Script Menu.
 
  • Create BBEdit's application scripts directory :
   
    % mkdir -p ~/Library/Scripts/Applications/BBEdit

  • Scripts placed in this directory should appear in the menubar Script Menu when BBEdit is the frontmost application. Generally they act as if they where run from the Script Editor.
 
  • Sometimes this allows you to do things you couldn't do from BBEdit's Script menu (like restarting BBEdit for example).
   
Option 2. Create a launchAgent that watches the folder containing your quarto files and that executes a script whenever a file is saved and thus refreshes the preview. (Replace '<rainer>' with your user account in the below paths.)
 
  • Save this launchAgent in ~/Library/LaunchAgents/quarto_watcher.plist
 
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
        http://www.apple.com/DTDs/PropertyList-1.0.dtd>
        <plist version="1.0">
        <dict>
            <key>Label</key>
            <string>quarto_watcher</string>
            <key>ProgramArguments</key>
            <array>
                <string>/Users/<rainer>/Library/Application Support/BBEdit/Scripts/quarto_previewer.sh</string>
            </array>
            <key>WatchPaths</key>
            <array>
                <string>/Users/<rainer>/Documents/Quarto</string>
            </array>
        </dict>
        </plist>
 
  • Save this script in ~/Library/Application Support/BBEdit/Scripts/quarto_previewer.sh and give it the execution permission.
 
        #!/usr/bin/env sh
       
        DOCPATH=$(osascript -e 'tell application "BBEdit" to (URL of first document) as string')
        EXTENSION="${DOCPATH##*.}"
       
        #echo $DOCPATH
        #echo $EXTENSION
       
        if [ $EXTENSION == "quarto" ]; then
            /usr/bin/open -a quarto "$DOCPATH"
        fi
 
  • Create the /Users/<rainer>/Documents/Quarto directory. (Or some other directory and change the launchAgent accordingly.)
 
  • Start the launchAgent in the terminal with:
 
     % launchctl load /Users/<rainer>/Library/LaunchAgents/quarto_watcher.plist
     
  • Now whenever a file with extension ".quarto" is saved in the ~/Documents/Quarto directory, the quarto_previewer.sh script should execute and open or reload this file in quarto.
 
HTH

Jean Jourdain

Rainer Krug

unread,
Mar 23, 2022, 4:55:10 AM3/23/22
to BBEdit Talk
Thanks Jean - these sound interesting options and definitely worth following. But thew (especially the launch agent approach) made me thinking: what if I background the quarto process?

I have now written the following script to start the previewer:

#!/bin/bash

quarto preview $BB_DOC_PATH &
pid=$!
pidfile=$(dirname "${BB_DOC_PATH}")/quarto.$BB_DOC_NAME.pid
echo pid: $pid
echo pidfile: $pidfile
echo $pid > $pidfile

But it has two problems:

1) I still have to click "cancel", but the previewer continues running, which is nice.
2) the file .pid does not contain the pid of the quarto process

The second one, I will solve with quarto, and the first one, I can live with. It would be nice, to have a message pops up which tells the user to close the dialog once the preview is visible?

Thanks,

Rainer

jj

unread,
Mar 23, 2022, 1:41:35 PM3/23/22
to BBEdit Talk
You should quote all paths otherwise if they contain spaces the script won't do what you expect.

Sam Birch

unread,
Mar 23, 2022, 2:10:23 PM3/23/22
to BBEdit Talk

I don’t recall the details of this, but you may need to disown the quarto process so that bash doesn’t wait around for it to finish before exiting.

P.S.: Shell scripting is a minefield and I suggest taking a look at shellcheck if you haven’t already.

Cheers,
-sam

*Option 1. Use the menubar Script Menu.*

• Activate the menubar Script Menu in Script Editor > Preferences >
General > Script Menu.

• Create BBEdit's application scripts directory :

% mkdir -p ~/Library/Scripts/Applications/BBEdit

• Scripts placed in this directory should appear in the menubar Script
Menu when BBEdit is the frontmost application. Generally they act as if
they where run from the Script Editor.

• Sometimes this allows you to do things you couldn't do from BBEdit's
Script menu (like restarting BBEdit for example).

*Option 2. Create a launchAgent that watches the folder containing your

quarto files and that executes a script whenever a file is saved and thus

refreshes the preview. *(Replace '<rainer>' with your user account in the
below paths.)

I have an using quarto <https://quarto.org> to render technical

documents (it is very nice!) and writing them in BBEdit.

Rainer Krug

unread,
Mar 24, 2022, 5:30:44 AM3/24/22
to BBEdit Talk
Shellcheck is great - thanks. I am using it now!

Concerning disown: I tried to add the `disown -a` command, but still had to quit with the Cancel button.

Rainer Krug

unread,
Mar 24, 2022, 6:51:17 AM3/24/22
to BBEdit Talk
OK - Please see the scripts here: https://github.com/rkrug/R-BBEdit/tree/main/R.bbpackage/Contents/Scripts/Quarto

Start quart preview:
```
#!/bin/bash
quarto preview "$BB_DOC_PATH" &


pid=$(ps -A -mm | grep -v grep | grep "quarto" | grep "preview ${BB_DOC_PATH}" | awk '{print $1}')

pidfile=$(dirname "${BB_DOC_PATH}")/quarto.$BB_DOC_NAME.pid


echo pid: $pid


echo pidfile: "$pidfile"

```

and

Stop quarto preview:
```
#!/bin/bash

pidfile="$(dirname "${BB_DOC_PATH}")/quarto.$BB_DOC_NAME.pid"


pkill -F "$pidfile"


rm -f "$pidfile"
```

They run nicely, only the initial backgrounding is not working and I have to Cancel the dialog box.

Also, I do not see a dialog box in the Stop script.

But I am happy with how it works (although automatic backgrounding ad closing ot=f the dialog box would be nice).

Thanks,

Rainer

jj

unread,
Mar 24, 2022, 11:48:57 AM3/24/22
to BBEdit Talk
Hi Rainer,

Good to see your are getting somewhere.

I tested this on my setup and it seems to do what you are after (no pid file needed, no dialog):

Start quarto preview:

    #!/bin/bash
    nohup quarto preview "$BB_DOC_PATH" >& /dev/null &

Stop quarto preview:

    #!/bin/bash
    pid=$(ps -A -mm | grep -v grep | grep "/Applications/quarto/bin/quarto.js preview ${BB_DOC_PATH}" | awk '{print $1}')
    kill -9 $pid

HTH,

Jean Jourdain

jj

unread,
Mar 24, 2022, 12:03:58 PM3/24/22
to BBEdit Talk
Added a test to 00) Start Quarto Preview.sh so the previewer will not be launched more than once.

    #!/bin/bash
    pid=$(ps -A -mm | grep -v grep | grep "/Applications/quarto/bin/quarto.js preview ${BB_DOC_PATH}" | awk '{print $1}')
    if [ -z "$pid" ]; then

        nohup quarto preview "$BB_DOC_PATH" >& /dev/null &
    fi

Jean

Rainer Krug

unread,
Mar 25, 2022, 6:45:35 AM3/25/22
to BBEdit Talk
Thanks Jean - `nohup` is the solution.

I changed your scripts a bit, so that the starts is restarting quarto if it is running:

#!/bin/bash
pid=$(ps -A -mm | grep -v grep | grep "quarto.js preview ${BB_DOC_PATH}" | awk '{print $1}')

if [ -z "$pid" ]; then
    pkill -F "$pidfile"
fi


nohup quarto preview "$BB_DOC_PATH" >& /dev/null &  

and to stop:

#!/bin/bash
pid=$(ps -A -mm | grep -v grep | grep "quarto.js preview ${BB_DOC_PATH}" | awk '{print $1}')
kill -9 $pid


Thanks a lot for your input,

Rainer

jj

unread,
Mar 25, 2022, 12:49:07 PM3/25/22
to BBEdit Talk
Hi Rainer,

I just discovered that you can use the quarto renderer directly from BBEdit.

 1. BBEdit > Preferences > Languages
    
    Add a Custom filename extension mapping
 
    Extension       Language
    ---------       --------
    .qmd            Markdown
 
 2. BBEdit > Preferences > Languages > Language-specific settings > markdown
 
    If it does not exist, add the markdown language with the [+] button.
    Double-click on the Markdown row to open the Markdown configuration pane.
 Screen Shot 2022-03-25 at 17.20.52.png
 3. Go to the Markdown tab and define the quarto render as a custom renderer.
 
    Markdown processor: Custom
    Command: quarto
    Arguments: render --output -
    Screen Shot 2022-03-25 at 17.21.07.png
 4. From the terminal, create a quarto test project on the desktop and open a *.qmd file:
 
    % quarto create-project ~/Desktop/quarto
    % bbedit ~/Desktop/quarto/quarto.qmd
   
 5. Use the BBEdit > Markup > Preview menu item to render your file.
 
    Your document should be rendered and re-rendered whenever you save the file in BBEdit.

    ⚠️  Apparently for this to work the *.qmd file has to be in a quarto project directory.


HTH

Jean Jourdain

Rainer Krug

unread,
Mar 28, 2022, 4:06:09 AM3/28/22
to BBEdit Talk
I was looking into that but I didn't think about using a quarto project, but wanted to use the "preview" with the name of the file. I think that "render" would work as well as I assume tat BBEdit is calling the rendere east time the document changes, and there would be no process left over.

But can is the file name of the source file available as a variable?
Reply all
Reply to author
Forward
0 new messages