Wednesday, August 8, 2018

I'm so out of it

I didn't even realize that Emacs 26.1 was released 3 months ago!

Saturday, October 23, 2010

Emacs Tip #38: Automatically diff binary files using hexl-mode

I saw a question on Stack Overflow which referred to a non-free (as in beer) file comparison application. My first thought was, "people pay for this?" Sure enough, there are quite a few non-free file comparison tools. Which leads to the question, what do they offer that I'm not getting in Emacs (using ediff). From the table on Wikipedia, it appears not too much. I updated a couple of fields which weren't specified for Ediff, and noticed there was a column for doing a binary diff.

I rarely have the need to do a binary diff, but I was curious what tools did to support it. The two I looked at just showed a standard diff of files using a display somewhat like hexl-mode.

I figured adding support for Ediff to automatically switch to a diff with hexl-mode would be easy enough, and it was. Here's the code to use. Note: it currently prompts to see if you want to do the diff in hexl-mode, remove the call to y-or-n-p to have it done automatically.

Edited Oct 24 to split the code into two pieces of advice to avoid an error.


(defvar ediff-do-hexl-diff nil
"variable used to store trigger for doing diff in hexl-mode")
(defadvice ediff-files-internal (around ediff-files-internal-for-binary-files activate)
"catch the condition when the binary files differ

the reason for catching the error out here (when re-thrown from the inner advice)
is to let the stack continue to unwind before we start the new diff
otherwise some code in the middle of the stack expects some output that
isn't there and triggers an error"
(let ((file-A (ad-get-arg 0))
(file-B (ad-get-arg 1))
ediff-do-hexl-diff)
(condition-case err
(progn
ad-do-it)
(error
(if ediff-do-hexl-diff
(let ((buf-A (find-file-noselect file-A))
(buf-B (find-file-noselect file-B)))
(with-current-buffer buf-A
(hexl-mode 1))
(with-current-buffer buf-B
(hexl-mode 1))
(ediff-buffers buf-A buf-B))
(error (error-message-string err)))))))

(defadvice ediff-setup-diff-regions (around ediff-setup-diff-regions-for-binary-files activate)
"when binary files differ, set the variable "
(condition-case err
(progn
ad-do-it)
(error
(setq ediff-do-hexl-diff
(and (string-match-p "^Errors in diff output. Diff output is in.*"
(error-message-string err))
(string-match-p "^\\(Binary \\)?[fF]iles .* and .* differ"
(buffer-substring-no-properties
(line-beginning-position)
(line-end-position)))
(y-or-n-p "The binary files differ, look at the differences in hexl-mode? ")))
(error (error-message-string err)))))

Sunday, October 10, 2010

Emacs Tip #37: fic-mode.el

I saw this question on Stack Overflow asking to highlight FIXME (and similar strings) in your code, but only in comments and strings.

