Gå til innhold

LSP (språkserver)-programtillegget

Kodeintelligens drevet av Language Server Protocol — feilbølgelinjer, navigasjon, opplysninger ved peking, fullføring, signaturhjelp, formatering, søk etter referanser, nytt navn og gå til symbol — for ethvert språk som har en språkserver. Redigereren snakker med tjeneren over LSP; programtillegget er klienten. Hvilke tjenere som finnes, er datastyrt (én liten JSON per språk), så C++ og clangd nedenfor er bare én av flere medfølgende definisjoner.

Redigereren leverer eller henter ingen tjenere

En språkserver er et eget program du installerer én gang. MTE finner en installert tjener og peker den mot prosjektet ditt; den leverer aldri en selv. Se Å skaffe en språkserver.

Funksjoner i dag

Funksjon Hvordan
Diagnostikk Feil og advarsler fra tjeneren kommer fram som bølgede understrekinger (rød = feil, ravgul = advarsel, blå = informasjon, grå = tips), oppdatert mens du skriver.
Gå til definisjonen Sett markøren på et symbol, og trykk F12, eller bruk Søk ▸ Kodenavigering ▸ Gå til definisjonen. Hopper til definisjonen og åpner om nødvendig en annen fil.
Søk etter referanser Markøren på et symbol → Shift+F12 (eller Søk ▸ Kodenavigering ▸ Søk etter referanser). Resultatene åpnes i et referansepanel nederst, gruppert etter fil med en forhåndsvisning av kildelinjen; dobbeltklikk for å hoppe dit.
Opplysninger ved peking Hold pekeren over et symbol; en boble viser typen eller signaturen og dokumentasjonen (gjengitt fra tjenerens Markdown).
Fullføring Ctrl+Mellomrom ber tjeneren om fullføringer og folder dem inn i redigererens fullføringsliste (foran de innebygde forslagene fra nøkkelord og ord i bufferen), filtrert mens du skriver.
Signaturhjelp Skriver du et kalls ( eller et ,, vises et kalltips med funksjonens signatur og den aktive parameteren uthevet; ) lukker det.
Formater dokumentet Alt+Shift+F (⌃⌥F på macOS; eller Rediger ▸ Formater dokumentet) formaterer hele dokumentet gjennom tjeneren, i ett angretrinn. Tjenerens eget oppsett styrer stilen (for clangd en .clang-format-fil).
Søk etter referanser (nevnt ovenfor) —
Gi symbolet nytt navn Markøren på et symbol → Shift+F6 (eller Rediger ▸ Gi symbolet nytt navn). Oppgi et nytt navn; hver bruk oppdateres. Strekker navnebyttet seg over flere filer, blir du bedt om å bekrefte først — hver fil åpnes, endres og lates endret, så du kan gå gjennom og lagre den.
Gå til symbol (i filen) Ctrl+Shift+O åpner kommandopaletten med hvert symbol i den gjeldende filen (funksjoner, klasser, metoder …); skriv for å filtrere, Enter hopper dit. Hver rad viser symbolets type og det det hører til.
Gå til symbol i arbeidsområdet Ctrl+T søker etter symboler i hele prosjektet mens du skriver (tjeneren matcher søket); Enter åpner filen ved symbolet.

Velgerne for gå til symbol er kommandopalettens symbolmodi — se Kommandopalett.

Kommandoene er nedtonet inntil en tjener kjører

Gå til definisjonen, Søk etter referanser, Formater dokumentet og Gi symbolet nytt navn er bare på når en språkserver for den gjeldende filens språk er klar — og når den tjeneren meldte i håndtrykket sitt at den støtter forespørselen. I en fil uten en oppsatt tjener, eller mens en holder på å starte eller starte på nytt eller har gitt opp, er menypostene nedtonet i stedet for ikke å gjøre noe når man trykker på dem. Statusvisningen nedenfor forteller deg hva som er tilfelle. Start språkserverne på nytt er aldri nedtonet: det er veien ut av en tjener som har gitt opp.

Referanser og nytt navn på tvers av filer krever tjenerens indeks

Søk etter referanser og Gi nytt navn når bare ut i andre filer når tjeneren har indeksert prosjektet. For C/C++ betyr det en compile_commands.json (se nedenfor) og clangds bakgrunnsindeks; uten den virker de bare i den gjeldende filen.

Nytt navn angres per fil inntil videre

Et navnebytte over flere filer tas i bruk én fil om gangen, så hver fil er sitt eget angretrinn (bekreftelsesvinduet sier det). Gå gjennom de endrede fanene før du lagrer.

I redigererens kontekstmeny

Høyreklikk på et symbol i teksten, så tilbyr menyen, under redigeringskommandoene, Gå til definisjonen, Søk etter referanser, Gi symbolet nytt navn og Formater dokumentet. Hvert av dem vises bare når den samme kommandoen i hovedmenyen ville virket akkurat nå — en språktjener for filen er klar og støtter den, og for nytt navn og formatering er dokumentet ikke skrivebeskyttet. I en ren tekstfil, i margen til venstre for teksten eller mens tjeneren starter, vises ingen av dem.

Oppføringene virker på symbolet du høyreklikket på, ikke på det under markøren; markøren og merkingen blir der de var. Nytt navn foreslår merkingen som gammelt navn når du høyreklikket inne i den, og ellers ordet under pekeren. Formater dokumentet formaterer alltid hele dokumentet. En meny som åpnes fra tastaturet, virker ved markøren.

