Showing posts with label mac. Show all posts
Showing posts with label mac. Show all posts

Mac keyboard with hidutil #

[Update: 13-Apr-2023 with some of the background context and some things I learned from hackernews]

[Update: 18-Dec-2023] This hidutil stopped working for me in MacOS 13.6 and 14.2. Also see other people having problems too.

[Update: 28-Jan-2024] Some people say hidutil works again in Mac OS 14.3.

On my Mac, I've used KeyRemap4Macbook, Karabiner, Karabiner Elements, and FunctionFlip for some of my key remapping needs. The main things I want:

  1. On the laptop keyboard, some media keys should be function keys but other media keys should stay media keys. When using fn I want to get the other version of the key.
  2. On external keyboards, make the function keys act like the laptop keyboard.
  3. On external keyboards, the numpad should act like "numlock off". For example, 4 should be Left Arrow.
  4. On external keyboards, the Windows key should act as Option, and the Alt key should act as Command. This can usually be set in the System Preferences. (Except it doesn't work on one of my keyboards)
  5. I also use those same external keyboards with my Windows and Linux machines, so I prefer to make these changes through software rather than firmware.

Labels: ,

Building Emscripten on Apple ARM M1 #

Update: [2021-01-24] The workarounds in this blog post are now obsolete, as openjdk, yuicompressor, and emscripten are now available in ARM homebrew.

On Mac, Emscripten is available in the Intel version of Homebrew, but not the ARM version of Homebrew. I use Emscripten rarely enough that this doesn't bother me. However, I thought I'd try compiling it on the ARM version.

I couldn't get openjdk working in ARM homebrew, but I was able to get emscripten installed in ARM homebrew by using the Intel/Rosetta version of openjdk:

Labels: ,

Building Emacs 27 on Apple ARM M1 #

On Mac, I sometimes run a prebuilt binary and sometimes compile my own. For Apple M1 (ARM) I started by using the x86 binaries from emacsformacosx.com but I wanted to try compiling a native ARM version too. I saw that the work branch of Mitsuharu Yamamoto's Mac port has M1 patches applied, so I decided to try it.

Screenshot of Emacs 27 compiled on Apple ARM M1

Labels: , ,

iTunes Sync Error -256 #

This was a mystery.

I had been messing with my photo sync settings in iTunes, so that I could get more photos onto my iPhone. I started getting this iTunes sync error, -256. I googled for this but naturally Google ignored "256", as it seems to enjoy ignoring the most important words in my queries. I couldn't find an answer, and I had no luck deleting and resyncing photos. I decided I should wipe the phone and restore from backup at some point, but "not today".

A few weeks later (today) I discovered the real culprit. At some point in the past few months I had accidentally deleted podcast files in iTunes. I had restored the iTunes catalog file, and I had restored the files themselves from Trash. Or so I thought. I discovered today that I hadn't gotten them all. Once I fixed that (by deleting in iTunes and telling it to download them again), the photo sync worked again!

Grr1: iTunes does too many things, and it's hard to diagnose errors. Grr2: "error -256" is unhelpful. If it told me what it was doing at the time, it would've helped me realize it was podcasts and not photos that were the problem. Grr3: iTunes catalog and the files on disk can get out of sync; this is fragile.

I'm writing this blog post so that if anyone else has error -256, and convinces Google not to ignore that term, they might find a solution here.

Labels:

Building Mac OS X Emacs 26 #

On 11 Oct 2017 Emacs 26.0.90 pretest was released. For Mac, there's a build on emacsformacosx.com. I have been using the "Mac port" from Mitsuharu Yamamoto because it feels smoother and faster on my system, and I decided to try his development branch. Here's what I ran:

brew install gnutls texinfo libxml2
cd ~/Projects/src
git clone --branch work --depth 1 https://bitbucket.org/mituharu/emacs-mac.git
cd emacs-mac
./autogen.sh
export PATH=/usr/local/opt/texinfo/bin/:$PATH
export PKG_CONFIG_PATH=/usr/local/opt/libxml2/lib/pkgconfig
./configure --with-mac \
     --prefix=/PersonalApplications/Emacs.app/Contents/MacOS \
     --enable-mac-app=/PersonalApplications
make
make install

It runs nicely!

A minor note: the byte-compiled .elc files compiled under Emacs 26 are not compatible with Emacs 25, so if you go back to an older version, you'll need to recompile the .elc files.

Labels: , ,

My OS X Karabiner setup #

On Mac OS X, there's a fantastic tool called Karabiner (previously KeyRemap4MacBook) that lets you control how your keyboard and mouse work — things like keyboard repeat rate, mouse acceleration, arrow keys, function keys, control/escape/shift/option/fn, adding keys to enter unicode characters, and many other things. I use it primarily for remapping the function keys. On my laptop, I want F1,F2 to control brightness, F3,F4,F5,F6,F7,F8,F9 to be function keys, and F10,F11,F12 to control volume. Mac OS X offers in the System Preferences a choice of having them all be function keys or all be special functions. I want five to be special functions and seven to be function keys. Karabiner lets me do that.

Karabiner's standard settings dialog lets me swap just some of these keys. First, I told Mac OS X to make them all function keys. Then in Karabiner, I selected

  • Change F1..F19 Key & Functional Key
    • Change Functional Key
      • Fn+Functional Keys to F1..F12
        • [X] Fn+Brightness Adjust to F1,F2
        • [X] Fn+Speaker Controls to F10,F11,F12
    • Change F1..F19 Key
      • F1..F12 to Functional Keys
        • [X] F1,F2 to Brightness Adjust
        • [X] F10,F11,F12 to Speaker Controls

Great! It now behaves how I want.

Except… I want more! Once I got an external keyboard, I wanted the function keys to behave differently. The external keyboard has its own volume keys, so I don't want them swapped there. I use it with an external display, so the brightness keys aren't useful to swap.

Karabiner offers an XML configuration file when the standard settings dialog isn't enough. Reading the XML file format documentation, I saw that I can restrict certain settings to only run in some apps or some devices. I came up with this equivalent for the above settings (and then later realized all the built-in settings have XML files like this one):

  <item>
    <name>Swap F1,F2 with Brightness keys</name>
    <identifier>amitp.brightness</identifier>
    <autogen>__KeyToKey__ KeyCode::F1, ConsumerKeyCode::BRIGHTNESS_DOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::F2, ConsumerKeyCode::BRIGHTNESS_UP</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::BRIGHTNESS_DOWN, KeyCode::F1</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::BRIGHTNESS_UP, KeyCode::F2</autogen>
  </item>
  <item>
    <name>Swap F10,F11,F12 with Volume keys</name>
    <identifier>amitp.volume</identifier>
    <autogen>__KeyToKey__ KeyCode::F10, ConsumerKeyCode::VOLUME_MUTE</autogen>
    <autogen>__KeyToKey__ KeyCode::F11, ConsumerKeyCode::VOLUME_DOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::F12, ConsumerKeyCode::VOLUME_UP</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::VOLUME_MUTE, KeyCode::F10</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::VOLUME_DOWN, KeyCode::F11</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::VOLUME_UP, KeyCode::F12</autogen>
  </item>

However, I want to swap these keys only on the laptop keyboard. I used Karabiner's Event Viewer helper application to figure out that my laptop keyboard's device id was 0x0259. I could then modify the settings to only apply to my laptop keyboard:

  <deviceproductdef>
    <productname>Apple_laptop</productname>
    <productid>0x0259</productid>
  </deviceproductdef>
  <item>
    <name>Swap F1,F2 with Brightness keys</name>
    <appendix>For laptop keyboard only</appendix>
    <identifier>amitp.brightness</identifier>
    <device_only>DeviceVendor::APPLE_COMPUTER, DeviceProduct::Apple_laptop</device_only>
    <autogen>__KeyToKey__ KeyCode::F1, ConsumerKeyCode::BRIGHTNESS_DOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::F2, ConsumerKeyCode::BRIGHTNESS_UP</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::BRIGHTNESS_DOWN, KeyCode::F1</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::BRIGHTNESS_UP, KeyCode::F2</autogen>
  </item>
  <item>
    <name>Swap F10,F11,F12 with Volume keys</name>
    <identifier>amitp.volume</identifier>
    <appendix>For laptop keyboard only</appendix>
    <device_only>DeviceVendor::APPLE_COMPUTER, DeviceProduct::Apple_laptop</device_only>
    <autogen>__KeyToKey__ KeyCode::F10, ConsumerKeyCode::VOLUME_MUTE</autogen>
    <autogen>__KeyToKey__ KeyCode::F11, ConsumerKeyCode::VOLUME_DOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::F12, ConsumerKeyCode::VOLUME_UP</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::VOLUME_MUTE, KeyCode::F10</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::VOLUME_DOWN, KeyCode::F11</autogen>
    <autogen>__KeyToKey__ ConsumerKeyCode::VOLUME_UP, KeyCode::F12</autogen>
  </item>

It works great!

I also solved another annoyance. My external keyboard always sends number keys from the number pad, and I'd rather send arrow keys. Karabiner can do that too. I had to find the device vendor and product id from the event viewer, and then I used these settings:

  <devicevendordef>
    <vendorname>KBTalking</vendorname>
    <vendorid>0x099a</vendorid>
  </devicevendordef>

  <deviceproductdef>
    <productname>Bluetooth_keyboard</productname>
    <productid>0x0100</productid>
  </deviceproductdef>
  
  <item>
    <name>Amit's Keypad</name>
    <appendix>Amit's keypad settings</appendix>
    <identifier>amitp.keypad</identifier>
    <device_only>DeviceVendor::KBTalking, DeviceProduct::Bluetooth_keyboard</device_only>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_5, KeyCode::F19</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_2, KeyCode::CURSOR_DOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_4, KeyCode::CURSOR_LEFT</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_6, KeyCode::CURSOR_RIGHT</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_8, KeyCode::CURSOR_UP</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_1, KeyCode::END</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_3, KeyCode::PAGEDOWN</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_7, KeyCode::HOME</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_9, KeyCode::PAGEUP</autogen>
    <autogen>__KeyToKey__ KeyCode::KEYPAD_DOT, KeyCode::FORWARD_DELETE</autogen>
  </item>

These small things have made my computing more pleasant. There's so much more that Karabiner can do, but I haven't explored most of its capabilities.

P.S. If you find Karabiner useful, consider donating.

Labels: ,

Annotating MP3 files with BPM #

I wanted to tag my music library with the BPM of each song. There are commercial products for doing this through iTunes, but I wanted to do it from the command line, because I also use my music library outside of iTunes, and I don't want to be tied to iTunes anyway.

The bpm-tools package can calculate bpm for a song. On Mac, it's easy to install with Homebrew. The base package only includes the analyzer; I wanted something to tag my MP3 files too, so I used the =-with-bpm-tag= option. It ends up installing dependencies: mad, sox, id3lib, id3v2, flac, libogg, libvorbis, libao, vorbis-tools.

brew install bpm --bpm-tag
cd Music/iTunes\ Music/
find . -name \*.mp3 -exec bpm-tag '{}' ';'

However, the id3v2 command (on Mac/Homebrew, anyway) doesn't work the way bpm-tag wants, and for some reason sed wasn't cooperating with me, so I changed one line of /usr/local/bin/bpm-tag from

BPM=`id3v2 -l "$FILE" | sed -n 's/^TBPM.*: \([0-9\.]\+\)/\1/p'`

to

BPM=`id3v2 -l "$FILE" | sed -n 's/^TBPM.*: //p'`

This made it skip files that already had a BPM tag.

It took a while to run, but now all my MP3 files have a BPM, and iTunes picks that up too. Yay!

Labels: ,

Mac OS: index source code #

A few weeks ago I posted how to make Mac OS Spotlight index source code. Mac OS is already indexing my C, C++, ObjC, Java, Fortran, Shell, Python, Perl, Ruby, Pascal, Ada, Javascript, and HTML files, but it doesn't get the other languages and text files I use. Here's the followup post.

Problem to solve: I want to search the contents of *.css and other text files with Spotlight.

In my previous blog post, I went into the Spotlight configuration file and told it to index certain file types like dyn.ah62d4rv4ge80e8drru, which I had determined was *.css. This wasn't satisfying. Instead of telling Spotlight, I wanted a solution at the Mac OS level.

Labels: ,

Mac OS: Spotlight and source code #

Mac OS X has a real time file indexing system called Spotlight. By itself, it's not terribly useful for me. What makes it useful is that it's accessible from the command line. I can search filenames:

locate mapgen2.as
mdfind -name mapgen2.as

The locate command relies on a database that's rebuilt nightly; mdfind is updated in real time. Spotlight also indexes the contents, which gives me something similar to recursive fgrep:

fgrep -R word *
mdfind -onlyin . word

It won't search for arbitrary regexps but for quickly narrowing down files to find certain words, it's useful.

Labels: ,

Extracting Safari's Reading List #

I use Safari's Reading List to transfer pages from my phone to my computer. But I don't really want to read these in Safari on my desktop. I'd rather read them in Firefox, maybe through Pinboard, which has an API to write items and mark them as "to read". This blog post documents what I learned.

Update: [2014-06-07] Deleting items out of the reading list does not work properly. It's ok to read everything out of there but I haven't figured out how to properly modify it. So I guess I need to delete things manually after I read them out.

Update: [2014-09-18] With iOS 8, I'm switching from Reading List to something else, maybe Pinner, to make this process easier.

I searched the web for some resources, and learned that the reading list, as well as other Safari bookmarks, are stored in ~/Library/Safari/Bookmarks.plist. I can use plutil and PlistBuddy to read and edit that file.

Labels: ,

Experiences with my Macbook Air #

Nearly two years ago, I got a Macbook Air. It's been nearly two years, and here are my thoughts:

Labels: ,

Bash Prompts on the Mac #

For a while now I've used colored prompts in bash. I typically make the machine name one color, the path another color, and the username bright red if I'm root. On some systems I show the date and time, the exit code of the previous command, whether I'm inside screen, or the ssh status. Other people have put the git branch, number of processes, job count, tty, system load, disk space, working files, or mailbox status into their prompts.

Labels: ,

Emacs: full screen on Mac OS X #

The methods for toggling full screen on Emacs/Mac vary by version. I've reorganized this post to document what I've used for various versions of Emacs. As of 2012-11-01 I was using the Yamamoto Mitsuharu version of Emacs, which has a very nice full screen mode; as of 2014-01-01 I switched to the Emacs 24.4 nightlies from EmacsForMacOSX.com, but I also suggest looking at the railwaycat emacs build, which is also available on Homebrew.

Carbon Emacs 22.2

You can run M-x mac-toggle-max-window to toggle full screen mode, with no menubar. This is handy enough that I've bound it to ⌘ Cmd+Return, which is similar to what some Linux and Windows apps use to toggle full screen mode.

(define-key global-map [(alt return)] 
  'mac-toggle-max-window)
Carbon Emacs 22.5

They seem to have removed the function from 22.2, but you can get it back with this code from Vebjorn Lsoja:

(defun mac-toggle-max-window ()
  (interactive)
  (set-frame-parameter nil 'fullscreen 
    (if (frame-parameter nil 'fullscreen)
      nil
      'fullboth))) 
Yamamoto Mitsuharu's Emacs Port

Use the mac-toggle-max-window function definition above.

GNU (Cocoa/Nextstep) Emacs 23

Neither approach above works with this version. Instead I'm using a patched version of maxframe.el, and this function from the EmacsWiki page:

(defvar maxframe-maximized-p nil "maxframe is in fullscreen mode")
(defun toggle-maxframe ()
  "Toggle maximized frame"
  (interactive)
  (setq maxframe-maximized-p (not maxframe-maximized-p))
  (cond (maxframe-maximized-p (maximize-frame))
        (t (restore-frame))))
(define-key global-map [(alt return)] 'toggle-maxframe)

Unfortunately this doesn't hide the menubar or titlebar.

For other versions, check the EmacsWiki page to see if there's a method that works on the version you run, or check this page for Aquamacs.

Labels: , ,

Why I got a MacBook Air #

Carrying case for the MacBook Air
My Air in its carrying case

I bought a MacBook Air. You know, that small puny computer that's been called a toy. The one that's overpriced. The one that fits in a manila envelope. Ha ha. I'm not going to review the product, but instead I wanted to explain why I ended up getting one. I wouldn't have gotten one if my MacBook hadn't deteriorated (due to my abuse), but since it was time to buy a computer, I spent a month evaluating how I use the computer, and ended up choosing the Air.

I've always been someone who enjoys the biggest, fastest, most powerful computer he can get. Until a few years ago, that's what I got. Back when people used CRTs, I got a 21" Sony that could display 2048x1536. I love high resolution (and still do) and love big screens (still do). Dual core? 64 bit? Lots of RAM? Love it! However…

Four years ago at work, I was assigned to a project in which I had to work in several different offices. They gave me a laptop for this. Eww. Tiny keyboard, slow processor, tiny screen, only 1400x1050 resolution. At the time Linux wasn't suitable for laptops so I got Windows on a Thinkpad. When I was in my main office I used my Linux workstation with a nice 20" LCD running at 1600x1200. But when I was away from there, I used the laptop with Cygwin + ssh + X to run things on my desktop, but display them on the laptop. It was less productive than having the big screen and full keyboard, but it was more productive than having nothing.

Then I discovered something. Portability is nice. Really nice. Really, really nice. I wasn't just working on that laptop in a few offices. I could work on the couch with the laptop in my lap. I could take it to meetings and show people the UI design on a projector. I could take it home and work from home. I could sit outside (if the lighting was right). The ability to move around was worth a lot to me. I found that although at my desk, the laptop is less productive than my desktop machine, the ability to move around (for example, find a quiet space away from distractions) made me more productive overall.

About two years ago I realized that even when I was back at my desk, I was still using my laptop. I almost never used the desktop machine directly. I did use it all the time for running programs. The laptop was a “dumb terminal” (X11 plus browser) for my desktop machine, and I could take it anywhere.

Once I realized how nice portability was, I decided to get a laptop at home. I wasn't thrilled with the idea of getting Windows, especially given that they'd be transitioning everyone from XP (which was reasonable) to Vista (which I'd heard horror stories about). So I decided to switch to Mac. I would've never switched when they had Mac OS 9 on PowerPC chips, but once they had a Unix base and on Intel chips, it became a reasonable option for me. I got a MacBook Pro. I've been reasonably happy with it.

Just as I transitioned from desktop to laptop at work, I found that I use the laptop for everything at home. Everything except games. For games I want Windows XP, a full sized trackball, a full sized keyboard, a big screen, a fast CPU, a fast graphics card, and nice speakers. I got none of this on the laptop. But for browsing, email, programming, editing, photos, music, and just about everything else, the laptop is great. So I now have a gaming desktop machine for games (and photos — I love Picasa on Windows and find iPhoto on Mac to be unpleasant) and a laptop for everything else.

At this point, a faster laptop wouldn't be any better, because I already have all the speed I need. I want: more battery life, lower weight, a screen that can be used outdoors, and higher reliability. Unfortunately none of the laptops I looked at were great. I'm sticking with Mac for now, but unfortunately the lightweight Mac laptops don't have great battery life (my Thinkpad got 7 hours, and newer ones can get 11). The Air does have a lower weight than my current laptop. With the flash drive I'm hoping for higher reliability, especially since I move around a lot when using the computer, and a majority of my crashes have been while moving the machine around. I generally prefer matte screens to glossy, but I've talked to several people who use glossy and say that it's much nicer than it initially seems. 64 GB is slightly small (100 GB is more than I need), but after going through my data and removing all the waste (like Apple's Mail app keeping two copies of all my emails, and the iPod sync program keeping a second, bloated copy of all of my photos), I think it'll be fine.

The Air seems like a reasonable upgrade for me, not for the usual things people want (CPU, graphics, RAM, disk, etc.), but for the things that matter to me (weight, size, reliability, portability). The standard complaints about the Air don't bother me: slow (it's as fast as my computer was two years ago, and somehow that didn't seem slow to me), battery isn't swappable (In 4 years I've never taken the battery out of my laptops), it's expensive (it does seem a little high, but that's always how it goes with early adopters, so if you're price sensitive, wait a few years), no DVD player or ethernet or firewire (I already don't use these).

My priorities have changed over the years. I used to want big: high speed, big storage, big screen, big computer, big keyboard, big mouse, high pixel count. Now I want small: low power consumption, low weight, easy to move around, ability to use anywhere. I can put the big stuff on servers; all I really want to carry around is a terminal — I can access my data remotely. The Air seems to be a good step in that direction.

Labels:

Mac OS X Keyboard Characters #

Sure, you Mac switchers already know about Mac OS X Keyboard Shortcuts, mostly using the ⌘ Command Key. If you're a typography geek like me, you'll want to explore all the useful characters (not commands) hidden behind the ⌥ Option Key.

⌥ + keyproduces this:…
[open double quote“
{close double quote”
]open single quote‘
}close single quote’
-en-dash–
_em-dash—
2trademark™
rregistered®
gcopyright©
;ellipsis…
/divide÷
*degree°
Rpermille‰
=not equals≠
+plus minus±
5infinity∞
8big bullet•
(small bullet·

There are some more, but I don't find them as useful. The keys probably vary by keyboard type; I use the US keyboard (not US Extended, which doesn't seem very useful). The best way to learn these is to go into System Preferences → International → Input Menu → Show input menu in menubar. Then go to the input menu in the menubar (a country flag) → Keyboard Viewer. Also fun to play with is the Character Palette; it lets you put in lots more characters, like ☛☆☺⏏℻♪. Exactly why these characters even exist in Unicode, I'll never know.

The typography geek in me says that the ⌥ Option Key is the best thing about switching to the Mac. Sure, some of you get the AltGr key in Windows and Linux, but I never figured out how to make it work. On the Mac, the Option key works out of the box, even on the US keyboard.

Update [2009-05-09]: Recent versions of Linux/X11 can emulate the Mac keyboard setup. In Gnome, go to Preferences → Keyboard → Layouts, then Add the USA/Macintosh layout, Remove the USA layout. Then go to Layout Options and set both Windows keys to be “third level choosers”. The Windows key will then act like the Option key on the Mac.

Labels: , ,

Weekend project: XEmacs to Emacs #

First, a bit of history.

I started using GNU Emacs in 1990. The latest version at the time was version 18. It had almost no support for menus, the mouse, fonts, colors, dialog boxes, drag & drop, etc. It was basically a text-only application. In these respects it was a step back from the editors I had been using in DOS, Windows, Mac, and OS/2. However, Emacs was what people used at school, and I needed to use it for some of my classes, so I learned it. I found that it was quite powerful, and I learned how to customize it to match my needs better. One of the things I liked best was automatic indentation. When you press Tab it will indent the line correctly based on what you're typing now and what you had typed earlier in the file. I want this on every line. Most of my classmates press Return and then Tab every line. I'm too lazy for that, so I changed Return to do the indentation (for Emacs users among you: (global-set-key "\r" 'reindent-then-newline-and-indent) does the trick). So now whenever I typed normally, it would automatically indent each line properly. A simple change but it made a big difference, and it encouraged me to learn more about Emacs customization.

I was still annoyed by the lack of colors, though. Colors in particular are quite useful when programming, because they can be used to highlight langauge constructs (keywords, punctuation, identifiers, expressions, definitions, etc.). It makes programs easier to read, and you can quickly spot errors as you type them because they show up in the wrong color. My classmates who had never used non-Unix editors had no idea what they were missing, but I did, and I kept looking for a way to have colors in Emacs. It was 1990, after all, six years after the introduction of Macintosh. Why should I be stuck in a black-and-white text-only world with only a single font? Ugh!

Well, Emacs 18 had come out in 1986. The Mac didn't even have color back then (but at least it had multiple fonts, which could have served the same purpose). Where was Emacs 19, I wondered, and would it have the features I wanted? As I looked around I found something intriguing: a version of Emacs called Epoch, maintained by someone named Marc Andreesen. I tried it out and I loved it. It had colors and fonts and supported multiple windows (what a concept!). I finally had a version of Emacs that gave me what I had been looking for. (Side note: Marc went on to write Mosaic, and then started a company called Netscape.)

Meanwhile, a few people were trying to work on Emacs 19, but work was apparently going very slowly, and a company named Lucid had been working on their own version of Emacs 19, called Lucid Emacs 19. Lucid's version progressed much faster than GNU Emacs 19 (thanks to Lucid's uber-hacker, Jamie Zawinski), and this was the beginning of the big split between Emacs and XEmacs. Around 1992 or 1993 I switched from Epoch to Lucid Emacs 19, and it was everything I wanted out of an Emacs system. When GNU Emacs 19 came out, I tried it, but it was missing so much. The menubar didn't match the standard Mac/Windows menubar, the scrollbar acted weird, you couldn't use multiple fonts, and lots of things in the UI seemed wrong to me. My impression was that GNU Emacs 19 had a UI designed for long-time Emacs users, and Lucid Emacs 19 was designed for the rest of us (DOS, Windows, Mac users). I stuck with Lucid Emacs, which later became XEmacs. (Side note: Jamie went on to a company called Netscape.)

While in school I found plenty of ways to procrastinate, and one of them was learning to customize my environment instead of working on my class project. I spent some time trying out and customizing window managers (twm, ctwm, vtwm, mwm, etc.), but most of my time I spent learning and customizing XEmacs. I tried out lots of extension packages and wrote my own customization. My classmates benefited from my procrastination, as I shared the best of what I had learned with them. Some of the Emacs customizations I developed back then are still in use.

Over the years I've continued to do learn, extend, and customize, and I've built up more and more XEmacs customization. A few years ago I tried running GNU Emacs, and my customization didn't work, and it didn't look easy to fix. XEmacs and GNU Emacs have diverged enough that the things I've learned for XEmacs weren't working in GNU Emacs. So I gave up on ever using GNU Emacs again.

The problem is that XEmacs development has slowed quite a bit. The “stable” version, XEmacs 21.4, came out in 2001. Features like anti-aliased fonts, support for the Mac, and UTF-8 are not available in that version. I've been using the development version, 21.5, and it has partial support for those things. One of the developers left XEmacs to work on his own version of Emacs, called SXEmacs (which looks neat). GNU Emacs on the other hand seems to be progressing faster, and is catching up in many ways to XEmacs. The stable version of GNU Emacs is also a few years old, so people who care about features run the development version (GNU Emacs 22).

The other problem is that last year, when I got a Mac, I found that none of the versions of XEmacs available on the Mac were satisfying. I tried out Aquamacs, which is GNU Emacs 22 for the Mac, and I liked it, except that none of my customizations worked. Non-Emacs editors like TextMate seem somewhat limited, and would require me to unlearn 15 years of Emacs. I had a tough choice to make: after 15 years of being on the XEmacs side of the Emacs/XEmacs split, should I switch back? After talking to several people about their experiences with both, I decided that I should at least consider it. GNU Emacs 22 seems like it has caught up with XEmacs in some ways (not all), and it's ahead of it in other ways.

I still love XEmacs. I like that it uses a package system, so you can choose packages, install new ones, and upgrade a package without upgrading XEmacs. The package system in XEmacs is somewhat like packages in popular Linux distributions. For example, I can download a new version of the Python editing package when that package is released, instead of installing it manually or waiting until a new version of Emacs is available. GNU Emacs doesn't seem to have anything like this. I like the XEmacs philosophy for colors/fonts (they are properties of how you look at a file) more than the GNU Emacs philosophy (that they are properties of the file itself). I like that XEmacs has abstract data types like hash tables. I like that XEmacs uses more readable names of key and mouse commands, like [(ctrl x) (alt tab)] instead of "C-x A-\t". I like that the XEmacs colorization package, font-lock, was more capable than the Emacs package, hilit19, although these days GNU Emacs also uses font-lock. I like that XEmacs had a menu structure more like other apps, although GNU Emacs seems to have adopted this too. I like that XEmacs can run as a “server”, where I can connect to it remotely and access all my open files from multiple machines (I've heard that GNU Emacs will get this at some point). I like that default XEmacs packages have historically seemed more advanced than GNU Emacs versions (for example, psgml seems much more advanced than html-helper-mode, and vm was more advanced than rmail). I like that XEmacs came with more packages standard. I like that XEmacs supported proportional fonts and multiple sized fonts in the same document (GNU Emacs seems to do that now, but it took them ten years). I like the XEmacs experiments (embedding XEmacs inside other apps, embedding other apps inside XEmacs, GTK support, incremental garbage collector, ability to run as a window manager, embedding images inside documents). I really like XEmacs. But I want really good Mac support, nice fonts, and UTF-8 support, so I'm going to try out GNU Emacs again.

This weekend's project is to look at GNU Emacs 22 (the Aquamacs version) much more closely. I'll try porting some of my XEmacs customizations to GNU Emacs. I'll look for GNU Emacs packages that do things similar to the XEmacs packages I had been using. And over the next few months I'll use both XEmacs (at work) and GNU Emacs (at home) and see how it goes.

Labels: ,

Mac OS X window management: Spooky #

To make the use of my computer screen space, I move windows to the edge of the screen. That way there's no wasted space between the edge of the window and the edge of the screen. In Windows, I use The Wonderful Icon for this. In Linux, I used the Sawfish window manager (but I see no way to do this in Metacity, the preferred GNOME window manager). In Mac OS X, I've been manually moving windows around. Today I found Spooky, a set of scripts that let you move and resize windows to the screen edge.

Spooky isn't user friendly. It's a set of scripts that you have to modify. Here's what I did:

  • Put Spooky into a folder.
  • Turn on “access” for universal devices (see the Spooky readme).
  • Edit the Spooky starter script to fix what appears to be a script error. I changed
    do shell script
      ("defaults write net.doernte.spooky 
            \"pathToSpooky\" " & spookyFile)
    

    to

    do shell script
      ("defaults write net.doernte.spooky 
            pathToSpooky \"" & spookyFile & "\"")
    
  • Copy the Spooky starter script to one script for each action (see the Spooky readme):
    for action in maximize centerWindow growWindow 
                  shrinkWindow maxBottomLeft
                  maxBottomRight maxBottom maxLeft maxRight 
                  maxTopLeft maxTopRight
                  maxTop moveBottomLeft moveBottomRight 
                  moveBottom moveLeft moveRight
                  moveTopLeft moveTopRight moveTop zoomWindow; do
         cp spooky\ starter.scpt spooky.$action.scpt; 
    done
    
  • I then had to edit each of these scripts in Script Editor, uncommenting out the line corresponding to the action for that script. In spooky.moveTop.scpt for example I uncommented out spooky("moveTop"). I would've liked to automate this using perl, but Applescripts are stored in some binary format (why?!).
  • Finally, I assigned hotkeys to run the scripts using Quicksilver's custom triggers. This was quite a pain, as Quicksilver didn't pick up these applications, so I had to drag each action manually into a custom trigger. I gave them the keybindings suggested in the Spooky readme.

Although setting things up was more of a pain than I'm used to, now that they're set up, I'm much happier. For my browser, which I want on the right side of the screen, I use Ctrl-Right, Ctrl-Shift-Down, Ctrl-Shift-Up to position and size it. For my work window (usually Emacs), the sequence is similar except I start with Ctrl-Left. I'm much happier having windows go to the edge of the screen; now I don't have to precisely position and size them with the mouse.

Update: [2014-07-03] I haven't used Spooky for quite a while. I now use BetterTouchTool and Alfred. But if you're looking for something programmable like Spooky, look at Hydra.

Update: [2016] Also take a look at BetterSnapTool, Sticker, Slate (for power users), Divvy, Moom, Spectacle. There are many more. I use Stay and Alfred these days.

Labels: ,

Mac Appearance: Limit Choice #

The Mac seems to limit your choices when it comes to its appearance. Maybe that's what makes it “easy” to use. For example, I use a solid desktop background. What does Windows offer me? A color selection dialog that lets me choose one of 16,777,216 colors. What does Linux (GNOME) offer me? A color selection dialog that lets me choose any color, or a gradient between two colors (281,474,976,710,656 possibilities). What does Mac offer me? A choice of 10 colors. Four blues, four grays, one dark green, and one lavender. That's it. No reds. No yellows. No browns. No oranges. I guess Steve Jobs doesn't like those colors.

Update: [2006-08-07] There's a way to trick the Mac into letting you choose a color.

The color scheme is even more restricted. Classic Windows lets you separately color titlebars, controls, windows, tooltips, etc. There are 3, 121,748,550, 315,992,231, 381,597,229, 793,166,305, 748,598,142, 664,971,150, 859,156,959, 625,371,738, 819,765,620, 120,306,103, 063,491,971, 159,826,931, 121,406,622, 895,447,975, 679,288,285, 306,290,176 color combinations. On the Mac, there are two: blue and gray. On Windows though most apps don't really honor a lot of the color settings, so it's not a fair comparison.

My main complaint isn't so much the lack of choice as the usability issue. I use a custom Windows color scheme to highlight the active window. It's really important to me. (I also use a custom Firefox style to highlight the active form control.) I easily lose track of the active window. On the Mac, the active window has a gray titlebar with black text. The inactive window has a gray titlebar with gray text. The difference is subtle. It's hard for me to keep track of the window focus. It's harder to use, in order to make it pretty.

There's a great Mac app called Doodim that provides an incredibly useful feature for people like me: it darkens all but the focused window. This is better than anything I've seen on Windows or Linux. I love this app! Unfortunately it's somewhat slow on my Intel Mac because it's a PowerPC application, and it's running under emulation. I'm also using MenuShade, which darkens the menubar when you're not using it. I tried out some apps similar to Doodim (FocusLayer and Zazen) but they didn't work as well for me. I wish Doodim's functionality was built into the OS.

The Mac approach to limiting choice seems to be largely about the appearance. When it comes to functionality, it's much better. With keyboard shortcuts, the Mac gives me far more choices than Windows or Linux. I'm impressed (but I'd like a little more—there are odd restrictions on which keys I'm allowed to use). Underneath it all, the Unix (BSD) foundation is there and gives me even more power. I'm quite happy to see Python, Ruby, Apache, and so on installed (although I do wonder why they use old versions of Ruby and Apache). I'll take a while to get used to the differences.

Labels: