emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Customizing universal-argument (C-u), instead of hardcoding 4?


From: Karl Fogel
Subject: Customizing universal-argument (C-u), instead of hardcoding 4?
Date: Sun, 07 Feb 2016 16:24:51 -0600

This question has surely come up here before, but I searched and didn't find 
the discussion.

The default value of 4 for `universal-argument' (the C-u prefix) is currently 
hardcoded.  It could be useful for it to be customizable.  One example: I find 
that the distance 'C-u C-p' and 'C-u C-n' move by default is a bit too small 
for most of my use cases, and often the multiples are not quite right either.  
I'm trying some other values, especially 5, and thinking "Hmm, why not make it 
easy for people to experiment and set the right value for them?"

Of course the default C-u value affects more than C-p and C-n, but the question 
is the same: why hardcode it?  There's nothing special about 4, and we don't 
really know if it's the right value for most people.

It's set in simple.el, and there are various places in the code that expect it 
to be 4 as well.  I haven't looked deeply into how hard it would be to change, 
because I first wanted to ask here if a) this has been considered, and b) if 
anyone would be opposed to customizability & if so why.  But here's what I 
found in a quick look at the code:

These are the core places in simple.el that would need to refer to a new 
customizable variable instead of hardcoding 4 (I don't think any modification 
to prefix-numeric-value() in callint.c is necessary, as it gets the value from 
Lisp):

  ;; FIXME: Declaration of `prefix-arg' should be moved here!?
  
  (add-hook 'prefix-command-echo-keystrokes-functions
            #'universal-argument--description)
  (defun universal-argument--description ()
    (when prefix-arg
      (concat "C-u"
              (pcase prefix-arg
                (`(-) " -")
                (`(,(and (pred integerp) n))
                 (let ((str ""))
                   (while (and (> n 4) (= (mod n 4) 0))
                     (setq str (concat str " C-u"))
                     (setq n (/ n 4)))
                   (if (= n 4) str (format " %s" prefix-arg))))
                (_ (format " %s" prefix-arg))))))
  
  
  (defun universal-argument ()
    "Begin a numeric argument for the following command.
  Digits or minus sign following \\[universal-argument] make up the numeric > 
argument.
  \\[universal-argument] following the digits or minus sign ends the argument.
  \\[universal-argument] without digits or minus sign provides 4 as argument.
  Repeating \\[universal-argument] without digits or minus sign
   multiplies the argument by 4 each time.
  For some commands, just \\[universal-argument] by itself serves as a flag
  which is different in effect from any particular numeric argument.
  These commands include \\[set-mark-command] and \\[start-kbd-macro]."
    (interactive)
    (prefix-command-preserve-state)
    (setq prefix-arg (list 4))
    (universal-argument--mode))
  
  (defun universal-argument-more (arg)
    ;; A subsequent C-u means to multiply the factor by 4 if we've typed
    ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
    (interactive "P")
    (prefix-command-preserve-state)
    (setq prefix-arg (if (consp arg)
                         (list (* 4 (car arg)))
                       (if (eq arg '-)
                           (list -4)
                         arg)))
    (when (consp prefix-arg) (universal-argument--mode)))

And here are some places in the code that currently seem to rely on the value 
being 4 or some power thereof, so we'd have to adjust them to to look at a 
variable (in some cases raised to a power >1):

  ./lisp/simple.el:   ((and (consp arg) (> (prefix-numeric-value arg) 4))
  ./lisp/vc/pcvs.el:     (new (> (prefix-numeric-value current-prefix-arg) 8))
  ./lisp/vc/pcvs.el:          (> (prefix-numeric-value current-prefix-arg) 8)
  ./lisp/vc/pcvs.el:          (> (prefix-numeric-value current-prefix-arg) 8)))
  ./lisp/vc/pcvs.el:          (> (prefix-numeric-value current-prefix-arg) 8)
  ./lisp/vc/diff-mode.el:      (when (> (prefix-numeric-value other-file) 8)
  ./lisp/progmodes/sql.el:      (when (>= (prefix-numeric-value product) 16)
  ./lisp/progmodes/sql.el:         ((= (prefix-numeric-value product) 4) ; C-u, 
prompt for product
  ./lisp/progmodes/python.el:        (= (prefix-numeric-value 
current-prefix-arg) 4))
  ./lisp/font-lock.el:          (let ((lines (if arg (prefix-numeric-value arg) 
16)))
  ./lisp/allout.el:                             ((<= (prefix-numeric-value 
keymode-cue) 4)
  ./lisp/allout.el:                             ((> (prefix-numeric-value 
keymode-cue) 4)
  ./lisp/emulation/cua-base.el:   ((and (consp arg) (> (prefix-numeric-value 
arg) 4))
  ./lisp/dabbrev.el:      (and arg (= (prefix-numeric-value arg) 16)))
  ./lisp/dired.el:       (if current-prefix-arg ?\040)))
  ./lisp/dired.el:       (if current-prefix-arg ?\040)))
  ./lisp/simple.el:                 (eq (car current-prefix-arg) 4)) "C-u ")
  ./lisp/vc/pcvs.el:     (new (> (prefix-numeric-value current-prefix-arg) 8))
  ./lisp/vc/pcvs.el:          (> (prefix-numeric-value current-prefix-arg) 8)
  ./lisp/vc/pcvs.el:          (> (prefix-numeric-value current-prefix-arg) 8)))
  ./lisp/vc/pcvs.el:          (> (prefix-numeric-value current-prefix-arg) 8)
  ./lisp/vc/pcvs.el:         (let ((current-prefix-arg '(4)))
  ./lisp/vc/pcvs.el:    (let ((current-prefix-arg '(16)))
  ./lisp/vc/vc-git.el:      ((equal current-prefix-arg '(16))
  ./lisp/vc/vc-git.el:    (if (equal current-prefix-arg '(4))
  ./lisp/progmodes/grep.el:      ((and grep-command (equal current-prefix-arg 
'(16)))
  ./lisp/progmodes/grep.el:             (confirm (equal current-prefix-arg 
'(4))))
  ./lisp/progmodes/grep.el:      ((and grep-find-command (equal 
current-prefix-arg '(16)))
  ./lisp/progmodes/grep.el:             (confirm (equal current-prefix-arg 
'(4))))
  ./lisp/progmodes/grep.el:     ((and grep-find-command (equal 
current-prefix-arg '(16)))
  ./lisp/progmodes/grep.el:               (confirm (equal current-prefix-arg 
'(4))))
  ./lisp/progmodes/python.el:        (= (prefix-numeric-value 
current-prefix-arg) 4))
  ./lisp/org/org.el:         (if (and (not (equal current-prefix-arg '(4)))
  ./lisp/sort.el:          (equal current-prefix-arg '(4))
  ./lisp/sort.el:          (equal current-prefix-arg '(16))
  ./lisp/sort.el:          (equal current-prefix-arg '(64))

(Again, this was a very cursory glance, so I'm sure I missed spots.)

Thoughts?

Best regards,
-Karl



reply via email to

[Prev in Thread] Current Thread [Next in Thread]