a Conflict of Hacks: Unix Shebang, Unicode BOM Mark

BOM mark is part of the unicode standard. If a tech declares full support for unicode, support for BOM mark is necessary. (the story i heard is that Haskell compiler chocked on BOM, and people are blaming Microsoft Notepad for adding the BOM. But the fact is, Haskell spec says it's source code is Unicode, thus chocking on BOM is Haskell's fault.)

BOM mark is a hack, but so is unix shebang mark. BOM mark being a given, it wouldn't have any problem if utf-8 isn't invented. utf-8 is invented by unix guy Ken Thompson and unix fanatic Rob Pike largely to help unix world move forward to unicode. As it is, BOM mark conflict with the spirit of utf-8 (because utf-8 is meant to be ASCII compatible as is, yet BOM mark byte sequence isn't in ASCII.)

i read the link Thien-Thin Nguyen posted: http://www.utf8everywhere.org/. At first i find it very informative, but in the end i wasn't convinced in its opinion that we should all adopt utf-8 instead of utf-16. I think if one switch a attitude, that utf-8 is the hack that introduced all this problems, then many of their argument for utf-8 doesn't stand.

side note… about that site, it's Windows oriented. As such, they didn't explain many terms and Windows tech they use, e.g. i have little idea what narrowchar or widechar they mean, nor of the many Windows libraries they mention.

also, the site is decidedly western-mind oriented. They forgot that in China, the encoding used is GB 18030, which has the same char set as unicode but different encoding, and is also compatible with ascii. No utf-8 nor utf-anything whatsoever. Chinese web traffic are like half of the world's or something.

the site wishes utf-16 to go away. Windows, Mac, NTFS, HFS+ file systems, all utf-16, plus java C# etc. Though, the web (html, xml, css) are all utf-8. Neither are likely to go away.

For some detail about BOM, see: Unicode BOM Byte Order Mark Hack.


Edward O'Connor (aka hober) vs Xah Lee

Perm URL with updates: http://xahlee.org/emacs/Edward_OConnor_hober_vs_Xah_Lee.html

This page documents some conflicts between Edward O'Connor (aka hober) and Xah Lee (me), from my perspective.

Edward O'Connor (aka hober) guy is a Free Software Foundation fanatic, and quick to label people who disagree with him as “troll”.

We first met in Freenode's IRC #emacs channel in ≈2006. At first he is friendly, but quickly considered me a “troll” due to my controversial opinions. Much more detail here: Freenode IRC Emacs Channel Ban on Xah Lee.

Why would he consider me troll? Here's few of my essays, he probably consider them trolling. Judge yourself:

Edward runs a emacs blog aggregate site http://planet.emacsen.org/. In ≈, people suggested that my emacs blog be added, he turned the request down, saying that i'm a “consummate troll”. The request is at https://github.com/hober/planet.emacsen.org/pull/2. Here's a screenshot:

Edward OConnor vs Xah Lee 2012-06-01
Edward OConnor vs Xah Lee. (screenshot of 〔https://github.com/hober/planet.emacsen.org/pull/2〕 as of 2012-06-01.)

I have since learned, he also labeled several other programers troll. See: http://edward.oconnor.cx/experiments/trolls/. Quote:

Experiments with troll markup

See also the simple container of hCards on the block list brainstorming page of the microformats wiki, and my troll-filters project on github.

People I consider to be trolls Troll  Email addresses
Rob Burns  rob@robburns.com
John Foliot  foliot@wats.ca, jfoliot@stanford.edu, foliot@stanford.edu
Xah Lee  xah@xahlee.org, xahlee@gmail.com
William Loughborough  wloughborough@gmail.com
Andy Mabbett  andy@pigsonthewing.org.uk
Shelley Powers  shelley.just@gmail.com, shelleyp@burningbird.net
Leif Halvard Silli  lhs@malform.no
Philip TAYLOR  P.Taylor@Rhul.Ac.Uk
Some stats related to HTML 5

All of the above trolls have participated or are participating in the HTML 5 standardization effort except for Xah.

Here's a screenshot:

Edward OConnor troll list 2012-06-01
Edward O'Connor's troll list. (Screenshot of 〔http://edward.oconnor.cx/experiments/trolls/〕 as of 2012-06-01)


Keyboard Geeking 2012-05-30

I went to local store and tried a bunch of keyboard again for like a hour. Made several discoveries.

• Discovered that Steelseries 6Gv2 keyboard amazon uses Cherry™ Black MX mechanical key switch.

• Cherry™ Black MX mechanical key switch. Don't like it at all. Too stiff. (See: Guide to Computer Keyboard Key Switch Mechanisms.)

• Discovered Corsair K60 Keyboard. FANTASTIC! Cherry MX Red switch. Full analysis here: Gaming Keyboards: Corsair K60, K90.

• Discovered that Logitch {G110, G510, G19} gaming keyboard are shit. That is, the key mechanism is SHIT. They are rubber dome, of course, i knew that. But different rubber dome have different feel, some are ok. Some rubber dome key's tactile feel still gives you a sense when a key is pressed. That is, when you press down a key, at some point, the dome collapses, and the key gets sucked down. This is good for typing. However, on Logitch gaming keyboards, they are rather linear, and no crisp bottom neither. So, the whole feel is mushy. This is worst for typing. I suppose they designed it that way for gamers. But even for gamers, especially today's Massively multiplayer online game, chatting is a major activity. Accordingly, updated: Gaming Keyboards for Programers (Emacs, Linux, Blender, …)

• The Logitech Wave Keyboard's key feel is complete SHIT. You know how some rubber dome key is such that sometimes when you try to press a key on a corner, it stuck and won't go down, due to the friction of the housing (your attack angle is WRONG!). The Wave keyboard's keys are like that. SHIT. Besides, it's strange curves has no ergonomic benefits. More of a gimmick. Thus, updated: Logitech Wave Keyboard, Thoughts.

Database Tech Snapshot 2012

Started to do some interview. Here's some random notes of tech snapshot, 2012. Some has been around for a few years and is used by many large companies.

Here's large scale database related tech:

  • MongoDB. document-oriented NoSQL database system.
  • Redis. networked, in-memory, key-value data store with optional durability.
  • Memcached. distributed memory caching system. For speed up dynamic database-driven websites by caching data and objects in RAM.
  • RabbitMQ. message broker software (i.e., message-oriented middleware) that implements the Advanced Message Queuing Protocol (AMQP) standard. The RabbitMQ server is written in Erlang.
  • http://haproxy.1wt.eu/. TCP/HTTP Load Balancer.
  • http://www.celeryproject.org/
  • Amazon EC2

Document-oriented database

Small scale database:

Gaming Keyboards: Corsair K60, K90

Perm URL with updates: http://xahlee.org/kbd/Corsair_keyboards.html

Corsair Vengeance K60, ≈$95

Corsair K60 keyboard
Corsair K60 keyboard, with extra colored and specially sculpted key-caps on (these extra caps come with the keyboard). amazon
Corsair K60 keyboard 2
Source www.bit-tech.net amazon


This keyboard is heavy. It doesn't have fancy features or extra keys, but the most important aspect of keyboard, the key mechanism, is top-notch here.

The key switch mechanism is Cherry™ MX Red. (linear feel, no click, light) (See: Guide to Computer Keyboard Key Switch Mechanisms.)

The keyboard is also of the highest quality. The keyboard's chassis is actually brush aluminum. Real metal. The keyboard's cable is nothing you've ever seen. It's very thick, wrapped with some type of cloth-like material, kinda like high-class electric cable you find in antic stores.

Corsair keyboard cable
Corsair keyboard cable.

It seems to require 2 USB ports (i suppose the reason is because of the 20 Key Roll-over over USB.). However, the keyboard also has a USB port (pass-thru, not hub).

Note: A normal keyboard (such as Microsoft & Logitech Normal Keyboards) has problem registering certain combination of 3 or more keys held down simultaneously. Majority of USB-based gaming keyboard, has special circuitry so that they can register 6 keys simultaneously. But 6 is the typical maximum, due to USB design. Here, they took care of this issue, and allows 20 key key-rollover over USB. That's probably why they require 2 USB connections. (See: Keyboard Ghosting; How Many Keys Your Keyboard Can Take?.)

Corsair K60 keyboard back
The back of the keyboard, showing the USB port, and the Windows Lock key (it prevents the Win key from activation.).
  • Cherry MX Red Mechanical key switches. (light, linear, feel. No click)
  • 20 Key Roll-over (20KRO) on USB
  • 6 multimedia keys — Stop, Previous, Play/Pause, Next, Mute, Volume Up/Down — with Solid metal, weighted volume “drum roller”
  • 2m non-tangle cable
Corsair K60 keyboard sound level drum roller
Multimedia keys and the “drum roller” for sound level control. Gorgeous. Source www.bit-tech.net

Love the volume control drum roller.

Note: special keys rubber dome switch: F1 through F12, Esc, PrtScn, Scroll Lock, Pause/Break, Insert, Home, Page Up Page Down, Delete, End.

Corsair Vengeance K90, ≈$110

A more expensive model is the K90.

Corsair K90 keyboard us lit top Corsair K90 keyboard us lit Corsair k90 keyboard
Corsair K90 keyboard, showing its extra function keys. amazon

What's the K90 got that's not in K60?

  • 18 extra function keys (G keys).
  • 36kb on-board memory.
  • Backlit.
  • Laser-etched, backlit keys with four illumination levels (off, 66%, 75%, and full illumination) selectable from the keyboard

K90 requires software, for those extra function keys. The K60 doesn't.


poetic chinese love song: 秋詩篇篇

Perm URL with updates: http://xahlee.org/music/qiu1_shi1_pian1_pian1.html

銀霞 -
Title: 秋诗篇篇 (movie 〈秋诗篇篇〉 theme song)
Date: 1978
Singer: 銀霞
Lyrics: 刘家昌
Music: 刘家昌
Arrangement: 鍾興民
深秋楓又紅 秋去留殘夢
我心付諸於流水 恰似落葉然飄零

轉眼之間 白雪遮晴空 寒風襲嚴冬
莫待櫻花盛開春來 也踏雪尋芳蹤

Emacs: Convenient Command to zip File in dired

(defun 2zip ()
  "Zip the current file/dir in `dired'.
If multiple files are marked, only zip the first one.
Require unix zip commandline tool."
  (require 'dired)
  (let ( (fileName (elt (dired-get-marked-files) 0))  )
    (shell-command (format "zip -r '%s.zip' '%s'" (file-relative-name fileName) (file-relative-name fileName)))

See also: Emacs: Convert Image Files in Dired.

Popular JavaScript Books 2012

  • JavaScript & jQuery: The Missing Manual By David Sawyer Mcfarland. @ amazon
  • JavaScript: The Definitive Guide By David Flanagan (Author). @ amazon
  • JavaScript: The Good Parts By Douglas Crockford. @ amazon
  • Eloquent JavaScript: A Modern Introduction to Programming By Marijn Haverbeke. @ amazon
  • Professional JavaScript for Web Developers By Nicholas C Zakas. @ amazon

i haven't read any. Have you? which's better?


Best Tool for Yak Shaving: Emacs

Perm URL with updates: http://xahlee.org/funny/emacs_yak_shaving.html

Here's an example:

“I was working on my thesis and realized I needed a reference. I'd seen a post on comp.arch recently that cited a paper, so I fired up gnus. While I was searching the for the post, I came across another post whose MIME encoding screwed up my ancient version of gnus, so I stopped and downloaded the latest version of gnus.”

“Unfortunately, the new version of gnus didn't work with emacs 18, so I downloaded and built emacs 20. Of course, then I had to install updated versions of a half-dozen other packages to keep other users from hurting me. When I finally tried to use the new gnus, it kept crapping out on my old configuration. And that's why I'm deep in the gnus info pages and my .emacs file — and yet it's all part of working on my thesis.”

And that, my friends, is yak shaving. (Not that this particular example happened to me recently or anything.)

post your emacs questions. May 28, 2012

2012-05-28 post your emacs questions.

comment here, or on g+ at Source plus.google.com, or twitter https://twitter.com/ErgoEmacs

Emacs Lisp: Writing Command to Accept universal-argument

Perm URL with updates: http://xahlee.org/emacs/elisp_universal_argument.html

This page shows you how to make your emacs lisp command accept universal-argumentCtrl+u】 given by user.

Problem Description

You have written a emacs command. You want the command's behavior to be slightly different if user presses 【Ctrl+u】 before calling your command.


Emacs has a mechanism for a command to have variant behavior if user calls universal-argumentCtrl+u】.

The universal argument has many uses. It can let user repeat a command n times. For example, type 【Ctrl+u 20 -】 and it'll type out --------------------.

For some commands, the universal argument is useful for variant behavior of the command. For example, in dired, typing w will copy the file name (dired-copy-filename-as-kill), but if you type 【Ctrl+u 0 w】, the copied name will be file full path.


Let's say you want a command to copy the file path of current file. But if universal-argument is called, then copy just the dir path. Here's how you code it:

(defun copy-file-path (prefixArgCode)
  "Copy the current buffer's file path or dired path to `kill-ring'.
If `universal-argument' is called, copy only the dir path."
  (interactive "P")
  (let ((fPath
         (if (equal major-mode 'dired-mode)
     (if (equal prefixArgCode nil)
       (file-name-directory fPath)
  (message "File path copied.") )

First, we set fPath.

Then, we check “prefixArgCode”. If it's not “nil”, then we truncate the file path to just the dir.

The gist of getting the universal arg is this:

(defun copy-file-path (prefixArgCode)
  (interactive "P")
  (if (equal prefixArgCode nil)
       (file-name-directory fPath)
       ) )

The (interactive "P") will pass the arg from universal-argument as your command's first argument.

Universal Argument Values

To make your command aware of universal argument, there are 2 major ways:

  • ① Query the global variable “current-prefix-arg”. It holds the value of universal argument.
  • ② Add (interactive "P") to your function. It will pass the value of “current-prefix-arg” to your function's first argument.
Key InputValue of “current-prefix-arg”
Ctrl+u -Symbol -
Ctrl+u - 2Number -2
Ctrl+u 1Number 1
Ctrl+u 4Number 4
Ctrl+uList '(4)
Ctrl+u Ctrl+uList '(16)

(info "(elisp) Prefix Command Arguments")

Complex Example of using universal-argument

Sometimes you do not want your function's parameter spec to explicitly contain universal argument. So, (interactive "P") is not appropriate. For example, suppose you are writing this command:

(defun wrap-html-tag (tagName &optional className id) 
  "Add a HTML tag to beginning and ending of current word or text selection."

Your command will create a HTML tag like this:

<div class="xyz">something</div>
<div id="id8295" class="xyz">something</div>

When called interactively, it can prompt user to enter “class” and “id” values. If user just press Enter without giving them any value, then don't add these attributes to the tag.

However, often, the prompting for “class” and “id” are annoying, because, in practice, many tags don't need them. e.g. {<p>One day, …</p>, <b>bold</b>, <i>italic</i>}.

So, you want your command to do extra prompt only when preceded by universal-argument.

Here's solution:

(defun wrap-html-tag (tagName &optional className ξid)
  "Add a HTML tag to beginning and ending of current word or text selection.

When preceded with `universal-argument',
no arg = prompt for tag, class.
2 = prompt for tag, id.
any = prompt for tag, id, class.

When called interactively,
Default id value is 「id‹random number›」.
Default class value is 「xyz」.

When called in lisp program, if className is nil or empty string, don't add the attribute. Same for ξid."
    ((equal current-prefix-arg nil)     ; universal-argument not called
      (read-string "Tag (span):" nil nil "span") ))
    ((equal current-prefix-arg '(4))    ; C-u
      (read-string "Tag (span):" nil nil "span")
      (read-string "Class (xyz):" nil nil "xyz") ))
    ((equal current-prefix-arg 2)       ; C-u 2
      (read-string "Tag (span):" nil nil "span")
      (read-string "id:" nil nil (format "id%d" (random (expt 2 28 ))))
    (t                                  ; all other cases
        (read-string "Tag (span):" nil nil "span")
        (read-string "Class (xyz):" nil nil "xyz")
        (read-string "id:" nil nil (format "id%d" (random (expt 2 28 )))) )) ) )
  (let (bds p1 p2 inputText outputText
            (classStr (if (equal className nil) "" (format " class=\"%s\"" className)))
            (idStr (if (equal ξid nil) "" (format " id=\"%s\"" ξid)))      
    (setq bds (get-selection-or-unit 'word))
    (setq inputText (elt bds 0) )
    (setq p1 (elt bds 1) )
    (setq p2 (elt bds 2) )
    (setq outputText (format "<%s%s%s>%s</%s>" tagName idStr classStr inputText tagName ) )

    (delete-region p1 p2)
    (goto-char p1)
    (insert outputText) ) )

The skeleton of the code is this:

(defun wrap-html-tag (tagName &optional className ξid)

    ((equal current-prefix-arg nil)     ; universal-argument not called
      (read-string "Tag (span):" nil nil "span") ))
    ((equal current-prefix-arg '(4))    ; C-u
      (read-string "Tag (span):" nil nil "span")
      (read-string "Class (xyz):" nil nil "xyz") ))
    ((equal current-prefix-arg 2)       ; C-u 2
      (read-string "Tag (span):" nil nil "span")
      (read-string "id:" nil nil (format "id%d" (random (expt 2 28 ))))
    (t                                  ; all other cases
        (read-string "Tag (span):" nil nil "span")
        (read-string "Class (xyz):" nil nil "xyz")
        (read-string "id:" nil nil (format "id%d" (random (expt 2 28 )))) )) ) )

  ;; function body  


The (interactive …) is used to fill out the parameters, when your function is called by user interactively (as opposed to from a lisp program).

One way to use the interactive function is for it to return a list. This list's element will be fed to the function as arguments.

In our code, we use a conditional (cond …) to check the values of “current-prefix-arg”. If it's “nil”, then that means universal-argument is not called. So, we simply prompt for the tag name. But if the value is other, then we prompt for more.

The weird ξ you see in my elisp code is Greek x. I use Unicode char in symbol name for easy distinction from builtin symbols. You can just ignore it. (➲ Programing Style: Variable Naming: English Words Considered Harmful)

The command uses get-selection-or-unit. You can get the code for that at get-selection-or-unit.


vim user is shocked!

This tweet is going around:

@lichray #Vim 用户表示震惊。 RT @ErgoEmacs: Emacs: How to Copy/Cut Current Line

Translation: «@lichray #Vim users are shocked! RT @ErgoEmacs: Emacs: How to Copy/Cut Current Line»