Xah Emacs Blog

Random news, tips, about anything that might be of interest to emacs users.

Emacs on G+ is Useful!

Google+ is actually quite useful. Blogs is going the ways of dinosaur. In social networks, you can write, interact with people, immediately, post pictures, hangout (real-time text chat, voice chat, video chat). And it's all much easier than running a blog. If you follow web tech communities (e.g. TechCrunch, etc.), you know that death of blogs have been written on the wall for a few years. With few exceptions, such as professional blogger. (for a fun intro of g+, see: What is Google Plus and Google+ Songs (humor).)

Anyway, i wanted to say that running a emacs page on g+ have already been useful to me, even just after a few days. I learned emacs tips. Here's today's post.

Some slightly advanced emacs tips.

① I just learned about Keyboard Macro Ring today after 10+ years emacs using. (Thanks to Jorge A Alfaro Murillo.)

② A info doc node in emacs can be referenced by a elisp expression. For example: (info "(emacs) Keyboard Macro Ring"). Put cursor at end of paren then call “eval-last-sexp” 【Ctrl+x Ctrl+e】. That'll take you to the emacs doc. The argument to “info” is string of the node's name.

③ When browsing emacs info doc inside emacs, you can get the node's name by calling “Info-copy-current-node-name” 【c】.

keyboard macro is a time saver. If you don't know the basics, see: Emacs Keyboard Macro and Examples.

My emacs g+ and Twitter pages can be found at: Xah Lee Feeds. Please Subscribe! I will still write blogs. But it's more for heavy weight tutorials, and will be focused on elisp. (because, after a few years, all emacs tips all seem to be repetitions) Brief practical daily tips goes to @ErgoEmacs Twitter and ErgoEmacs g+. Thank you for reading.

My Emacs Online Feeds

For Twitter users, now all my emacs related tweets will be from @ErgoEmacs. This way, those who just want emacs tips can stay focused.

For Google+ users, you might join g+ emacs page. There, i post one or two short emacs tip a day.

For a complete list of feeds of available topics, please see: Subscribe to XahLee.org Site Feed.

Thank you very much for reading!

ErgoEmacs Logo and Mascot

Xah's Emacs Tutorial Update 2012-01-20

I have a new version of my emacs tutorial ready.

If you've bought it before, please just email to xah@xahlee.org with subject “emacs tutorial upgrade”. I'll email you the download location. Sorry i don't have a automatic update system. So just send the email please if you would like the updated version.

If you haven't bought it, you can get it for just $10. See: Buy Xah Emacs Tutorial. As far as i know it's more complete and detailed tutorial than any emacs book, printed or not, especially the elisp section.

Thank you for support!

Emacs Tip: a Hotkey for “repeat-complex-command”

There's a emacs command repeat-complex-command.

I actually never used it. But in a recent post by Dan Espen (Source groups.google.com), it seems useful.

To make it useful, you should give it a easy hotkey, such as F5.

I'm already starting to use it and found it useful.

Here's why it's useful. In many emacs commands, after you call the command, you have to give arguments. For example, the query-replace. To do the same replacement again, you have to call it again, then use to go back to previous arg, Enter, then same for replacement.

but with repeat-complex-command, you don't have to input the args again.

In some ancient keyboard such as Sun Microsystem's Type 6 Keyboard, there's a key labeled “Again” that is bound to repeat-complex-command. But that key doesn't exist on PC keyboard today. So, you can bind it to F5 for example, or a single key on the number pad.

If you don't know how to set keys, see: Emacs: How to Define Keyboard Shortcuts.

Emacs Page on G+, Today's Tip: Hotkeys

i started a g+ emacs stream at https://plus.google.com/b/113859563190964307534/ . You might want to join. Here's today's post.

in emacs, once you got on the train and know all the basic concepts, there's 1 most important aspect of increasing efficiency. That is, keyboard shorts (keybindings).

emacs has 3k commands out of the box. Everything is a command, including when you type “a” (self-insert-command). For most frequently used commands, there's a key assigned for it.

by default emacs has 1.3k keybindings!

If we take away ancient impractical ones (for obsolete lisp keyboards), there are few hundred keybindings that are actually useful. Most of us probably use around a hundred or 2.

ok. what i want to say is that for daily operation, assiging keys to commands is probably the most useful in creasing your productivity. Emacs is too big. Everyone has different set of commands that each use frequently. So, if you find yourself typing Meta+x to call a particular command often in past weeks, it's time to give it a hotkey! (if it doesn't already have one; or if you find yourself bending your fingers on the default key sequence.)

All your F1F12 should be used. And some of those 【Ctrl+x Ctrl+】 and 【Ctrl+c Ctrl+】 you use often probably should have a shorter key.

if you don't know how to set keys, see:

Emacs: How to Define Keyboard Shortcuts

here's related tips on keys

g+

List Matching Lines in Emacs

learned 2 new commands from a emacs hacker friend Jon Snader (jcs): multi-occur and multi-occur-in-matching-buffers.

See his blog about several ways of listing matching lines:

there, he covered several ways to list matching lines in current buffer or existing buffers.

if you are new to emacs, you might think “i'll just call unix grep; one less thing to learn”. Actually, the emacs commands are much more convenient. I use them several times everyday for past years.

if you want to know the ways to find matching lines in files (as opposed to already opened files), see also: Emacs: Searching for Text in Files (grep, find).

Emacs Lisp: Testing Equality of Symbol Variables

When setting your emacs preferences, you can check whether your machine is {Windows, Mac, Linux}, by the variable system-type, like this:

(defun open-in-desktop ()
  "Open the current file in desktop.
Works in Microsoft Windows, Mac OS X, Linux."
  (interactive)
  (cond
   ((string-equal system-type "windows-nt")
    (w32-shell-execute "explore" (replace-regexp-in-string "/" "\\" default-directory t t)))
   ((string-equal system-type "darwin") (shell-command "open ."))
   ((string-equal system-type "gnu/linux") (shell-command "xdg-open ."))
   ) )

But i have a question. According to the describe-variable and elisp manual ((info "(elisp) System Environment")), the var “system-type”'s value is a symbol. However, why does the following work? (string-equal system-type "windows-nt")

It appears, any symbol can be tested as if it is a string. For example:

(string-equal 'x 'x) ; ⇒ t
(string-equal 'x 'y) ; ⇒ nil

