{"icon":"http:\/\/curtclifton.net\/style\/feedicon.png","user_comment":"This feed allows you to read the posts from this site in any feed reader that supports the JSON Feed format. To add this feed to your reader, copy the following URL — http:\/\/curtclifton.net\/feed.json — and add it your reader.","favicon":"http:\/\/curtclifton.net\/style\/touch-icon.png","description":"Full-text posts, generally related to software development on Apple’s platforms. Programming language geekery.","version":"https:\/\/jsonfeed.org\/version\/1","title":"curtclifton.net","items":[{"date_published":"2018-01-06T08:00","title":"Twitter Quitter","id":"twitter-quitter","content_html":"
I’ve decided to close my Twitter account. William Van Hecke makes a convincing case<\/a> for its diminishing utility, and it’s clear that Jack<\/a> is more concerned with eyeballs than standards<\/a>.<\/p>\n\n I stopped regularly reading my timeline months ago. The few times I have dipped in, I’ve ended up angry or depressed. Despite occasional bright spots, there is always someone sharing the angst of the day. I read the news. I don’t need Twitter to make me more anxious. As such, I’ve only been using Twitter for cross posting from my micro.blog account<\/a> and responding to mentions. Slack<\/a> meets my social chat needs without the screaming-into-the-void that Twitter has become.<\/p>\n\n After some reflection, I’ve concluded that even posting to Twitter is just providing content to a platform for hate and anger. I can’t fix that problem, but I can stop contributing to the platform. And so I will.<\/p>\n\n I’m taking my Twitter account private. I’ll stop reading and (after this) posting to it. If you want to get in touch, please email<\/a>, iMessage, or drop a mention Be well. Find the good in the world. Peace.<\/p>\n","url":"http:\/\/www.curtclifton.net\/twitter-quitter"},{"date_published":"2017-12-15T08:00","title":"Next Actions","id":"next-actions","content_html":" After six and a half wonderful years, today is my last with the Omni Group. It’s been the joy and privilege of a lifetime to work with the great people at Omni. Care for others permeates the culture at Omni, from interpersonal interactions, to software design, to our amazing Support Humans. It’s been especially rewarding to contribute to OmniFocus<\/a>, an app that’s been invaluable to me personally and that helps many others achieve their goals.<\/p>\n\n While it’s difficult to say goodbye to all that, I have an opportunity to join a small fruit company in Cupertino working on iPad software for education. The role combines several of my passions: teaching, learning, mentoring, and building elegant software. I’m looking forward to joining my new team in January and making great things together.<\/p>\n\n I’ll miss the amazing Xcoders<\/a> community, but hope to make it back occasionally. And, of course, I’ll see you all when you come to San Jose for WWDC and related festivities. <\/p>\n\n It will be great to be able spend more time with friends in the Bay Area. The next few weeks will be a whirlwind with the holidays and moving, but if you’re in the area hit me up<\/a> in the new year and let’s get together.<\/p>\n","url":"http:\/\/www.curtclifton.net\/next-actions"},{"date_published":"2017-10-27T07:00","title":"These are a Few of My Stateful Machines","id":"these-are-a-few-of-my-stateful-machines","content_html":" I’m excited to be presenting at the inaugural Swift by Northwest<\/a> conference today. My talk is on state machines and how easy they are to implement in Swift.<\/p>\n\n Share and enjoy.<\/p>\n","url":"http:\/\/www.curtclifton.net\/these-are-a-few-of-my-stateful-machines"},{"date_published":"2017-09-03T07:00","title":"Terminal Palettes","id":"terminal-palettes","content_html":" For some recent work, I was switching between OmniFocus and OmniPlan code often. To keep my source directories straight in my head, I tweaked the colors of the two Terminal tabs to use the apps’ branding fonts: purple text for OmniFocus; yellow text for OmniPlan. I mentioned this hack in an engineering meeting and Ken<\/a> promptly dropped the nerd snipe: “Does it switch automatically?”<\/p>\n\n It didn’t then. Now it does.<\/p>\n\n With a three part solution — AppleScript, shell script, and a zsh hook — my Terminal palette now updates whenever I switch between source directories. Yours can too.<\/p>\n\n I added the following code to my This code first declares a local function, Inside the function, we percent-encode the current working directory. Then we set the tab title, save the working directory so it restores on the next launch of Terminal, and finally call the The The script starts with a fairly standard preamble like so:<\/p>\n The script takes a single argument. That argument can either be a file URL, like<\/p>\n or the name of a Terminal.app profile, like <\/p>\n The preamble just checks for any single argument and reports the correct usage if the argument is missing.<\/p>\n\n Next, we bridge the shell argument into AppleScript so we can drive Terminal.app:<\/p>\n Invoked with <\/span>@<\/span>curt<\/span><\/code> on micro.blog<\/a>. I’d also be happy for an invite to your Slack group or a friend request on Facebook<\/a>.<\/em> (While Facebook is also an addiction-exploiting attention hole, it provides much more control to users. The positives there outweigh the negatives.)<\/p>\n\n
\n
ZSH Hook<\/h2>\n\n
<\/span>.<\/span>zshrc<\/span><\/code> file:<\/p>\n
<\/span>if<\/span> [[<\/span> "<\/span>$TERM_PROGRAM<\/span>"<\/span> ==<\/span> "Apple_Terminal"<\/span> ]]<\/span> &&<\/span> [[<\/span> -z "<\/span>$INSIDE_EMACS<\/span>"<\/span> ]]<\/span>;<\/span> then<\/span>\n\n update_terminal_cwd()<\/span> {<\/span>\n # Identify the directory using a "file:" scheme URL, including<\/span>\n # the host name to disambiguate local vs. remote paths.<\/span>\n\n # Percent-encode the pathname.<\/span>\n # http:\/\/superuser.com\/questions\/313650\/resume-zsh-terminal-os-x-lion\/328148#328148<\/span>\n local<\/span> URL_PATH<\/span>=<\/span>''<\/span>\n {<\/span>\n # Use LANG=C to process text byte-by-byte.<\/span>\n local<\/span> i ch hexch LANG<\/span>=<\/span>C\n for<\/span> ((<\/span>i<\/span> =<\/span> 1<\/span>;<\/span> i <=<\/span> ${#<\/span>PWD<\/span>}<\/span>;<\/span> ++i))<\/span>;<\/span> do<\/span>\n ch<\/span>=<\/span>"<\/span>$PWD<\/span>[i]"<\/span>\n if<\/span> [[<\/span> "<\/span>$ch<\/span>"<\/span> =<\/span>~ [<\/span>\/._~A-Za-z0-9-]<\/span> ]]<\/span>;<\/span> then<\/span>\n URL_PATH<\/span>+=<\/span>"<\/span>$ch<\/span>"<\/span>\n else<\/span>\n hexch<\/span>=<\/span>$(<\/span>printf<\/span> "%02X"<\/span> "'<\/span>$ch<\/span>"<\/span>)<\/span>\n URL_PATH<\/span>+=<\/span>"%<\/span>$hexch<\/span>"<\/span>\n fi<\/span>\n done<\/span>\n }<\/span>\n\n local<\/span> PWD_URL<\/span>=<\/span>"file:\/\/<\/span>$HOST$URL_PATH<\/span>"<\/span>\n #echo "$PWD_URL" # testing<\/span>\n print -Pn "\\e]0;%n@%m: %~\\a"<\/span> # get the tab title right: http:\/\/www.tldp.org\/HOWTO\/Xterm-Title-4.html#ss4.1<\/span>\n printf<\/span> '\\e]7;%s\\a'<\/span> "<\/span>$PWD_URL<\/span>"<\/span> # get path restore right<\/span>\n ~\/bin\/terminalPalette.sh "<\/span>$PWD_URL<\/span>"<\/span> # update colors<\/span>\n }<\/span>\n\n # Register the function so it is called whenever the working<\/span>\n # directory changes.<\/span>\n autoload add-zsh-hook\n add-zsh-hook chpwd update_terminal_cwd\n\n # Tell the terminal about the initial directory.<\/span>\n update_terminal_cwd\nfi<\/span>\n<\/pre><\/div>\n
<\/span>update_terminal_cwd<\/span>()<\/span><\/code>, then hooks the shell directory change command to run the function. Finally it calls the function so that a new terminal window will trigger the code as well.<\/p>\n\n
<\/span>terminalPalette<\/span>.<\/span>sh<\/span><\/code> script to update the color palette.<\/p>\n\n
Shell Script<\/h2>\n\n
<\/span>terminalPalette<\/span>.<\/span>sh<\/span><\/code> script lives in the
<\/span>bin<\/span><\/code> subdirectory of my home directory.<\/p>\n\n
<\/span>#!\/bin\/zsh<\/span>\n\nfunc usage()<\/span> {<\/span>\n echo<\/span> "Usage:"<\/span>\n echo<\/span> "<\/span>${<\/span>0<\/span>}<\/span> (<file url>|<settings name>)"<\/span>\n}<\/span>\n\nPROFILE<\/span>=<\/span>${<\/span>1<\/span>}<\/span>\n\nif<\/span> [[<\/span> -z ${<\/span>PROFILE<\/span>}<\/span> ]]<\/span> ;<\/span> then<\/span>\n usage\n exit<\/span> 1<\/span>\nfi<\/span>\n<\/pre><\/div>\n
<\/span>terminalPalette.sh file:\/\/localhost\/Users\/curt\/bin\n<\/pre><\/div>\n
<\/span>terminalPalette.sh "Man Page"<\/span>\n<\/pre><\/div>\n
<\/span>osascript - `<\/span>tty`<\/span> ${<\/span>PROFILE<\/span>}<\/span> <<SCRIPT\n<\/pre><\/div>\n
<\/span>-<\/span><\/code> as the first argument,
<\/span>osascript<\/span><\/code> will run a script passed in on standard input, feeding the subsequent arguments to the embedded script. Here we pass the current tty<\/a> — we’ll see why shortly — and the original argument. Then we begin a here doc<\/a> with the
<\/span><<<\/span>SCRIPT<\/span><\/code> incantation. Until the end of the here doc<\/em>, we’re coding in AppleScript:<\/p>\n
<\/span>on<\/span> run<\/span> argv<\/span>\n set<\/span> theTTY<\/span> to<\/span> item<\/span> 1<\/span> of<\/span> argv<\/span>\n set<\/span> settingsNameOrPath<\/span> to<\/span> item<\/span> 2<\/span> of<\/span> argv<\/span>\n if<\/span> settingsNameOrPath<\/span> starts with<\/span> "file:\/\/"<\/span> then<\/span>\n set<\/span> settingsName<\/span> to<\/span> my<\/span> settingsNameForPath<\/span>(<\/span>