Como fazer com que o Emacs desembrulhe um bloco de código?
-
09-06-2019 - |
Pergunta
Digamos que eu tenha uma linha em um buffer do emacs parecida com esta:
foo -option1 value1 -option2 value2 -option3 value3 \
-option4 value4 ...
Eu quero que fique assim:
foo -option1 value1 \
-option2 value2 \
-option3 value3 \
-option4 value4 \
...
Quero cada par opção/valor em uma linha separada.Também quero que as linhas subsequentes sejam recuadas adequadamente de acordo com o modo, em vez de adicionar uma quantidade fixa de espaços em branco.Eu preferiria que o código funcionasse no bloco atual, parando na primeira linha não vazia ou na linha que não contém um par opção/valor, embora eu pudesse aceitar que ele funcionasse em uma região selecionada.
Alguém conhece uma função elisp para fazer isso?
Solução
Ninguém tinha o que eu procurava, então decidi tirar a poeira do meu manual do elisp e fazer isso sozinho.Isso parece funcionar bem, embora a saída não seja exatamente o que eu pedi.Nesta versão, a primeira opção entra sozinha em uma linha, em vez de permanecer na primeira linha, como na minha pergunta original.
(defun tcl-multiline-options ()
"spread option/value pairs across multiple lines with continuation characters"
(interactive)
(save-excursion
(tcl-join-continuations)
(beginning-of-line)
(while (re-search-forward " -[^ ]+ +" (line-end-position) t)
(goto-char (match-beginning 0))
(insert " \\\n")
(goto-char (+(match-end 0) 3))
(indent-according-to-mode)
(forward-sexp))))
(defun tcl-join-continuations ()
"join multiple continuation lines into a single physical line"
(interactive)
(while (progn (end-of-line) (char-equal (char-before) ?\\))
(forward-line 1))
(while (save-excursion (end-of-line 0) (char-equal (char-before) ?\\))
(end-of-line 0)
(delete-char -1)
(delete-char 1)
(fixup-whitespace)))
Outras dicas
Neste caso eu usaria uma macro.Você pode começar a gravar uma macro com C-x (e parar de gravá-la com C-x ).Quando você quiser reproduzir a macro, digite C-x e.
Nesse caso, eu digitaria C-a C-x ( C-s v a l u e C-f C-f \ RET SPC SPC SPC SPC C-x )
Isso registraria uma macro que procura por "valor", avança 2, insere uma barra e uma nova linha e, finalmente, espaça a nova linha para alinhar.Então você poderia repetir esta macro algumas vezes.
EDITAR:Acabei de perceber que seu texto literal pode não ser tão fácil de pesquisar quanto “valor1”.Você também pode procurar espaços e percorrer os resultados.Por exemplo, acertar C-s algumas vezes após a primeira partida para pular algumas partidas.
Observação:Como o seu exemplo é "ad-hoc", esta solução também será.Muitas vezes você usa macros quando precisa de uma solução ad hoc.Uma maneira de fazer com que a macro seja aplicada de forma mais consistente é colocar toda a instrução original em uma linha (também pode ser feito por uma macro ou manualmente).
EDITAR:Obrigado pelo comentário sobre ( versus C-(, você estava certo, meu erro!
Pessoalmente, faço coisas assim o tempo todo.
Mas não escrevo uma função para fazê -lo, a menos que faça isso todos os dias durante um ano.
Você pode fazer isso facilmente com substituição de consulta, assim:
m-x (query-replace "-option" "^Q^J -option")
Eu digo ^q ^j como é isso que você digitará para citar uma nova linha e colocá -la na string.
Em seguida, basta pressionar 'Y' para que as cordas substituam e 'n' para pular os casos de canto mais estranhos que você encontraria.
Outra função de trabalho de trabalho é a consulta-repele-regexp que pode fazer substituições de expressões regulares.
e também Grep-Query-Replace, que executará o Reparplate, analisando a saída de um comando grep.Isso é útil porque você pode procurar "foo" em 100 arquivos e, em seguida, fazer o substituto de consulta em cada ocorrência pulando de arquivo para o arquivo.
Seu modo já pode suportar isso.No modo C e no modo Makefile, pelo menos, M-q (parágrafo de preenchimento) irá inserir continuações de linha na coluna de preenchimento e quebrar suas linhas.
Em que modo você está editando isso?