Skip to content

Instantly share code, notes, and snippets.

@czottmann
Last active December 30, 2022 19:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save czottmann/a672ed2bfdcdb1dc637b27a6606083cb to your computer and use it in GitHub Desktop.
Save czottmann/a672ed2bfdcdb1dc637b27a6606083cb to your computer and use it in GitHub Desktop.
Xcode helper: SwiftFormat the currently focussed doc w/o losing undo history
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- # This script formats the currently open and focussed Swift file
-- # using SwiftFormat. It does so *without* resetting the editor's
-- # undo history.
-- #
-- # Version 2022-12-30.01
-- #
-- # Author: Carlo Zottmann
-- # - carlo@zottmann.org
-- # - https://zottmann.org/,
-- # - https://norden.social/@czottmann
-- # Thanks to Dimitar Nestorov for some valuable help!
-- # Prerequisites: SwiftFormat installed via homebrew:
-- # `brew install swiftformat`
-- # CHANGELOG:
-- #
-- # - 2022-12-30.01: correctly finds current frontmost editor now
-- # - 2022-12-13: Initial release
tell application "Xcode"
set windowTitle to name of front window
set delim to ""
set o to offset of delim in windowTitle
if o = 0 then return
set fileName to second item in my splitText(windowTitle, delim)
set editorDoc to source document named fileName
set filePath to (path of editorDoc) as text
set currentCursorPos to selected character range of editorDoc
-- # Only format Swift source files
if not (filePath ends with ".swift") then
return
end if
-- # Save original clipboard contents for later use
set prevClipboard to (the clipboard as record)
-- # Format the current file and copy it to the clipboard
set filePath to "'" & filePath & "'"
do shell script "cat " & filePath & ¬
" | /opt/homebrew/bin/swiftformat stdin --stdinpath " & filePath & ¬
" | pbcopy"
-- # Overwrite the current editor contents
tell application "System Events"
keystroke "a" using {command down}
keystroke "v" using {command down}
delay 0.2
end tell
-- # Put the cursor back to its original position
set selected character range of editorDoc to currentCursorPos
-- # Set the clipboard to its previous contents
set the clipboard to prevClipboard
end tell
on splitText(theText, theDelimiter)
set AppleScript's text item delimiters to theDelimiter
set theTextItems to every text item of theText
set AppleScript's text item delimiters to ""
return theTextItems
end splitText
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment