Showing posts with label emacs. Show all posts
Showing posts with label emacs. Show all posts

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.

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)

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)

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

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, 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