That darn Maps app

Dear Maps team,

Please don’t route me onto a dirt road again. It was super un-fun. I ended up going back up to I-80 and heading over to Wyoming from Nebraska, adding another state and about 5 hours to my trip including the not-joy of I-25 rush hour traffic instead of the much quieter I-76 through Fort Morgan.

It was impossible to get any live data from said dirt road so I just went with my gut until I could get directions again, which took about 2 hours, placing me just outside Cheyenne.

Navigation through Nebraska is always horrible horrible horrible, usually just blank tiles until I hit either Colorado or South Dakota. When going state to state, I’d like to cache tiles along several possible routes because with so much highway construction, I don’t want to be caught with blank tiles in the middle of Nebraska when I have to go twenty or forty miles off to the left or right to avoid a road that isn’t roading at the moment.

Caching tiles and directions along many possible routes would have helped the whole dirt road fiasco. The no-data-no-tiles-no-rerouting trap is both unsafe and unpleasant. Plus it made me miss Sidney, NE, with the only truck stop I’ve ever encountered in the United States that offered bidets (!) in their bathrooms. A true tourist’s experience.

While I’m venting, please respect my wishes about “No tolls” or “No highways” for my entire trip, even if I take a slight detour to avoid traffic. Forgetting “Show me how to get to [Someplace] avoiding tolls” when I reroute cost me  unnecessary funds recently by putting me onto 470, aka the hell road. I was properly billed (thankfully!) and paid immediately but no one voluntarily drives on E470.

Maps folk, please let me say “Show me how to get to Colombia, MO avoiding tolls and dirt roads” and remember that request until I’m safely at my destination. And let me add those requests as I’m driving. During rush hour, let me say “Hey, let’s get off the highways until I’m close to 225”. That’s totally doable from a programming point of view.

Speaking of slight detours, I generally know better than Maps how to tweak directions within the first few miles of my home. For example, I prefer to take the relatively quiet 13th and 14th streets from downtown instead of Colfax or 6th. There’s an incredibly unsafe left turn near our house that Maps always recommends. I drive a little further and make a safe U-turn at a light with a dedicated left turn signal.

I do these tweaks near my home all the time and Maps shouldn’t be fighting me on this, announcing updated directions every single block. I’d like a setting that limits any directions at all (after the initial announcement) for the first, say, mile or two or three away from my home or other “known” starting points that I could add to a list.

In fact, I know how to get to many major milestones within the greater Denver metropolitan area like 225 and Vasquez, and Hampden and 25, and Colorado and 70. I’d like to be able to have navigation kick off once  I’m near a known point or I’m close to the highway or fairly far along towards my destination. That shouldn’t be too hard to develop and customize, requiring no in-car interaction so it’s safe.

In many cases, I only need last mile assistance when driving in-city, including other cities I’m familiar with like Colorado Springs and Fort Collins. I wish I could ask for a “guide me when I’m close to” setting for these kinds of navigation requests.

Thank you all. You know I appreciate everything you do!

Making @KeyboardMaestro work in Mojave

Unfortunately, Apple seems to have messed up assistive apps like Keyboard Maestro in Mojave and if you depend on macros, that’s a very bad thing indeed. I upgraded to Mojave late last week (even though it is still not theoretically a GM) and found that although some actions still worked without problem like app launching others (specifically my universal Emacs key equivalents for arrow moves) did not.

I found this thread about the issue on a Keyboard Maestro forum. The hints on that thread helped me work out this solution to the Mojave problem. Note that you may have to repeat steps after rebooting your Mac.

  1. Copy /Applications/Keyboard\ Maestro.app/Contents/MacOS/Keyboard Maestro Engine.app to /Applications.
  2. In Terminal, kill the Keyboard Maestro and Engine processes.
  3. Open System Preferences > Security and Privacy > Accessibility. Grant privileges to both apps: Maestro and the copied Engine. (I also granted privileges to Finder and Safari, which probably wasn’t necessary.)
  4. Launch the Engine from /Applications. Check the process list for /Applications/Keyboard Maestro Engine.app/Contents/MacOS/Keyboard Maestro Engine and test your macros. You may have many types of macros and you’ll want to hit as many bits of the OS as possible when ensuring that each kind of macro is properly launched and executed.

 

Converting projects by hand to Swift 4.2

If Xcode is acting up for you the way it is for me, you may want to step back from automated migration and just do it by hand. I spent far too much time this morning trying to get Xcode to finish migrating for what were extremely trivial changes.

If you’re going by hand, make sure to change your “didFinishLaunching” launch options (in your App delegate) from [UIApplicationLaunchOptionsKey: Any] to use UIApplication.LaunchOptionsKey. (Notice the period in the name.)

To set the compiler from Swift 4 to Swift 4.2, open Target > Build Settings. Navigate to Swift Language Version and use the pop-up to select the proper compiler:

For some projects (especially small sample code) this alone may be sufficient to get you back and working.

Preparing to teach/demo

Normally I use a separate account to present talks and demos but I’ve recently taken up a more regular instruction gig and in doing so, it’s too inconvenient to move from my main account. My main account is where all my development tools and code are a few clicks and keystrokes away. The demo one is very safe for public presentation but also very distant from my workflow.

To address this, I’ve built a demo-setup utility in Swift. I thought I’d share some of the features and approaches. A lot of these were non-trivial to track down in terms of time and I thought having them in one place could be useful to some of you reading my blog.

If you have others to share, please let me know.

Desktop Wallpaper

I use Backdrop from Apps from Outer Space to cover my normal desktop with a plain and  boring background. Set up preferences in the app and then use open /Applications/Backdrop.app / killall Backdrop to toggle. It covers your wall paper without having to set it back to your favorite picture each time you enter and leave demo mode.

Do Not Disturb

Automate DND with AppleScript. I grabbed code off the web, letting me enable and disable do not disturb mode. (Make sure to enable Script Editor in Accessibility so they’ll run: Settings > Security & Privacy > Accessibility > Allow the apps below to control your computer.)

I didn’t make these pretty or write the osascript stuff into my code. They’re just two scripts in ~/bin right now. At some point, time allowing, I’ll unify these into a single script or app but as they work for now, shrug:

Desktop Icons

I keep a lot of work on my desktop that I’d prefer not to share. It’s easy to hide and show my desktop icons with a simple defaults command:

defaults write com.apple.finder CreateDesktop false; killall Finder"

Substitute true for false to re-enable.

Keyboard Maestro Macros

I not only quit email (killall Mail) but I also disable my Keyboard Maestro shortcut so I don’t accidentally re-launch it from muscle memory.

osascript -e 'tell application "Keyboard Maestro" to setMacroEnable "8E84EF4C-13F8-41AB-85EC-44AF70A52909" without enable'

Grab the unique identifiers for troublesome shortcuts from the files stored in ~/Library/Application\ Support/Keyboard\ Maestro. Use with and without enable to automate the macros off and then back on.

Safari History

No one wants their personal browsing history to pop up during demos in Safari as part of auto-completion suggestions. (Imagine, if you will, typing “s”, and having all your sloth sites listed as possible completions. Or, heaven forfend, things worth than sloth sites.)

If you use iCloud bookmarks, you can disable iCloud, remove your history and bookmarks files from ~/Library/Safari, and relaunch Safari (open /Applications/Safari.app). To re-enable, restart iCloud and wait for the data to sync back to your Mac.

I automated file deletion (actually, moving the files to another location) once iCloud is off and after quitting Safari (killall Safari). However, I didn’t automate enabling/disabling iCloud Safari bookmark sync from the command line. Instead, I used open 'x-apple.systempreferences:com.apple.preference.icloud' to get me to the right place for a single check mark toggle.

I hide my favorites bar:

defaults write com.apple.Safari ShowFavoritesBar-v2 false

Use true instead of false to restore.

You may want to limit Autofill and Search options (Safari > Preferences > Autofill and Search). I didn’t as they don’t really impact my presentations. I’m okay with Safari providing Search Engine-supplied suggestions, especially when searching for tech topics, as for me these are features not bugs.

System Calls

Here’s my ancient code to perform system calls to execute all the setup and teardown without using system(). Although lightly updated, I haven’t spent a lot of time improving something that works. If you have better solutions, please let me know:

extension NSString {
  /// Trim output
  var trimmed: String {
    return self.trimmingCharacters(in: .whitespacesAndNewlines)
  }
}

/// Execute a command as a shell script
@discardableResult
func perform( _ command: String) -> [String] {
  let task = Process()
  (task.launchPath, task.arguments) = ("/bin/sh", ["-c", command])

  let pipe = Pipe()
  task.standardOutput = pipe
  task.launch()
  
  let data = pipe.fileHandleForReading.readDataToEndOfFile()
  task.waitUntilExit()

  if let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)?.trimmed {
    return output.components(separatedBy: "\n")
  }
  
  // Something went wrong
  print(task.terminationStatus); return []
}

Better table processing

Thanks to Andy Lester:

#! /bin/sh

# Process pasteboard contents to md table. Thanks, Andy Lester.
# Copy table from Numbers or other tab-delimited spreadsheet.
pbpaste | perl -le'$_=<>;&x;s/[^|]/-/g;&x;for(<>){&x}sub x{chomp;s/\t/|/g;print"|$_|";}' | pbcopy

# Done.
echo "Styled pasteboard to table"

Converting spreadsheet data to Markdown

I find it’s a lot easier to prepare a table with Numbers than by hand. I was using this today and thought I’d share the how-to.

Step 1: Select the material you want to table-ize.

Step 2: Paste it into text edit. Numbers uses tab delimiters (at least it does for me).

Step 3: Use find/replace to replace all tabs with a vertical pipe symbol (|). Copy any of your tabs to populate the find field.

Step 4: Use find/replace to replace all newlines with the sequence pipe symbol – newline -pipe symbol. Copy a newline from your text to the find field and in the replace field type |, then paste the newline again, and then type | again.

Step 5: Add pipe signs to the start and end of your file. Before:

After:

Step 6: Duplicate the first line and replace all text between bars with dashes:

Step 7: If you have an empty left-top-corner like I do, add at least 3 dashes to the 2nd line between the first set of pipes:

And you’re done.

Are you red-green color blind? How do you handle git color coding?

Git version control, whether at the GitHub site or at the command line is ostentatiously color-coded. How do red-green color blind users (a common issue for Engineers) deal with this? Any suggestions for discussing how to use the alerts and coding as in the following screenshots aimed at a potentially color blind audience? Thanks in advance!

Untracked and tracked files are color coded

Additions and deletions are color coded

Pushing the gist envelope: gists with pics and zips

People often don’t realize how powerful GitHub’s gist pasting service is. It’s more than just a “paste” site. Gist offers a full version control system extension to GitHub’s main site. I’ve been working on developing version control training materials and gist is a great way to introduce the fundamentals.

Many gist users know that the site offers you pushbutton convenience to paste one or more files. You can create open gists and “secret” ones hidden from public view. Gist also lets you fork, revise, and explore diffs between revisions.

For example, you can work in groups when writing. Collaborators can fork and make changes to offer content feedback. You can then use diffs to see what edits were made.

Here are some diffs from a recent Raw String proposal I worked on:

And this is the corresponding “rich diff”, which is slightly prettier:

And there’s a lot more you can do with gist. That’s because gists, as version control repositories, can be cloned to your computer, modified, and pushed back to GitHub. This means you can, for example, set up albums of pictures or host an easy-to-distribute zip file.

Each gist URL is a repository’s address:

git clone https://gist.github.com/erica/7cd24c6ab2f737735a9ab2b95628c549

As a gist’s owner, you have commit privileges, allowing you to edit your gist from your computer.

The command line enables you to add binary files that you can’t from the web interface. I grabbed a bunch of kitten pictures from Pexels and added them to my gist. A nice way to create simple albums:

If you click “Download ZIP” at the top right, GitHub zips up the repository contents (in this case five kitten PNGs) and copies them to your computer. This is not cloning; the zip file just stores the source files, not the full git repo.

It’s just as easy to host an archive file. When you have an Xcode project or playground that you need to share, Gist provides a great intermediate service alternative to iCloud or Dropbox. If you need privacy, use the “secret gist”  button when creating the gist.

This isn’t, of course, the end of what you can do with gists. Because each gist is a git repository, you can perform all the same commands you would in any git repo. Gist, of course, has a limited interface, so you won’t be able to, for example, switch between branches from the gist website. On the other hand, you can perform other tasks that don’t depend on a GitHub UI like listing diffs:

% git diff cb9271da5070f11602d3ab436a05fb9705409fd2
diff --git a/raw.md b/raw.md
index 8ed7306..ea4b5ed 100644
--- a/raw.md
+++ b/raw.md
@@ -104,9 +104,8 @@ Escaping hinders readability and interferes with inspection, especially in the l
 
 ### Candidates
 
-A good candidate for raw strings:
+A good candidate for raw strings is non-trivial and is burdened by escaping because it:
 
-* Is non-trivial.
 * Is obscured by escaping. Escaping actively harms code review and validation.
 * Is already escaped. Escaped material should not be pre-interpreted by the compiler.
 * Requires easy transport between source and code in both directions, whether for testing or just updating source.

I think GitHub’s gists are pretty awesome. And now, at least for me, they’ve gone from handy but mindless pastes to something really special.

Do you have a special way to use gists? I’d love to hear about unconventional ways to use this utility site to push boundaries and introduce new functionality. Drop a comment or an email and let me know.

Using TextEdit as your git editor

For a little while, I’ve been using emacs as my git editor because I strongly feel that vi is something that should happen to other people. It’s been fine but not everyone loves emacs or likes the debris it leaves in its wake. So I thought I’d try out TextEdit instead.

After a little testing of approaches, I first tried out this:

