Modo rapido per attivare / disattivare una variabile


9

Sarebbe bello avere un modo rapido per attivare o disattivare una variabile. Ecco qualcosa che ho in mente.

  • Chiamare una funzione "toggle var".
  • L' completing-readdovrebbe elencare solo le variabili che hanno valori singoli (non elenchi o alists). Non so se sia possibile farlo. Sarebbe ancora meglio se elenca solo i var che hanno valori come uno to nil. Abbastanza sicuro che questo non può essere fatto.
  • La funzione imposta quindi il valore var su tse il suo valore attuale è nile viceversa.

La domanda è se abbiamo già una funzione elisp che lo fa. In caso contrario, e se le persone hanno affrontato questo problema con la loro soluzione personalizzata, vorrebbe vedere come lo fanno.

Aggiornare:

Una caratteristica bonus sarebbe quella di rendere il completing-readsuggerimento il simbolo sotto punto (se presente) per attivare / disattivare.

Pertanto, se "toggle var" fn è associato C-c ~, l'utilizzo sarà breve quanto C-c ~ RET.


La mia attuale procedura per attivare / disattivare una var è la seguente:

  • C-h v VAR, ottiene il valore var corrente.
  • M-: (setq VAR toggled-value).

o

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

Sto cercando un modo per accelerare questo processo (meno digitando).

Risposte:


4

Ecco una risposta rapida:

(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))))

Ma se usi Icicles puoi semplicemente usare il comando icicle-toggle-option(con un arg del prefisso negativo, se vuoi una variabile, e non solo un'opzione utente):

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’.

La soluzione funziona benissimo per attivare / disattivare i var e mi piace il messaggio di conferma che stampa alla fine. Ma non restringe l'elenco a solo booleani var. Per questo, credo di dover esaminare la fonte dei ghiaccioli, giusto?
Kaushal Modi,

Ho appena aggiornato la domanda con una bella funzionalità: prendi il punto simbolo come predefinito (aspettando che l'utente prema semplicemente RET).
Kaushal Modi,

Se vuoi variabili rigorosamente te nilvalutate, usa la versione aggiornata, che raccoglie anche il nome di una variabile (con valore booleano) come predefinito.
Ha

Sì, se vuoi gestire variabili booleane generalizzate (ovvero, dove non- nilpuò significare vero , proprio come tfa), o se vuoi essere in grado di scegliere se usare opzioni o variabili, vedi il codice Icicles .
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)))

Se si dispone di timone installato, è possibile utilizzare il comando helm-apropos, esso

  • fornire un'interfaccia di completamento per tutte le variabili
  • può selezionare la variabile nel punto, se presente
  • fornire azioni per modificare il valore della variabile (è necessario inserire un nuovo valore nel Minibuffer)

il vantaggio è che puoi cercare la stringa di documenti della variabile e modificarne il valore all'interno di una helm-apropossessione.


2

Prova lispy-setq per attivare la variabile point o ora-custom-setq dalla mia configurazione per impostare una variabile con completamento:

(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)))))))

Sarebbe bello indicare quale sia il valore corrente della variabile (specialmente quando si imposta su zero o t). Oppure il valore predefinito nell'edera "menu a discesa" può essere impostato su zero se il valore corrente è t (e viceversa)?
Kaushal Modi,

Ho appena aggiornato la domanda con una bella funzionalità: prendi il punto simbolo come predefinito (aspettando che l'utente prema semplicemente RET).
Kaushal Modi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.