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)))
Tuesday, June 22, 2010
vc-diff tweak
Posted by
a
at
1:14 PM
4
comments
Labels: emacs, emacs-intermediate, emacs-lisp
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))
Posted by
a
at
5:19 PM
2
comments
Labels: emacs, emacs-basic, emacs-lisp
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?
Posted by
a
at
12:04 PM
0
comments
Labels: emacs, emacs-advanced, emacs-lisp, stackoverflow
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)
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).
Posted by
a
at
3:02 PM
0
comments
Labels: emacs, emacs-lisp, stackoverflow
Monday, March 24, 2008
Emacs Tip #15: indent yanked code
I'm a bit apprehensive about this chunk of code, mainly because it facilitates cut/paste coding, which I abhor. Nevertheless, it does come in handy.
When you (shudder) cut/paste code, one of the first things you do is immediately indent the code appropriately. Well, why not have that done automatically for you? This chunk of emacs lisp does the trick rather nicely.
It will not indent regions that are too large (see yank-advised-indent-threshold) and given a prefix argument, it will not indent.
;; automatically indenting yanked text if in programming-modes
(defvar yank-indent-modes '(emacs-lisp-mode
c-mode c++-mode
tcl-mode sql-mode
perl-mode cperl-mode
java-mode jde-mode
lisp-interaction-mode
LaTeX-mode TeX-mode)
"Modes in which to indent regions that are yanked (or yank-popped)")
(defvar yank-advised-indent-threshold 1000
"Threshold (# chars) over which indentation does not automatically occur.")
(defun yank-advised-indent-function (beg end)
"Do indentation, as long as the region isn't too large."
(if (<= (- end beg) yank-advised-indent-threshold)
(indent-region beg end nil)))
(defadvice yank (after yank-indent activate)
"If current mode is one of 'yank-indent-modes, indent yanked text (with prefix arg don't indent)."
(if (and (not (ad-get-arg 0))
(member major-mode yank-indent-modes))
(let ((transient-mark-mode nil))
(yank-advised-indent-function (region-beginning) (region-end)))))
(defadvice yank-pop (after yank-pop-indent activate)
"If current mode is one of 'yank-indent-modes, indent yanked text (with prefix arg don't indent)."
(if (and (not (ad-get-arg 0))
(member major-mode yank-indent-modes))
(let ((transient-mark-mode nil))
(yank-advised-indent-function (region-beginning) (region-end)))))
Posted by
a
at
10:13 AM
3
comments
Labels: emacs-intermediate, emacs-lisp, emacs-tip
Monday, January 14, 2008
Emacs Tip #10: sig-quote (intelligent, random signatures)
Way back when I first started using Emacs, I read email with it. A friend had some script which modified his .signature file with a random quote every 30 seconds. I thought that was kind of neat, but I wanted every email to get its own, random, quote. At the time I didn't know how to get a random number in a simple shell script, so I started writing something using Emacs directly.
A random signature wasn't enough though, I then wanted to be able to have different categories of quotes and send different people quotes from those different categories. From the documentation:
;; This mode is designed to allow a user to have quotes appended to
;; their mail and news posts according to whom/where the mail is
;; being sent. For example, one might wish to have "insightful"
;; quotes sent to Prof. Apple, and "crude" quotes to your brother
;; Sam. With this mode, upon sending a piece of mail, the email
;; addresses are scanned (this includes the To:, CC:, and BCC:
;; headers), and an appropriate quote is inserted into the letter.
Thus began my Emacs fascination.
You can download the source here.
Posted by
a
at
1:38 PM
4
comments
Labels: emacs-intermediate, emacs-lisp, emacs-tip, email, link
Wednesday, January 2, 2008
Emacs Tip #7: resolve-sym-link
It's often nice to find the true path to a file or directory. Since I work in Emacs, it's often easier to use find-file to discover the path, and then invoke this little diddy. I like having it bound to C-r(defun resolve-sym-link ()
"Replace the string at the point with the true path."
(interactive)
(beginning-of-line)
(let* ((file (buffer-substring (point)
(save-excursion (end-of-line) (point))))
(file-dir (file-name-directory file))
(file-true-dir (file-truename file-dir))
(file-name (file-name-nondirectory file)))
(delete-region (point) (save-excursion (end-of-line) (point)))
(insert (concat file-true-dir file-name))))
(define-key minibuffer-local-completion-map (kbd "C-r") 'resolve-sym-link)
Posted by
a
at
9:08 AM
0
comments
Labels: emacs-intermediate, emacs-lisp, emacs-tip