Der plattformen viser hurtigtaster i kontekstmenyer (Windows), viser hver oppføring sin hurtigtast — den som gjelder, inkludert dine egne endringer i Tildel hurtigtaster. På macOS viser kontekstmenyer ingen hurtigtaster.

Hvordan endringene dine når tjeneren

Det å skrive sender ikke en melding per tastetrykk. Endringer samles i en brøkdel av et sekund og sendes så som én endring — og som ett endret område i stedet for hele filen, når tjeneren sier at den kan ta imot et (det kan de fleste). En stor fil koster derfor et par dusin byte per skriveutbrudd i stedet for en kopi av seg selv.

Alt som spør tjeneren om teksten — opplysninger ved peking, gå til definisjonen, søk etter referanser, gi nytt navn, formater, fullføring, signaturhjelp — sender den ventende endringen først, så et svar aldri viser til en versjon du alt har forlatt. Det samme skjer når du lagrer en fil.

Å starte en tjener sperrer heller ikke redigereren: prosessen startes i bakgrunnen, og statusavsnittet viser … inntil den er ferdig med håndtrykket sitt. Et tjenerprogram som henger ved oppstart, koster deg ikke annet enn det språket.

Et tak på hvor mange problemer som tegnes

Det tegnes høyst 2000 bølgelinjer per dokument. Utover det er filen uleselig likevel, og hver ekstra markør koster redigereren virkelig tid — så når en fil gir flere, vises de første 2000, og statuslinjen sier Viser de første 2000 av N problemer i denne filen, i stedet for at antallet i stillhet ser mindre ut enn det er. Det er som regel et tegn på at tjeneren ser galt på filen: en manglende kompileringsdatabase, eller en generert fil som ikke er ment å kunne kompilere alene.

Tjenerens statusvisning

Statuslinjen viser et kompakt LSP:-avsnitt (til venstre for de andre programtilleggsavsnittene) som sammenfatter hver språkserver som betyr noe for de åpne filene dine:

LSP: cpp ✓ · no compile database  python ↻2  rust ✗
Tegn Betydning
… Starter — tjeneren er startet og utveksler håndtrykk.
✓ Klar — betjener forespørsler.
↻n Starter på nytt — tjeneren stoppet uventet; automatisk omstartsforsøk n er satt i kø.
✗ Ingen tjener installert for dette språket. Installer en (se nedenfor), og bruk så Start språkserverne på nytt.
⚠ Ga opp — tjeneren fortsatte å krasje, og de automatiske omstartene stanset. Bare en omstart for hånd vekker den til live.

Et språk kan bære en kort tilføyelse etter tegnet — tjeneren kjører, og noe ved prosjektet ditt begrenser fortsatt hva den kan svare på. Det vises bare én om gangen, den alvorligste først:

Tilføyelse Betydning
· server not responding Flere forespørsler på rad ble stående ubesvart. Tjeneren er i live, men står fast; bruk Vis loggen til språkserveren og deretter Start språkserverne på nytt. Tilføyelsen forsvinner i det øyeblikket tjeneren svarer på noe som helst.
· no compile database C/C++-tjeneren kjører, men kan bare se den filen du har åpen — se C/C++-prosjekter krever compile_commands.json.
· no Cargo.toml, · no go.mod, · no tsconfig.json … Prosjektet har ingen av de filene denne tjeneren trenger for å forstå det som et prosjekt. Den virker fortsatt i den åpne filen; svar på tvers av filer vil være ufullstendige inntil filen finnes. Det nøyaktige navnet er det tjeneren helst vil ha — se Hva hver tjener trenger fra prosjektet ditt.

Avsnittet kommer fram når det første dokumentet med et oppsatt språk åpnes, følger bare de språkene du faktisk har dokumenter åpne for — lukker du et språks siste fil, fjernes posten dens (åpner du en igjen, kommer den tilbake med det samme) — og skjules helt når det ikke er flere slike dokumenter.

Søk ▸ Kodenavigering ▸ Vis loggen til språkserveren viser de nyeste utdataene fra hver kjørende tjener. Det er der en tjener forklarer seg: en manglende verktøykjede, en uleselig oppsettfil, et prosjekt den nektet å laste inn. Vinduet er et vanlig vindu du kan endre størrelse på — hvert språk er en overskrift som navngir den tjeneren som kjører for det, teksten kan merkes, Kopier legger hele loggen på utklippstavlen, og den størrelsen du gir vinduet, huskes.

Hvis en tjener krasjer

En språkserver som avslutter uventet, startes på nytt av seg selv med en økende forsinkelse (1 s, 2 s, 4 s … med tak ved 30 s). Mens det skjer, viser visningen ↻n, og en melding i statuslinjen melder det første krasjet. Etter en vellykket omstart meldes de åpne dokumentene dine til tjeneren på nytt, og diagnostikken kommer tilbake av seg selv; foreldede bølgelinjer fra den døde tjeneren fjernes med det samme. Redigeringen sperres aldri.

Etter 5 mislykkede forsøk på rad gir programtillegget opp: visningen viser ✗, en melding peker deg mot innstillingene, og språket blir stående mørkt inntil du starter det på nytt for hånd. En tjener som gikk fint i minst ett minutt, får et nytt sett forsøk når den senere krasjer.