The current fixme-mode.el found on the Emacs Wiki is kind of clunky (it's really a major mode) and awkward to read. So I took the challenge to write a new minor-mode which answers the question.

I give you fic-mode.el. It's named fic as an acronym for Fixme In Comments.

To use it, add something like the following to your .emacs:



(require 'fic-mode)
(add-hook 'c++-mode-hook 'turn-on-fic-mode)
(add-hook 'emacs-lisp-mode-hook 'turn-on-fic-mode)



Or, you can manually start it with M-x fic-mode.

Tuesday, June 22, 2010

vc-diff tweak

For a while I've noticed that 'vc-diff (C-x v =) would pop up a buffer when there were no differences, and that buffer would just say there weren't any differences. It finally got on my nerves, so I wrote this code which works around that issue.

I don't totally understand the vc code, but parts are set up to run asynchronously, and that is what was tripping up 'vc-diff in my case. The diff would come back as identical, but at the time of the callback, Emacs had already lost the window configuration - so it was forced to pop up a buffer.


(defvar my-vc-diff-pre-diff-window-configuration nil
"place to store window configuration,
because sometimes (usually) the vc-diff does things asynchronously")

(defadvice vc-diff-internal (around
vc-diff-dont-show-diff-buffer-when-no-diff
activate)
"no changes still results in *vc-diff* buffer being shown, try to avoid that"
(setq my-vc-diff-pre-diff-window-configuration (current-window-configuration))
(let* ((res ad-do-it))
(when (or (null res)
(string-match-p "^No changes between"
(with-current-buffer "*vc-diff*"
(buffer-substring-no-properties
(point-min) (point-max)))))
(set-window-configuration my-vc-diff-pre-diff-window-configuration))))

(defadvice vc-diff-finish (after
vc-diff-finish-dont-show-diff-buffer-when-no-diff
activate)
"when buffer says no differences, revert window configuration"
(when (and my-vc-diff-pre-diff-window-configuration
(string-match-p "^No changes between"
(with-current-buffer "*vc-diff*"
(buffer-substring-no-properties
(point-min) (point-max)))))
(set-window-configuration my-vc-diff-pre-diff-window-configuration)))

Wednesday, April 28, 2010

Emacs Tip #36: Abort the minibuffer when using the mouse

A friend of mine loves using Emacs, but is always complaining about something. This time it's Emacs' behavior to keep the minibuffer active when you use the mouse to select another window. For example, you start doing a C-x C-f, click elsewhere, and do the C-x C-f again. Emacs will beep and tell you Command attempted to use minibuffer while in minibuffer.

After swallowing my, "well don't use the mouse" response I set about trying to fix it. I'm sure this has been solved before, I just didn't have enough google-fu to find the solution.


(defun stop-using-minibuffer ()
"kill the minibuffer"
(when (and (>= (recursion-depth) 1) (active-minibuffer-window))
(abort-recursive-edit)))

(add-hook 'mouse-leave-buffer-hook 'stop-using-minibuffer)


Edited to add:
A commenter suggested using recursive minibuffers. I think that the resulting behavior is more confusing than helpful.

Yes, it avoids the error, but then you get this ever-increasing stack of minibuffers building up. If/when the user notices the minibuffer hanging around it'll be annoying (I've had people ask, "Why is it trying to find a file?" (because the minibuffer still shows Find file: /path/to/somewhere)). And heaven forbid they click in the minibuffer, type C-g and get back to the window configuration they were looking at when they started that command, which was ... 15 minutes ago.

Saturday, February 20, 2010

Emacs Tip #35: framemove

Ever wanted to easily navigate between frames? Perhaps using arrow keys? Surprisingly, this didn't exist before (AFAIK).

I wrote the package framemove to have the same usage as Emacs' built in windmove package. And, even better, it can integrate with windmove so that when you run out of windows to move between, you'll jump to the next frame in that direction.

To install framemove on its own:


(require 'framemove)
(framemove-default-keybindings) ;; default prefix is Meta

But you might want to use this in conjunction with windmove, in which case this is the integration code to add to your .emacs:

(require 'framemove)
(windmove-default-keybindings)
(setq framemove-hook-into-windmove t)

With the integration with windmove, you just do SHIFT-right to move focus to the window to the right of the current, and when there are no more, focus will shift to the frame to the right.

Switching frames is a little more challenging than switching windows - mostly because windows are simply rectangular divisions of a window - it is easy to tell what window (if any) is to the right of the point. For frames, the answer is ambiguous because the placements of frames is free-form, and frames can overlap. I think this initial implementation does a reasonable job of choosing which frame to select. It first tries the frame directly in line with the point, and if one doesn't exist, it then uses the distance between the point (projected onto the edge of the current frame) and the frames in the given direction, and after that it just tries any frame that extends beyond the current frame in that direction.

Check it out.

Currently, when focus shifts to a new frame - the point does not change inside the frame.

Thursday, February 11, 2010

Emacs Tip #34: line-beginning-position, line-end-position

Such a simple thing - finding the position of the beginning or end of the current line. I've been completely oblivious to the existence of the functions line-beginning-position and line-end-position.

They return the position of the beginning or end of the current line.
They both accept an optional argument, which has the same
meaning as the argument to beginning-of-line or end-of-line.

They were first introduced in Emacs 20, in the middle of 2006. Which means I've been unnecessarily typing this for 4 years:
(save-excursion
(beginning-of-line)
(point))

Wednesday, December 23, 2009

Emacs Paper from 1981

It's been a while since I read RMS's paper on Emacs. Back in 1981, I still had another 2 years before I even saw my first computer. Reading the paper gives some insight into some of the issues they were trying to solve (real time display, extensibility, portability).

The first thing that came to mind when I first read this paper was that (to an outsider at least) Emacs really hasn't changed fundamentally since 1981 - the basic structures have held up well. I don't see any mention of subprocesses in the original paper, so that's something pretty fundamental that is new (since 1981). Of course the other obvious additions are MULE, image support, fonts, and the graphical interface.

Amusingly, vi was not mentioned in the Other Interesting Editors section. From reading the wikipedia article on vi, it certainly was available (it's a part of the Unix standard).

But what really struck me as interesting and powerful was the decision to use dynamic binding. I'd remembered playing with the differences between dynamic and lexical scoping in my SICP class in college, but never saw a reason to use it. Well, it totally fits when you want to customize Emacs' behavior.

The paper is certainly worth the 10 minutes it takes to read.

Wednesday, September 30, 2009

Emacs Tip #33: paredit

I recently found paredit. It is a mode which allows you to edit s-expressions (sexps) in a structured way.

Essentially it forces you to maintain balanced parentheses by always inserting/deleting matched pairs. It is very easy to modify the current sexp to: enclose (wrap) the next element, to merge it up one level (aka splice, i.e. remove a set of parentheses), to split the current sexp, etc.

It works with round parens (), square brackets [], curly braces {}, and angle braces <>. It also handles string quotes " the same way.

Deleting and killing of text also works nicely. For example, C-k is bound to 'paredit-kill which has the following behavior (note: | represents the cursor position):

(foo bar)|     ; Useless comment!
->
(foo bar)|

(|foo bar) ; Useful comment!
->
(|) ; Useful comment!

|(foo bar) ; Useless line!
->
|

(foo "|bar baz"
quux)
->
(foo "|"
quux)
It's taking a little getting used to, but I'm finding myself thinking less about where the current block of code ends than I used to. The parentheses just take care of themselves...

This is how I enabled it:


(defun turn-on-paredit-mode ()
(paredit-mode +1))

;; I didn't like C-j being overridden, I want it to still work the old way in lisp-interaction
(eval-after-load "paredit"
'(progn
(define-key paredit-mode-map (read-kbd-macro "C-j") nil)))

(add-hook 'emacs-lisp-mode-hook 'turn-on-paredit-mode)

The cheat sheet is probably the best way to get an idea of what is possible. Check it out here. Also, the command documentation is very complete (see the above which was grabbed right from the C-k documentation, so it's easy to remind yourself what is possible.

About the only problem I've had is when I've yanked code that has unbalanced parens. So I wrote a little advice which at least warns you and allows you to abort if the yanked text is unbalanced. It's not perfect, but it is a reasonable first implementation:

(defun paredit-check-region-for-yank ()
"run after yank and yank-pop to verify balanced parens"
(when paredit-mode
(save-excursion
(save-restriction
(narrow-to-region (point) (mark))
(condition-case nil
(check-parens)
(error
(if (not (y-or-n-p "The text inserted has unbalanced parentheses, continue? "))
(delete-region (point-min) (point-max)))))))))

(defadvice yank (after yank-check-parens activate)
(paredit-check-region-for-yank))
(defadvice yank-pop (after yank-pop-check-parens activate)
(paredit-check-region-for-yank))

Somewhat meta: blogs on reddit

Recently, doing a vanity search, I saw a link to this blog from reddit. I'm not a reddit user, but found it interesting that some of my posts had made it on there (as you can see here: trey-jackson.blogspot.com on reddit.com).

What I find curious about reddit as it applies to blogs is that it ends up taking the conversation away from the blog. This works well for reddit users, but ends up fracturing the audience. I don't get many comments (I have very few readers) and would have appreciated the reading the comments made on reddit.

For what it's worth, I did update a post to fix a coding bug noticed by someone on reddit (ironically, their fix had syntax problems at the same spot as well).

Tuesday, August 4, 2009

Emacs Tip #32: completion-ignore-case and Emacs 23

Everyone is all a-buzz over the new release of Emacs. I've started using it, and I do like the font support.

There was one surprise. I had the old setting

(setq completion-ignore-case t)

because I hate typing capital letters when I can avoid it. Enter Emacs 23.1, and I now have to type capital letters for buffer names and file names (which is 90% of what I use minibuffer completion for). It turns out, there are two new variables, one for each of the types of completion:

(setq read-buffer-completion-ignore-case t)
(setq read-file-name-completion-ignore-case t)


Everything else in the upgrade has been smooth.

Wednesday, June 24, 2009

Emacs Tip #31: kill-other-buffers-of-this-file-name

A friend mentioned he wanted a way to get rid of all the other buffers visiting files that of the same file name. I instantly realized this was something I'd wanted for a long time without knowing it.

My usage is that I'm often viewing different versions of the same file, usually in different sandboxes. And, I might also have older versions checked out, whose file names are the same, but end with ".~1.12~" (or whatever version number was checked out).

I'm still old-school and don't use anything fancy for my buffer switching like `ido` or `icicles` or `iswitchb` or any of the other myriad of choices. And, as a result, it's a pain to switch because I have to now discern between the variants. Well, do that once, type `C-x K`, and that'll be the only buffer left for that file name.


(global-set-key (kbd "C-x K") 'kill-other-buffers-of-this-file-name)
(defun kill-other-buffers-of-this-file-name (&optional buffer)
"Kill all other buffers visiting files of the same base name."
(interactive "bBuffer to make unique: ")
(setq buffer (if buffer (get-buffer buffer) (current-buffer)))
(cond ((buffer-file-name buffer)
(let ((name (file-name-nondirectory (buffer-file-name buffer))))
(loop for ob in (buffer-list)
do (if (and (not (eq ob buffer))
(buffer-file-name ob)
(let ((ob-file-name (file-name-nondirectory (buffer-file-name ob))))
(or (equal ob-file-name name)
(string-match (concat name "\\(\\.~.*\\)?~$") ob-file-name))) )
(kill-buffer ob)))))
((message "This buffer has no file name."))))

Edited Sept. 30, 2009 to fix coding error.

Friday, June 19, 2009

Searching GNU From Firefox

When writing up answers for Emacs related questions on stackoverflow.com, I like to include links to the info pages. I got tired of having to go to the gnu site and then do a google site-specific search. I tried looking for a Firefox search plugin that already did that (or something similar), but to no avail.

However, it's pretty easy to write the search plugin yourself. The main page for creating search plugins on mozilla's developer site gives you pretty much all you need to know, except for where to put the xml file. This page shows you that the installation dir is very likely C:\Program Files\Mozilla Firefox\searchplugins.

You can read the documentation yourself, or just check out the snippet of XML I wrote.

Probably the "hardest" part was finding an icon, and the all-knowing google led me to the www.favicon.cc web page, where someone had drawn the standard GNU icon and made it available under a Creative Commons license:

Friday, June 12, 2009

Emacs Tip #30: igrep

Finding text in files is an everyday (every hour) occurrence for most programmers. And in Unix-land, people generally use grep to do the searching.

Of course Emacs has an interface to grep, which now (as of Emacs 22) even has interfaces for using both find and grep together to search through directory structures (grep-find, rgrep).

But, before those existed, someone wrote a nice package igrep.el, which has a very intuitive (IMO) interface.

M-x igrep-find RET RET /search/in/here/*.cxx RET

which will search for regexp in all the files with the extension .cxx underneath the /search/in/here/ directory.

As you'd expect, the results of the search show up in a buffer, and clicking on any one of them jumps you to that spot in the file. And the standard M-x next-error (aka C-x `) will jump you to the next match.

About the only thing I don't like is that the paths returned in the results are the fully expanded path. In other words, when the paths to the files are really long, most of the result buffer is taken up with just the pathname. So I wrote this little snippet of code which post-processes the buffer to trim the names relative to the search path entered (in the example above, all the /search/in/here/ would be removed from the file names.


(defun my-shorten-filenames-in-compilation (buffer &optional stat)
"remove the absolute filenames if they match the default-directory"
(interactive "b")
(save-excursion
(set-buffer buffer)
(goto-char (point-min))
(let ((buffer-read-only nil)
(base-dir (if (re-search-forward "find \\([^ ]+\\) " nil t)
(if (string-match "/$" (match-string 1))
(match-string 1)
(concat (match-string 1) "/"))
default-directory)))
(setq default-directory base-dir)
(while (re-search-forward (concat "^" default-directory) nil t)
(replace-match "")))))

(add-hook 'compilation-finish-functions 'my-shorten-filenames-in-compilation)


I do realize that the built-in M-x rgrep does this automatically, I just prefer the igrep interface.

Tuesday, May 19, 2009

Emacs Tip #29: customizing hippe-expand

I read A Curious Progammer's post on customizing dabbrev - specifically to skip certain regular expressions at the front of words.

I remember customizing it for Tcl to avoid looking at the $ used to dereference variables. But, I no longer use dabbrev, I use the slightly more general hippie-expand. However, hippie-expand doesn't use the dabbrev settings.

So, the question is, can you get hippie-expand to do the same thing? The answer is, "yes" of course.

hippie-expand does things slightly differently - a little cleaner IMO. It uses syntax tables to determine what to skip. And, since syntax tables are set up appropriately for every mode, the skipping does what you want w/out having to potentially customize a regexp for each mode.

Syntax tables are Emacs' way of encoding the syntactic use of each character in a buffer, and this knowledge is used for motion and regular expressions. That's how forward-word has reasonable meaning in the various programming modes, text mode, shell mode, etc. Similarly, the syntax tables define list motion.

The syntax table has the basic character types: whitespace, punctuation, word, symbol, open/close parenthesis, string, comment start/end, etc. For example, the alpha-numeric characters are generally word constituents. In html-mode the <> symbols are matching parentheses, but in most other programming modes they are punctuation characters.

The variable you set is hippie-expand-dabbrev-as-symbol, which defaults to t. Basically, if non-nil, hippie-expand will try to expand the word under the point including symbol characters, which is not what I personally want. I want to only expand the word characters under my point, so I've set it to nil.

(setq hippie-expand-dabbrev-as-symbol nil)

Friday, May 15, 2009

Stupid VNC Trick

At my office I have a dual monitor setup, and at home I have two monitors as well, so most of my VNC sessions are wide (3280 pixels).

Which presents a problem on the occasions I decide to work from a coffee shop or some other place where I only have my laptop's screen. How do you effectively interact with a VNC session where the session is twice the size of the physical screen?

Clearly scrolling the screen with the mouse is a lose.

My solution is to have two VNC viewers running simultaneously. One shows the right half of the session, and the other shows the left half. That way I can easily CTRL-TAB from one side to the other.

Simple, but pretty effective.

Monday, April 27, 2009

dot-emacs trickery (emacs-fu)

It's been a while, and to be honest, emacs-fu has been doing such a great job putting up useful snippets of Emacs information...

He just put up a question asking for folk's favorite dot-emacs tricks. I added my two cents with:

(defun tj-find-file-check-make-large-file-read-only-hook ()
"If a file is over a given size, make the buffer read only."
(when (> (buffer-size) (* 1024 1024))
(setq buffer-read-only t)
(buffer-disable-undo)
(message "Buffer is set to read-only because it is large. Undo also disabled.")))


(add-hook 'find-file-hooks 'tj-find-file-check-make-large-file-read-only-hook)

Friday, March 27, 2009

Don't Like It? Code it Yourself!

Jeff Atwood writes on a topic that's interested me for quite a while:

Coding Horror: Don't Like It? Code it Yourself!

To me, at least, sponsorship seems like a constructive way for people who are unable or unwilling to write code to affect the direction of a project. For example, I've sponsored several bugfixes in a key .NET open source library that we use for Stack Overflow. These are bugfixes they considered low priority, but were serious issues for our site. I was happy to give back to the project, and it was certainly a more realistic option than us carving out a chunk of our own development time to contribute the bugfixes ourselves.

That said, I am concerned that this sort of aggregated sponsorship system hasn't naturally evolved on its own by now. Is it not sustainible, or incompatible with the kind of intrinsic motivations that drive most open source development?

In my previous job, we wrote software that heavily relied upon open source and GPL'ed software. The entire department developed and deployed software (primarily) for Linux systems, used gcc, Tcl/Tk, and a bunch of smaller open source tools. When compared to the more proprietary systems used (AIX, HP-UX), the savings were huge - both in software, hardware, and overall productivity.

At one point, the department decided to look into providing a "better"(?) debugging experience. After some research, they settled on a proprietary debugger. A year passed, licenses were finally purchased, and ... it was quietly released into the department, with very little fanfare.

I eventually found out about it, tried it out, and found the experience to be underwhelming to say the least. Several of the touted "features" were still in development (visualization of STL containers) and not to be delivered for another year, and the rest of the "features" had been in DDD/GDB for years. As an added hassle, it required the object files to be post-processed to obtain debugging symbols in their proprietary format.

To make a long story short(er), I found out we had paid many times my annual salary for a set of licenses for software that didn't have the features found in open-source software, and we had to pay this amount annually.

I fed this information up the chain of command, which just got the manager of software-development-environment angry at me. I proposed we use the money to instead hire a contractor to work on any bugs/enhancements for GDB/DDD, using the logic that not only would it be cheaper, it'd provide a return on investment faster, as well as be available to the entire department/company/world from here on out - at no extra cost. At the very least, it seemed to me, it was a tiny price to pay for the company's ability to use the open source Linux systems for development.

Management wasn't interested, not in the slightest. About the only argument they'd give me for keeping the status quo was that companies preferred working with other companies, and not contractors.

This always seemed to be more of a duck than a real argument.

I figured, if the software was good enough to use, it should be good enough to pay to improve.

Tuesday, March 3, 2009

More Advice

Way back when I wrote a tip about Emacs Lisp's advice.

How I wish other languages had this capability. A couple of questions came up recently on stackoverflow.com that were (imo) best answered using advice. So, if you're struggling to see when to use advice, I think they're pretty good examples.

"Diff, save or kill" when killing buffers in emacs

Can I change emacs find-file history?

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).