Un moyen rapide de basculer une variable

9

Ce serait bien d'avoir un moyen rapide de basculer une variable. Voici quelque chose que j'ai en tête.

  • Appelez une fonction "toggle var".
  • Le completing-readne doit répertorier que les variables qui ont des valeurs uniques (pas des listes ou des listes). Je ne sais pas si cela peut être fait. Il serait encore mieux de ne répertorier que les vars dont les valeurs sont soit tou nil. Je suis sûr que cela ne peut pas être fait.
  • La fonction définit ensuite la valeur var sur tsi sa valeur actuelle est nil, et vice-versa.

La question est de savoir si nous avons déjà une fonction elisp qui le fait. Sinon, et si les gens ont résolu ce problème avec leur solution personnalisée, aimeraient voir comment ils le font.

Mise à jour:

Un bonus serait de faire completing-readsuggérer le symbole sous le point (si présent) pour basculer.

Donc, si le "toggle var" fn est lié à C-c ~, l'utilisation sera aussi courte que C-c ~ RET.


Ma procédure actuelle pour basculer un var est la suivante:

  • C-h v VAR, obtenez la valeur var actuelle.
  • M-: (setq VAR toggled-value).

ou

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

Je cherche un moyen d'accélérer ce processus (moins de frappe).

Kaushal Modi
la source

Réponses:

4

Voici une réponse rapide -

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

Mais si vous utilisez Icicles, vous pouvez simplement utiliser la commande icicle-toggle-option(avec un préfixe négatif arg, si vous voulez une variable, et pas seulement une option utilisateur):

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’.
A dessiné
la source
La solution fonctionne très bien pour basculer les vars et j'aime le message de confirmation qu'il imprime à la fin. Mais cela ne restreint pas la liste aux vars uniquement booléens. Pour cela, je crois que je dois regarder la source des glaçons, n'est-ce pas?
Kaushal Modi
Je viens de mettre à jour la question avec une fonctionnalité intéressante: ramasser le point de symbole par défaut (en attendant que l'utilisateur appuie simplement sur RET).
Kaushal Modi
Si vous voulez des variables strictement tet nilvalorisées, utilisez la version mise à jour, qui récupère également le nom d'une variable (à valeur booléenne) au point, par défaut.
Drew
Oui, si vous souhaitez gérer des variables booléennes généralisées (c'est-à-dire, où non nilpeut signifier vrai , tout comme le tfait), ou si vous voulez pouvoir choisir d'utiliser des options ou des variables, consultez le code 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)))

Si vous avez installé helm, vous pouvez utiliser la commande helm-apropos, il

  • fournir une interface de complétion pour toutes les variables
  • peut par-sélectionner la variable au point le cas échéant
  • fournir une action pour changer la valeur de la variable (vous devez insérer une nouvelle valeur dans le Minibuffer)

l'avantage est que vous pouvez rechercher la chaîne doc de variable et changer sa valeur au sein d'une helm-apropossession.

xuchunyang
la source
2

Essayez lispy-setq pour basculer la variable au point ou ora-custom-setq de ma configuration pour définir une variable avec achèvement:

(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)))))))
abo-abo
la source
Il serait intéressant d'indiquer quelle est la valeur actuelle de la variable (en particulier lors de la définition de nil ou t). Ou la valeur par défaut dans la "liste déroulante" du lierre peut-elle être définie sur zéro si la valeur actuelle est t (et vice-versa)?
Kaushal Modi
Je viens de mettre à jour la question avec une fonctionnalité intéressante: ramasser le point de symbole par défaut (en attendant que l'utilisateur appuie simplement sur RET).
Kaushal Modi