Is er een manier om letterlijke tekenreeksen met meerdere regels uit te schakelen in de c ++ – modus?

Stel dat ik een korte string heb in C ++ en ik verwijder per ongeluk de dubbele aanhalingstekens die eraan eindigen. Wat Emacs doet, is de rest van de code markeren als een enkele zeer lange string, die alle opmaak verpest totdat ik de dubbele aanhalingstekens er weer in doe. Het voelt ook een beetje traag als het de hele buffer opnieuw invult.

Ik bladerde door cc-mode.el, maar ik kon de instelling ervoor niet vinden of de plaats waar tekenreekslettertypen plaatsvinden.

Is er een manier om vertel c ++ – mode (of font-lock misschien?) dat mijn strings nooit nieuwe regels bevatten en dat het nooit verder moet kijken dan de eerste nieuwe regel als het een niet-afgesloten letterlijke tekenreeks vindt?

Opmerkingen

  • Gebruikt u syntaxiscontrole? d.w.z. zoals flycheck of flymake? Ze zullen je de regel met de fout laten zien, zodat het gemakkelijk te corrigeren is.
  • @Ian Zelfs als ik weet waar het dubbele aanhalingsteken ontbreekt, zorgt het er nog steeds voor dat de hele buffer eruitziet als een enkele lange draad. Dat is wat ik ' m probeer te vermijden.
  • Weet u zeker dat u dit wilt wijzigen? Het systeem werkt zoals het is ontworpen en geeft je feedback dat je code niet ' t correct is.
  • @TrippLilley Ja: lettertypen ongedaan maken en vervolgens de volledige buffer na de tekenreeks opnieuw invullen ziet er lelijk uit en er is ook een merkbare UI-vertraging. Flycheck en lsp zullen me hoe dan ook altijd vertellen over syntaxisfouten. Xcode markeert bijvoorbeeld strings met een ontbrekend laatste citaat tot aan de volgende nieuwe regel, en het ziet er op die manier veel beter uit.
  • I ' m ervan uitgaande dat dit het wijzigen van syntaxis-tabellen met zich meebrengt, aangezien deze modus het lettertype misschien niet zelf vergrendelt.

Answer

De functie c-literal-limits, gedefinieerd in progmodes/cc-engine.el bepaalt hoe strings en commentaren worden geïdentificeerd in alle c-mode varianten. Het gebruikt deze twee definities om dit te doen:

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

Helaas, aangezien dit geen configureerbare variabele, je kunt hem niet zomaar opnieuw toewijzen, en c-mode laten doen wat je wilt. U zou in feite “advies” (zie: defadvice) moeten implementeren voor de c-literal-limits functie die in plaats daarvan uw constanten gebruikt. Deze constanten zouden een EOL toevoegen (dwz "\\s$") om de tekenreeksexpressie te beëindigen.

Dit is natuurlijk niet hoe de C / C ++ taal werkt echter, dus ik raad ten zeerste aan om dit niet te doen, maar de keuze is aan jou, en zoals je kunt zien, is het geen gemakkelijke weg.

Opmerkingen

  • Het was niet ' t totdat C ++ 0x dat C ++ meerregelige letterlijke tekenreeksen had. C niet ' hebben ze helemaal niet AFAIK.
  • Je hebt gelijk. Ik denk dat het beter zou zijn als Emacs ze markeert als een fout in niet-C ++ bestanden.
  • Multi -line string literals in C ++ hebben een speciale syntaxis geïntroduceerd in C ++ 11, ze zouden niet ' moeten verschijnen als gewone strings voor emacs (bijvoorbeeld R""(string-contents)"".
  • Dit werkt, maar ik wil ' niet " accepteren " dit antwoord omdat het zo ingewikkeld lijkt om advies / bewerk cc-engine.el alleen om deze functie te krijgen. Als ik het goed heb begrepen, werkt dit alleen voor c-mode, wat me verraste omdat ik ' dacht dat het identificeren van letterlijke tekenreeksen iets was dat door emacs zelf werd gedaan en vervolgens werd blootgesteld via functies zoals syntax-ppss.
  • @Kirill " Dit werkt, maar ik ' Ik wil dit antwoord " " accepteren omdat het zo ingewikkeld lijkt om cc-engine.el te moeten adviseren / bewerken om deze functie " Ik hoor je. De syntaxis-engine in c-mode is niet altijd flexibel omdat het veel functies ondersteunt, helaas …

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *