Manera rápida de alternar una variable


9

Sería bueno tener una forma rápida de alternar una variable. Aquí hay algo que tengo en mente.

  • Llame a una función "alternar var".
  • El completing-readdebe mostrar sólo las variables que tienen valores individuales (no listas o listas-A). No sé si eso se puede hacer. Sería aún mejor si solo enumera los vars que tienen valores como to nil. Estoy bastante seguro de que esto no se puede hacer.
  • Luego, la función establece el valor var en tsi su valor actual es nil, y viceversa.

La pregunta es si ya tenemos una función elisp que hace esto. Si no es así, y si las personas han solucionado este problema con su solución personalizada, les gustaría ver cómo lo hacen.

Actualizar:

Una característica adicional sería hacer completing-readsugerir el símbolo debajo del punto (si está presente) para alternar.

Por lo tanto, si el "toggle var" fn está vinculado C-c ~, el uso será tan breve como C-c ~ RET.


Mi procedimiento actual para alternar una var es el siguiente:

  • C-h v VAR, obtenga el valor var actual.
  • M-: (setq VAR toggled-value).

o

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

Estoy buscando una manera de acelerar este proceso (menos escribir).

Respuestas:


4

Aquí hay una respuesta rápida:

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

Pero si usa Icicles , puede usar el comando icicle-toggle-option(con un prefijo negativo arg, si desea cualquier variable, y no solo una opción de usuario):

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 solución funciona muy bien para alternar los vars y me gusta el mensaje de confirmación que imprime al final. Pero no limita la lista a solo variables booleanas. Para eso, creo que necesito investigar la fuente de carámbanos, ¿correcto?
Kaushal Modi

Acabo de actualizar la pregunta con una característica agradable: tomar el punto del símbolo por defecto (esperando que el usuario simplemente presione RET).
Kaushal Modi

Si desea variables estrictas ty nilvaloradas, utilice la versión actualizada, que también selecciona el nombre de una variable (valor booleano) en el punto, como valor predeterminado.
Drew

Sí, si desea manejar variables booleanas generalizadas (es decir, donde no nilpuede significar verdadero , al igual que lo thace), o si desea poder elegir si usar opciones o cualquier variable, consulte el código de 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 tiene instalado el timón, puede utilizar el comando helm-apropos, se

  • Proporcionar interfaz de finalización para todas las variables
  • puede seleccionar la variable en el punto si existe
  • proporcionar acción para cambiar el valor de la variable (debe insertar un nuevo valor en el Minibúfer)

La ventaja es que puede buscar la cadena de documentación de la variable y cambiar su valor dentro de una helm-apropossesión.


2

Pruebe lispy-setq para alternar la variable en el punto o ora-custom-setq desde mi configuración para configurar una variable con finalización:

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

Sería bueno indicar cuál es el valor actual de la variable (especialmente cuando se establece en nil o t). ¿O puede el valor predeterminado en el "menú desplegable" de hiedra establecerse en nulo si el valor actual es t (y viceversa)?
Kaushal Modi

Acabo de actualizar la pregunta con una característica agradable: tomar el punto del símbolo por defecto (esperando que el usuario simplemente presione RET).
Kaushal Modi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.