Czy istnieje sposób na wyłączenie wielowierszowych literałów ciągów w trybie c ++?

Załóżmy, że mam krótki ciąg znaków w C ++ i przypadkowo usuwam podwójny cudzysłów, który go kończy. To, co robi Emacs, to podświetla resztę kodu jako pojedynczy, bardzo długi ciąg, który psuje całe formatowanie, dopóki nie wstawię z powrotem podwójnego cudzysłowu. Wydaje się również trochę powolny, gdy ponownie łączy cały bufor.

Przejrzałem cc-mode.el, ale nie mogłem znaleźć dla niego ustawienia ani miejsca, w którym występuje czcionka tekstu.

Czy jest sposób, aby powiedzieć c ++ – mode (lub może font-lock?), że moje łańcuchy nigdy nie zawierają znaków nowej linii i nie powinny wychodzić poza pierwszy znak nowej linii, jeśli znajdzie niezakończony literał ciągu?

Komentarze

  • Czy używasz narzędzi do sprawdzania składni? czyli jak flycheck czy flymake? Pokażą ci wiersz z błędem, więc będzie można go łatwo poprawić.
  • @Ian Nawet jeśli wiem, gdzie brakuje podwójnego cudzysłowu, nadal sprawia, że cały bufor wygląda jak pojedynczy długi strunowy. To jest to, czego ' staram się uniknąć.
  • Czy na pewno chcesz to zmienić? System działa zgodnie z założeniami, dając Ci informację, że Twój kod nie jest ' poprawny.
  • @TrippLilley Tak: anulowanie, a następnie ponowne podłączenie całego bufora po ciągu wygląda brzydko i występuje również zauważalne opóźnienie interfejsu użytkownika. Flycheck i lsp i tak zawsze powiedzą mi o błędach składniowych. Na przykład Xcode podświetla ciągi z brakującym ostatnim cudzysłowem tylko do następnego znaku nowej linii i w ten sposób wygląda to znacznie lepiej.
  • I ' m zakładając, że wiąże się to ze zmianą tabel składni, ponieważ ten tryb może nie blokować czcionki.

Odpowiedź

Funkcja c-literal-limits, zdefiniowane w progmodes/cc-engine.el, określa sposób identyfikowania ciągów znaków i komentarzy we wszystkich wariantach c-mode. Wykorzystuje do tego dwie definicje:

 ;; 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\""))  

Niestety, ponieważ jest to nie jest zmienną konfigurowalną, nie możesz jej po prostu ponownie przypisać i pozwolić c-mode robić to, co chcesz. W zasadzie należałoby zaimplementować „poradę” (zobacz: defadvice) dla funkcji c-literal-limits, która zamiast tego używa twoich stałych. Te stałe dodałyby EOL (tj. "\\s$"), aby zakończyć wyrażenie tekstowe.

Oczywiście nie jest to sposób, w jaki C / C ++ język działa, więc zdecydowanie nie zalecam tego robić, ale wybór należy do Ciebie i jak widać, nie jest to łatwa ścieżka.

Komentarze

  • Nie było ' t aż do C ++ 0x, że C ++ miał wieloliniowe literały ciągów. C nie ' nie mam ich wcale AFAIK.
  • Masz rację. Myślę, że lepiej byłoby, gdyby Emacs oznaczył je jako błąd w plikach innych niż C ++.
  • Multi -line literały łańcuchowe w C ++ mają specjalną składnię wprowadzoną w C ++ 11, nie będą one ' nie pojawiać się koniecznie jako zwykłe ciągi dla emacsa (np. R""(string-contents)"".
  • To działa, ale nie ' nie chcę " akceptować " ta odpowiedź, ponieważ po prostu wydaje się tak zawikłana, aby mieć poradę / edytuj cc-engine.el tylko po to, aby uzyskać tę funkcję. Jeśli dobrze zrozumiałem, działa to tylko dla trybu c, co mnie zaskoczyło, ponieważ ' d pomyślałem, że identyfikowanie literałów ciągów było czymś robionym przez sam emacs, a następnie ujawnianym przez funkcje takie jak syntax-ppss.
  • @Kirill " To działa, ale ja nie ' nie chcę " zaakceptować " tę odpowiedź, ponieważ wydaje się tak zawiłe, że trzeba doradzać / edytować cc-engine.el tylko po to, ta funkcja " Słyszę. Silnik składni w c-mode nie zawsze jest elastyczny, ponieważ obsługuje wiele funkcji, niestety …

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *