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 …