Emacs Stuff

[ Llama Fresh Farms ][ Ramblings of a Gay Man ][ Emacs Offerings ][ Music CD Trading ][ Favorite Recipes ][ Links Outta Here ]


* What's Emacs?
* Packages Written by Me
* Other People's Packages
* Code Snippets
* Useful Links

What's Emacs?

Emacs - noun ('ee-max)
  1. A text editor.

Emacs is arguably the world's most powerful text editor. It's quite old now (available since 1976) and quite mature in its abilities. But there's always room for improvement, and tens of thousands of little (and not so little) programs abound to do everything from reading & composing email to (I kid you not) brewing coffee.

I just recently discovered the joys of Emacs. I've been resisting the switch to Emacs for years and years, but I finally tried it out of desperation. I was trying to find an editor that could grok Perl quoting syntax correctly, and Emacs was the first one I'd found, and remains the only one that I know of (see below if you think your editor can do it). That hooked me in and its extensibility has kept me on long enough that now I couldn't imagine working without Emacs.

From what I understand, Emacs at its core is nothing but a Lisp interpreter, interpreting a special dialect of Lisp called elisp (or emacs-lisp). Lisp itself is one of the most bizarre languages I've ever programmed in. It's ugly stuff and somewhat counter-intuitive (at least at first), but boy is it powerful! And fast! The entire editor is itself written in elisp, which makes it very easy to seamlessly customize it.

And customizing editors is one of my most favorite past-times. Don't ask me why, but I've always been fascinated by text editors. My very first original, non-trivial program was a sprite editor on a Vic-20 (not quite a text editor, but they are more similar than you may think, at least how I wrote it). My next non-trivial, non-school-related program was implementing a full-fledged text editor using an experimental text editing package on the Mac (I think the package was called core-edit, or something like that). I have the documentation for it still, somewhere, as well as the print-out of my editor.

Ever since, I've been pushing editors to their limits, first with Brief, then vi and vile (VI-Like-Emacs), and then with Visual Slick-Edit. I came to my current job and someone there turned me on to Emacs (thanks Phil!!), and I've been a Lisp-ing fool ever since.

So on these pages you'll find out some things that I've discovered either on my own or through the generosity of others on email lists and newsgroups all over the world. Enjoy!

Perl Syntax Highlighting Challenge
Think your editor can grok Perl correctly? Try this on for size:

print 'This is a test of your editor's ability to grok Perl (or something equally complex)\n' if exists $foo{$bar};

That wasn't too bad, right? Most modern editors can handle that without too much trouble. Try this equally valid Perl command:

print q(This is a test of your editor's ability to grok Perl (or something equally complex)\n) if exists $foo{$bar};

As you see it above is how Emacs would interpret it. Here's how most editors would interpret it:

print q(This is a test of your editor's ability to grok Perl (or something equally complex)\n) if exists $foo{$bar};

or maybe, if you're really lucky:

print q(This is a test of your editor's ability to grok Perl (or something equally complex)\n) if exists $foo{$bar};

Note: this is not meant to start any religious editor wars. It's presented merely as a way to show that my editor is better than yours. Natty, natty, poo-poo!! <g>

Packages Written by Me

My meager contributions:

bar-cursor.el (zip / gz[Last Revision: 09-Jul-2001; Version: 1.1; Change Log]
Small Emacs package that changes the cursor from a block to a bar. In overwrite-mode, it changes back to a block.

cua-lite.el (zip / gz[Last Revision: 16-Aug-2003; Version: 1.4; Change Log]
CUA emulator package for Emacs. There are three things that make this package different from the others already out there:

  1. it is a quasi-minor mode, meaning that it can be turned on & off easily (though only globally; hence the "quasi-")
  2. it is easily extendable
  3. it does NOT attempt to override the existing use of <Ctrl><X> and <Ctrl><C> (use CUA-mode for that)
Now with Emacs-21 support (though, sadly, no Xemacs support -- see note in source for details).

cua-lite-bootstrap.el (zip / gz[Last Revision: 09-Jul-2001; Version: 1.1; Change Log]
Bootstrap for cua-lite (which see).

dired-single.el (zip / gz[Last Revision: 29-Oct-2008; Version: 1.7; Change Log]
Emacs package that provides a way to reuse the current dired buffer to visit another directory (rather than creating a new buffer for the new directory). Optionally, it allows the user to specify a name that all such buffers will have, regardless of the directory they point to.

em-joc.el (zip / gz[Last Revision: 01-Jan-2001; Version: 1.5; Change Log]
Provides some small additional function of eshell, the full-featured shell written in elisp. Functions include a prompt replacement (primarily replaces value of $HOME with a "~"), a "clear" function, which clears the screen/buffer much like clear (Unix) or cls (DOS), and a remote command, which lets you send the eshell a command from some outside piece of lisp code.

gnus-alias.el (zip / gz[Last Revision: 16-Aug-2003; Version: 1.4; Change Log]
Add-on to Gnus (5.8.8+) that allows for Identities to be defined and chosen automatically based on the context of the new message, and eases the switching of Identities on the current message. Also allows forwarded messages (email or news) to be treated as a reply/follow-up with respect to having their headers available to help determine the new message's Identity. Tested with Gnus 5.10.2, too.

hobo.el (zip / gz[Last Revision: 19-Jan-2002; Version: 1.2; Change Log]
Emacs package that provides an alternative to TRAMP when editing remote files via SCP. Hobo facilitates editing remote files by automating file transfers via SCP, relying on SSH-AGENT to authenticate. Hobo stores files locally in a temporary directory structure and can automatically clean up the temporary files and directories when you're done. In addition, it makes accessing the remote files a tad easier using aliases/shortcuts with all of the connection info already set up.

java-find.el (zip / gz[Last Revision: 10-Jan-2001; Version: 1.4]; Change Log]
Emacs package that provides a way to find and visit Java source files (indicated by a classname or filename under point) located somewhere in the user's SOURCEPATH. There are other packages out there that do similar things, including some things in JDE, but I like this one. It works regardless of your mode, and without tags. The only thing you need is a valid $SOURCEPATH.

swbuff-advice.el (zip / gz[Last Revision: 16-Jul-2001; Version: 1.5]; Change Log]
Emacs package that provides advice for several swbuff functions to allow the use of more than one set of regexp filters. Now includes the ability to specify inclusive and additive-exclusive filters, in addition to the normal exclusionary ones.

toggle-case.el (zip / gz[Last Revision: 20-Nov-2008; Version: 1.5]; Change Log]
Emacs package that emulates the vi ~ function (toggles case of character at point and advances).

toggle-buffer.el (zip / gz[Last Revision: 28-Jan-2001; Version: 1.1]; Change Log]
Emacs package that toggles between the current buffer and the previous one. I couldn't find anything that did what I wanted, so I wrote my own. Hope it wasn't done needlessly!

whole-line-or-region.el (zip / gz[Last Revision: 27-Nov-2008; Version: 1.2]; Change Log]
Cut and paste whole lines if regions is not active.

Other People's Packages

Here's a list of the packages I find most useful. I've provided links to the author's site whenever possible. If it doesn't respond, you can always try some of the Lisp archives mentioned below.

And let's not forget the packages that come with Emacs:

Code Snippets

A note on Named vs. Anonymous functions
Very small, one-line functions can be converted into anonymous functions if that better suits your needs. Actually, anonymous functions can be any size you want, but in other programming languages with which I'm familiar, it's generally better to restrict their use to very small functions except in certain circumstances. If you know what those circumstances are, then you probably don't need this little tutorial.

Anyhow, small one-liners can be turned into anonymous functions and back again with ease. It's mostly a matter of isolating the one line in question. For example:

   (defun joc-enlarge-by-ten()
     "enlarges a window 10 lines"
     (enlarge-window 10))
(enlarge-window 10) is the main part of this function; the rest is just the function definition. It could be rewritten anonymously like this:

       (lambda () "enlarges a window 10 lines" (interactive) (enlarge-window 10)))
As a general rule of thumb, if you're never going to call the function from some other function, it's OK to be anonymous. Of course, this then implies that the anonymous function definition is done where the function is to be used. For example:

   (defun joc-enlarge-by-ten()
     "enlarges a window 10 lines"
     (enlarge-window 10))

   (global-set-key [(f3)] 'joc-enlarge-by-ten)

   (global-set-key [(f3)] (function
       (lambda nil "enlarges a window 10 lines" (interactive) (enlarge-window 10))))
The choice is purely stylistic. All of my functions here are presented as named functions for those of you who are a little intimidated with the whole anonymous function concept.

Window-resizing Functions
I often find that, with split windows, I only want the second window as a reference. Consequently, I keep these resize functions handy.
(defun joc-enlarge-by-ten()
  "enlarges a window 10 lines"
  (enlarge-window 10))
(defun joc-shrink-by-five()
  "shrinks a window 5 lines"
  (shrink-window 5))

Printing under NT
I use an excellent freeware print program called PrintFile. I've written a couple of lisp functions to help with the printing. The first function makes a valid file name out of a buffer name passed in. Essentially, it strips out invalid characters like leading spaces and '*', and trailing spaces and '*'. It does this because the second program will write the text to be printed to a temporary file with this name (without altering the real file being visited), so that the PrintFile program can print the filename out in the header or footer (if desired). The function creates and then deletes this special print directory.
(defun joc-make-fname-from-buffer-name (fname-in)
  "Returns a valid filename from a given buffer name"
  (interactive "b")
  (let* ((start (string-match "[^ \*]" fname-in))
		 (end (string-match "[ \*]*$" fname-in (match-end 0))))
	(substring fname-in start end)))
(if (or (eq window-system 'w32) (eq window-system win32))
	(defun joc-print-buffer-or-region (prefix)
	  "Prints buffer or region via PrintFile32.	 If a prefix arg is set (via C-u) then
	   the current region is printed, otherwise the current buffer is printed."

	  (interactive "P")

	  ;; ----- set the print directory, fname and args -----
	  (let* ((print-dir (expand-file-name "~/emacs/print"))
			 (print-fname (joc-make-fname-from-buffer-name (buffer-name)))
			 (print-fullpath (concat print-dir "/" print-fname))
			 (print-args "/delete")
			 ;; ----- set rstart and rend to the current region -----
			 (rstart (point-min)) (rend (point-max)))

		;; ----- if prefix given, set them to region -----
		(if (and prefix)
			(if (and (point) (mark) (/= (point) (mark)))
				(progn (setq rstart (min (point) (mark)))
					   (setq rend (max (point) (mark))))
			  (error "No region defined")))

		;; ----- make the directory -----
		(if (not (file-directory-p print-dir))
			(make-directory print-dir))

		;; ----- write buffer/region to a temp file, print it, delete directory -----
		(write-region rstart rend print-fullpath)
		(call-process "prfile32" nil t nil print-args print-fullpath)
		(delete-directory print-dir))))
;; ----- use <Ctrl><P> to print the entire file -----
;; ----- use <Ctrl><U> <Ctrl><P> to print the current region -----
(if (or (eq window-system 'w32) (eq window-system win32))
	(global-set-key [(control p)] 'joc-print-buffer-or-region))

This little ditty bounces between matching parens (or brackets or braces) just like the '%' key in vi. I'm not sure I'm using the term sexp correctly here, but thankfully it doesn't affect the function.
(defun joc-bounce-sexp ()
  "Will bounce between matching parens just like % in vi"
  (let ((prev-char (char-to-string (preceding-char)))
	(next-char (char-to-string (following-char))))
	(cond ((string-match "[[{(<]" next-char) (forward-sexp 1))
		  ((string-match "[\]})>]" prev-char) (backward-sexp 1))
		  (t (error "%s" "Not on a paren, brace, or bracket")))))

This is useful for getting rid of the MULE menu. Thanks to someone on the NT Emacs mailing list for this one.
(global-unset-key [menu-bar mule])

Alternatives to <Alt><Tab> for NT Users
Under Windows, <Alt><Tab> switches programs. While there's a way to turn this behaviour off from within Emacs, I prefer to keep it, and change Emacs' behaviour. I don't really miss the <Alt><Tab> except in Customize buffers, where it can be used for completion of buffer names and function names (and file names and directory names, etc.). So, this snippet maps <Ctrl><Tab> to be the equivalent of <Alt><Tab>. Thanks, again, to an unnamed NT-Emacs mailing list contributor.
(define-key function-key-map [(control tab)] [?\M-\t])

Useful Links

General Emacs Resources

NT-specific Emacs Resources

Lisp Archives

.emacs Resources

Useful Personal Homepages

(lambda) Live Free, that's the message! (rainbow flag)


Copyright © Joseph L. Casadonte Jr. 2000-2001. All rights reserved.
Emacs Offerings / 30 December 2001 / emacs@northbound-train.com
HTML 3.2 Validated! Created with Emacs