Maneira rápida de alternar uma variável

9

Seria bom ter uma maneira rápida de alternar uma variável. Aqui está algo que eu tenho em mente.

  • Chame a função "alternar var".
  • O completing-readdeve listar apenas variáveis ​​que possuem valores únicos (não listas ou listas). Não sei se isso pode ser feito. Seria ainda melhor se ele listasse apenas os vars que possuem valores como tou nil. Certamente isso não pode ser feito.
  • A função define o valor var como tse seu valor atual é nile vice-versa.

A questão é se já temos uma função elisp que faz isso. Caso contrário, e se as pessoas tiverem lidado com esse problema com sua solução personalizada, gostariam de ver como o fazem.

Atualizar:

Um recurso de bônus seria fazer da completing-readsugestão o símbolo abaixo do ponto (se presente) para alternar.

Portanto, se a opção "alternar var" fn estiver vinculada C-c ~, o uso será tão curto quanto C-c ~ RET.


Meu procedimento atual para alternar um var é o seguinte:

  • C-h v VAR, obtenha o valor atual do var.
  • M-: (setq VAR toggled-value).

ou

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

Estou procurando uma maneira de acelerar esse processo (menos digitação).

Kaushal Modi
fonte

Respostas:

4

Aqui está uma resposta 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))))

Mas se você usar Icicles , poderá usar o comando icicle-toggle-option(com um prefixo negativo arg, se desejar alguma variável e não apenas uma opção do usuário):

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’.
Desenhou
fonte
A solução funciona muito bem para alternar os vars e eu gosto da mensagem de confirmação impressa no final. Mas isso não restringe a lista a apenas vars booleanos. Para isso, acredito que preciso procurar a fonte de gelo, correto?
Kaushal Modi
Acabei de atualizar a pergunta com um recurso interessante: escolha o ponto do símbolo como padrão (aguardando o usuário pressionar RET).
Kaushal Modi
Se você desejar variáveis estritas te com nilvalor, use a versão atualizada, que também seleciona o nome de uma variável (com valor booleano) no ponto, como padrão.
Desenhou
Sim, se você deseja manipular variáveis ​​booleanas generalizadas (ou seja, onde não nilpode significar verdade , exatamente como o tfaz), ou se quiser escolher se deseja usar opções ou quaisquer variáveis, consulte o código Icicles .
Desenhou
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 você tem leme instalado, você pode usar o comando helm-apropos, ele

  • fornecer interface de conclusão para todas as variáveis
  • pode selecionar a variável no ponto, se houver
  • forneça uma ação para alterar o valor da variável (você precisa inserir um novo valor no Minibuffer)

a vantagem é que você pode procurar a sequência de documentos da variável e alterar seu valor em uma helm-apropossessão.

xuchunyang
fonte
2

Tente lispy-setq para alternar a variável no ponto ou ora-custom-setq da minha configuração para definir uma variável com a conclusão:

(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
fonte
Seria bom indicar qual é o valor atual da variável (especialmente ao definir como nil ou t). Ou o valor padrão no "dropdown" da hera pode ser definido como nulo se o valor atual for t (e vice-versa)?
precisa saber é o seguinte
Acabei de atualizar a pergunta com um recurso interessante: escolha o ponto do símbolo como padrão (aguardando o usuário pressionar RET).
Kaushal Modi