EMACS: Como avaliar a menor expressão S em que o cursor está ou a seguinte expressão S

StackOverflow https://stackoverflow.com/questions/2171890

  •  24-09-2019
  •  | 
  •  

Pergunta

Qual é uma boa maneira de avaliar o (+ 100 (+ 100 100)) parte em

(+ (+ 1 2) (+ 100 (+ 100 100)))

?

Por enquanto, faço isso por CX CE, o que significa que preciso localizar os parênteses finais, o que é difícil na maioria dos casos. Options > Paren Matching Highlighting Ajuda, mas ainda preciso mover o cursor em direção aos parênteses finais até que a correspondência destacada seja o parêntese inicial.

Uma maneira seria ter a versão reversa do CX CE, para que eu possa colocar o cursor nos parênteses iniciais como este:

(+ (+ 1 2) |(+ 100 (+ 100 100)))

e depois pressione a ordem de chave apropriada.

Ou eu poderia colocar o cursor dentro da expressão, mas não dentro de expressões menores::

(+ (+ 1 2) (+ | 100 (+ 100 100)))

e pressione uma chave de chave. Porque o objetivo de um alvo é mais fácil se o alvo for grande.

Como posso fazer esse comando? Ou já existe um fornecido?

Sidenote: Cursor do bar e cursor de caixa

Emacsers que usam o Cursor da caixa (padrão) podem se perguntar onde estou colocando o cursor com a notação de barra acima. No Emacs, você pode escolher o cursor da caixa ou o cursor de barra, (bar-cursor-mode t). Quando o cursor da barra está entre as letras A e B, o cursor da caixa está em B. Portanto, a barra é a parede esquerda da caixa.

Aliás, o conceito de cursor de bar é útil de alguma maneira incomum: a prática de itentar do index1 para o índice2-1 na programação surpreende iniciantes. Ajuda a imaginar index1 e index2 como barras indicadoras (paredes esquerdas) em vez de caixas.

Foi útil?

Solução

Vincule uma chave para um ou ambos:

(defun eval-next-sexp ()
  (interactive)
  (save-excursion
    (forward-sexp)
    (eval-last-sexp nil)))

(defun eval-surrounding-sexp (levels)
  (interactive "p")
  (save-excursion
    (up-list (abs levels))
    (eval-last-sexp nil)))

Relacionado tangencialmente, eu recomendo paredit Para trabalhar com expressões S. Os comandos e encadernações de edição da estrutura tornam a edição S-Expressões uma brisa. Liga c-down a up-list, para que eval-surrounding-sexp Acima é quase exatamente o mesmo que C-down CX CE (a única diferença é que a função usa save-excursion para impedir o movimento).

Outras dicas

Você pode escrever um comando assim:

(require 'thingatpt)
(defun eval-sexp-at-or-surrounding-pt ()
  "evaluate the sexp following the point, or surrounding the point"
  (interactive)
  (save-excursion
    (forward-char 1)
    (if (search-backward "(" nil t)
        (message "%s" (eval (read-from-whole-string (thing-at-point 'sexp)))))))

Dentro Pingentes de gelo Existe uma maneira geral de fazer o que você deseja.

Por padrão, no minibuffer M-. está ligado a um comando que insere texto (ou próximo) ponto no minibuffer (não entra ou faz mais com ele; apenas insere).

Você pode, por exemplo, usar M-: Para avaliar um Lisp Sexp, e então você usa M-. Para pegar um sexo em/próximo ponto.

Se você repetir M-. Em seguida, ele cai o que apenas agarrou e pega algum outro tipo de coisa (texto) em/próximo ponto e insere isso. Por padrão, ele percorre esse tipo de coisa, em ordem:

uma. Um símbolo Lisp ou nome do arquivo.

b. A região ativa (texto selecionado) ou uma palavra.

c. A lista mais imediata.

d. A próxima maior lista.

e. A próxima maior lista.

f. Qualquer arquivo ou url da função ffap-guesser suposições.

g. Qualquer que seja a função thing-at-point-url-at-point suposições.

O que isso significa para o seu exemplo de (+ (+ 1 2) (+ 100 (+ 100 100)))?

Se o ponto é antes do 1 do segundo a pouca 100, por exemplo, esses são os sexps que são inseridos consecutivamente no minibuffer quando você bate M-. repetidamente, em ordem:

uma. +

b. 100

c. (+ 100 100)

d. (+ 100 (+ 100 100))

e. (+ (+ 1 2) (+ 100 (+ 100 100)))?

Então, para inserir as maiores listas de anexo que você faria MILÍMETROS-. M-. M-. M-. M-., isto é, atingido M-. cinco vezes.

Para esse comportamento, em particular para a captura precisa das listas, você também precisa da biblioteca Coisa no ponto+.

Há um embutido eval-defun. Está vinculado por padrão para C-M-x. É semelhante ao que você deseja, mas Evalals o Defun de nível superior. Talvez você possa adaptar isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top