Schneller Weg, um eine Variable umzuschalten


9

Es wäre schön, eine Variable schnell umzuschalten. Hier ist etwas, an das ich denke.

  • Rufen Sie eine "toggle var" -Funktion auf.
  • Das completing-readsollte nur Variablen auflisten, die einzelne Werte haben (keine Listen oder Listen). Ich weiß nicht, ob das möglich ist. Es wäre sogar noch besser, wenn nur die Variablen aufgelistet würden, deren Werte entweder toder sind nil. Ich bin mir ziemlich sicher, dass dies nicht möglich ist.
  • Die Funktion setzt dann den var-Wert auf, twenn sein aktueller Wert ist nil, und umgekehrt.

Die Frage ist, ob wir bereits eine Elisp-Funktion haben, die dies tut. Wenn nicht, und wenn die Leute dieses Problem mit ihrer benutzerdefinierten Lösung gelöst haben, möchten sie sehen, wie sie es tun.

Aktualisieren:

Eine Bonusfunktion wäre completing-read, das Symbol unter Punkt (falls vorhanden) zum Umschalten vorzuschlagen.

Wenn also das "toggle var" fn gebunden ist, C-c ~ist die Verwendung so kurz wie C-c ~ RET.


Mein aktuelles Verfahren zum Umschalten einer Variable lautet wie folgt:

  • C-h v VAR, erhalten Sie den aktuellen var-Wert.
  • M-: (setq VAR toggled-value).

oder

  • M-: (setq VAR (not VAR)).

Ich suche nach einer Möglichkeit, diesen Prozess zu beschleunigen (weniger Tippen).

Antworten:


4

Hier ist eine schnelle Antwort -

(defun my-toggle-var (var)
  "..."
  (interactive
   (let* ((def  (variable-at-point))
          (def  (and def 
                     (not (numberp def))
                     (memq (symbol-value def) '(nil t))
                     (symbol-name def))))
     (list
      (completing-read
       "Toggle value of variable: "
       obarray (lambda (c)
                 (unless (symbolp c) (setq c  (intern c)))
                 (and (boundp c)  (memq (symbol-value c) '(nil t))))
       'must-confirm nil 'variable-name-history def))))
  (let ((sym  (intern var)))
    (set sym (not (symbol-value sym)))
    (message "`%s' is now `%s'" var (symbol-value sym))))

Wenn Sie jedoch Eiszapfen verwenden , können Sie einfach den Befehl verwenden icicle-toggle-option(mit einem negativen Präfix arg, wenn Sie eine Variable und nicht nur eine Benutzeroption möchten):

icicle-toggle-option is an interactive compiled Lisp function in
`icicles-cmd1.el'.

It is bound to menu-bar options icicles icicle-toggle-option.

(icicle-toggle-option)

Toggle option’s value.  This makes sense for binary (toggle) options.
By default, completion candidates are limited to user options that
have ‘boolean’ custom types.  However, there are many "binary" options
that allow other non-nil values than t.

You can use a prefix argument to change the set of completion
candidates, as follows:

 - With a non-negative prefix arg, all user options are candidates.
 - With a negative prefix arg, all variables are candidates.

Read input, then act on it.

Input-candidate completion and cycling are available.  While cycling,
these keys with prefix ‘C-’ are active:

‘C-mouse-2’, ‘C-return’ - Act on current completion candidate only
‘C-down’, ‘C-wheel-down’ - Move to next completion candidate and act
‘C-up’, ‘C-wheel-up’ - Move to previous completion candidate and act
‘C-next’  - Move to next apropos-completion candidate and act
‘C-prior’ - Move to previous apropos-completion candidate and act
‘C-end’   - Move to next prefix-completion candidate and act
‘C-home’  - Move to previous prefix-completion candidate and act
‘C-!’     - Act on *all* candidates, successively (careful!)

When candidate action and cycling are combined (e.g. ‘C-next’), user
option ‘icicle-act-before-cycle-flag’ determines which occurs first.

With prefix ‘C-M-’ instead of ‘C-’, the same keys (‘C-M-mouse-2’,
‘C-M-RET’, ‘C-M-down’, and so on) provide help about candidates.

Use ‘mouse-2’, ‘RET’, or ‘S-RET’ to finally choose a candidate, or
‘C-g’ to quit.

This is an Icicles command - see command ‘icicle-mode’.

Die Lösung eignet sich hervorragend zum Umschalten der Vars und ich mag die Bestätigungsmeldung, die am Ende gedruckt wird. Die Liste wird jedoch nicht nur auf boolesche Variablen eingegrenzt. Dafür glaube ich, dass ich in die Eiszapfenquelle schauen muss, richtig?
Kaushal Modi

Ich habe die Frage gerade mit einer netten Funktion aktualisiert: Nehmen Sie den Symbolpunkt als Standard (warten Sie darauf, dass der Benutzer nur drückt RET).
Kaushal Modi

Wenn Sie streng tund nilbewertete Variablen möchten , verwenden Sie standardmäßig die aktualisierte Version, die auch den Namen einer (Booleschen) Variablen am Punkt übernimmt.
Drew

Ja, wenn Sie Boolesche Variablen verallgemeinert behandeln möchten (dh wo nicht nilbedeuten kann wahr , genau wie der tFall ist), oder wenn Sie wollen , ob Optionen Gebrauch wählen können oder irgend Variablen, dann das sehen Icicles - Code.
Drew

3
(defun toggle-variable (variable)
  (interactive
   (let ((v (variable-at-point))
         val)
     (setq val (completing-read (if (symbolp v)
                                    (format
                                     "Toggle variable (default %s (= %s)): " v (symbol-value v))
                                  "Toggle variable: ")
                                obarray
                                'boundp
                                t nil nil
                                (if (symbolp v) (symbol-name v))))
     (list (if (equal val "")
               v (intern val)))))
  (set variable (not (symbol-value variable)))
  (message "%s toggled (= %s)" variable (symbol-value variable)))

Wenn Sie Helm installiert haben, können Sie den Befehl verwenden helm-apropos, es

  • Vervollständigungsschnittstelle für alle Variablen bereitstellen
  • kann die Variable gegebenenfalls per Punkt auswählen
  • Geben Sie eine Aktion an, um den Wert der Variablen zu ändern (Sie müssen einen neuen Wert in den Minibuffer einfügen).

Der Vorteil ist, dass Sie die Dokumentzeichenfolge der Variablen nachschlagen und ihren Wert innerhalb einer helm-aproposSitzung ändern können .


2

Versuchen Sie lispy-setq , die Variable am Punkt umzuschalten , oder ora-custom-setq aus meiner Konfiguration, um eine Variable mit Abschluss festzulegen :

(defun ora-custom-setq ()
  "Set a custom variable, with completion."
  (interactive)
  (let ((sym (intern
              (ivy-read "Variable: "
                        (counsel-variable-list))))
        sym-type
        cands)
    (when (and (boundp sym)
               (setq sym-type (get sym 'custom-type)))
      (cond
        ((and (consp sym-type)
              (memq (car sym-type) '(choice radio)))
         (setq cands (mapcar #'lispy--setq-doconst (cdr sym-type))))
        ((eq sym-type 'boolean)
         (setq cands
               '(("nil" . nil) ("t" . t))))
        (t
         (error "Unrecognized custom type")))
      (let ((res (ivy-read (format "Set (%S): " sym) cands)))
        (when res
          (setq res
                (if (assoc res cands)
                    (cdr (assoc res cands))
                  (read res)))
          (eval `(setq ,sym ,res)))))))

Es wäre schön anzugeben, wie hoch der aktuelle Wert der Variablen ist (insbesondere wenn auf null oder t gesetzt wird). Oder kann der Standardwert in der Efeu-Dropdown-Liste auf Null gesetzt werden, wenn der aktuelle Wert t ist (und umgekehrt)?
Kaushal Modi

Ich habe die Frage gerade mit einer netten Funktion aktualisiert: Nehmen Sie den Symbolpunkt als Standard (warten Sie darauf, dass der Benutzer nur drückt RET).
Kaushal Modi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.