Omstart for hånd — en av disse:

  • Søk ▸ Kodenavigering ▸ Start språkserverne på nytt (ingen hurtigtast som standard; finnes også i kommandopaletten), eller
  • knappen Søk på nytt / start serverne på nytt under Innstillinger ▸ Språkserver.

Vil du se hvorfor en tjener er misfornøyd før du starter den på nytt, så bruk Søk ▸ Kodenavigering ▸ Vis loggen til språkserveren.

Begge river hver tjener ned, kjører letingen på nytt med de gjeldende innstillingene og nullstiller feilbudsjettet — bruk dem etter at du har installert en tjener som manglet, eller rettet en som var i stykker.

Å skaffe en språkserver

Installer tjeneren for språket ditt, og se til at den ligger i PATH (eller oppgi en uttrykkelig sti i innstillingene). Finnes det ingen, gjør funksjonen ganske enkelt ingenting for det språket — statusvisningen viser ✗, og loggen noterer et tips én gang, men ingenting avbryter deg.

MTE leverer tjenerdefinisjoner (ikke tjenerne) for mange språk, så de fleste krever bare at tjeneren er installert — ingen JSON-redigering. De medfølgende definisjonene dekker C/C++, Objective-C, Python, Rust, Go, TypeScript, JavaScript, C#, Java, Kotlin, Swift, HTML, CSS/SCSS/Less, JSON, YAML og skallskript.

Språk Tjener Hvor du får den
C/C++ clangd winget install LLVM.LLVM (Windows), komponenten «C++ Clang tools» i Visual Studios installasjonsprogram, brew install llvm (macOS), eller distribusjonens clang-tools-extra-pakke.
Python pyright eller pylsp npm i -g pyright (krever Node.js), eller pip install python-lsp-server (krever bare Python).
TypeScript/JS typescript-language-server npm i -g typescript-language-server typescript.
Rust rust-analyzer rustup component add rust-analyzer.
Go gopls go install golang.org/x/tools/gopls@latest.
C# csharp-ls eller OmniSharp dotnet tool install -g csharp-ls (ett enkelt dotnet-verktøy, som prøves først), eller hent en OmniSharp-utgave.
Java jdtls (Eclipse JDT Language Server) brew install jdtls (macOS), eller pakk ut en utgave, og legg bin-mappen dens i PATH.

Kontroller det i en terminal, for eksempel med clangd --version eller where clangd / which clangd. For et språk MTE ikke leverer en definisjon for, kan du legge til en slik som beskrevet under Å legge til et språk.

Python: pyright eller pylsp

Python har to medfølgende definisjoner, og OctoEdit kjører den som faktisk er installert:

  1. pyright (pyright-langserver) prøves først. Den er en npm-pakke, så den krever Node.js: npm i -g pyright.
  2. pylsp (python-lsp-server) brukes når pyright ikke finnes. Den er en pip-pakke og krever bare Python: pip install python-lsp-server.

Er begge installert, vinner pyright. Det er én innstillingsrad for Python (én bryter og én stioverstyring), og den gjelder uansett hvilken tjener som brukes — oppgir du en uttrykkelig sti til et pylsp-program, kjøres pylsp med dens oppstartsargumenter og ikke pyrights. Vis loggen til språkserveren navngir den tjeneren som faktisk kjører.

Flere tjenere for ett språk

Dette er en allmenn mekanisme og ikke et særtilfelle for Python: et språk kan ha et hvilket som helst antall medfølgende definisjoner, ordnet etter et priority-felt, og den første der programmet finnes på maskinen din, er den som starter. C# virker på samme måte — csharp-ls først, OmniSharp deretter — for de to tar ulike oppstartsargumenter, og bare én av dem kan være riktig.

Java: tjenerens eget arbeidsområde

jdtls nekter å starte uten en skrivbar arbeidsområdemappe av sin egen (-data). OctoEdit stiller en til rådighet av seg selv, per prosjekt, under programtilleggsdatamappen sin:

<user data>/plugins/org.mte.lsp/jdtls-workspaces/<project id>/

Du må aldri lage eller gi navn til den. Det er trygt å slette mappen — jdtls bygger den opp igjen, bare på bekostning av én ny indeksering.

Å sette det opp på Windows

En fersk Windows-maskin har som regel ingen av clangd, cmake, ninja, node eller python i PATH. Dette avsnittet sier hvor hver av dem kommer fra, og hvordan du kontrollerer det. Du behøver normalt ikke å redigere PATH selv — OctoEdit leter også i de økosystemmappene som er listet nedenfor.

Du vil ha Installer Hvor den lander
clangd (C/C++) winget install LLVM.LLVM C:\Program Files\LLVM\bin\clangd.exe
cmake og ninja Komponenten «C++ CMake tools for Windows» i Visual Studios installasjonsprogram …\Microsoft Visual Studio\2022\<edition>\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin og …\CMake\Ninja — ikke i PATH, men de kan nås gjennom Visual Studios utviklermiljø (se nedenfor). En selvstendig winget install Kitware.CMake / winget install Ninja-build.Ninja legger dem i PATH i stedet.
pyright (Python) winget install OpenJS.NodeJS.LTS, og deretter npm i -g pyright %APPDATA%\npm\pyright-langserver.cmd
pylsp (Python, uten Node) Python fra Microsoft Store eller python.org, og deretter pip install python-lsp-server %LOCALAPPDATA%\Packages\PythonSoftwareFoundation.Python.3.*_*\LocalCache\local-packages\Python3*\Scripts\pylsp.exe (Store) eller %APPDATA%\Python\Python3*\Scripts\pylsp.exe

