# Arbre du projet — explication ## De quoi s'agit-il ? `F9` ouvre une fenêtre listant les fichiers du projet, et `Entrée` sur l'un d'eux l'ouvre. Cette page traite des trois décisions contenues là-dedans : où l'arbre s'enracine, pourquoi c'est une fenêtre plutôt qu'un panneau sur le côté, et pourquoi il ne remarque pas tout seul l'apparition de fichiers. ## Pourquoi la racine est le répertoire de travail L'éditeur contient déjà deux réponses différentes à « qu'est-ce que le projet ». Le serveur de langage remonte depuis le fichier ouvert jusqu'à trouver un `pyproject.toml`, parce qu'un module a une frontière réelle — en être à l'intérieur est un fait à propos du code, et pylsp a besoin de ce dossier précis pour travailler. Le fichier de réglages, lui, ne remonte pas du tout : `.turbo-python/settings.toml` est cherché dans le répertoire de travail et nulle part ailleurs. L'arbre suit le fichier de réglages, et il vaut la peine de dire pourquoi l'*autre* règle était tentante. Remonter jusqu'au `pyproject.toml` ferait qu'ouvrir un fichier de n'importe où dans un projet montrerait tout le projet, ce que fait habituellement un explorateur. Mais cela signifie aussi que la racine de l'arbre dépend d'un fichier trois dossiers plus loin auquel vous n'avez peut-être pas pensé, et cela cesse d'être prévisible dès qu'un dépôt contient plus d'un module — un monorepo vous montrerait le module auquel appartient le fichier que vous avez ouvert par hasard. La règle retenue est celle qui tient en une phrase et qui est vraie partout dans l'éditeur : **le projet est le dossier depuis lequel vous avez lancé l'éditeur.** Elle coûte quelque chose, et ce coût est nommé dans le [guide](../how-to/browse-a-project.md) : lancez depuis un sous-dossier et vous obtenez l'arbre de ce sous-dossier. La réponse est de lancer depuis la racine du projet, là où vous feriez `go build` et `git` de toute façon. ## Pourquoi `.git` est masqué et rien d'autre Le dialogue Open masque toute entrée commençant par un point. Recopier cela ici était la chose évidente, et aurait été faux. `.turbo-python/settings.toml` est un fichier que cet éditeur demande aux gens d'éditer — c'est la raison d'être de la coloration TOML. `.gitignore` et `.qlty/qlty.toml` sont eux aussi des fichiers du projet. Un arbre qui les cacherait rendrait la configuration de l'éditeur inaccessible depuis l'explorateur de fichiers de l'éditeur, ce qui est un endroit curieux où aboutir. `.git` diffère par nature et non par orthographe : rien à l'intérieur n'est fait pour être ouvert à la main, et il contient assez d'objets pour enterrer tout le reste dans la liste. Un seul nom, masqué pour une raison énonçable. Respecter aussi `.gitignore` a été envisagé et écarté pour l'instant : cela masquerait `bin/` et `release/`, ce qui serait réellement plus agréable, et cela coûte un moteur de motifs gitignore — négations, `**`, ancrage — qui est une fonctionnalité à part entière plutôt qu'un détail d'arbre. ## Pourquoi une fenêtre, pas un panneau Tous les autres éditeurs mettent leur arbre de fichiers dans une bande fixe à gauche. C'était l'alternative, et elle a été écartée à cause de ce qu'elle aurait coûté au reste de l'éditeur. Un panneau ancré signifie que le bureau n'est plus un simple rectangle où vivent les fenêtres. `Desktop` aurait besoin d'une notion de bords réservés ; `Window.fitInto` et les modes de croissance devraient les respecter ; agrandir voudrait dire « tout le bureau sauf le panneau » ; la mise en mosaïque et en cascade devraient en tenir compte. C'est une modification des fondations de toute l'interface, pour un seul widget. En fenêtre ordinaire, l'arbre obtient tout gratuitement et se comporte comme le reste : `F6` l'atteint, `Alt-2` le remonte, `[x]` le ferme, `[■]` lui donne tout le bureau, **Window ▸ Tile** le met à côté de votre fichier. Rien dans `ui` n'a eu à changer. Si un panneau ancré est voulu plus tard, c'est une fonctionnalité de `ui` à concevoir pour elle-même, plutôt qu'à faire passer en douce avec un explorateur de fichiers. ## Pourquoi il n'y en a qu'un Deux arbres sur le même projet seraient deux vues d'une même chose sans rien pour les distinguer, et le projet ne peut pas changer pendant que l'éditeur tourne — la racine est fixée au démarrage. `F9` sur un arbre ouvert le remonte donc au lieu d'en créer un autre, exactement comme ouvrir un fichier déjà ouvert remonte sa fenêtre. ## Pourquoi il ne surveille pas le disque Un arbre qui remarquerait `go build` produisant `bin/` serait meilleur. Le faire correctement signifie surveiller le système de fichiers, et en Go cela signifie `fsnotify` — une troisième dépendance, contre un projet qui s'en tient à deux depuis le début et qui traite l'ajout d'une dépendance comme une décision à défendre. Ce n'est pas non plus une petite dépendance en comportement : surveillances récursives, descripteurs épuisés sur les grosses arborescences, et une sémantique différente sur chaque plateforme — pour une fonctionnalité dont le mode d'échec est une ligne périmée dans une liste. L'arbre relit donc à la demande, et l'éditeur choisit les moments dont il peut être sûr. Enregistrer un fichier en est un : c'est l'éditeur qui l'a fait, il le sait donc. `F5` et `Ctrl-R` sont l'autre, parce qu'une compilation dans une fenêtre terminal est quelque chose que seul l'utilisateur sait terminée. Le rafraîchissement conserve la forme de l'arbre et ne relit que les dossiers réellement ouverts : il coûte ce qui est à l'écran, pas un parcours du projet. ## Pourquoi l'arbre a ses propres clés de thème L'économie évidente était de le dessiner avec les clés `list.*` — un arbre est une liste, après tout, et cela n'aurait ajouté aucune clé que les thèmes utilisateur puissent manquer. Cela ne marche pas, et la raison mérite d'être consignée. `list.selected` est colorée pour ressortir sur un **dialogue**. Dans `turbo-classic` c'est blanc sur navy, et `window.body` est silver sur **navy** — un arbre dans une fenêtre aurait surligné sa ligne sélectionnée exactement dans la couleur de fond sur laquelle elle repose. La sélection aurait été invisible dans le thème que l'éditeur livre par défaut. D'où `tree.text`, `tree.directory`, `tree.selected` et `tree.unfocused`, et un test qui tient chaque thème livré à un contraste minimal entre la première et la troisième, de la même façon que les couleurs du curseur sont vérifiées. Un thème utilisateur qui n'en définit aucune retombe le long des points sur `default` : un arbre lisible, sans la distinction fichier/dossier, plutôt que rien du tout. ## Liens avec le reste - Toutes les touches et toutes les règles, exactement : [Référence de l'arbre du projet](../reference/project-tree.md) - L'utiliser : [Parcourir un projet et ouvrir des fichiers depuis un arbre](../how-to/browse-a-project.md) - L'autre endroit où « le projet » est défini de la même façon : [Réglages de projet](project-settings.md) - Où `filetree` se situe parmi les paquets : [Architecture](architecture.md)