The Challenge
Jon over at Irreal’s Emacs blog posted an interesting solution to a challenge raised by Xah Lee:
How do you convert a string like this
37°26′36.42″N 06°15′14.28″Winto a decimal answer like this37.44345 -6.25396.
First off, I’m not sure Xah’s example answer is entirely correct; my understanding of latitude and longitude is limited to what I can google, and if I type the original degrees, minutes and seconds into this tool by the U.S. FCC it returns 37.44345 6.25396.
Anyway, on with the challenge. Jon’s solution is very interesting, but it got me thinking: surely Emacs has the facility in place to do this already? It’s Emacs, right? Right.
Fun with Emacs Calc
Emacs is equipped with a really, really awesome and spiffy RPN calculator (HP calculator fans, rejoice) capable of manifold things like algebraic and symbolic manipulation; matrix manipulation; conversion routines and much, much more. It’s truly wonderful but really complex, but it does come with a really nice Info manual (type C-h i g (calc) and check it out.) It’s a shame so few people know about its potential, as it’s basically a much simpler version of Mathematica, or even Wolfram Alpha (arguably you’ll have as much trouble telling Calc what you want as you would Wolfram Alpha…)
Anyway, I figured the Emacs calculator would have a facility in place for converting Deg-Min-Sec to decimal form, and sure enough, it does.
To try it out, type C-x * * and the calculator will open. Two windows will appear: the calculator mode and the trail containing a trail — a history — of commands and actions. The first thing we need to do is switch the calculator to “HMS” mode so we can try it out. To do this, type m h in the mode (the left) window and the modeline will change and say something like Calc: 12 Hms. The 12 is the floating point precision.
Next, type in the expression, replacing the unicode symbols above with @ for degrees; ' for minutes; and " for seconds. If you typed it in correctly, it will appear in the calculator window.
All we have to do now is convert it. Calc can convert between a wide range of units and systems, but we only care about decimals. Type c d and Calc will convert it to a decimal number. If you entered 37@26'36.42" you should see 37.44345 appear in its place.
OK, so we know it can do it, but how do we weaponize it? It so happens that Calc comes with a neat, little (though underdocumented) command called calc-eval.
Entering IELM, M-x ielm, we can query the calculator in real time:
ELISP> (calc-eval "1+2") "3"
Yep. It does work. The hardest part about using it is mapping the “algebraic” notation used above with the indirect, keybinding-based input you use in the RPN calculator. Thankfully, the manual and (often) the trail will tell you the name of the function you are calling.
Let’s digress a little so I can show you how neat this calculator actually is: solving the elementary equation 2x+5=10. In the calculator, type m a to go to algebraic mode; next, type (2x + 5 = 10) — don’t forget the brackets — and it should appear as an equation. Finally, type a S to “solve for” a variable — and when prompted, answer x. The answer will appear in your calculator window. How awesome is that?
Back to the challenge. Calling the “convert to degrees” function is what we need to do, and the answer is hidden in the trail — it’s called deg.
Putting it all together, and we get:
ELISP> (calc-eval "deg(37@ 26' 36.42\")") "37.44345"
That looks right. But the original challenge said that we had to take a string, like the one given above, and map that. So here’s my solution:
(defun hms-to-dec (hms-str) (let ((hms (split-string hms-str "[°′″NW ]" t))) (flet ((to-deg () (string-to-number (calc-eval (format "deg(%s@ %s' %s\")" (pop hms) (pop hms) (pop hms)))))) (list (to-deg) (to-deg)))))
Calling it from IELM yields the following answer:
ELISP> (hms-to-dec "37°26′36.42″N 06°15′14.28″W") (37.44345 6.25396666667)
Looks good to me. Job done, and a fun challenge.
In my What’s New In Emacs 24 series (part one, part two) I briefly mentioned that pcomplete, the programmable completion library featured prominently in Eshell, now supports M-x shell out of the box. That’s great news for shell mode fans as the completion mechanism adds a lot of nifty functionality to a mode that lacks the native completion provided by underlying the shell itself.
The most amazing thing about the completion mechanism is that it has been in Emacs for ages but never made much of a public appearance and has gone virtually unnoticed due to its limited use in Emacs. In fact, I think it’s only used in EShell, ERC, Org Mode and now, finally, Shell Mode.
Programmable, Context-Sensitive Completion
To use pcomplete you won’t have to do anything, because as of Emacs 24 it is now supported automatically when you launch a new shell session. Emacs ships with a handful of pcomplete functions that enhance the otherwise drab filename completion with context-sensitive completion similar to what you can do with bash/zsh completion. Of particular note is the scp, ssh, mount, umount and make support.
The following table lists the commands supported by shell mode (or indeed any mode that supports pcomplete, including Eshell.)
| Command | Notes |
|---|---|
| bzip2 | Completes arguments and lists only bzipped files. |
| cd | Completes directories. |
| chgrp | Completes list of known groups on the system. |
| chown | Completes user and group perms, but only if you use user.group. |
| cvs | Completes commands and parameter options and cvs entries and modules. |
| gdb | Completes only directories or files with eXecute permission. |
| gzip | Completes arguments and lists only gzipped files. |
| kill | Lists signals if completed with just a -, otherwise it completes all system PIDs. |
| make | Completes arguments and valid makefiles in the directory; if a valid makefile is completed with make -f FILE a list of rule names from the file itself are completed. |
| mount | Completes arguments and valid filesystem types if completed with mount -t TYPE. |
| pushd | Identical to cd. |
| rm | Completes arguments and filenames and directories. |
| rmdir | Completes directories. |
| rpm | Very sophisticated completion mechanism for most of rpm, the Redhat Package Manager. Context-sensitive completion for almost all commands, including package lookup. |
| scp | Completes arguments, SSH known hosts and remote file lookup (using TRAMP) if the format is scp host:/. |
| ssh | Completes arguments and SSH known hosts. |
| tar | Completes arguments, including context-sensitive completion for POSIX arguments, and file name completion. |
| time | Completes directories and files with eXecutable permission. |
| umount | Completes arguments, mounted directories and filesystem types (like mount) |
| which | Supposed to provide simple filename completion of all known binaries (wouldn’t be useful otherwise!) but appears to not work right. |
| xargs | Completes directories and files with eXecutable permission. |
Custom Completion
It goes without saying that a completion library called programmable completion is, well, programmable.
Adding simple parameter completion is an easy job but anything more than that and it gets hairy as, not surprisingly, this library is virtually undocumented (though an optimist would say the source is all the documentation you need…)
I’ll demonstrate how to add rudimentary support for git.
The first thing we need to do is establish the order in which parameters must be given; for git, it’s somewhat consistent: git [options] <command> [<args>]
For now I’ll stick to the commands as that’s what people use the most anyway. The commands, in list form, are:
(defconst pcmpl-git-commands '("add" "bisect" "branch" "checkout" "clone" "commit" "diff" "fetch" "grep" "init" "log" "merge" "mv" "pull" "push" "rebase" "reset" "rm" "show" "status" "tag" ) "List of `git' commands")
The syntax for pcomplete is rather clever: it will use dynamic dispatch to resolve the elisp function provided it is named a certain way. All commands are named pcomplete/COMMAND or pcomplete/MAJOR-MODE/COMMAND. Provided you follow that naming scheme your command will automagically work.
Next, we need to present a list of valid commands — in this case the ones in pcmpl-git-commands, but it could be any form — to the command pcomplete-here.
(defun pcomplete/git () "Completion for `git'" (pcomplete-here* pcmpl-git-commands))
Now when you try to tab-complete the first argument to git it will list our commands. Sweet.
Let’s extend it further by adding support for the add and rm commands. I want the aforementioned commands to provide the standard filename/filepath completion if, and only if, the command is add or rm.
This is surprisingly easy to do using pcomplete-match, a function that asserts a certain regexp matches a particular function argument index. Note that the call to pcomplete-here is in a while loop; this is so you can complete as many files as you like, one after another. One advantage of pcomplete-here is that it won’t display files you have already completed earlier in the argument trail — that’s very useful for a command like add.
(defun pcomplete/git () "Completion for `git'" ;; Completion for the command argument. (pcomplete-here* pcmpl-git-commands) ;; complete files/dirs forever if the command is `add' or `rm'. (if (pcomplete-match (regexp-opt '("add" "rm")) 1) (while (pcomplete-here (pcomplete-entries)))))
Ok, that was easy. Now let’s make it a bit more dynamic by extending our code to support the git checkout command so it will complete the list of branches available to us locally.
To do this we need a helper function that takes the output of a call to shell-command and maps it to an internal elisp list. This is easily done with some quick hackery.
The variable pcmpl-git-ref-list-cmd holds the shell command we want Emacs to run for us. It gets every ref there is and we then filter by sub-type (heads, tags, etc.) later. The function pcmpl-git-get-refs takes one argument, type, which is the ref type to filter by.
(defvar pcmpl-git-ref-list-cmd "git for-each-ref refs/ --format='%(refname)'" "The `git' command to run to get a list of refs") (defun pcmpl-git-get-refs (type) "Return a list of `git' refs filtered by TYPE" (with-temp-buffer (insert (shell-command-to-string pcmpl-git-ref-list-cmd)) (goto-char (point-min)) (let ((ref-list)) (while (re-search-forward (concat "^refs/" type "/\\(.+\\)$") nil t) (add-to-list 'ref-list (match-string 1))) ref-list)))
And finally, we put it all together. To keep the code clean I’ve switched to using a cond form for readability.
(defconst pcmpl-git-commands '("add" "bisect" "branch" "checkout" "clone" "commit" "diff" "fetch" "grep" "init" "log" "merge" "mv" "pull" "push" "rebase" "reset" "rm" "show" "status" "tag" ) "List of `git' commands") (defvar pcmpl-git-ref-list-cmd "git for-each-ref refs/ --format='%(refname)'" "The `git' command to run to get a list of refs") (defun pcmpl-git-get-refs (type) "Return a list of `git' refs filtered by TYPE" (with-temp-buffer (insert (shell-command-to-string pcmpl-git-ref-list-cmd)) (goto-char (point-min)) (let ((ref-list)) (while (re-search-forward (concat "^refs/" type "/\\(.+\\)$") nil t) (add-to-list 'ref-list (match-string 1))) ref-list))) (defun pcomplete/git () "Completion for `git'" ;; Completion for the command argument. (pcomplete-here* pcmpl-git-commands) ;; complete files/dirs forever if the command is `add' or `rm' (cond ((pcomplete-match (regexp-opt '("add" "rm")) 1) (while (pcomplete-here (pcomplete-entries)))) ;; provide branch completion for the command `checkout'. ((pcomplete-match "checkout" 1) (pcomplete-here* (pcmpl-git-get-refs "heads")))))
And that’s that. A simple completion mechanism for git. Put this in your .emacs or init file and you’re done.
As I mentioned in my What’s New In Emacs 24 series (part one, part two) Emacs 24 can now sort the colors in M-x list-colors-display based on the RGB or HSV distance to another color. This is perhaps of most interest to web designers or color theme creators, but it’s still a fun little addition.
Unfortunately, this functionality is only available through the customize interface, and that means most people will never bother with it at all. Hence, I’ve written two helper commands below to make this neat addition to Emacs 24 easier to use.
If you’re looking up a named color (like red) then it must exist in M-x list-colors-display; if it’s an HTML color then as long as it is valid it will work.
To use it, you must invoke M-x find-nearest-color and enter the name of a color. The other command, find-nearest-color-at-point does just that: it looks at what your point is on and tries to look it up.
(defun find-nearest-color (color &optional use-hsv) "Finds the nearest color by RGB distance to `color'. If called with a universal argument (or if `use-hsv' is set) use HSV instead of RGB. Runs \\[list-colors-display] after setting `list-colors-sort'" (interactive "sColor: \nP") (let ((list-colors-sort `(,(if (or use-hsv current-prefix-arg) 'hsv-dist 'rgb-dist) . ,color))) (if (color-defined-p color) (list-colors-display) (error "The color \"%s\" does not exist." color)))) (defun find-nearest-color-at-point (pt) "Finds the nearest color at point `pt'. If called interactively, `pt' is the value immediately under `point'." (interactive "d") (find-nearest-color (with-syntax-table (copy-syntax-table (syntax-table)) ;; turn `#' into a word constituent to help ;; `thing-at-point' find HTML color codes. (modify-syntax-entry ?# "w") (thing-at-point 'word))))
If you hack a lot of elisp you will notice that I’ve chosen to hack the syntax table (temporarily) to make thing-at-point play nice with the HTML color syntax (#ABCDEF) as the character — and this will depend on your mode and thus your syntax table, of course — # is rarely a “word” constituent. I think this is a much cleaner way of “getting” things at point than messing with regular expressions as you will inevitably end up reinventing most of thing-at-point doing so.
With Emacs 24 looming around the corner I figured it was time I took a close look at all the new features and changes. As it’s not officially out yet I will settle for the pretest build (get it here.) With that said, there’s little difference (in my experience anyway) between the pretest versions of Emacs and the real mccoy. They’re usually rock-solid and won’t crash on you, but the featureset is, of course, still subject to change.
I’ve annotated most changes and given my view of how useful each change is to most people. Obviously I do not speak for all of us, so don’t neglect to read the NEWS file in its entirety yourself (C-h n.)
Installation Changes in Emacs 24.1
** By default, the installed Info and man pages are compressed.
You can disable this by configuring –without-compress-info.
Useful configure flag for people who value time over space; of course, most of us use a package manager and thus we have no say in how our software is built.
Emacs can be compiled with ImageMagick support.
Emacs links to ImageMagick if version 6.2.8 or newer of the library is
present at build time. To inhibit ImageMagick, use the configure
option `–without-imagemagick’ .
Neat. Imagemagick is a set of tools for manipulating, viewing and converting images and other media files like PDF and PS. With any luck we might get “native” PDF/PS support in Emacs. DocView (the Emacs document viewer) converts each PDF/PS page to PNG and displays that on your screen. Hardly ideal.
Startup Changes in Emacs 24.1
On Windows, Emacs now warns when the obsolete _emacs init file is used,
and also when HOME is set to C:\ by default.
Warning when the HOME directory is unset (or set to C:\)
will aid new Emacs users greatly as it is a rather obscure requirement
that you have to set the HOME environment variable to
control where Emacs will read the init.el or .emacs file from.
Changes in Emacs 24.1
auto-mode-case-fold is now enabled by default.
The auto-mode-alist variable is an association list (hence the -alist bit) of key-value pairs that define what major mode Emacs should set when you open a certain file type. By setting the case fold flag to t Emacs will search the list twice: first time around it will use case sensitive matching and, if no matches were found, it will try again but with insensitive matching. This switch has no effect on Windows.
Completion
shell-mode uses pcomplete rules, with the standard completion UI.
Yowzah! There’s a lot of cool, new functionality hidden away in this gem of a change. The author of pcomplete is John Wiegley — the same guy who wrote EShell — and in Eshell you can complete commandline arguments for things like kill, rmdir, etc. in the same way zsh (or newer versions of bash) does it: by writing your own “programmable” (that’s the p in pcomplete) completion engines for individual commands. Nifty. Of course, this concept is not limited to just shells. You could write completion libraries for programing modes and what have you as well.
This feature is a Big Deal to people (like me) who use M-x shell all the time for day-to-day work. If you’re using Emacs 24 right now try this on for size (Linux, et al only): chgrp TAB and you should see a completion window appear listing all the various groups on your system. Cool! Type M-x apropos pcomplete/ to see a list of all the completion engines available.
I’m definitely going to cover this in greater detail later.
Many packages have been changed to use `completion-at-point’
rather than their own completion code.
Another lovely change made in the name of standardization. The command completion-at-point is a generic command that, by fiddling with the variable completion-at-point-functions, you can control how Emacs does completion in a particular buffer. Lots of modes and packages have their own little completion engines, thus diminishing the value of having such a generic facility in place.
`completion-at-point’ now handles tags and semantic completion.
CEDET’s Semantic library is now usable from the Emacs completion framework. The easiest way to test it is to open up a C source code file and typing M-TAB or C-M-i and watch as Semantic automagically completes for you. For languages where semantic is not enabled by default, you can add it the following line to your major mode hook of choice:
(add-to-list 'completion-at-point-functions 'semantic-completion-at-point-function)
Completion in a non-minibuffer now tries to detect the end of completion
and pops down the *Completions* buffer accordingly.
This behaviour has always been a major source of frustration for me and, I’m sure, others as well. Historically Emacs would leave completion windows hanging around well after you were done using them; not so any more. Emacs will try to hide them automatically “when you’re done with them.” This works really well for me in M-x shell as I’m always TAB-completing paths and filenames.
Completion can cycle, depending on completion-cycle-threshold.
Another productivity enhancer! If you set completion-cycle-threshold to t then Emacs will always cycle through the completion choices if there is more than one left. And because this feature affects completion-at-point it should work in most modes. Set it to an integer and it will only cycle if there are fewer than N items. Set it to nil (the default) and it is disabled entirely.
I like this feature, so I have set it to cycle if there are fewer than 5 items:
(setq completion-cycle-threshold 5)
New completion style `substring’.
The new substring style gives you “wildcard”-style partial completion where Emacs will cast as wide a net as it can to complete your text.
Historically, Emacs has gone through quite a few completion “styles”; that is, different ways in which Emacs tries to complete your query when you press (usally) TAB. There’s a host of them, and you can (surprise!) add your own as well if you really want to. The association list completion-styles-alist lists all the current styles and the variable completion-styles contains an ordered list of styles to cycle through. To use the new substring style you can add it to the completion styles list. Keep in mind that some modes will override the defaults. See the next item.
(add-to-list 'completion-styles 'substring)
Completion style can be set per-category `completion-category-overrides’.
As I mentioned in the above entry you can tell Emacs to only use certain styles in certain parts of Emacs.
Completion of buffers now uses substring completion by default.
This is no doubt a welcome change to the, oh, five or so people out there who choose not to use iswitchb or IDO Mode. Sarcasm aside, this is useful if you screw up your init file and you need to switch to the *Messages* buffer.
Mail changes
default of `send-mail-function’ is now `sendmail-query-once’,
which asks the user (once) whether to use the smtpmail package to send
email, or to use the old defaults that rely on external mail
facilities (`sendmail-send-it’ on GNU/Linux and other Unix-like
systems, and `mailclient-send-it’ on Windows).
The first time you use C-x m (compose-mail) and try to send an e-mail Emacs will now ask you how it should send the e-mail. Simple stuff, really.
smtpmail changes
smtpmail now uses encrypted connections (via STARTTLS) if the
mail server supports them. It also uses the auth-source framework for
getting credentials.
Good news for people who can’t use unencrypted mail servers.
The variable `smtpmail-auth-credentials’ has been removed.
That variable used to have the default value “~/.authinfo”, in which
case you won’t see any difference. But if you changed it to be a list
of user names and passwords, that setting is now ignored; you will be
prompted for the user name and the password, which will then be saved
to ~/.authinfo.You can also manually copy the credentials to your ~/.authinfo file.
For example, if you had(setq smtpmail-auth-credentials
‘((“mail.example.org” 25 “jim” “s!cret”)))then the equivalent line in ~/.authinfo would be
machine mail.example.org port 25 login jim password s!cret
The variable `smtpmail-starttls-credentials’ has been removed.
If you had that set, then you need to put
machine smtp.whatever.foo port 25 key “~/.my_smtp_tls.key” cert “~/.my_smtp_tls.cert”
in your ~/.authinfo file instead.
Useful knowledge if you’re composing mail in Emacs.
sendmail changes
can now add MIME attachments to outgoing messages with the new
command `mail-add-attachment’.
command `mail-attach-file’ was renamed to `mail-insert-file’; the
old name is now an obsolete alias to the new name.
Emacs server and client changes
New option `server-port’ specifies the port on which the Emacs
server should listen.
New emacsclient argument -q/–quiet suppresses some status messages.
New emacsclient argument –frame-parameters can be used to set the
frame parameters of a newly-created graphical frame.
If emacsclient shuts down as a result of Emacs signaling an
error, its exit status is 1.
New emacsclient argument –parent-id ID.
This opens a client frame in parent X window ID, via XEmbed, similar
to the –parent-id argument to Emacs.
More changes to Emacs’s Client-Server architecture. The port command change is probably the most interesting bit.
Internationalization changes
Emacs now supports display and editing of bidirectional text.
Text that includes characters from right-to-left (RTL) scripts, such
as Arabic, Farsi, or Hebrew, is displayed in the correct visual order
as expected by users of those scripts. This display reordering is a
“Full bidirectionality” class implementation of the Unicode
Bidirectional Algorithm. Buffers with no RTL text should look exactly
the same as before.For more information, see the node “Bidirectional Editing” in the
Emacs Manual.
New buffer-local variable `bidi-display-reordering’.
To disable display reordering in any given buffer, change this to nil.
New buffer-local variable `bidi-paragraph-direction’.
If nil (the default), Emacs determines the base direction of each
paragraph from its text, as specified by the Unicode Bidirectional
Algorithm.Setting this to `right-to-left’ or `left-to-right’ forces a particular
base direction on each paragraph in the buffer.Paragraphs whose base direction is right-to-left are displayed
starting at the right margin of the window.
Enhanced support for characters with no glyphs in available fonts.
If a character has no glyphs in any of the available fonts, Emacs
normally displays it either as a hexadecimal code in a box or as a
thin 1-pixel space. In addition to these two methods, Emacs can
display these characters as empty box, as an acronym, or not display
them at all. To change how these characters are displayed, customize
the variable `glyphless-char-display-control’.On character terminals, these methods are used for characters that
cannot be encoded by the `terminal-coding-system’.
New input methods for Farsi: farsi and farsi-translit.
Right-to-Left support in Emacs has been a long time coming and a difficult and complex change to Emacs’s display engine. If you’re a RTL user I’d love to hear how functional and useful it actually is.
`nobreak-char-display’ now also highlights Unicode hyphen chars
(U+2010 and U+2011).
If nobreak-char-display is t Emacs will highlight facsimile unicode whitespace and hyphen characters so you can tell them apart from their ASCII counterpart.
Improved GTK integration
GTK scroll-bars are now placed on the right by default.
Use `set-scroll-bar-mode’ to change this.
GTK tool bars can have just text, just images or images and text.
Customize `tool-bar-style’ to choose style. On a Gnome desktop, the default
is taken from the desktop settings.
GTK tool bars can be placed on the left/right or top/bottom of the frame.
The frame-parameter tool-bar-position controls this. It takes the values
top, left, right or bottom. The Options => Show/Hide menu has entries
for this.
The colors for selected text (the `region’ face) are taken from
the GTK theme when Emacs is built with GTK.
Emacs uses GTK tooltips by default if built with GTK. You can turn that
off by customizing x-gtk-use-system-tooltips.
A slew of GTK changes for people who use Emacs compiled with GTK.
New basic faces `error’, `warning’, `success’ are available to
highlight strings that indicate failure, caution or successful operation.
Good news for customize fans. No longer will you have to hunt down fifty different faces that do the same thing. Simply invoke M-x customize-face RET facename, where facename is one of the aforementioned three, and change the face there. The changes you make at the root faces will now properly propagate to all faces that inherit from them.
Lucid menus and dialogs can display antialiased fonts if Emacs is built
with Xft. To change font, use the X resource font, for example:
Emacs.pane.menubar.font: Courier-12
On graphical displays, the mode-line no longer ends in dashes.
Also, the first dash (which does not indicate anything) is just
displayed as a space.
Truly the end of an era.
Basic SELinux support has been added.
This requires Emacs to be linked with libselinux at build time.
Emacs preserves the SELinux file context when backing up, and
optionally when copying files. To this end, copy-file has an extra
optional argument, and backup-buffer and friends include the SELinux
context in their return values.
The new functions file-selinux-context and set-file-selinux-context
get and set the SELinux context of a file.
Tramp offers handlers for file-selinux-context and set-file-selinux-context
for remote machines which support SELinux.
Good news for hardcore SELinux hackers.
Changes for exiting Emacs
The function kill-emacs is now run upon receipt of the signals
SIGTERM and SIGHUP, and upon SIGINT in batch mode.
A nice change, for sure. However this will not trigger the usual “Do you wish to save your buffer” query as that is done at a higher level in Emacs. So don’t think this’ll save your skin if you nuke Emacs from the commandline!
kill-emacs-hook is now also run in batch mode.
If you have code that adds something to kill-emacs-hook, you should
consider if it is still appropriate to add it in the noninteractive case.
My kill-emacs-hook is mostly filled with miscellaneous gunk like saving my recentf and bookmarks.
Scrolling changes
New scrolling commands `scroll-up-command’ and `scroll-down-command’
(bound to C-v/[next] and M-v/[prior]) do not signal errors at top/bottom
of buffer at first key-press (instead move to top/bottom of buffer)
when `scroll-error-top-bottom’ is non-nil.
New variable `scroll-error-top-bottom’ (see above).
About time! This is useful if you make macros and you don’t want Emacs to cancel out of your macro recorder (or indeed in the macro itself) if it reaches the end of the buffer. I foresee lots of custom macro recorder functions that disable the top/bottom error signal when you’re recording…
New scrolling commands `scroll-up-line’ and `scroll-down-line’
scroll a line instead of full screen.
Pretty self-explanatory!
New property `scroll-command’ should be set on a command’s symbol to
define it as a scroll command affected by `scroll-preserve-screen-position’.
This is an elisp change that only really concerns people who write elisp packages. Basically, it means you can with greater granularity control if a particular movement command is affected by the user-defined setting in scroll-preserve-screen-position; itself a command that let’s you control how Emacs scrolls on your screen.
If you customize `scroll-conservatively’ to a value greater than 100,
Emacs will never recenter point in the window when it scrolls due to
cursor motion commands or commands that move point (e.f., `M-g M-g’).
Previously, you needed to use `most-positive-fixnum’ as the value of
`scroll-conservatively’ to achieve the same effect.
Interesting change, but not something I find all that useful. I rather prefer knowing where a line (or what have you) I want to see is in roughly the same spot every time.
``Aggressive'' scrolling now honors the scroll margins.
If you customize `scroll-up-aggressively' or
`scroll-down-aggressively' and move point off the window, Emacs now
scrolls the window so as to avoid positioning point inside the scroll
margin.
This is another one of those changes that people with rather interesting views on how Emacs should scroll care about. I personally just use the defaults so I don't have too much to say about it.
To Be Continued...
I think I'm going to end my post here. Emacs has hundreds of new features and changes and -- according to my modeline -- I have only covered about 30% of the NEWS file.
A little more than a year ago I set out to write a blog about the things I knew about Emacs. I had been collecting tips, concepts and snippets in a large org file for years with the goal of one day sharing what I knew with other people. I picked up Emacs when I was in University having heard about it before, but never really used it. All I knew about it was that it was really advanced, had meta keys and came with a built-in psychotherapist (try it — M-x doctor.)
When I mentioned this to someone more experienced in the world of editor-fu at the University’s computer science society, he told me that he used vim, and it was the editor of choice bar none, and that no other editor was worth using; that the modal concept was superior in every way to Emacs, and I was a fool for considering a fate worse than death if I defied his sage advice.
I immediately started using Emacs, and I have never looked back.
But I never had the opportunity to learn from an Emacs master myself. So when I finally sat down and wrote my first article a little more than a year ago I wrote it with the assumption that simply knowing what a keystroke does is not enough if you want to master Emacs; you must understand the why and not just the how. Thankfully, although Emacs has a steep learning curve, once you “get” it — you get it. And reaching that step is not an unattainable goal if you try to grasp the why. I remember when it finally “clicked” for me and I finally got how the editor functioned and why it functioned the way it did. Unfortunately, to achieve this level of enlightenment will involve a smidgeon of Lisp — and that’s probably what puts off most people. If you are an Emacs user and you are put off by elisp — overcome it and give it a shot. Elisp is arguably the most practical application of Lisp for most professional developers. You can write it, use it right away, and enrich your Emacs experience at the same time.
As I’ve written quite a few articles I have come to the realization that finding stuff on my site is, ah, not that easy. Therefore, I have created a reading guide to help newcomers find their way around.
Here’s to another year.
Overall Vimgolf Rank
Suppose you are trying to figure out what your overall rank is at Vimgolf(the sum of all the ranks you got), and as a Vim ninja you decided to use Vim to do the job. Your solution should work for every Vimgolf profile page(The actual input file for this challenge is my Vimgolf profile page). So, direct answer insertion is considered cheating.
Here’s another fun vimgolf challenge. The task is simple: get the sum of all the ranks on your vimgolf profile page.
A pretty specific goal, but the concept will work with anything involving summing numbers in a buffer. Anyway, off we go..
Given this input:
Generate Fibonacci Numbers - Rank: 1/66, Score: 20 Use your super vim powers to generate Fibonacci Numbers. Remove Accent off the Letter - Rank: 1/49, Score: 38 Remove all the accent from extremely accented statements. Remember FizzBuzz? - Rank: 1/118, Score: 53 Output FizzBuzz to 100. Start with nothing. (snip)
Get this output:
794
Now, in the vim challenge you are supposed to end up, as I understand it, with a buffer with nothing but the result — but that’s not a very productive (nor easy) way to accomplish the task.
Option 1: Using Registers
The first thing we need to do is mark the entire buffer with C-x h. Next, we need to set an emacs register — which is a simple store and recall register that you can save things like text, numbers, the point and frame or window configurations to for later re-use — by typing M-0 C-x r n a. To break that down a bit, we use the universal argument M-0 to tell Emacs that we want the number zero stored in a numeric register a by calling number-to-register, bound to C-x r n.
Next, we will use query-replace-regexp bound to C-M-% and use a little-known feature of Emacs’s regexp engine to, in effect, use the side effect of a regexp replace on each match.
Input the following:
Query replace regexp: Rank: \([0-9]+\) Query replace regexp with: \,(increment-register (string-to-number \1) ?a)
So here we are invoking increment-register (bound to C-x r +) and passing it the contents of the regexp capture group 1 (the rank) by first converting it to an integer so increment-register can make sense of it. We are also passing ?a as we need to give it the character a and not the string.
When you replace all matches (type !) you’ll see that Emacs will do a “rolling sum” by returning the contents of the new register and thus slowly add up all the ranks, one by one. Thus, if you scroll to the very bottom the last “match” will have the correct answer.
Obviously altering the text is probably not desirable so simply C-/ to undo the regexp replace.
And that’s it. Not the snappiest solution but it shows what you can do with Emacs if you really want to.
Option 2: Using Elisp
Well, if you can write elisp this problem is trivial; the code below will do the same as the above, but it’s a little bit neater and perhaps a bit easier to recycle for other tasks as well.
If you want to know how to run it, then you should read my article on Evaluating Elisp in Emacs.
(let ((counter 0)) (while (re-search-forward "Rank: \\([0-9]+\\)" (point-max) t) (incf counter (string-to-number (match-string 1)))) (message "Total sum %d" counter))
I’ve been having a lot of fun with vimgolf, a site where vim users try to complete certain tasks (sort this, format that, scrub this data, etc.) in as few keys as possible. It’s an interesting site and the problem set is varied and a good source of inspiration for Emacs blog posts. I learned about this site from Jon’s Emacs blog and I’ve been having a fun time solving the problems in Emacs.
It’s obvious to most of us that to attempt a “fewest possible keystrokes” exercise in Emacs will invariably end in tears, as we can’t compete against vim in that regard; but with that said, we do have a lot of tricks up our sleeve.
In reading — or attempting to, more like — the “solutions” I’ve made a few observations about most of them: they are tailored to the input, and that input only; thus, it wouldn’t necessarily scale to larger problem sets or even smaller ones. I’m going to try to solve these problems so they’re technically correct — the best kind of correct — and thus work with larger or smaller input.
Alphabetize the Directory
Put the contacts and their information in alphabetical order.
So the task is simple. We need to sort by a key (the name heading), preserving the details associated with each contact.
The easiest way to solve this is to imagine the input below as an org-mode file, so that’s what we’ll do:
M-x org-mode and org mode immediately picks up on the file contents and collapses the headings.
Next, we need to sort the items, whilst we preserve the order of the subitems, and this is done by first moving to the heading level you want to sort by (in this case it’s the Smith, George heading) and invoking M-x org-sort and selecting a for alphabetic sort.
Org mode will sort the file and the output should match the expected vim golf output. And that’s it.
Input
## Directory
* Smith, George
- 1234 Avenue, New York, NY
* Bailey, Stephen
- 4545 Harbor Ln, Atlanta, GA
- Phone: (412) 291-1238
* Thomas, Brent
- 1482 Mystic Oaks, Anaheim, CA
* Grant, Jenny
- 198 Circle Dr, Houston, TX
- Phone: (213) 198-9842
- Email: jenny.grant@gmail.com
* Percy, Adam
- 221 Jaguar Pkwy, Missoula, MT
* Garfield, Misty
- 5988 Apple Tree Ln, Memphis, TN
* Parsons, Betty
- Phone: (235) 523-2378
- Email: bettyboop123@gmail.com
* Sanders, Terry
- Email: sanderst@yahoo.com
* Smith, Pete
- Phone: (294) 984-2938
* Frost, Jennifer
- 2498 Temple Terrace, Miami, FL
* Matthews, Frank
- 418 Happy Trail, Phoenix, AZ
- Phone: (985) 129-2394
- Email: frank@phoenixrealtors.net
* Allen, Taylor
- Email: allen.taylor@hotmail.com
* McCullen, Sarah
- 247 Hidden Elm, Seattle, WA
- Phone: (288) 283-4568
* Perkins, Mike
- 992 Peartree Ln, Bowling Green, KY
Expected Output
## Directory
* Allen, Taylor
- Email: allen.taylor@hotmail.com
* Bailey, Stephen
- 4545 Harbor Ln, Atlanta, GA
- Phone: (412) 291-1238
* Frost, Jennifer
- 2498 Temple Terrace, Miami, FL
* Garfield, Misty
- 5988 Apple Tree Ln, Memphis, TN
* Grant, Jenny
- 198 Circle Dr, Houston, TX
- Phone: (213) 198-9842
- Email: jenny.grant@gmail.com
* Matthews, Frank
- 418 Happy Trail, Phoenix, AZ
- Phone: (985) 129-2394
- Email: frank@phoenixrealtors.net
* McCullen, Sarah
- 247 Hidden Elm, Seattle, WA
- Phone: (288) 283-4568
* Parsons, Betty
- Phone: (235) 523-2378
- Email: bettyboop123@gmail.com
* Percy, Adam
- 221 Jaguar Pkwy, Missoula, MT
* Perkins, Mike
- 992 Peartree Ln, Bowling Green, KY
* Sanders, Terry
- Email: sanderst@yahoo.com
* Smith, George
- 1234 Avenue, New York, NY
* Smith, Pete
- Phone: (294) 984-2938
* Thomas, Brent
- 1482 Mystic Oaks, Anaheim, CA
Interacting with external commands in Emacs ranges from simple one-off commands to launching interactive sessions using comint, the Emacs command interpreter library. In earlier articles I covered shell integration and terminal emulation in Emacs, but this time I want to talk about the other use case: executing shell commands and capturing their output; how to use them in elisp code; how to make them work with unicode and different coding systems; and a few unique ways of using the commands.
read more…
Mastering Emacs