Å kontrollere hva som er synlig. I en vanlig ledetekst eller PowerShell:

where clangd
where cmake
where ninja
where pyright-langserver
where pylsp

where leter bare i PATH. Et verktøy den ikke finner, kan likevel bli funnet av OctoEdit, for letingen dekker også økosystemmappene ovenfor — særlig Pythons skriptmapper ligger aldri i PATH. Blir et språk stående ✗ etter at du har installert tjeneren for det, så bruk Søk ▸ Kodenavigering ▸ Start språkserverne på nytt, som kjører hele letingen på nytt.

Genereringen av kompileringsdatabasen kjører inne i Visual Studios utviklermiljø. Når OctoEdit kjører CMake for deg (nedenfor), finner den først Visual Studio — gjennom VSINSTALLDIR, ellers vswhere.exe — og pakker kallet inn i den installasjonens VsDevCmd.bat -arch=x64. Det er dét som legger cl, Windows SDK-et og Visual Studios egen cmake og ninja på stien for nettopp den ene kommandoen, så redigereren slett ikke trenger dem i PATH. Uten Visual Studio (en maskin med bare clang eller MinGW) gjøres kallet helt vanlig i redigererens eget miljø, og loggen sier det; da må du selv sørge for at cmake og ninja kan nås, og at det finnes en kompilator CMake kan gjenkjenne.

Å generere på nytt ved behov. Søk ▸ Kodenavigering ▸ Generer kompileringsdatabase… kjører den samme genereringen når som helst — også når det alt finnes en database (den settes opp på nytt på stedet), og når du tidligere har svart Ikke spør for dette prosjektet. Posten er alltid tilgjengelig — kan den ikke generere, sier den hvorfor i statuslinjen (intet C/C++-dokument, ingen prosjektmappe, ingen CMakeLists.txt i prosjektets rot, ingen cmake, eller ingen generator her som kan eksportere en) i stedet for å være nedtonet av en grunn du ikke kan se.

Hvor «ikke spør»-svaret lagres. Ikke spør for dette prosjektet lagres per prosjektrot i %APPDATA%\7-bits\OctoEdit.ini, under plugins/org.mte.lsp/noCompileDbPrompt/<hash> (prosjektstien hashes, fordi en sti ikke er en lovlig innstillingsnøkkel). Kjører du Generer kompileringsdatabase…, tømmes det for det prosjektet.

Hvor OctoEdit leter etter en tjener

Du bør ikke måtte sette opp noe. Når tjeneren er installert, er det nok å åpne en mappe og en kildefil. Redigereren prøver i denne rekkefølgen:

  1. en uttrykkelig sti som du har satt i innstillingene — den er avgjørende: kan den ikke finnes, blir språket stående mørkt i stedet for i stillhet å falle tilbake på noe annet;
  2. PATH-en din, etter tjenerens kommando og hvert kjente alias (clangd-20, clangd-19 …);
  3. de installasjonsstedene som står i tjenerens definisjon, for operativsystemet ditt;
  4. en innebygd liste over økosystemmapper.
Økosystemmapper det letes i
Windows npms globale prefiks og %APPDATA%\npm, %LOCALAPPDATA%\Microsoft\WinGet\Links, %USERPROFILE%\.cargo\bin, %USERPROFILE%\go\bin og %LOCALAPPDATA%\go\bin, %USERPROFILE%\.dotnet\tools, %ProgramFiles%\LLVM\bin, %ProgramFiles%\nodejs, samt Pythons skriptmapper per bruker: %APPDATA%\Python\Python3*\Scripts, %LOCALAPPDATA%\Packages\PythonSoftwareFoundation.Python.3.*_*\LocalCache\local-packages\Python3*\Scripts (Python fra Microsoft Store) og %LOCALAPPDATA%\Programs\Python\Python3*\Scripts
macOS /opt/homebrew/bin og /opt/homebrew/opt/llvm/bin (Homebrews clangd ligger i den andre — den lenkes aldri inn i den første), /usr/local/bin, /usr/local/opt/llvm/bin, ~/.cargo/bin, ~/go/bin, ~/.local/bin, ~/.npm-global/bin, ~/.dotnet/tools, ~/Library/Python/3.*/bin
Linux /usr/local/bin, /usr/lib/llvm*/bin, Linuxbrew og de samme ~/.cargo/bin, ~/go/bin, ~/.local/bin, ~/.npm-global/bin, ~/.dotnet/tools

Postene med * er virkelige jokertegn: den versjonsmappen Python lager (Python313, 3.13 eller Stores …Python.3.13_qbz5n2kfra8p0), matches mot det som faktisk er på disken, nyest først. Det er der pip install python-lsp-server legger pylsp, og det er derfor det ikke krever en endring av PATH å installere den.

macOS: å starte fra Finder mot fra en terminal

