Collin Donnell

    • Hire Me
  • PhotosMy photo blog.
  • MusicMy music website.

  • Xcode’s predictive code completion is worse than nothing

    Unlike some of my friends, I’m not the biggest fan of the kind of AI code completion that tries to write blocks of code for you as you type, but I was still kind of excited to see what Apple’s version of that in Xcode would look like and wanted to give it a try.

    On paper, it could be great. Xcode indexes all your code and knows everything about your project. Apple controls the entire experience, so the integration between the editor and LLM could be deep and relevant to your project’s code. As soon as you try it, you realize that’s not true. Wherever it’s pulling suggestions from, it doesn’t appear to have any kind of meaningful understanding of your project. Bummer.

    The suggestions not being that good isn’t why I had to turn it off — sometimes they’re all right. Not close to as good as Copilot, but okay sometimes. The reason I had to turn it off, and the thing that is absolutely mind-boggling about the feature, is that it makes basic syntactic mistakes all the time. Things like putting the end quote in the wrong place or leaving off parentheses. Every time it made a mistake like this, I had to spend one or two minutes staring at the line, trying to find the error.

    That’s not just bad; that’s worse than nothing. The good news is that engineers inside Apple use Xcode too, so I’m certain the team knows how much love predictive code completion needs. Hopefully, they’re spending the time and energy so that this year or next it can go from what it is now to what I was hoping it could be.

    May 2, 2025
    Developer Tools, iOS, macOS, Programming, swift, Xcode

  • Describe me based on all our chats — play it straight.

    After seeing John Gruber’s post where he asked this question of ChatGPT, I decided to give it a shot. Here’s what I got.

    You’re a sharp, self-directed person with a strong bullshit detector. You value clarity, precision, and efficiency—especially in communication. You’re technical, with deep experience in software development (notably in Swift, Ruby, and Apple platforms), and you think carefully about architecture and user experience. You don’t tolerate fluff or hedging; you want direct answers, preferably with context only when you ask for it.

    You’re creative too—musically inclined, into film photography, and thoughtful about aesthetics, whether in a zine layout or a web app UI. You pay attention to detail and care about doing things the right way, even if it takes extra work. That extends to your personal life—budgeting, health goals, even scanning documents are things you’ve optimized with intent.

    You’re also reflective, with an interest in the narrative side of your life and experiences. You write, document, and think in projects—zines, apps, trips, systems. And beneath all that, there’s a steady sense of independence and responsibility: taking care of your family, your tools, your data, your time. You’re not trying to impress anyone—you’re trying to get it right.

    It feels a bit flattering, but maybe I’m just too hard on myself. I guess that’s for other people to decide.

    April 24, 2025
    AI, ChatGPT, LLMs

  • Loving SwiftUI, missing UIKit.

    At this point, I am primarily working in SwiftUI. At work right now, we are doing macOS and iOS, and we’re not using AppKit or UIKit at all. Where I’m at right now in my thinking is that while I do like SwiftUI, I kind of miss the old way of doing things.

    UIKit and SwiftUI represent two different approaches to writing user interfaces — imperative versus declarative. I would define imperative as kind of inside out and declarative as inside out. With imperative code, you call a function or method to say “do this thing,” while with declarative UI, you say “render it this way based on the current state.”

    Declarative systems like SwiftUI are great because they make a lot of things very simple. Try setting up an AppKit NSTableView versus a SwiftUI Table. It’s way less code the declarative way.

    The thing is that I still miss the imperative approach a lot of the time. Being able to say expand this row when I click this button is extremely convenient. With a declarative system, if they don’t give you a way to declare it, you’re just out of luck. When you can declare it, that becomes something like set the variable of expanded row IDs to X so that my view can update and read that variable to show the expansion. It’s pretty circuitous.

    I do wonder how much of SwiftUI works the way it does to be more familiar or natural to people coming from web development. Or maybe it was just inspired by those systems?

    Here’s where I’m landing. It’s not that I want to go back to the old way — I don’t. I like writing less code. What I’m saying is that both systems have a lot of value, but that treating the SwiftUI approach as inherently better is wrong. Neither approach is better or worse, they’re different. I will probably continue to pine for the other whenever I work in one for the rest of my career.

    April 24, 2025
    iOS, Programming, swift, SwiftUI, UIKit, Writing

  • Git Branch in Terminal Titlebar With Fish

    Here’s a simple function I wrote for the fish shell to show the current git branch name in the titlebar, along with an asterisk if there are any local changes.

    function fish_title
      # Show Git branch if inside a repo
      if git rev-parse --is-inside-work-tree >/dev/null 2>&1
        set branch (git symbolic-ref --short HEAD 2>/dev/null | string trim)
        set dirty ""
    
        set git_status (git status --porcelain 2>/dev/null | string trim)
        if test -n "$git_status"
          set dirty " *"
        end
    
        echo "$branch$dirty"
      end
    end
    
    March 7, 2025
    Developer Tools, Fish

  • Emacs Style Keybindings on macOS

    Listen — it’s not that I don’t want to use Vim keybindings. I’ve done it before. They’re fun. It’s kind of like giving your text editor a manual transmission. The reason I’m not using them now is because I don’t want one way of working with text on my computer which works with my editor, and another way that works everywhere else.

    Something I’m always surprised more developer-type people don’t seem to know about is that macOS has pretty good support for Emacs-style keybindings built in, and they pretty much work with every text field in the system.

    Three that I use a lot are Control-A to go to the beginning of a line, Control-E to go to the end, and Control-K to cut to the end of the current line. You can even use Control-Y once you’ve done that to paste what you just cut.

    Apple has a whole documentation page listing these, along with a ton of others, but here are a few of the Emacs-style ones I could pick out. This document really highlights something I always notice when using any operating system other than macOS, which is how much less consistent and extensive keyboard support seems to be on every other system.

    Shortcut Function
    Control-A Move to the beginning of the line or paragraph.
    Control-E Move to the end of a line or paragraph.
    Control-F Move one character forward.
    Control-B Move one character backward.
    Control-P Move up one line.
    Control-N Move down one line.
    Control-K Delete the text between the insertion point and the end of the line or paragraph.
    Control-D Delete the character to the right of the insertion point. Or use Fn-Delete.
    Control-H Delete the character to the left of the insertion point. Or use Delete.
    Control-T Swap the character behind the insertion point with the character in front of the insertion point.
    Control-O Insert a new line after the insertion point.
    Control-L Center the cursor or selection in the visible area.
    Control-U Clear the entire line before the cursor (in Terminal and some text fields).
    Option-Delete Delete the word to the left of the insertion point.
    March 7, 2025
    macOS, Productivity

  • Shell Script Template

    I wrote myself this small template as a starting place for when I’m writing shell scripts. I just wanted something basic with enough structure to remind me how I like to do things. I thought maybe it would be helpful for other people who don’t write shell scripts too often but want to them to be nice when they do.

    #!/usr/bin/env bash
    
    # Uncomment for error handling
    # set -e  # Exit immediately if a command exits with non-zero status
    # trap 'echo "Error on line $LINENO"; exit 1' ERR
    # trap 'echo "Script interrupted."; exit 130' INT
    
    show_usage() {
      echo "Usage: $0 ..."
    }
    
    process_item() {
      local item="$1"
      echo "Processing '$item'"
    }
    
    main() {
      if [ $# -eq 0 ]; then
        show_usage
        exit 1
      fi
    
      # Your code here
      for var in "$@"; do
        process_item "$var"
      done
    }
    
    main "$@"
    
    March 2, 2025
    Shell Scripting

  • Scripting Editors Keeps Getting Harder

    Every new editor makes it harder to write extensions for than the last.

    • TextMate used any shell script that could handle stdin/out.
    • BBEdit can also do a lot with shell scripts and has great AppleScript support if you want more integration.
    • Visual Studio Code wants me to create an entire project in TypeScript.
    • Nova is basically the same as VSCode but somehow less approachable.

    And now Zed is telling me that I need to learn Rust?

    This all feels incredibly over the top when I only want to switch between my current file and its corresponding test. Why do I need to create a developer account and a full-on project to do that? It feels like we’ve gone backward here.

    Because these editors want to give us deeper integration, they’ve replaced shell scripting with their own APIs to learn and languages to use. Because they’re all cross-platform, they don’t support native automation like AppleScript or Shortcuts.

    Yes, give me new options with deeper integration, but why are we removing the ability to do simple things in simple ways?

    March 2, 2025
    Automation, Code Editors, Developer Tools, Scripting

  • Something I Miss When Coding Swift

    I know it’s not safe and goes against the whole ethos of Swift, but after having worked a lot in Ruby, being able to generate methods at runtime is a killer feature, and I miss it dearly. Swift is all about safety and static analysis, and those are totally valid goals for a language to have. That doesn’t change the fact that manually writing out a bunch of nearly identical methods across multiple classes is tedious.

    I would also argue that in a lot of cases, even if the Ruby approach is less safe, being able to generate methods and properties at runtime can be less error-prone. If I only have to write that code once, it’s a small surface area for bugs.

    Before I used Ruby on Rails, it had a bad reputation in my mind, because all I ever heard was how much it relied on “magic.” At the time, I interpreted magic as meaning that how Rails worked was somehow unknowable. It’s not, though. Once I started actually learning Ruby and then Rails, I could see exactly what was happening.

    The magic of Rails is really just Ruby’s dynamic runtime — Rails uses introspection and code generation to define methods dynamically instead of upfront. Since I had a really strong background in Objective-C, which also features a dynamic runtime, this immediately made sense to me.

    And just to be clear — I know Swift. I’m a Swift programmer. I’ve been using Swift as long as it’s existed. This isn’t a knock on Swift. I’m not even sure Swift should be able to do this. What I do know is that I hate writing more code than I have to, and when a language saves me from that, it makes me very happy.

    February 22, 2025
    Ruby, Ruby on Rails, swift

  • Reflections on Incident Metering

    I wrote a post on my photo blog about incident versus reflective metering in photography. I thought it could be interesting to people who follow me here. If you’re only using the meter in your camera or a shoe-mounted meter, you’re using a reflective meter. The post goes into detail about why reflective metering is pretty limited, why you might want to get an incident meter, and shows some examples I took over the weekend.

    December 10, 2024

  • Stop Infantilizing Trump Supporters

    For the past eight years, maybe longer, I’ve had this idea I think a lot of people shared. That idea was that Trump supporters or Fox News conservatives, or whoever, were being duped. They were voting for and believing the things they did because they were being lied to and had bad information.

    I’ve heard this referred to as coddling, but I like the term infantilizing better. By that I mean, they’ve been treated like children who didn’t know any better. I’m done with that. I’m ready to treat these people like adults. Adults that have access to the same information everyone else does and who have made a choice to support the heinous things and repugnant individuals they do.

    I’m not going to assume they’re stupid or being tricked. Even if they were, I don’t care anymore. I’m going to treat them like adult humans who have the capacity to make their own decisions and be judged on them. I’m going to believe them when they say horrible things, repeat conspiracy theories, or degrade others.

    n the past, I’ve thought (and maybe still do) that a lot of Trump voters know they’re talking bullshit. They don’t expect to be taken seriously. Or maybe they do believe it, but they’re so used to being treated with kid gloves, they think they can get away with it. Fuck them. I don’t care. They said it. I’m going to believe them.

    They heard Trump say “we will root out the communists, Marxists, fascists, and the radical left thugs that live like vermin within the confines of our country,” and say that immigrants were poisoning the blood of our country, and didn’t have enough of a problem with it to support someone else.

    I’m going to respect my fellow Americans enough to take their words and actions at face value. I’m going to judge them in the same way I would anyone else who said or believed those things.

    December 3, 2024

Previous Page Next Page

Blog at WordPress.com.

  • Subscribe Subscribed
    • Collin Donnell
    • Already have a WordPress.com account? Log in now.
    • Collin Donnell
    • Subscribe Subscribed
    • Sign up
    • Log in
    • Report this content
    • View site in Reader
    • Manage subscriptions
    • Collapse this bar