Suponha que eu tenha uma string curta em C ++ e acidentalmente exclua as aspas duplas que a encerram. O que o Emacs faz é destacar o resto do código como uma única string muito longa, que bagunça toda a formatação até que eu coloque as aspas duplas de volta. Também parece um pouco lento quando está refontificando todo o buffer.
Eu dei uma olhada em cc-mode.el
, mas não consegui encontrar a configuração para ele ou o lugar onde a fonte de string acontece.
Existe uma maneira de diga c ++ – mode (ou font-lock talvez?) que minhas strings nunca contêm novas linhas e nunca devem olhar além da primeira nova linha se encontrar uma string literal não terminada?
Comentários
- Você usa verificadores de sintaxe? ou seja, como flycheck ou flymake? Eles mostrarão a linha com o erro, por isso será fácil de corrigir.
- @Ian Mesmo que eu saiba onde está faltando as aspas duplas, ele ainda faz com que todo o buffer após ele pareça um único longo fragmento. Isso é o que eu ' estou tentando evitar.
- Tem certeza de que deseja mudar isso? O sistema está funcionando conforme projetado, dando a você feedback de que seu código não está ' correto.
- @TrippLilley Sim: removendo a fonte e, em seguida, remontando todo o buffer após a string parece feio e também há um atraso perceptível na interface do usuário. Flycheck e lsp sempre me informarão sobre erros de sintaxe. O Xcode, por exemplo, destaca strings sem aspas finais apenas até a próxima nova linha, e parece muito melhor para mim dessa forma.
- I ' m presumindo que isso envolve a alteração das tabelas de sintaxe, pois este modo pode não bloquear a fonte por si só.
Resposta
A função c-literal-limits
, definido em progmodes/cc-engine.el
determina como strings e comentários são identificados em todas as c-mode
variantes. Ele usa essas duas definições para fazer isso:
;; String syntax chars, suitable for skip-syntax-(forward|backward). (defconst c-string-syntax (if (memq "gen-string-delim c-emacs-features) "\"|" "\"")) ;; Regexp matching string limit syntax. (defconst c-string-limit-regexp (if (memq "gen-string-delim c-emacs-features) "\\s\"\\|\\s|" "\\s\""))
Infelizmente, já que isso é não é uma variável configurável, você não pode simplesmente reatribuí-la e fazer com que c-mode
faça o que você deseja. Você teria que implementar basicamente “conselho” (consulte: defadvice
) para a função c-literal-limits
que usa suas constantes. Essas constantes adicionariam um EOL (ou seja, "\\s$"
) para encerrar a expressão de string.
Isso, é claro, não é como o C / C ++ linguagem funciona, então eu recomendo fortemente não fazer isso, mas a escolha é sua e, como você pode ver, não é um caminho fácil.
Comentários
- Não era ' t até C ++ 0x que C ++ tinha literais de string de várias linhas. C não ' não tenho nenhum AFAIK.
- Você está certo. Acho que uma coisa melhor seria o Emacs sinalizá-los como um erro em arquivos não C ++.
- Multi literais de string de linha em C ++ têm uma sintaxe especial introduzida em C ++ 11, eles não ' necessariamente aparecem como strings regulares para emacs (por exemplo,
R""(string-contents)""
. - Isso funciona, mas eu não ' não quero " aceitar " esta resposta porque parece tão complicado ter que aconselhar / edite cc-engine.el apenas para obter esse recurso. Se entendi corretamente, isso só funciona para o modo c, o que me surpreendeu porque ' achei que identificar literais de string era algo feito pelo próprio emacs e depois exposto por meio de funções como
syntax-ppss
. - @Kirill " Isso funciona, mas eu não ' não quero " aceitar " esta resposta porque parece tão complicado ter que aconselhar / editar cc-engine.el apenas para obter este recurso " Eu ouvi. O mecanismo de sintaxe em
c-mode
nem sempre é flexível porque suporta muitos recursos, infelizmente …