Et program som startes fra Finder eller Dock, arver ikke PATH fra skallprofilen din — macOS gir det en minimal (/usr/bin:/bin:/usr/sbin:/sbin). Homebrew, Cargo, Go og npm ville alle vært usynlige. OctoEdit spør derfor påloggingsskallet ditt hva PATH-en dens er, og leter også i den, og gir det miljøet den ender opp med, videre til den tjeneren den starter — så en tjener som er installert med et av de verktøyene, blir funnet uansett hvordan du starter redigereren.

Tjeneren startes én gang per språk og stenges ned sammen med redigereren.

C/C++-prosjekter krever compile_commands.json

clangd forstår bare koden din nøyaktig når den kjenner kompileringsflaggene, fra en kompileringsdatabase (compile_commands.json). Uten en faller clangd tilbake på å gjette, og funksjoner på tvers av filer (søk etter referanser, gi nytt navn) blir værende begrenset til den åpne filen. clangd startes likevel i begge tilfeller.

Et C/C++-prosjekt teller som satt opp når det har en av disse:

  • en compile_commands.json i prosjektets rot eller i en av de byggemappene OctoEdit går gjennom (build/, Build/, out/, out/build/, cmake-build-debug/, cmake-build-release/, .mte-compile-commands/);
  • en compile_flags.txt i prosjektets rot;
  • en .clangd-oppsettfil i prosjektets rot.

clangd leser de to siste selv, så det meldes ingenting om dem.

Når ingen av dem finnes — for hvert C/C++-prosjekt, uansett hvilket byggesystem det bruker — viser statusavsnittet · no compile database, og en melding i statuslinjen sier det én gang. Ingenting sperres; intet vindu avbryter skrivingen din.

Å la OctoEdit generere den (CMake-prosjekter)

Har prosjektets rot en CMakeLists.txt og en CMake som faktisk ville gitt en database, blir du tilbudt dette én gang per prosjekt:

  • Generer — kjører CMake i bakgrunnen, bare oppsett: ingenting kompileres, og dine egne byggemapper røres ikke. Resultatet havner i <project>/.mte-compile-commands/. Lykkes det, startes clangd på nytt mot den nye databasen; mislykkes det, vises de siste linjene av CMake-loggen sammen med den nøyaktige kommandoen som ble forsøkt, så du kan gjenta den selv.
  • Slik gjør du det manuelt — viser den samme kommandoen uten å kjøre den.
  • Ikke spør for dette prosjektet — huskes per prosjektrot.

Både vinduet «slik gjør du det manuelt» og feilvinduet viser den nøyaktige kommandolinjen i en kodeboks du kan merke i, over én enkelt Kopier-knapp der hjelpetipset sier hva den tar: kommandoen alene, eller kommandoen sammen med slutten av CMake-loggen når det er en. Feilvinduet kan endre størrelse og husker den størrelsen du gir det — hvert av disse vinduene husker sin egen størrelse, så det å forstørre tjenerloggen får ikke et veiledningsvindu på to linjer til å åpne seg like stort.

Du er ikke bundet til det ene tilbudet: Søk ▸ Kodenavigering ▸ Generer kompileringsdatabase… starter den samme genereringen når du vil — etter at du har lagt til filer, endret byggevalg eller svart Ikke spør for dette prosjektet (som den tømmer). En database som alt finnes, settes opp på nytt på stedet. Posten er alltid tilgjengelig; kan den ikke generere, sier den hvorfor i statuslinjen.

Dine forhåndsoppsett kommer først. Har prosjektet en CMakePresets.json (eller en CMakeUserPresets.json), setter OctoEdit opp med et av dine forhåndsoppsett i stedet for å finne på en kommandolinje — cmake --preset <name> -B <project>/.mte-compile-commands -DCMAKE_EXPORT_COMPILE_COMMANDS=ON. På den måten er generatoren, verktøysettet og forhåndsoppsettets environment-blokk (en QT6_DIR, en SDK-sti) de prosjektet alt bygger på, og CMake tar dem i bruk selv. Forhåndsoppsett som er skjult, som en condition utelukker på operativsystemet ditt, eller som setter opp med en generator som ikke kan eksportere, hoppes over; et navn som inneholder debug, foretrekkes. Din egen byggemappe røres aldri — redigereren leder alltid resultatet et annet sted med -B.

På Windows kjøres CMake inne i et Visual Studio-utviklermiljø. En redigerer som er startet fra Utforskeren eller startmenyen, har ingen cl i PATH, og CMake ville da i stillhet nøyd seg med den andre kompilatoren den finner — også den clang.exe som følger med inne i en Visual Studio-installasjon, og som straks feiler på MSVC-spesifikke innstillinger. OctoEdit finner derfor Visual Studio med vswhere og pakker kallet inn i VsDevCmd.bat -arch=x64. Er det ingen Visual Studio installert (en maskin med bare MinGW eller clang), gjøres kallet helt vanlig, og loggen sier det.

Et tidligere mislykket forsøk ryddes bort før et nytt: CMakeCache.txt-en fra det ville ellers låst fast den kompilatoren som feilet. En mappe som alt inneholder en fungerende compile_commands.json, settes opp på nytt på stedet og slettes aldri.

Hvorfor tilbudet iblant ikke kommer fram

