Tuesday, February 17, 2009

Dynamic Modal Bindings (auto prefixing)

A guy posted an interesting question on stackoverflow:

Most emacs modes include some sort of prefix to activate their features. For example, when using GUD "next" is "C-c C-n". Of these modes, many provide special buffers where one can use a single key to activate some functionality (just 'n' or 'p' to read next/previous mail in GNUS for example).

Not all modes provide such a buffer, however, and repeatedly typing the prefix can be tiresome. Is there a well-known bit of elisp that will allow for ad-hoc specification of prefix keys to be perpended to all input for some time? (Until hitting ESC or some other sanctioned key, for example)

Very intriguing, how does one go about solving that?

I don't think you want that (in general) because many of the prefix commands contain an extensive set bindings which clobber too many useful keys. That being said, I'm sure there are places this could come in handy.

I wrote up a solution that prompts you for a key sequence, and it promotes the prefix command keymap to the toplevel (associated with this particular minor mode). The minor mode is buffer specific, and it only allows one prefix command to be promoted at a time.

Check out my answer (won't put the code here in case I need to make an update).

Tuesday, January 13, 2009

Emacs Tip #28: e-blog

There are a number of different packages purporting to enable blogging from Emacs, but most people (including myself) have failed to get any of them to work.

I recently heard about: http://code.google.com/p/e-blog/, as a simple blogging package specifically for blogger.

This is my first post.

Note: It does depend on curl.

Wednesday, December 10, 2008

stackoverflow.com

If you read Coding Horror or Joel On Software, you already know about stackoverflow.com. In a nutshell, it's a place where you can ask coding questions and receive answers quickly. You can also participate by voting answers up/down and answering questions.

stackoverflow.com works really well, the overall design is very simple, clean, and easy to use.

The emacs community there is pretty small, but questions do come up now and then. In general the answers are fairly good (I think mine are stupendous, feel free to look at them and vote them up).

Like any good (modern) web page, this one has plenty of RSS feeds. This is the feed I use to watch questions tagged emacs elisp emacs-lisp dot-emacs.

Monday, December 1, 2008

Emacs Tip #27: midnight-mode

I generally have a single emacs session that runs for a couple weeks, up to about 3 months (when work does it's quarterly preventative maintenance reboot), and because of this, I often have dozens of buffers open. Periodically I'd go through them and remove a bunch - mostly to free up memory.

Luckily, there's a mode that already does that for you, periodically flushing unused and old buffers:

(require 'midnight)
The following variables can be used to customize the behavior of the clean-buffer-list (which is run daily at midnight). It responds to settings of the following variables:
clean-buffer-list-kill-buffer-names
clean-buffer-list-kill-regexps
clean-buffer-list-kill-never-buffer-names
clean-buffer-list-kill-never-regexps
clean-buffer-list-delay-general
clean-buffer-list-delay-special
I love finding packages that implement functionality I hadn't realized I wanted. It is very relieving, like accidentally scratching an itch I didn't know was bothering me.

Edited to reflect proper require statement.

Wednesday, October 22, 2008

Gödel, Escher, Bach

I'm a Yegge fan-boy, and his most recent post mentioned Gödel, Escher, Bach - the Pulitzer Prize-winning book by Douglas Hofstadter. Which got me to thinking...

A couple of programmers/bloggers I respect have the book on their must-have lists: Joel, Stevey. And most programming bloggers refer to it reverently.

I tried to read the book shortly after graduating college. I didn't finish it, because it was incredibly boring and repetitive and boring ... and repetitive. Turns out many don't finish the book, no surprise to me.

I'll repeat myself (in the spirit of GEB I should probably recurse), GEB was a complete snoozer. It reminded me much of Ayn Rand's Atlas Shrugged - another snoozer. There's only so much repetition I can stand.

I'm sure I missed all the puzzles and word-play - I certainly didn't get to the end where Hofstadter's characters discuss books that end before the final page (a joke that took 700 pages to set up).

Perhaps the book provides a path to enlightenment to people who are not familiar with recursion, self-reference, and the incompleteness theorem. Or, maybe there is enough wordplay and "charming" dialog to get you to wade through all 800 pages (there is that one nearly at the end).

I'd have been happier if the book were condensed to 150 pages.

Friday, October 10, 2008

Emacs Tip #26: CUA mode (specifically rectangle editing)

I'd heard of CUA mode, but generally dismiss it because I don't want the "windows" bindings for cut/copy/paste/undo. But when I saw this video of CUA's rectangle support, I knew this was the way to edit rectangles.


Emacs Column Editing from Mark Mansour on Vimeo.

To activate in emacs 22.1 - with minimal intrusion (I don't like transient mark mode):
(setq cua-enable-cua-keys nil)
(setq cua-highlight-region-shift-only t) ;; no transient mark mode
(setq cua-toggle-set-mark nil) ;; original set-mark behavior, i.e. no transient-mark-mode
(cua-mode)


The *info* page doesn't have the rectangle bindings (as far as I can see), so here is the documentation from the code:


;; CUA rectangle support
;; ---------------------
;; Emacs' normal rectangle support is based on interpreting the region
;; between the mark and point as a "virtual rectangle", and using a
;; completely separate set of "rectangle commands" [C-x r ...] on the
;; region to copy, kill, fill a.s.o. the virtual rectangle.
;;
;; cua-mode's superior rectangle support uses a true visual
;; representation of the selected rectangle, i.e. it highlights the
;; actual part of the buffer that is currently selected as part of the
;; rectangle. Unlike emacs' traditional rectangle commands, the
;; selected rectangle always as straight left and right edges, even
;; when those are in the middle of a TAB character or beyond the end
;; of the current line. And it does this without actually modifying
;; the buffer contents (it uses display overlays to visualize the
;; virtual dimensions of the rectangle).
;;
;; This means that cua-mode's rectangles are not limited to the actual
;; contents of the buffer, so if the cursor is currently at the end of a
;; short line, you can still extend the rectangle to include more columns
;; of longer lines in the same rectangle. And you can also have the
;; left edge of a rectangle start in the middle of a TAB character.
;; Sounds strange? Try it!
;;
;; To start a rectangle, use [C-return] and extend it using the normal
;; movement keys (up, down, left, right, home, end, C-home,
;; C-end). Once the rectangle has the desired size, you can cut or
;; copy it using C-x and C-c (or C-w and M-w), and you can
;; subsequently insert it - as a rectangle - using C-v (or C-y). So
;; the only new command you need to know to work with cua-mode
;; rectangles is C-return!
;;
;; Normally, when you paste a rectangle using C-v (C-y), each line of
;; the rectangle is inserted into the existing lines in the buffer.
;; If overwrite-mode is active when you paste a rectangle, it is
;; inserted as normal (multi-line) text.
;;
;; If you prefer the traditional rectangle marking (i.e. don't want
;; straight edges), [M-p] toggles this for the current rectangle,
;; or you can customize cua-virtual-rectangle-edges.

;; And there's more: If you want to extend or reduce the size of the
;; rectangle in one of the other corners of the rectangle, just use
;; [return] to move the cursor to the "next" corner. Or you can use
;; the [M-up], [M-down], [M-left], and [M-right] keys to move the
;; entire rectangle overlay (but not the contents) in the given
;; direction.
;;
;; [C-return] cancels the rectangle
;; [C-space] activates the region bounded by the rectangle

;; If you type a normal (self-inserting) character when the rectangle is
;; active, the character is inserted on the "current side" of every line
;; of the rectangle. The "current side" is the side on which the cursor
;; is currently located. If the rectangle is only 1 column wide,
;; insertion will be performed to the left when the cursor is at the
;; bottom of the rectangle. So, for example, to comment out an entire
;; paragraph like this one, just place the cursor on the first character
;; of the first line, and enter the following:
;; C-return M-} ; ; C-return

;; cua-mode's rectangle support also includes all the normal rectangle
;; functions with easy access:
;;
;; [M-a] aligns all words at the left edge of the rectangle
;; [M-b] fills the rectangle with blanks (tabs and spaces)
;; [M-c] closes the rectangle by removing all blanks at the left edge
;; of the rectangle
;; [M-f] fills the rectangle with a single character (prompt)
;; [M-i] increases the first number found on each line of the rectangle
;; by the amount given by the numeric prefix argument (default 1)
;; It recognizes 0x... as hexadecimal numbers
;; [M-k] kills the rectangle as normal multi-line text (for paste)
;; [M-l] downcases the rectangle
;; [M-m] copies the rectangle as normal multi-line text (for paste)
;; [M-n] fills each line of the rectangle with increasing numbers using
;; a supplied format string (prompt)
;; [M-o] opens the rectangle by moving the highlighted text to the
;; right of the rectangle and filling the rectangle with blanks.
;; [M-p] toggles virtual straight rectangle edges
;; [M-P] inserts tabs and spaces (padding) to make real straight edges
;; [M-q] performs text filling on the rectangle
;; [M-r] replaces REGEXP (prompt) by STRING (prompt) in rectangle
;; [M-R] reverse the lines in the rectangle
;; [M-s] fills each line of the rectangle with the same STRING (prompt)
;; [M-t] performs text fill of the rectangle with TEXT (prompt)
;; [M-u] upcases the rectangle
;; [M-|] runs shell command on rectangle
;; [M-'] restricts rectangle to lines with CHAR (prompt) at left column
;; [M-/] restricts rectangle to lines matching REGEXP (prompt)
;; [C-?] Shows a brief list of the above commands.

;; [M-C-up] and [M-C-down] scrolls the lines INSIDE the rectangle up
;; and down; lines scrolled outside the top or bottom of the rectangle
;; are lost, but can be recovered using [C-z].

Wednesday, September 3, 2008

The Web Interface Is Morphing Into Emacs

A while back, Steve Yegge wrote a post on Emacs and its future. My executive summary of his post is that Emacs needs to compete or die - and the competition is the browser.

This got a little thread started on the Emacs development list, but not much activity. If Steve's line of reasoning is correct, then I surmise Emacs is dead b/c the Emacs development team is not at all interested in competing with the browser. Heck, they recently had a discussion on moving from CVS to a modern (distributed) version control system - and while there appears to be a tentative decision to move to Bazaar for version control, main development is still on CVS.

I personally think Emacs is a niche product. Like Unix, it has a dedicated fan base and will be around for the foreseeable future. But, it is never going to grow a large base of end-users. It has got a lot of ... baggagehistory that turns some people off: GPL, RMS, lisp, (lack of) speed, text-based, carpal tunnel, etc.

I love Emacs and do most everything inside Emacs, but it is not and probably will never be hip, exciting, new, or perceived as leading edge technology.

What was my point? Oh, right, Ubiquity was recently announced at Mozilla Labs.

I watched the 6 minute video demo. And my first impression? It is Emacs, only instead of M-x you use C-SPC. Soon, people will tire of typing things out and come up with shortcuts based on various key combinations, and it'll turn into Emacs.

Of course, if Ubiquity does that, it'll be cool/hip, and people won't complain about the key-bindings.

It's just like XML over Lisp. The reaction to Lisp is, "OMG! Parentheses! Run!" On the other hand, XML (with twice the number of parenthesis</>) is cool/hip and folks have flocked to it.

Steve was right about the competition, the browser has fired the first salvo, and it looks a lot like Emacs.

Mozilla Labs » Introducing Ubiquity