Ben
Ben

Reputation: 873

transient-mark-mode, pre-command-hook and with-current-buffer

I'm writing a minor mode (a keylogger) which stores detailed (timestamp, etc.) info about every command through a custom pre-command-hook. But it doesn't work nicely with transient-mark-mode - specifically setting another buffer as active in the hook through with-current-buffer seems to stuff up the active region in the buffer I'm actually working on.

I have transient-mark-mode on, and when I C-SPC and move the point around, the active region is highlight as normal, and all the active-region commands work. However, once I've added my logging hook which contains a call to with-current-buffer, then I can't highlight regions anymore.

Minimal broken example:

(defun test-pre-command-hook ()
  (with-current-buffer (get-buffer-create "*test-buffer*")
    (insert "foo")))

(add-hook 'pre-command-hook 'test-pre-command-hook)

at this point, C-h v transient-mark-mode is still t but visually the active region isn't highlighted, and commands which work on the active region e.g. comment-dwim don't work.

Once I remove the hook, things are hunky dory again.

(remove-hook 'pre-command-hook 'test-pre-command-hook)

Any ideas?

Upvotes: 2

Views: 236

Answers (1)

Stefan
Stefan

Reputation: 28541

The problem is not set-buffer or with-current-buffer but insert which sets deactivate-mark globally. The usual workaround is to let-bind deactivate-mark around your pre-command-hook:

(defun test-pre-command-hook ()
  (let (deactivate-mark)
    (with-current-buffer (get-buffer-create "test-buffer")
      (insert "foo"))))

Note that this problem should hopefully be fixed in the current Emacs trunk (i.e. what will probably become Emacs-24.5).

Upvotes: 2

Related Questions