CMAKE_EXPORT_COMPILE_COMMANDS følges bare av generatorene Ninja og Makefile; Visual Studio-generatoren ser bort fra den og skriver ingen database. På Windows kommer tilbudet derfor bare fram for et prosjekt uten et brukbart forhåndsoppsett når ninja ligger i PATH. Er et prosjekts eneste anvendelige forhåndsoppsett Visual Studio-forhåndsoppsett, og er det heller ingen Ninja, sier OctoEdit hvilket forhåndsoppsett som sto i veien, i stedet for å tilby å kjøre noe som ikke kunne virke.

Å generere den selv (CMake)

CMAKE_EXPORT_COMPILE_COMMANDS følges bare av generatorene Ninja og Makefile — Visual Studio-generatoren ser bort fra den (den gir ingen compile_commands.json, heller ikke med flagget satt). Generer derfor databasen med Ninja, inn i en egen mappe, atskilt fra den du normalt bygger i: CMake nekter å sette opp en eksisterende byggemappe på nytt med en annen generator, så et prosjekt du pleier å bygge med Visual Studio, trenger sin egen Ninja-mappe.

Det er et steg med bare oppsett (det trengs ikke noe fullstendig bygg). Fra prosjektets rot:

cmake -S . -B .mte-compile-commands -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
  • .mte-compile-commands/ er en av de mappene MTE går gjennom, så den resulterende compile_commands.json blir funnet av seg selv. Enhver mappe som gås gjennom, virker også (build/, out/, cmake-build-* eller prosjektets rot) — hold den bare atskilt fra en mappe som er satt opp med en annen generator.
  • Kjør den fra et miljø der prosjektet faktisk lar seg sette opp: den riktige kompilatoren i PATH (for eksempel en x64 Native Tools Command Prompt på Windows) og de variablene prosjektet ditt trenger (som QT6_DIR i et Qt-prosjekt). Kan cmake ikke finne kompilatoren eller SDK-et ditt, ender databasen tom eller uten inkluderingsstier, og clangd indekserer ikke godt.
  • Åpne mappen på nytt etterpå. Loggen bør ikke lenger si «no compile_commands.json»; gi clangd et øyeblikk til å bygge bakgrunnsindeksen sin før referanser og nytt navn strekker seg over filer.

Andre byggesystemer: Bear (bear -- make), compiledb, Meson, Bazel og andre kan alle gi en compile_commands.json som programtillegget vil finne.

Hvilken tjener som betjener hvilken fil

Filnavnet avgjør. Hver tjenerdefinisjon lister de filendelsene den betjener, og den første definisjonen som tar en fils filendelse, er den som starter. Matchingen ser bort fra store og små bokstaver, og bare det siste punktumet teller — Deploy.Prod.SH er et skallskript.

Dette er med vilje uavhengig av syntaksfargingen. Å slå fargingen av, eller å åpne en fil som er større enn fargingens størrelsesgrense, koster deg ikke lenger språkserveren i tillegg.

Fargeleggerens id er fortsatt en reserve

Er det ingen definisjon som tar filendelsen, faller OctoEdit tilbake på den språk-id-en fargeleggingsmotoren tildelte. Det holder en håndskrevet definisjon i gang når den navngir et språk, men ikke lister noen filendelser.

Det navnet tjeneren får vite, er en annen og egen sak: LSP har sitt eget ordforråd av språk-id-er, og flere av dem passer ikke til OctoEdits. En .sh-fil meldes som shellscript, en .scss som scss, en .jsx som javascriptreact, en .mm som objective-cpp. Tjenere som oppfører seg ulikt fra språk til språk — CSS-tjeneren, TypeScript-tjeneren — trenger at dette er riktig.

Filendelse Betjenes av Meldes som
.cpp .cxx .cc .h .hpp .hh .hxx .ipp .inl clangd cpp
.c clangd c
.m / .mm clangd objective-c / objective-cpp
.sh .bash .zsh .ksh bash-language-server shellscript
.css / .scss / .less vscode-css-language-server css / scss / less
.ts .mts .cts / .tsx typescript-language-server typescript / typescriptreact
.js .mjs .cjs / .jsx typescript-language-server javascript / javascriptreact
.json / .jsonc .json5 vscode-json-language-server json / jsonc

.h tas av C/C++-definisjonen og ikke av Objective-C-definisjonen — begge kjører clangd, som selv avgjør hva en hodefil inneholder.

Hva hver tjener trenger fra prosjektet ditt

Flere tjenere virker bare ordentlig når en bestemt fil ligger i prosjektets rot. Mangler den, sier statusvisningen fra i stedet for å late som om alt er i orden:

Språk Vil ha Uten den
Rust Cargo.toml rust-analyzer laster ikke inn pakken i det hele tatt.
Go go.mod gopls kan ikke bestemme modulen.
TypeScript tsconfig.json (eller package.json) svar på tvers av prosjektet er ikke tilgjengelige.
JavaScript jsconfig.json (eller package.json) som ovenfor.
Python (pyright) pyproject.toml / pyrightconfig.json / setup.py pyright virker fortsatt; den bruker bare standardverdier for importrøtter og strenghet.
Java pom.xml / build.gradle jdtls kan ikke bygge en klassesti.
C/C++ compile_commands.json se avsnittet ovenfor.

Å legge til et språk

