Naviguer et refactorer le code avec un serveur de langage (lsp)
Ce guide montre comment donner un serveur de langage à mm, pour que le modèle demande au compilateur où un symbole est défini, qui l'utilise, quel est son type, ce qui ne va pas dans un fichier, et le renomme partout — plutôt que de grepper et de deviner. Il suppose que mm tourne avec un fichier de configuration modifiable, et qu'au moins un serveur de langage est installé.
Étapes
-
Installez le serveur de votre langage et vérifiez qu'il est sur le
PATH:Langage Serveur Installation command/argsGo gopls go install golang.org/x/tools/gopls@latestgoplsTypeScript, JavaScript typescript-language-server npm i -g typescript typescript-language-servertypescript-language-server,["--stdio"]Python pyright pip install pyrightounpm i -g pyrightpyright-langserver,["--stdio"]Rust rust-analyzer rustup component add rust-analyzerrust-analyzerC, C++ clangd apt install clangd,brew install llvmclangdJava Eclipse JDT LS votre gestionnaire de paquets, ou la release jdtls jdtlsZig zls release de la chaîne zig, oubrew install zlszlswhich gopls(ou le nom du serveur) doit répondre. Un serveur configuré mais introuvable est ignoré avec un avertissement au démarrage. -
Déclarez les serveurs dans le fichier YAML. L'extension du fichier choisit le serveur :
lsp: servers: - name: gopls command: gopls extensions: [".go"] - name: typescript command: typescript-language-server args: ["--stdio"] extensions: [".ts", ".tsx", ".js", ".jsx"] - name: python command: pyright-langserver args: ["--stdio"] extensions: [".py"] - name: rust command: rust-analyzer extensions: [".rs"]Le fichier livré
agent.lsp.yamlestagent.dmr.yamlavec ce bloc (gopls actif, les autres prêts à décommenter) et un prompt système écrit pour l'outil — partez de lui. -
Dites au modèle quand utiliser l'outil. Un petit modèle ne va pas chercher un nouvel outil de lui-même ; le prompt système doit le dire. Le bloc ci-dessous est celui d'
agent.lsp.yaml; collez-le dans votresystem:(il est en anglais, la langue dans laquelle le modèle lit le mieux ses consignes) :CODE NAVIGATION (lsp) You have an `lsp` tool: it asks the project's language server what the compiler knows. Its description says which file extensions it covers. Use it INSTEAD of grep or reading whole files for anything about a symbol: - "where is X defined / declared" → action definition, symbol X - "who calls / uses X", "find usages" → action references, symbol X - "what is the type / signature of X" → action hover, symbol X - "what does this file contain" → action symbols, path only - "are there errors", after every edit → action diagnostics, path only - "rename X to Y everywhere" → action rename, symbol X, new_name Y (rename NEEDS new_name — the new identifier; never rename with edit_file: {"action": "rename", "path": "main.go", "symbol": "Greet", "new_name": "Hello"}) Point at a symbol with its NAME (the `symbol` field), exactly as written in the code; add `line` only to pick one occurrence among several. Do not guess columns. Answers are "path:line:column <source line>": quote them, they are the evidence. Before changing a symbol used in several files, call references and say how many places are affected. After editing, call diagnostics on each edited file and fix what it reports before running tests.Le skill
lsp-navigationlivré dansskills/dit la même chose plus longuement ; avecskillsDirpointant dessus, le modèle peut le charger avecread_skillquand la tâche le demande. -
Lancez
mmdepuis le répertoire du projet (les serveurs le reçoivent comme racine de travail) et lisez la bannière :[warning: lsp server ghost (no-such-lsp-server) not found on the PATH — skipped] mm v0.0.3 | config: agent.lsp.yaml | provider: dmr | model: … | ctx: unknown | tools: bash, read_skill, read_file, write_file, edit_file, lsp | skills: 4lspdans la colonnetools:signifie qu'au moins un serveur a été trouvé. Les serveurs démarrent à leur premier usage, pas ici. -
Posez des questions. Quelques prompts pour tester les six actions, sur n'importe quel projet couvert par le serveur :
Prompt Ce que vous devez voir Where is the function greet defined in main.go? Use lsp.🔎 lsp: definition main.go greetpuis une lignemain.go:6:6 func greet(…), citée dans la réponse.Who uses greet? List every call site.🔎 lsp: references main.go greet,N reference(s):avec une ligne par site.What is the signature of greet?🔎 lsp: hover main.go greet, la signature et le commentaire de doc du serveur.What does main.go contain? Give me its outline.🔎 lsp: symbols main.go, une ligne par fonction, type, variable.Are there compile errors in main.go?🔎 lsp: diagnostics main.go,no diagnostics: main.go is cleanou une ligne par erreur.Rename greet to hello everywhere, then check main.go for errors.🔎 lsp: rename main.go greet → hello,renamed to hello: N edit(s) in M file(s), puis un appeldiagnostics.Add a parameter to greet. Before you edit, tell me how many places call it.referencesd'abord, puisedit_file, puisdiagnostics— la procédure que le skill enseigne.Les prompts en français marchent aussi (« Où est définie la fonction greet ? ») : c'est le prompt système qui décide de l'outil, pas la langue de la question. La ligne de récapitulatif après la réponse compte les appels :
⚙ 0 command(s) · 🔎 2 lsp call(s).
Depuis un éditeur (ACP) et dans le mode fenêtre
Rien à configurer : le même YAML s'applique. Les appels de navigation apparaissent comme des appels d'outil de sorte read, sans boîte de permission ; rename est de sorte edit et demande la permission comme edit_file (permissions: ask dans le mode fenêtre). Les serveurs démarrent dans le répertoire où mm a été lancé — pour un éditeur, le projet qu'il a ouvert.
Variantes
- Un projet en plusieurs langages. Listez un serveur par famille d'extensions ; chacun ne démarre que quand on l'interroge sur un fichier de sa sorte.
- Un serveur avec des réglages. Passez-les en
args(beaucoup de serveurs lisent un drapeau ou un fichier de configuration à la racine du projet) ;mmrépond « pas de réglages » à un serveur qui demande sa configuration, qui tourne alors avec ses valeurs par défaut. - Positions exactes. Quand le modèle a une position exacte — via
read_fileavecnumbered=true— il peut envoyerlineetcolumn(base 1, dans l'identifiant) au lieu desymbol.symbolest la voie fiable : les petits modèles comptent rarement les colonnes juste. - Aucun serveur sur cette machine. L'outil n'est pas déclaré et la bannière dit
lsp: none of the configured servers is on the PATH — the lsp tool is not declared. La configuration peut rester ; l'agent fonctionne sans. - Première réponse lente. Le premier appel pour un langage démarre le serveur et le laisse indexer le projet ;
diagnosticspeut direas last publishedouno diagnostics received … within 3s— redemandez une fois.
Voir aussi
- Référence des outils intégrés — les champs, sorties et échecs de
lsp - Référence de la configuration — les clés
lsp.serverset les erreurs de validation - Pourquoi un seul outil
lsp, et pourquoi un champsymbol - Ajouter un skill — le format du skill
lsp-navigation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
|