Okay, I hit a rabbithole today. I'm not saying it's not fun, but probably not my smartest use of time.

Long story shorter than I want, I find myself googling "SSMS equivalent on macOS" fairly often, meaning [Microsoft] SQL Server Management Studio, the Windows-specific tool you use not simply to manage SQL Servers via a GUI, but to throw raw T-SQL at it and view the results. It's barely changed since at least the 1990s.

I used to use SQuirreL-SQL on Mac a lot when I dabbled (and also worked!) in Java, which really came in handy once when my boss didn't realize we were installing a Java app dbms onto a Linux-only network, and I briefly enjoyed Azure Data Studio until it got 86'd.

Azure Data Studio was introduced as a lightweight, cross-platform tool tailored for database professionals working with SQL Server, Azure SQL Database, and other data platforms. It provided a modern interface, integrated notebooks, and extensibility through extensions. However, over time, the overlap between Azure Data Studio and Visual Studio Code became increasingly apparent. Both tools shared similar architectures, extensibility models, and even some of the same extensions.

It would probably still work great, but it's frustrating that yet another MS tool got tossed into a VS Code extension. Look, VS Code is cool, but it's not an IDE. It feels like chicken wire and duct tape on a good day. And the last thing I want to do is have MORE things living in this single scripting app. I like dedicated apps, for heaven's sake.

But you know what I've done for nearly thirty years now? Written apps that interface with SQL Server! Why don't I just write my own query client for SQL Server!

Ah, but with what UI? Originally, I figured why not just the console? In an hour or so, I got a pretty simple client up that would send queries and parse up results into columns of plain text. Not too shabby!

My introduction to TUIs

But was that enough? Of course not! We need a true console app, whatever that is, that intelligently formatted results and allowed complex SQL edits, not just line by line input.

I started by wading into Spectre Console which allows you to style console text like mad and even has some neat widgets like this table, but it also says it's not really about complex UI management:

Thank you for posting an issue, but this goes beyond the scope of what Spectre.Console is, so this is not something that we will consider. I would recommend you to take a look at something like Textual or GUI.cs

Also all its widgets are output-minded, not truly interactive. Okay, fine. Fair.

Next up was Terminal.Gui, which seems to be a modern, C#-powered take on the sort of 1980s style DOS apps that you still find in backwater DMVs and tax preparer offices (I'm seeing a TurboTax commercial running during Celtics-76ers making fun of just such a UI now). Which is awesome! Except it was immediately buggy on macOS, and even when I got that working, the first text editing widget I tried allowed text entered to bleed into the widget under it. So that's a mess. Next?

I've played with C#'s Console objects a bit before. How tough can writing my own TUI views from scratch be?

Insanely. It's insanely tough. I've copiloted the heck out of this today, and, you know, it turns out writing a text editor in a console is a pita.

The toughest part? You have to manage all the scrolling. And since you're in a console, you lose all the built in cursor movement... if you want to insert instead of overwrite, that takes some work. And if you want to go to the end of the line, well, the macOS Terminal eats command-right arrow (which means "end") and uses that combo as a shortcut to go to the next terminal window instead.

Solutions? Well, rather than reinvent the wheel, I find that readline on Linux has a lot of solutions. Here are some good ones:

  • C-b
    • Move back one character.
  • C-f
    • Move forward one character.
  • DEL or Backspace
    • Delete the character to the left of the cursor.
  • C-d
    • Delete the character underneath the cursor.
  • C-a
    • Move to the start of the line.
  • C-e
    • Move to the end of the line.
  • M-f
    • Move forward a word, where a word is composed of letters and digits.
  • M-b
    • Move backward a word.

I'm starting to see why vi was born. Though apparently I'm also learning Emacs now too (the above shortcuts are the same in Emacs, maybe?).

So throw those in. Awesome! A little esoteric, but that'll do, pig.

Except the Meta ones aren't working...

Guess what?!

Why that happens

  • On macOS Option by default produces alternate characters (Option+B โ†’ โˆซ on many layouts).
  • Terminal.app only treats Option as Meta if you enable "Use Option as Meta key" (or remap the key). Otherwise the terminal sends the Unicode character.
  • .NET's Console reports what the terminal sends: a character with no ConsoleModifiers in this case.

How to get Meta-M (M-b) behavior instead

  • Terminal.app โ†’ Preferences โ†’ Profiles โ†’ Keyboard โ†’ check "Use Option as Meta key" (or add a custom mapping to send ESC+b).

[thanks GPT-5 mini]

And there you have it. That's a lot learned today. Not sure I needed the history lesson or to write a scrollable text view for a rich console app, but I've taken on both, nonetheless.

Labels: , , ,