Tjenere beskrives av JSON-filer som programtillegget laster inn ved oppstart fra <editor>/lsp-servers/*.json, pluss din egen mappe. Hver post knytter et språk til kommandoen sin pluss pekepinner til letingen:

{
    "language":    "cpp",
    "languageId":  "cpp",
    "languageIds": { ".c": "c" },
    "command":     "clangd",
    "aliases":     ["clangd-20", "clangd-19"],
    "args":        ["--background-index", "--log=verbose"],
    "extensions":  [".cpp", ".h", ".hpp", ".c"],
    "projectMarkers": [],
    "searchDirs":      ["${LLVM}/bin", "${ProgramFiles}/LLVM/bin"],
    "searchDirsMac":   ["/opt/homebrew/opt/llvm/bin"],
    "searchDirsLinux": ["/usr/lib/llvm-20/bin"],
    "docsAnchor":  "cpp-clangd",
    "compileCommandsArg": "--compile-commands-dir=${dir}"
}
  • language er OctoEdits egen id for språket — den nøkkelen innstillingssiden, statusavsnittet og forbindelsen grupperes etter. command/aliases er de programnavnene som prøves i PATH.
  • extensions er den primære knytningen mellom fil og språk (se ovenfor). Ta med punktumet.
  • args er ett tabellelement per argument. ["--background-index", "--log=verbose"] sender to argumenter; ["--background-index --log=verbose"] sender ett argument som tilfeldigvis inneholder et mellomrom, og det avviser hver tjener — og fordi den da avslutter med det samme, ser resultatet ut som en krasjløkke og ikke som en skrivefeil. OctoEdit advarer om den formen i diagnostikkloggen når den laster inn filen din.
  • languageId (valgfritt) er den id-en som sendes til tjeneren i didOpen; den er som standard language. Bruk den når LSP-spesifikasjonens navn er et annet enn vårt (bash → shellscript, objc → objective-c).
  • languageIds (valgfritt) overstyrer languageId per filendelse, for én tjener som betjener flere språk i spesifikasjonen.
  • projectMarkers (valgfritt) er de filnavnene tjeneren vil ha i prosjektets rot. Er ingen av dem der, sier statusavsnittet ingen <first marker>; det stopper aldri tjeneren.
  • searchDirs er listen over installasjonssteder på Windows; searchDirsMac og searchDirsLinux er motstykkene per plattform. Alle tre utvider ${VAR}, og POSIX-listene utvider også en innledende ~. En post der variablene ikke er satt, hoppes over i stedet for å bli til en meningsløs sti.
  • args kan bruke to plassholdere: ${dataDir}, programtilleggets skrivbare datamappe, og ${rootHash}, en kort, stabil id for det gjeldende prosjektet. Slik får jdtls -data <dir>. En plassholder som ikke kan finnes, blir stående ordrett i argumentet i stedet for å bli utvidet til ingenting.
  • compileCommandsArg (valgfritt) legges til, med ${dir} erstattet av den databasemappen som ble funnet — slik pekes clangd mot compile_commands.json.
  • priority (valgfritt, 0 som standard) ordner flere definisjoner av samme språk: det laveste tallet prøves først, og den første definisjonen der programmet finnes, er den som starter. Slik får Python pyright (priority: 0) med pylsp (priority: 10) som reserve.

Dine egne tjenerdefinisjoner

De medfølgende definisjonene ligger inne i installasjonsmappen, som ikke er din å redigere i (Program Files på Windows, et signert programbunt på macOS). Legg dine egne ved siden av dem i stedet: Innstillinger ▸ Språkserver ▸ Åpne mappen med brukerens serverdefinisjoner lager og åpner

<user data>/plugins/org.mte.lsp/lsp-servers/

Hver *.json i den lastes inn etter det medfølgende settet, og:

  • en fil der language og command passer til en medfølgende definisjon, erstatter den — slik endrer du clangds argumenter eller legger til en letemappe;
  • alt annet legges til — en tjener nummer to for et språk vi leverer, eller et språk OctoEdit slett ikke leverer noe for.

En fil som ikke er gyldig JSON, eller som mangler language eller command, hoppes over og meldes i diagnostikkloggen i stedet for i stillhet å koste deg et språk.

Definisjonene leses én gang, ved oppstart: start redigereren på nytt etter at du har redigert dem (knappen Søk på nytt / start serverne på nytt kjører letingen på nytt, ikke innlastingen).

En minimal brukerdefinisjon: <user data>/…/lsp-servers/zig.json
{
    "language":   "zig",
    "command":    "zls",
    "extensions": [".zig", ".zon"],
    "projectMarkers": ["build.zig"],
    "searchDirs":      ["${LOCALAPPDATA}/zls"],
    "searchDirsMac":   ["/opt/homebrew/bin", "~/.local/bin"],
    "searchDirsLinux": ["~/.local/bin"]
}

Hvilken mappe tjeneren får

En språkserver må vite hvor prosjektet er: rust-analyzer laster ikke inn en pakke uten det, gopls trenger modulens rot, pyright leser pyrightconfig.json derfra, og clangd leter etter databasen sin der.

  • Med en mappe åpen (Fil ▸ Åpne mappe) hører filer inne i den til den mappen.
  • For en fil utenfor den åpne mappen, eller uten noen mappe åpen, går OctoEdit oppover fra filen og leter etter compile_commands.json, compile_flags.txt, .clangd, CMakeLists.txt, Cargo.toml, go.mod, pyrightconfig.json, pyproject.toml, setup.py, tsconfig.json, package.json, pom.xml, build.gradle, en .sln, .git og til sist en .editorconfig som erklærer root = true. Filens egen mappe er reserven, så en tjener står aldri uten et prosjekt.
  • Det virker å åpne mappen etter filen. Tjenere som forstår endringer av arbeidsområdets mapper, får beskjed om den nye mappen; resten startes på nytt, og de åpne dokumentene dine meldes til dem igjen av seg selv. Det trengs ingen omstart for hånd.

Feilsøking

Symptom Hva du bør se etter
LSP:-avsnittet kommer aldri fram Ingen tjenerdefinisjon tar denne filens filendelse. Se hvilken tjener som betjener hvilken fil, eller legg til en definisjon.
· server not responding Tjeneren har sluttet å svare. Bruk Vis loggen til språkserveren og deretter Start språkserverne på nytt.
✗ for et språk du har installert en tjener for Bekreft at programmet virkelig er der: where clangd (Windows) / which clangd (macOS, Linux). Bruk så Søk ▸ Kodenavigering ▸ Start språkserverne på nytt, som kjører hele letingen på nytt.
⚠ Tjeneren startet og fortsatte så å krasje. Vis loggen til språkserveren navngir som regel grunnen; rett den, og bruk så Start språkserverne på nytt.
· no compile database i et C/C++-prosjekt Se ovenfor. Søk etter referanser og Gi nytt navn ser bare den åpne filen inntil det er rettet.
Fullføringen gir ingenting i én C++-fil Den filen mangler sannsynligvis i compile_commands.json (en hodefil som ingen oversettelsesenhet inkluderer, eller en fil som er kommet til siden databasen ble generert). Generer den på nytt.
Alt virker når redigereren startes fra en terminal, men ikke fra Finder Meld fra — oppslaget av påloggingsskallets PATH skal nettopp gjøre de to like. Vis loggen til språkserveren og diagnostikkloggen noterer hva det ble lett i.
En tjener trenger en prosjektfil du ikke har typescript-language-server trenger typescript-pakken, gopls en go.mod, rust-analyzer en Cargo.toml og pyright en pyrightconfig.json eller pyproject.toml for å kunne svare på tvers av prosjektet.

Innstillinger for språkservere

Innstillinger ▸ Språkserver viser hvert språk det finnes en tjenerdefinisjon for. Per språk kan du:

  • Slå tjeneren av eller på (et språk som er slått av, starter aldri en).
  • Oppgi en uttrykkelig filbane til programmet (med Bla gjennom…). Den overstyringen vinner over letingen i PATH og searchDirs ovenfor — nyttig når tjeneren ikke ligger i PATH, eller når du vil ha et bestemt bygg.
  • Legge til ekstra argumenter, som legges etter definisjonens egne — for eksempel --log=verbose for clangd. Linjen deles opp slik en kommandolinje deles opp, så sett anførselstegn rundt en verdi som inneholder mellomrom.

Stifeltet er en sti, ikke en kommandolinje

Skriver du C:\tools\clangd.exe --log=verbose i Filbane til programmet, ber du OctoEdit om å finne en fil der navnet slutter på .exe --log=verbose, og den finnes ikke — språket melder da slett ingen tjener. Legg programmet i stifeltet og argumentene dets i Ekstra argumenter. Skjer det likevel, sier diagnostikkloggen det rett ut.

Endringene får virkning når du trykker på OK / Bruk: har en bryter eller en sti faktisk endret seg, startes tjenerne på nytt av seg selv med de nye innstillingene (en urørt side forstyrrer aldri tjenerne som kjører). Knappen Søk på nytt / start serverne på nytt tvinger i tillegg fram en nedstengning og en ny leting med de gjeldende innstillingene — nyttig etter at du har installert en tjener redigereren tidligere ikke kunne finne, og den nullstiller også budsjettet for omstart etter krasj.

Åpne mappen med brukerens serverdefinisjoner lager og åpner den mappen som er beskrevet under Dine egne tjenerdefinisjoner.

Begrensninger

  • Kodens farging inne i bobler med opplysninger ved peking brukes ikke (teksten formes — halvfet, overskrifter, fast tegnbredde — men syntaksfarges ikke).
  • Nøyaktigheten avhenger av tjeneren: for C/C++ faller clangd uten compile_commands.json tilbake på tommelfingerregler, og resultatene kan være ufullstendige.
  • OctoEdit installerer eller henter aldri en tjener. Den finner en du har installert, og starter den; er det ingen, blir funksjonen stående mørk, og statusavsnittet sier fra.
  • Én tjenerprosess per språk, delt av hvert åpne prosjekt på det språket. Et prosjekt nummer to legges til som en arbeidsområdemappe når tjeneren støtter det; ellers betjenes det under det første prosjektets rot.
  • Kotlin, Swift og Objective-C får kodeintelligens, men ingen syntaksfarging — redigereren har ennå ingen fargelegger for dem. De to tingene er uavhengige nå, så tjeneren virker uansett.
  • Tjenerdefinisjoner leses én gang ved oppstart; å redigere dem (dine egne eller de medfølgende) krever en omstart av redigereren.