(setq myVar 'tt )
(string-equal myVar "tt") ; ⇒ t

Ted Zlatanov, a emacs dev, comes to the rescue on the why!

From the docstring:

string-equal is a built-in function in `C source code'.

(string-equal S1 S2)

Return t if two strings have identical contents.
Case is significant, but text properties are ignored.
Symbols are also allowed; their print names are used instead.

Emacs Dired: Opening Files in External Apps

Emacs: Getting Environment Variable When Launching Emacs from GUI

On Windows or Mac, when you launch emacs from desktop, often the environment variables are not inherited. How to solve this?

On Windows, you need to set them in Registry. You can do that using command line (setx in “cmd.exe”) or GUI (“SystemPropertiesAdvanced.exe”). see Windows Environment Variables Basic Tutorial.

On Mac, you need to set a file 〔~/.MacOSX/environment.plist〕 See: Source developer.apple.com

thx to Adam Jiang for asking.

There's a subword-mode that lets you move by camelCase. New in emacs 23, but isn't mentioned in emacs NEWS file. See: Source debbugs.gnu.org bug#6614

Emacs Pinky and RSI

someone on stackoverflow is asking about how to avoid the emacs pinky. See: Source stackoverflow.com

the guy already developed emacs pinky.

Note that this is quite a frequently asked question. People ask about it year round all over. On Reddit, Hacker News, Quara, StackOverflow …, and on lots personal blogs. Many already got RSI. Here's a example of another post about it: Source superuser.com.

On StackOverflow itself, the topics comes up frequently. Sometimes in the name of “what's the best emacs keyboard”.

Here's my take, old article but popular: How to Avoid the Emacs Pinky Problem.

This article is probably one of the top ten most valuable in my ~300 html pages emacs/elisp tutorial: How to Write a Emacs Major Mode for Syntax Coloring.

Updated: Emacs Lisp's Library System: What's require, load, load-file, autoload, feature?

Updated with new code: Emacs Lisp: Writing a url-linkify Command.

Updated: Keyboard Ghosting & N-key Rollover: How Many Keys Your Keyboard Can Take?. This is relevant to emacs if you define Hyper and Super. See bottom of the article.

2 Songs for Emacs Hacking

I must offer you emacs coders 2 songs today. The first one is Pulse. Let the tranquil beat accompany you in your hackathon.

Now, the second song i offer is Information High. This is when you are hyper, such as emacs's Hyper key. When you are high. When your thoughts run faster can you can type.

More Keyboard Geeking

Updated: Guide to Computer Keyboard Key Switch Mechanisms.

ErgoEmacs Hit Hacker News

ErgoEmacs hits Hacker News last week. See Emacs for the rest of us: ErgoEmacs @ Source news.ycombinator.com

Thanks to “Macro Lapse” (aka macco) for posting.

Here's a review of ErgoEmacs Keybinding.

Ergonomic Emacs Keybindings By Jeff Pace. @ Source jpace.wordpress.com

Updated: Emacs Lisp: Cycle Replace Space Hyphen Underscore

Updated: Emacs Lisp Text Processing: find-file vs with-temp-buffer.

In my previous report, the timing difference is by a factor of 45. That's because i had stuff in my init file. (i have hooks for both find-file and html-mode, and that probably caused the major slowdown.) Now, the factor is actually just about 5.

You should still use with-temp-buffer instead of find-file besides speed, because find-file has quite some side effects.

Big thanks to Trey Jackson.

“Truly Ergonomic Keyboard” has Docked!

Updated: Keyboard Hardware Design Flaws.

Updated. The ultimate emacs keyboard: The μTRON Keyboard. Well, one of the ultimate.

Emacs Lisp: Convert Lisp Form to XML Form

Jon Snader (jcs) wrote a series of nice tutorial about how to transform text in the form of lisp expression into XML form, with a focus on making each head of lisp expression a executable function itself (as opposed to just parsing a input text and spit out XML form). In the last article, he proposed a little challenge for readers to solve. See:

If you got stuck, check out his previous articles (linked in his article), which shows you how.

Emacs Lisp Text Processing: find-file vs with-temp-buffer

Xah's Blogs Reminder

Emacs: How to Turn a Minor Mode on/off/toggle?

This is a frequently confusing point someone just asked again in gnu.emacs.help. How to turn a mode on/off? Is it a function or variable? Is it {1, 0} or {t, nil}? See, updated: Emacs: How to Turn a Minor Mode on/off/toggle?.

Updated: Emacs's Menu Usability Problem.

How to Choose a Keyboard with Good Function Keys

bad function keys-2
Worst example of function keys. ① Continuous row, no group-gap. ② hard-to-press cheap buttons.
keyboard function keys
Good Function Keys. Quality standard key. Grouped so it's easy to hit the correct key without sight.

See explanation at Computer Keyboard: What Are F1 … F12 Keys Used For? Increase Productivity Using Function Keys

Fixing Emacs's Scratch Buffer

Emacs's scratch buffer has lots of problems. This is a controversial issue, because the scratch buffer is one of those things that serves as a identity of emacs. Any criticism on it is like attacking emacs.

But i tell you, dear readers, frankly and directly, this is a emacs cult problem and i've wrote about often. (See: Emacs Undo & Emacs Cult ProblemEmacs Idolization: Have You Read the Emacs Manual From Cover to Cover?)

For a detailed description of scratch buffer problems, see: Emacs: Problems of the Scratch Buffer.

If you are a user of ErgoEmacs Keybinding, the problem is already fixed for you. Simply press 【Ctrl+n】 and new scratch will be created for you, and when you close a modified unsaved buffer, it'll prompt you for save.

In ErgoEmacs keybinding, it's implemented by 2 commands: {new-empty-buffer, close-current-buffer}. The “new-empty-buffer” simply creates a new buffer, titled “untitled”, “untitled<2>”, etc. The code for “close-current-buffer” is a bit more involved. It kills the current buffer, but check if it is modified, but also, add the closed file into a list, so that people can re-open the last closed file, much like web browser's 【Ctrl+Shift+t】 (supported by Firefox, IE9, Chrome, Opera, except Safari.). The key is the same. The key to close current file is also the browser standard 【Ctrl+w】.

If you really want to stick with GNU emacs's keys, but want these convenient functions, you can download and copy/modify the code from ErgoEmacs keybinding. Or, J V Toups provided a implementation for persistent scratch buffer. See:

Emacs: Convert Image Files in Dired

Updated: Emacs: Text Pattern Matching (regex) tutorial.

Note: last week's exercise about writing “latitude-longitude-decimalize” will be coming up.

Emacs Lisp Exercise: latitude-longitude-decimalize

This week's emacs lisp exercise, write a function “latitude-longitude-decimalize”.

It should take a string like this: 「"37°26′36.42″N 06°15′14.28″W"」. The return value should be a pair of numbers, like this: 「[37.44345 -6.25396]」.

Feel free to use perl, python, ruby, etc.

Updated: Tips on Long Term Emacs Productivity.

Updated: Emacs: Info-mode Keys and How to Add Web Browser Keys.

Updated: Emacs Regex Quirk: Matching Beginning/End of Line/String/Buffer

Emacs: You Have Widescreen? Have Screen Flow Side by Side

Today, most of us use very wide screen. When viewing a long document, you have to page down often. You can make emacs display them side by side, such that left bottom continues to right top. Also, when your mouse moves to the bottom of left pane, it'll appear on the right top. Here's what to do:

Call split-window-horizontallyCtrl+x 3】 (in ErgoEmacs it's 【Alt+$】). Then, call follow-mode.

You can also set the arrow key to scroll instead of moving cursor.

; set up/down arrow to scroll screen by line
(global-set-key (kbd "<up>") (lambda () (interactive) (scroll-down 1)))
(global-set-key (kbd "<down>") (lambda () (interactive) (scroll-up 1)))

You can still move cursor by {【Ctrl+p】,【Ctrl+n】}. (or {【Alt+i】, 【Alt+k】} in ErgoEmacs.)

You can also set to {【Ctrl+】, 【Ctrl+】} instead. Use the syntax (kbd "<C-up>"). (See: Emacs: How to Define Keyboard Shortcuts.)

Thanks to Zhang Tianjin for mentioning this tip.

Emacs 24.0.91.1 for Windows; Crash on linum-mode

Steps to reproduce:

Thanks to Jon Snader for discussion.

Spent about 10 hours keyboard geeking again. Several major updates in the following pages. Addition of some 15 glorious photos of keyboards and their layouts.

The Glorious μTRON Keyboard

Emacs: Insert Brackets by Pair

Emacs Lisp Example: wrap-html-tag

A little elisp command, useful if you do a lot HTML coding.

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

If tagName is empty or nil, use “span”.
If className is empty or nil, don't add any class attribute.
If ξid is empty or nil, don't add id attribute."
  (interactive "sEnter tag name:
sEnter class:
sEnter id:")
  (let (bds p1 p2 inputText outputText)
    (setq bds (get-selection-or-unit 'word))
    (setq inputText (elt bds 0) )
    (setq p1 (elt bds 1) )
    (setq p2 (elt bds 2) )

    (setq
     outputText
     (concat
      "<"
      (if (or (equal tagName nil) (string= tagName "")) "span" tagName)
      (if (or (equal ξid nil) (string= ξid "")) "" (concat " id=\"" ξid "\""))
      (if (or (equal className nil) (string-equal className "")) "" (concat " class=\"" className "\""))
      ">"
      inputText
      "</"
      (if (or (equal tagName nil) (string= tagName "")) "span" tagName)
      ">" ) )

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

Remember to bind it to a key.

I used some elisp utils i wrote. You'll need to get it at: code.google.com xeu_elisp_util.el. Or, replace the get-selection-or-unit part by thing-at-point. For tutorial, see: Emacs Lisp: Using thing-at-point.

by the way, you could define your own commands for all html tags, but you probably shouldn't. html-mode has keys to insert many basic html tags. (See: Emacs and HTML Tips) Also, yasnippet has a whole set of html templates. (See: Emacs Templates with YASnippet). Though, still sometimes they don't cover everything you need. That's when adding your own is helpful.

from yesterday: Ergonomic Keyboards: Microsoft 4000 vs Natural Elite @ http://xahlee.blogspot.com/2011/11/ergonomic-keyboards-microsoft-4000-vs.html. PS if you are a customer of Amazon, feel free to buy from my site's links. Thank you for support.

Thank You from Xah Lee

I want to write a quick Thank You to those of you who read my emacs blog, and also to many who have donated.

Reminder: it's preferred that you post questions as comments to my blog or website, because it gets seen by many, also better for my blog because people can see interaction. My email is often flooded, though i try to reply to all.

Also thank you for those who have donated, or bought my emacs tutorial. I haven't had a chance to update my Donor List. There is one person, Aigerim, who bought my entire website (for offline reading) for $100. Thank you Aigerim so much!

Am writing this quickly, been wanting to write it for a couple of weeks now. Wanted to mention all names but big plan always results in no action.

I want to thank those who retweeted my emacs tutorials, linked to my site, those who commented on my articles, or exchanged emails, and also those on Facebook and g+. I'm not much a social person, not much into chitchat, and don't like to follow marketing strategies on “establishing communities” or such, but i appreciate many discussions and support. Lew Perin recently sent me a printed pamphlet “Emacs Quick Ref”, of 3 leaflets, that was from 1984 of MIT's Project Athena. Thank you Lew for such a treasure. I hope to take a photo of it and show it to all soon.

On last note, my annual income is about USD$2.5k for the past few years. (or ~$200/month.) So, your donation is appreciated, or, Buy Xah Emacs Tutorial. As far as i know, no emacs book covers elisp as much except GNU Emacs Lisp Reference Manual. With your donation, i'd be able to write a complete cookbook, covering topics such as full controlling GUI elements (windows, frames, menu), text highlighting, emacs input system, display system, IO system, etc, and always with a little practical application you can use right away.

Emacs Lisp Command: curly-quotes-to-emacs-function-tag

In my emacs tutorial, i want to put HTML markup on elisp functions. For example, if i wrote:

<p>Call “sort-lines” to sort.</p>

I want it to be like this:

<p>Call <var class="εf">sort-lines</var> to sort.</p>

This way, i can write a Javascript that pops up documentation when mouse hovers on the function name.

I already have 300 HTML files of emacs/lisp tutorial. How to fix them?

One way is to write a elisp script that go thru all files. Another way is to write a interactive command that can be used on a case-by-case basis. I experimented with both, and decided to use the latter approach as of now.

Here's the command:

(defun curly-quotes-to-emacs-function-tag (p1 p2)
  "Replace “word” to HTML markup for elisp function in text selection or current buffer (respects `narrow-to-region').

For example, the text:
 <p>Call “sort-lines” to sort.</p>
becomes
 <p>Call <var class=\"εf\">sort-lines</var> to sort.</p>

Note: a word is changed only if all of the following are true:

① It is enclosed in <p> tag, or <ul>, <ol>, <table>, <figcaption>. (For example, not inside <h1> or <title>, <a>, or other tags.)
② It is enclosed in “double curly quotes”.
③ `fboundp' returns true.

This command assumes that all tags are closed in your HTML. e.g. <p> must be closed with </p>.

This command also makes a report of changed items.

Some issues:

• If the lisp functions name is less than 2 chars, it won't be tagged. e.g. + - 1+ ….

• Only words contaning lowercase a to z, 0 to 9, or hyphen, are checked, even though elisp identifier allows many other chars. e.g. “yas/reload-all” used by yasnippet.

• Some words are common in other lang, e.g. “while”, “print”, “string”, unix's “find”, “grep”, HTML's “kbd” tag, etc. But they are also built-in elisp symbols. So, you may not want to tag them.

• Personal emacs functions will also be tagged. You may not want them to be because they are not standard functions.

• Some functions are from 3rd party libs, and some are not bundled with GNU emacs , e.g. 「'cl」, 「'htmlize」. They may or may not be tagged depending whether they've been loaded."
  (interactive
   (if (region-active-p)
       (list (region-beginning) (region-end))
     (list (point-min) (point-max)) ) )
  (require 'sgml-mode) ; from html-mode, needs sgml-skip-tag-forward
  (let (p3 p4 mStr (ξi 0) (case-fold-search nil) )
    (save-excursion
      (save-restriction
        (narrow-to-region p1 p2)
        (goto-char (point-min))
        (while (search-forward-regexp "<p>\\|<ul>\\|<ol>\\|<table\\|<figcaption>" nil t)
          (backward-char)
          (setq p3 (point) )
          (sgml-skip-tag-forward 1)
          (setq p4 (point) )

          (save-restriction
            (narrow-to-region p3 p4)
            (goto-char (point-min))
            (while (search-forward-regexp "“\\([-a-z0-9]+\\)”" (point-max) t)
              (setq mStr (match-string 1) )

              (when (and (fboundp (intern mStr))
                         (> (length mStr) 2))
                (replace-match (concat "<var class=\"εf\">" mStr "</var>") t t)
                (setq ξi (1+ ξi) )
                ) ) ) )
        (when (> ξi 0)
          (occur "<var class=\"εf\">[-a-z0-9]+</var>" )) ) ) ))

With this code, i can just press a button, and the whole buffer will be so marked. Or, i can select a region of text, press a button, and have that part marked, with a report of the changes (in a second pane).

This still means i have to manually go thru my 300 existing files. The thing is, a batch script that fix all 300 files would not be accurate. For example, many words are also other language's keywords. There is no way for the script to really know unless it has strong AI. For example, on this page: Emacs Lisp Idioms, i have this passage:

Note that, when the thing is a “symbol”, it usually means any alphanumeric sequence with dash “-” or underscore “_” characters. For example, if you are writing PHP reference lookup command, and the cursor is on p in print_r($y);, you want to grab the whole “print_r” not just “print”. The exact meaning of symbol depends on current major mode's Syntax Table.

Notice it contains the string “print” there. The print there refers to PHP's print, and shouldn't be marked as a elisp function.

Still, there are many way to help fix all the 300 files. The good thing about emacs i love is that everything can be done in a incremental, interactive way. So, i start by having this command. This command basically is a semi-automatic way. With this command, in 20 minutes, i could have fixed 20 pages, and i would have learned any complexities of the task. (for example, i learned, that you don't want them marked inside <title> or <h1> tags.) So, i work and modify the command as i go. By the time the command is in good shape as it is now, i've already fixed some 100 pages. Then, if i want, i can modify this command into a batch script. (by now i've fixed basically all pages, maybe 30 left.)

Review of ErgoEmacs by Joseph Buchignani

Joseph Buchignani wrote a review of ErgoEmacs, at: Source www.cyborganize.org. Check it out!

Besides some praises, he also listed several items he believed to be bad. He made many excellent points. Some of his points are due to him being a experienced emacs user, but some are still good points. I think we will follow up about half of his points in next release. Here's a list that is now fixed:

For org-mode, the only customization in ErgoEmacs is (add-hook 'org-mode-hook 'soft-wrap-lines). What the soft-wrap-lines function do is to set “truncate-lines” to false and “word-wrap” to true. Otherwise, long lines will disappear into the right window border. Am not sure this is a good thing. Has newer org-mode changed this behavior?

Also, emacs 24 beta is out, and people are saying it's pretty stable. So, next release will probably be based on emacs 24.

Thanks to Joseph. Check out his review linked above.

Updated a function “toggle-line-spacing” for emacs 24, at How to Set Emacs's User Interface to Modern Conventions. Thanks to Ivan Kozik for the tip.

Emacs: Updates: insert-random-uuid, forward-close-bracket

Last week, we discussed how to write a elisp to generat UUID. Christopher Wellons provided a excellent implementation involving random info from emacs, then calling md5. See bottom at: Emacs Lisp Exercise: insert-random-uuid.

For those of you using backward-close-bracket and forward-close-bracket, there's a bug that's been fixed. The bug is this: it misses some brackets because there's some typo in the regex in the code, it contained extra space. Get updated code at: Emacs: Commands and Keys to Navigate Brackets.

Inconsistency of Emacs Text-Searching Features

Few days ago, i wrote a tutorial on emacs text-searching commands. See: Emacs: Searching for Text in Files (grep, find). There are lots of them: {list-matching-lines, grep, rgrep, lgrep, grep-find, find-dired, dired-do-search, …}. However, they are inconsistent.

list-matching-lines (alias of occur) is implemented with elisp, while the others rely on unix utils {find, grep}.

The interface also isn't consistent. e.g. grep and grep-find (alias find-grep) both directly prompt you to enter unix command in one shot. But find-dired, rgrep, lgrep, do several prompts asking for: {search string, file extension, directory}. (though, they still require user to be familiar with the unix commands. e.g. When “find-dired” promps “Run find (with args):”, you have to give -name "*html" or -type f etc.)

People who are not unix sys admin or unix programer won't be able to search a folder. The unix find/grep parameters are quite complex, and emacs documentation doesn't try to explain them. You have to know about “man pages” to read its documentation, and even so it's pretty much incomprehensible.

Also, occur shows result with search term highlighted. Nice. But the grep command doesn't (at least not on emacs 23.2 for Windows).

It seems to me, they could all use elisp, with a single code engine, and with the same interface. The files to be searched can be from buffer list or dired marked files, or entered from prompt with emacs regex. The output can be a output like occur or can be dired list or buffer list. For example, you could have a command list-matching-lines, and then “list-matching-lines-directory” with options to do nested dirs, and options to use a pattern to filter files to search for, or options to get marked files in dired, and also options to show result as file list in dired.

Calling external util has lots problems, especially under Windows. First of all, on Windows, external util may not be installed. This is a show stopper. Searching text is a critical feature of emacs. Then, there's Cygwin, MinGW and other variety issues. Emacs has to go thru several layers to interface with them. On unix/linux including Mac OS X, there's also complex issues of identifying the version of grep/find used, which differ in options and behavior. I recall that rgrep didn't work on Mac OS X neither. Then, emacs has to process the output to make syntax coloring. Also, if your search string contains Unicode, then there's extremely complex problem about setting some emacs variables or shell environment variables related to character encoding.

On the other hand, these text searching task is what elisp is designed to do, is rather trivial to code. It would eliminate the whole external program problems.

The core are already in emacs. occur, dired-do-query-replace-regexp, dired-do-search, and probably something in eshell too. They are just scattered and not unified.

By the way, doing it inside elisp is not that slow. Slower than those written in C, but remeber that emacs has to parse their output and the communication overhead might just make it up. I've written a grep command in elisp (See: How to Write grep in Emacs Lisp.). My script is more or less equivalent to unix's grep -c. Just tested now, calling it on a dir with subdir with total of 1592 files. Using a search word that returns over a thousand files. Both my script and unix util are close to 3 seconds. (e.g. call shell in emacs, then give grep -c */*html) Calling grep -c */*html by shell-command is less than 1 second. Calling grep -c */*html by emacs's grep is about 3 seconds too.

I think am going to polish my elisp grep script so it's going to be a general emacs command for all things grep. To begin with, i shall improve it for my own use to the degree that i never need to call unix find/grep directly or indirectly when in emacs.

Has someone written other grep util in elisp other than the above mentioned? What do you think about making emacs not rely on unix find/grep?

comp.emacs discussion

Emacs Lisp Example: title-case-string-region-or-line

In english writing, the title follows a particular convention of capitalization. For example, it should be “A Tale of Two Cities”, not “A Tale Of Two Cities”.

I think this is rather a silly convention. For a while, i experimented by simply following a logically simpler style, of capitalizing the first letter of all words. (See: The Writing Style on XahLee.org.) But after a while, i find it rather jarring.

Part of the reason is that it's new, thus it will get some used to. This i expected. However, the other thing that turns out is that, the capitalization has subtle function for emphasis. For example, “Kung Fu versus Karate” seems better than “Kung Fu Versus Karate”.

It's rather cumbersome to manually capitalize words following this convention. So, i wrote a emacs command. Here's the code:

(defun title-case-string-region-or-line (ξstring &optional ξregion-boundary)
  "Capitalize the current line or text selection, following title conventions.

Capitalize first letter of each word, except words like {to, of,
the, a, in, or, and, …}. If a word already contains cap letters
such as HTTP, URL, they are left as is.

When called in a elisp program, if ξREGION-BOUNDARY is nil,
returns the changed ξSTRING, else, work on the region.
ξREGION-BOUNDARY is a pair [from to], it can be a vector or
list."
  (interactive
   (let ((bds (get-selection-or-unit 'line)))
     (list nil (vector (elt bds 1) (elt bds 2)) ) ) )

  (let ( replacePairs
         (workOnStringP (if ξregion-boundary nil t ) )
         (p1 (elt ξregion-boundary 0))
         (p2 (elt ξregion-boundary 1))
         )
    
    (setq replacePairs '(
                         [" A " " a "]
                         [" And " " and "]
                         [" At " " at "]
                         [" As " " as "]
                         [" By " " by "]
                         [" Be " " be "]
                         [" Into " " into "]
                         [" In " " in "]
                         [" Is " " is "]
                         [" It " " it "]
                         [" For " " for "]
                         [" Of " " of "]
                         [" Or " " or "]
                         [" On " " on "]
                         [" The " " the "]
                         [" That " " that "]
                         [" To " " to "]
                         [" Vs " " vs "]
                         [" With " " with "]
                         [" From " " from "]
                         ))

    (let ((case-fold-search nil))
      (if workOnStringP
          (progn
            (replace-pairs-in-string-recursive (upcase-initials ξstring) replacePairs)
            )
        (progn
          (save-restriction
            (narrow-to-region p1 p2)
            (upcase-initials-region (point-min) (point-max) )
            (replace-regexp-pairs-region (point-min) (point-max) replacePairs t t)
            ) ) ) ) ) )

I used some elisp utils i wrote. You'll need to get it at: code.google.com xeu_elisp_util.el. This command is also bundled there.

Emacs: Enter Unicode by Decimal

Added to Emacs and Unicode Tips.

Emacs Lisp Example: mark-unicode

Often, when coding HTML, i need to mark a character as Unicode, using a custom HTML tag with special CSS markup, like this:

<b class="u">∑</b>

The <b>bold</b> tag is used to markup a text to stand out, with no particular semantic meaning (as opposed to <strong>strong</strong> or <em>emphasis</em>. (See: HTML5 Tags.)). The class “u” just indicate its Unicode. This way, i can write a Javascript so that when mouse hovers on the symbol, it'll show the Unicode number and also a large glyph of the char.

I have several elisp commands that wraps HTML tags in various ways, but i need to do this so often that i decided to write a dedicated command just for this. Here it is:

(defun mark-unicode (p1)
  "Wrap 「<b class=\"u\"></span>」 around current character.

When called in elisp program, wrap the tag at point P1."
  (interactive (list (point)))
    (goto-char p1)
    (insert "<b class=\"u\">")
    (forward-char 1)
    (insert "</b>"))

All my easy keys are used up, so i give it a alias of “u”. (See: Emacs: Defining Alias to Increase Productivity.)

1990s Web, Emacs W3 Browser, XEmacs, Nostalgia

Discovered a old W3C doc that proposes some HTML Entities to represent some commonly used icon-like symbols. What's interesting is that, one of the contributor listed: William M Perry, is the guy who wrote the “w3” web browser in emacs lisp. (See: See: www.emacswiki.org w3.) It's not just a text browser like lynx and many others. “w3” supports images, HTML table, and, and CSS too. Back in the 1990s, it's a big deal. It is bundled with XEmacs. I actually used it during 1999. If i recall correctly, Javascript support was planned but never implemented.

The w3 browser was declared abandoned around ~2006. Rather expected. Today's browsers are too complex to be implemented purely with emacs lisp.

Also of interest is that, in the file, you see some history of the web. Many of the icons proposed, are widely used in late 1990s. You see such things as telnet, gopher, ftp, uuencode, TeX DVI, “under construction” sign. See: Unicode: W3C Proposed Icons {Image, Video, Sound File, Trash, Keyboard, Mouse, …}.

Updated: Usability Problems of Emacs's Letter-Case Changing Commands.

Poll: Behavior of Home/End Keys

Poll: do you prefer the Home/End keys to:

Results:

Emacs: Searching for Text in Files (grep, find)

GNU Emacs Bug: rgrep, “find: invalid predicate `-nam'”

Added to Emacs Misc Bugs, bottom.

Updated: Emacs Lisp: Multi-Pair String Replacement Function.

proper elbow position during typing
Proper Elbow Position During Typing

Emacs Package: lookup-word-on-internet.el

A new package 〔lookup-word-on-internet.el〕 for lookup in {google search, dictionary, Wikipedia}. See the download link at: Emacs: Perl PHP Dictionary Wikipedia Google … Reference lookup.

Editing Lisp Code with ErgoEmacs Keybinding without ParEdit

Two weeks ago, i had a lisp exercise of writing “extract-url”. Here is a solution: Emacs Lisp: Writing a Command to Extract URL.

Updated 2 neglected but very useful articles:

Solution to last week's elisp exercise: Emacs Lisp Exercise: insert-random-uuid.

Updated with new examples: Emacs Keyboard Macro and Examples.

New major version of math symbol input mode is out, at v1.3.3.

Feature additions:

Buy it at: Emacs Unicode Math Symbols Input Mode (xmsi-mode).

If you have bought this package before, just email me with subject line “xmsi-mode update”, then i'll email it to you. Your support is much appreciated.

Emacs Lisp Exercise: insert-random-uuid

Emacs Lisp Programing: Beware of Region Boundary Change

Got stung by region in emacs, wasted about 4 hours. Here's what i learned:

Whenever you work in a region, remember that the boundaries of the text that you are interested is changed when you add or remove text in that region. For example, suppose p1 and p2 is the boundary of some text you are interested. After doing some change there, suppose you want to do some more change. Don't just call (something-region p1 p2) again, because p2 is no longer the correct boundary (of the region you are interested).

Use “save-restriction” and “narrow-to-region”, like this:

(save-restriction
  (narrow-to-region pos1 pos2)
  (something1-region (point-min) (point-max))
  (something2-region (point-min) (point-max))
  …
)

Last week, i updated the article Emacs Lisp: Syntax Color Source Code in HTML and re-implemented several of my personal commands, and today found that it behaved incorrectly: it deleted text outside of a region!

Here's a function “dehtmlize-span-region” effected by this:

;; WRONG! INCORRECT! DO NOT USE
(defun dehtmlize-span-region (p1 p2)
  (interactive "r")
  (replace-regexp-pairs-region p1 p2 '(["<span class=\"[^\"]+\">" ""]))
  (replace-pairs-region p1 p2 '( ["</span>" ""] ["&amp;" "&"] ["&lt;" "<"] ["&gt;" ">"] ) )
  )

Note how innocuous it looks. p1 and p2 are my region boundaries, and i work on them. Here's the correct code:

;; correct
(defun dehtmlize-span-region (p1 p2)
  (interactive "r")
  (save-excursion
    (save-restriction
      (narrow-to-region p1 p2)
      (replace-regexp-pairs-region (point-min) (point-max) '(["<span class=\"[^\"]+\">" ""]))
      (replace-pairs-region (point-min) (point-max) '( ["</span>" ""] ["&amp;" "&"] ["&lt;" "<"] ["&gt;" ">"] ) ) ) ) )

Looks so trivial a thing, but i spent 4 hours debugging to realize the fact that when i modified the text in region by my first function, the region boundary has changed. I remember, few years ago, i also spent half a day on region problems and wrongly concluded that “narrow-to-region” should be avoided in elisp program.

Unicode Characters for Space

See: http://xahlee.blogspot.com/2011/11/unicode-character-for-space.html

Solution to the problem last week: Emacs: Aligning Text and Sorting by Fields.

Past Articles by Date

2011-102011-092011-062011-042010-122010-092010-05