Swap Word Instances in BBEdit

Sometimes I want to swap all instances of “foo” with “bar”. That is, I want every instance of “foo” turned into “bar” and vice-versa.

This may sound odd, but I encounter often it enough that I formed a strategy long ago, three replacement operations:

  1. Replace “foo” with something unique (a sentinal) in the document. I often use a bullet (•) for this.

  2. Replace “bar” with “foo”.

  3. Finally replace the sentinel string with “bar”.

Encountering this again tonight, I decided to finally automate the three-operation replacement:

set uuid to "1DB2FC05-1011-4467-BA2C-A8F3A8B530BC"
set findPasteboard to do shell script "pbpaste -pboard find"
set findPasteboard to findPasteboard & "↔"
display dialog "Swap a↔b" default answer findPasteboard
set swapSet to split of (text returned of result) by "↔"
set term1 to item 1 of swapSet
set term2 to item 2 of swapSet
tell application "BBEdit"
    tell text window 1
        replace term1 using uuid
        replace term2 using term1
        replace uuid using term2
    end tell
end tell

to split of textToSplit by splitter
    set oldTextItemDelimiters to AppleScript's text item delimiters
    if the class of splitter is list then
        set AppleScript's text item delimiters to splitter
    else
        set AppleScript's text item delimiters to {splitter}
    end if
    set theResult to text items of textToSplit
    set AppleScript's text item delimiters to oldTextItemDelimiters
    return theResult
end split

I now use a hard-coded UUID instead of a bullet for my sentinel, but the idea is the same.

AppleScript’s simple display dialog doesn’t allow two separate text input fields, so I delimit the input with ↔. Hacky.

applescript bbedit Sep 24 2011

Switch Between Tabs and Spaces in BBEdit

Here’s a script I wrote to make it easy to switch between tab-based and space-based indention in BBEdit 10:

tell application "BBEdit"
    tell text window 1
        if expand tabs then
            set currentMode to "Spaces (" & tab width & ")"
        else
            set currentMode to "Tabs"
        end if
        display dialog "Current Mode: " & currentMode & ".
Enter new mode (blank for tabs):" default answer "4"
        set newTabWidth to text returned of result as number
        if newTabWidth = 0 then
            set expand tabs to false
        else
            set expand tabs to true
            set tab width to newTabWidth
        end if
    end tell
end tell

Indention control in BBEdit is painful. Whether tabs or spaces are used is in the Edit > Text Options sheet (confusingly named “Auto-expand tabs”) and the amount of spaces inserted in space-indention mode in stuck to the bottom of the Fonts panel (accessible via View > Text Display > Show Fonts).

This script makes it one action to figure out the current mode and modify it if necessary.

applescript bbedit Sep 21 2011

BBEdit Script: Set Tab Width to Widest Cell

Often I’ll have textual data in columnar (tab-delimited) form.

For serious manipulation, I’ll eventually copy and paste it to a spreadsheet and work with it there, but usually I don’t need to go that far.

I’ve been using this BBEdit AppleScript for years that greatly eases viewing and editing tabular data:

--  Get the input.
tell application "BBEdit"
    set input to the selection of text window 1 as text
    if input is "" then
        set input to the text of window 1
    end if
end tell

--  Break the input into rows.
set inputRows to paragraphs of input
if (count of inputRows) is 0 then error "no rows found"

--  Find the longest cell.
set maximumInputCellLength to 0
set oldTextItemDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {tab}
--  Iterate over the rows.
repeat with inputRow in inputRows
    set inputCells to text items of inputRow
    --  Iterate over the cells in each row.
    repeat with inputCell in inputCells
        set inputCellLength to the length of inputCell
        if inputCellLength > maximumInputCellLength then ¬
            set maximumInputCellLength to inputCellLength
    end repeat
end repeat
set AppleScript's text item delimiters to oldTextItemDelimiters

tell application "BBEdit"
    set the tab width of text window 1 to maximumInputCellLength + 1
end tell

It turns this:

untitled text 42

Into this:

untitled text 42

This is the important point: the script doesn’t alter the data itself. Instead, it merely finds the “widest” tab-delimited cell and sets BBEdit’s tab width to match.

Works like a charm.

bbedit applescript Dec 16 2009

BBEdit 9.3 Instaprojects

BBEdit 9.3 is out and my favorite new feature hands-down is support for instaprojects.

The concept is old news for TextMate users: drop a folder onto the app, and it opens a project window listing all items contained there in. The app also understands all these files are related, enabling features such as project-wide searching.

While the feature old news to TextMate users, I prefer BBEdit’s new implementation to TextMate’s.

TextMate represents open files as a strip of horizontal tabs along the top of the window. Unfortunately my brain seems limited enough that this arrangement doesn’t work to well for me. It’s fine for maybe up to five files, and then I’ll lose track of things and have to close all the tabs and start over.

BBEdit 9.3 lists open documents in a drawer in a vertical list. Besides being friendlier to opening many files with long names, I seem able to maintain my orientation more effectively.

bbedit Nov 4 2009