4

I am trying to understand the implication of using

(setq deactivate-mark t)

vs

(deactivate-mark)

In order to try to notice any difference, I made this dummy function:

(defun my/dummy-fn (arg start end)
  (interactive "P\nr")
  (if arg
      (setq deactivate-mark t)
    (deactivate-mark))
  (message "Arg: %0s Region: %s" arg (buffer-substring start end)))
(global-set-key (kbd "C-c n") #'my/dummy-fn)

Eval the above, including the global-set-key; it will be easier to try out the snippet. You can later eval (global-set-key (kbd "C-c n") nil) to free up the C-c n binding.

  • When you select a region and hit C-c n, (deactivate-mark) will be used and it will print

    Arg: nil Region:«YOUR-SELECTED-REGION»

  • When you select a region and hit C-u C-c n, (setq deactivate-mark t) will be used and it will print

    Arg: (4) Region:«YOUR-SELECTED-REGION»

I did not notice any difference between the two executions (and most likely this dummy function was not ideal to tell the difference).

So my question is:

When would one use the function and not the setq, and vice-versa?


A rough survey in emacs elisp source code tells that both are used, but the use of (deactivate-mark) as a function is more prominent.

Below, the number following the file name and colon tells the number of times the searched pattern occurred in that file.

Use as a function

km²~/downloads/:git/emacs> ag '\(deactivate-mark[\st]*\)' -G '\.el' -c
emacs-lisp/ert-x.el:1
emulation/cua-base.el:1
emulation/edt.el:1
emulation/viper-util.el:1
erc/erc-goodies.el:2
emacs-lisp/tcover-ses.el:1
gnus/nnnil.el:1
isearch.el:1
info.el:2
international/mule.el:2
leim/quail/hangul.el:1
mail/rmail.el:1
mwheel.el:1
replace.el:2
mouse.el:5
obsolete/mouse-sel.el:1
obsolete/tpu-edt.el:1
org/org-w3m.el:1
ses.el:1
ps-print.el:1
org/org.el:4
progmodes/f90.el:2
skeleton.el:1
tempo.el:1
term/ns-win.el:2
startup.el:1
term.el:1
textmodes/picture.el:2
simple.el:10
textmodes/reftex-index.el:1
textmodes/bibtex.el:1
type-break.el:1
vc/ediff-util.el:1
winner.el:1

Setting the var

km²~/downloads/:git/emacs> ag '\(setq deactivate-mark t\)' -G '\.el' -c
delsel.el:1
emulation/cua-rect.el:1
emulation/cua-base.el:1
indent.el:1
ses.el:2
rect.el:2
register.el:4
simple.el:2
  • You are the guru with 6K+ reputation, so I want to be careful about trying to make a comment when you are the one who usually teaches people like me. The function in question is elisp (not C) and is just 19 lines long -- it triggers (among other things) the function that is found within simple.el which normally runs multiple times per redisplay cycle and affects the visible windows -- i.e., redisplay--update-region-highlight Setting the variable alone is not going to trigger that redisplay function or set/launch other variables and functions within the function deactivate-mark. – lawlist May 14 '15 at 5:23
  • I tried to understand the functionality of the function. But from the application point of view, using just the setq is enough for the dummy fn. So I am wondering what the cases would be when you would need to use (deactivate-mark). For the dummy function, the selection cleared up fine on doing C-u C-c n (which uses setq) even when the redisplay--update-region-highlight wasn't called. About the reputation, it's probably just because I got addicted to this site from day 1. There is no correlation between the reputation and emacs guruness :) – Kaushal Modi May 14 '15 at 5:29
  • 1
    Your test example prints the region in each case because the region is always present (as long as there is a mark in that buffer). That says nothing about whether the region is active. Try this call to message instead: (message "Arg: %0s, Active: %S, Region: %s" arg (region-active-p) (buffer-substring start end)) – Drew May 14 '15 at 5:52
  • @Drew That's awesome! That perfectly demonstrates what you have in your answer; that the deactivate-mark fn deactivates the region instantly whereas setting the var deactivates the region at the end of the command. So the region is still active in the latter case when the message is being printed. But for a use case where all I care is to deactivate the region at the end of the command, I gather that using the either approach should not matter. – Kaushal Modi May 14 '15 at 6:04
  • You got it. That's my understanding, anyway. Maybe someone else will add to the explanation. – Drew May 14 '15 at 6:06
5

Good question. If you compare the doc strings of the two, or compare their code, the use cases amount to these, I think:

  • Variable: If it is non-nil at the end of a command, then the command loop deactivates the mark after that command. If it is nil at the end of the command then the mark is not deactivated. You can set it to nil at the end of a command that you will invoke while the region is active, to keep it active when the command is done.

  • Function: Use it to deactivate the mark now. For example, your code or the user has activated the region and maybe done some stuff with that active region. But then your code needs to do some stuff without the region being active, so it deactivates it. IOW, you can call this function to deactivate the mark, so subsequent code won't do something wrong because the region is active.

They are really about two different things. The variable is used generally to prevent subsequent automatic deactivation (e.g. by the command loop). The function's aim is to turn off the region now, so that some subsequent processing is not messed up because it might act wrong if the region were active.

Example of using the variable (from misc-cmds.el - the command needs to keep the region active when it finishes:

(defun mark-buffer-after-point (reversep)
  "Select the part of the buffer after point.
With a prefix argument, select the part before point."
  (interactive "P")
  (push-mark (if reversep (point-min) (point-max)) nil t)
  (setq deactivate-mark  nil))

Example of using the function (from info.el) - the command wants to do its thing with the region deactivated, so the first thing it does is deactivate it.

(defun Info-search (regexp &optional bound _noerror _count direction)
  (interactive...)
  (deactivate-mark)
  ...
  • Thanks! So does it mean that in applications like these where it is "select region → do stuff on region or using region → deactivate mark", it should not matter if I use (deactivate-mark) or (setq deactivate-mark t)? In such cases, would using setq be more efficient (as I don't seem to be affected if I don't execute the extra nested functions that the deactivate-mark function is calling)? – Kaushal Modi May 14 '15 at 5:58
  • 1
    I don't have the time to check all that your code is doing. But if you just want to deactivate the mark then I would use the function. IIUC, the variable does not deactivate the region itself - it is the command loop (typically) that checks the variable and deactivates the region or not, according to its value. IOW, it is a flag. If you don't need to deactivate right then and there, then I suppose you can just set the flag (variable). But I would call the function, if I really wanted to deactivate at that point in the code. (It also runs a hook.) – Drew May 14 '15 at 6:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.