git config --global core.editor /Applications/TextEdit.app/Contents/MacOS/TextEdit

I picked this rather than some of the other approaches because it’s straightforward in launching the app. There’s one problem though, which is that git doesn’t pick up on the fact that a file has been edited and closed when the application remains active:

% git commit --amend 
hint: Waiting for your editor to close the file... 
(...waits forever...)

The commit completes and works when I quit TextEdit but I don’t like  to quit the app each time I update a commit, especially if I have other files open. The amended commit does complete on quit:

% git commit --amend [master 59a0934] Testing TextEdit!
Author: erica <erica@ericasadun.com>
Date: Thu Jul 12 08:02:26 2018 -0600
1 file changed, 3 insertions(+), 1 deletion(-)

So I changed my approach. I turned to open instead:

git config --global core.editor "open -W -n"

TextEdit is open‘s natural environmental editor for text. You don’t have to specify more than open for git to work with the right editor.

This approach uses two tweaks. When you launch an app with open, the -n flag instructs open to launch a new instance of the application even if one is already running. You may see two “TextEdit” icons open in your dock, for example.

Combine -n with -W and you have a slightly better solution.  The -W “wait” flag tells open to keep waiting until the launched application has finished running. This allows git to to wait “for your editor to close the file”, which you do by quitting TextEdit. Sure, I’d much prefer that TextEdit run using a “single file” mode, but this isn’t a bad solution.

Sadly, I couldn’t find any undocumented launch flags to make TextEdit run in single file mode and while it’s easy enough to write a Mac app that edits a single file at a time and quits on closing, it’s not a practical solution for everyone.

Is there a way to automatically propagate “done” back to git without ending a TextEdit process? I couldn’t find one. If you have a better idea, please let me know.

My Mac mini, kernel_task, and dusty hardware: Bring back my mini’s zing

Over the past few weeks, my Mac mini has been getting less and less responsive. The kernel_task has been spinning up taking up ridiculous amounts of CPU time and dragging my system to its knees.

I did what anyone would: I ran hardware diagnostics (passed). I ran SMART diagnostics (passed) and then I web searched the hell out of the interwebs, and there I found an unusual suggestion. Several sites suggested that I may have built up dust accumulation in my mini and that the fan control was trying to mitigate this.

Fortunately, I’m one of the lucky ones (for very low values of “lucky”) with a self-serviceable 2012 Mac mini instead of the upgrade a few years later that removed the service hatch. (*shakes fist*. *darn you Apple.*)

I opened it up and sure enough it was pretty dirty in there. I vacuumed and then I used compressed air to finish (after finding the child who had “acquired” it for an “important project” several months ago and never returned it). I performed a thorough vac and dust of the work area where it rests along with my many backup and external data drives.

Plugged it back in and for nearly a week so far I have not had the same issues reoccur. It seems a tiny bit black magic but it also seems to be working (fingers crossed).

I thought I’d write up a quick post to share my experience and see if anyone else has been through this and has advice or suggestions. For me, it’s like having my Mac back again. I still need a refreshed mini (hint Apple hint) but I have serious concerns about buying one without a self service hatch.

Apple’s move away from self-service products has cemented its appeal as a “computing appliance” provider but it also means expensive service calls for any problem. Much as I’d like them to give us a Mac Pro Lite, at a lower price point than the Pro and a higher one than the mini, with lots of configuration options,  I just cannot see that kind of product ever existing in today’s Applesphere.

A lot of us mini owners cling tenaciously to our six-year-old hardware (or, for some, 4 year old), but I’ve seen no indication that the mini has a future at all in the lineup. If it’s not a product appealing to the BMW owner set or essential for internal Apple use, I don’t really see it having a place in Apple’s marketplace.

One indication against this gloom is Apple’s magnificent iPod line, which has at least gotten semi regular updates. The iPod touch is about the best value you can buy with an Apple logo on it outside of the core iPad released this past March. Both fit into if not BMW owner appeal, then at least BMW owner’s kids appeal. I just don’t see the Mac mini doing that.

Is the mini dead forever? I’m not sure. I like bringing my own displays, my own mechanical keyboard, and thousands and thousands of dangled USB add-ons. That’s what a desktop does for me and why the (self service) mini is the perfect fit.

If you want to point at one change Apple made that said to me: “No mini for you, move to the left!” a la that Seinfeld episode, it was the death of the escape key. The escape key philosophically services a self-reliant power user. And I’m just not sure that Apple is in that market anymore.

Will I get my mini pro? Probably not. Will there be a paradigm shift so profound that customized dev systems can co-exist with mechanical keyboards using a new desktop system? Maybe. What do you think? Are you a mini devotee? Share your thoughts.