Question

In Emacs 23 and 24, the following works fine:

(defun foo (&optional arg)
  (interactive "^p")
  (message "arg is %i" arg))

In Emacs 22, I get the following error:

Invalid control letter `^' (136) in interactive calling string

I tried this:

(defun foo (&optional arg)
  (interactive (concat (if (> emacs-major-version 22) "^" "") "p"))
  (message "arg is %i" arg))

but I get:

Wrong type argument: listp, "^p"

What is the best way to use ^ in Emacs 23 or 24 but not in Emacs 22?

Was it helpful?

Solution 2

You could define a macro that expands to a defun, where the interactive form would start with a ^ if shift selection is supported. For example:

(defmacro my-defun (name args doc inter &rest body)
  "Like `defun' but enables shift selection, if supported.

Note that the documentation string and the `interactive' form
must be present. Requires a string literal as argument to
`interactive'.

See `this-command-keys-shift-translated' for the meaning of shift
translation.

This is implemented by adding the `^' token to the `interactive'
string, when shift selection is supported."
  `(defun ,name ,args
     ,doc
     ,(progn
        (assert (stringp doc))
        (assert (listp inter))
        (assert (eq (length inter) 2))
        (assert (eq (car inter) 'interactive))
        (let ((s (nth 1 inter)))
          (assert (stringp s))
          (if (fboundp 'handle-shift-selection)
              (setq s (concat "^" s)))
          (list 'interactive s)))
     ,@body))

OTHER TIPS

I think you would need to do something like

(interactive
  (progn
    (when (fboundp 'handle-shift-selection)
      (handle-shift-selection))
    (list (prefix-numeric-value current-prefix-arg))))

If the argument to interactive is not a string, it should evaluate to a list (remember that interactive is not a function, it is a special form).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top