unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Customizing universal-argument (C-u), instead of hardcoding 4?
@ 2016-02-07 22:24 Karl Fogel
  2016-02-07 22:36 ` John Wiegley
  0 siblings, 1 reply; 4+ messages in thread
From: Karl Fogel @ 2016-02-07 22:24 UTC (permalink / raw)
  To: Emacs Devel

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



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-02-08 13:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-07 22:24 Customizing universal-argument (C-u), instead of hardcoding 4? Karl Fogel
2016-02-07 22:36 ` John Wiegley
2016-02-07 22:55   ` Karl Fogel
2016-02-08 13:02     ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).