{"id":235183,"date":"2022-02-18T11:54:32","date_gmt":"2022-02-18T10:54:32","guid":{"rendered":"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/"},"modified":"2025-09-18T15:17:51","modified_gmt":"2025-09-18T14:17:51","slug":"dans-les-coulisses-de-fleet-presentation-detaillee-de-l-editeur","status":"publish","type":"fleet","link":"https:\/\/blog.jetbrains.com\/fr\/fleet\/2022\/02\/dans-les-coulisses-de-fleet-presentation-detaillee-de-l-editeur\/","title":{"rendered":"Dans les coulisses de Fleet, Partie II\u00a0\u2013 Pr\u00e9sentation d\u00e9taill\u00e9e de l&#8217;\u00e9diteur"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_17 counter-hierarchy ez-toc-transparent\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\">Sommaire<\/p>\n<\/p>\n<\/div>\n<nav>\n<ul class=\"ez-toc-list ez-toc-list-level-1\">\n<li class=\"ez-toc-page-1 ez-toc-heading-level-1\"><a class=\"ez-toc-link ez-toc-heading-1\" title=\"Un agr\u00e9gat de structures de donn\u00e9es\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#An_aggregate_of_data_structures\">Un agr\u00e9gat de structures de donn\u00e9es<\/a>\n<ul class=\"ez-toc-list-level-2\">\n<li class=\"ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-2\" title=\"Des cordes partout\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#Ropes_everywhere\">Des cordes partout<\/a>\n<ul class=\"ez-toc-list-level-4\">\n<li class=\"ez-toc-heading-level-4\">\n<ul class=\"ez-toc-list-level-4\">\n<li class=\"ez-toc-heading-level-4\"><a class=\"ez-toc-link ez-toc-heading-3\" title=\"&nbsp;\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#i\">&nbsp;<\/a><\/li>\n<\/ul>\n<\/li>\n<li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-4\" title=\"Arbres d'intervalle pour les widgets et autres.&nbsp;\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#Interval_trees_for_widgets_et_al\">Arbres d&#8217;intervalle pour les widgets et autres.&nbsp;<\/a><\/li>\n<li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-5\" title=\"Cordes pour les jetons et Arbre de syntaxe abstrait\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#Ropes_for_Tokens_and_the_Abstract_Syntax_Tree\">Cordes pour les jetons et Arbre de syntaxe abstrait<\/a><\/li>\n<li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-6\" title=\"Cordes pour le rendu&nbsp;\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#Ropes_for_Rendering\">Cordes pour le rendu&nbsp;<\/a><\/li>\n<\/ul>\n<\/li>\n<li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-7\" title=\"Remarque sur l'immutabilit\u00e9\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#A_note_on_immutability\">Remarque sur l&#8217;immutabilit\u00e9<\/a><\/li>\n<\/ul>\n<\/li>\n<li class=\"ez-toc-page-1 ez-toc-heading-level-1\"><a class=\"ez-toc-link ez-toc-heading-8\" title=\"En r\u00e9sum\u00e9\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/#Summary\">En r\u00e9sum\u00e9<\/a><\/li>\n<\/ul>\n<\/nav>\n<\/div>\n<p>Cet article fait partie d&#8217;une s\u00e9rie consacr\u00e9e \u00e0 la conception et au fonctionnement de Fleet, notre IDE nouvelle g\u00e9n\u00e9ration.<\/p>\n<ul>\n<li><a class=\"ek-link\" href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/01\/fleet-below-deck-part-i-architecture-overview\/\">Partie&nbsp;I \u2013 Vue d&#8217;ensemble de l&#8217;architecture<\/a><\/li>\n<li>Partie II \u2013 Pr\u00e9sentation d\u00e9taill\u00e9e de l&#8217;\u00e9diteur<\/li>\n<\/ul>\n<p>Le permier article de cette s\u00e9rie \u00e9tait consacr\u00e9 \u00e0 l&#8217;architecture de Fleet. Dans cette deuxi\u00e8me partie, nous allons parler des algorithmes et des structures de donn\u00e9es utilis\u00e9s au c\u0153ur de l&#8217;\u00e9diteur.<\/p>\n<h1 id=\"an-aggregate-of-data-structures\"><span id=\"An_aggregate_of_data_structures\" class=\"ez-toc-section\"><\/span>Un agr\u00e9gat de structures de donn\u00e9es<\/h1>\n<p>Regardez cette capture d&#8217;\u00e9cran de la fen\u00eatre de l&#8217;\u00e9diteur dans Fleet :<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231004\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/image-7.png\" alt=\"\" width=\"1126\" height=\"154\"><\/figure>\n<p>On y voit une ligne de texte dans laquelle les \u00e9l\u00e9ments de syntaxe sont mis en \u00e9vidence et un widget fournissant des informations sur les utilisations de la variable. Il est possible d&#8217;afficher ces informations de diff\u00e9rentes fa\u00e7ons, mais le probl\u00e8me avec les \u00e9diteurs est qu&#8217;ils ne sont pas en lecture seule. Les donn\u00e9es sont affich\u00e9es, mais peuvent aussi \u00eatre mises \u00e0 jour. Une op\u00e9ration simple, telle que la modification d&#8217;un nom de fonction, peut avoir un impact en cascade, notamment sur la mise en \u00e9vidence des \u00e9l\u00e9ments de syntaxe, les utilisations, et toute autre fonctionnalit\u00e9 accessible, telle que l&#8217;analyse statique ou la compilation \u00e0 la vol\u00e9e.&nbsp;<\/p>\n<p>Afin de pouvoir fournir la meilleure exp\u00e9rience possible, nous devons nous assurer que l&#8217;\u00e9dition du texte et la visualisation qui en d\u00e9coule soient aussi fluides que possible. Pour ce faire, il faut stocker et manipuler les donn\u00e9es de mani\u00e8re efficace. Ceci dit, il n&#8217;y a pas qu&#8217;une seule fa\u00e7on de stocker les donn\u00e9es. En fait, dans image ci-dessus, les donn\u00e9es sont stock\u00e9es de plusieurs fa\u00e7ons, en s&#8217;appuyant sur diff\u00e9rentes structures de donn\u00e9es, qui forment ensemble ce que nous appelons l&#8217;\u00e9diteur. En d&#8217;autres termes, l&#8217;\u00e9diteur peut \u00eatre consid\u00e9r\u00e9 comme un agr\u00e9gateur de structures de donn\u00e9es&nbsp;!<\/p>\n<p>Regardons de plus pr\u00e8s ses diff\u00e9rents \u00e9l\u00e9ments&nbsp;!<\/p>\n<h2 id=\"ropes-everywhere\"><span id=\"Ropes_everywhere\" class=\"ez-toc-section\"><\/span>Des cordes partout<\/h2>\n<p>Tous ceux d&#8217;entre vous qui ont l&#8217;habitude de manipuler de grandes quantit\u00e9s de texte savent que l&#8217;utilisation de cha\u00eenes (ou tableau de caract\u00e8res) pour les stocker n&#8217;est pas tr\u00e8s efficace. G\u00e9n\u00e9ralement, toute op\u00e9ration sur un tableau implique de devoir cr\u00e9er un autre tableau, plus grand ou plus petit, et \u00e0 copier le contenu de l&#8217;ancien tableau dans le nouveau. Cela n&#8217;a rien d&#8217;efficace.&nbsp;<\/p>\n<p>Une meilleure approche, qui est aussi plus standardis\u00e9e, consiste \u00e0 utiliser des <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rope_(data_structure)\" target=\"_blank\" rel=\"noopener\">structures de corde<\/a>. Ce type de donn\u00e9es abstrait stocke les cha\u00eenes dans les n\u0153uds feuilles d&#8217;un arbre.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231855\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/1_diagram-2x-1.png\" alt=\"\" width=\"1600\" height=\"832\"><\/figure>\n<\/p>\n<p>Chaque n\u0153ud feuille contient une cha\u00eene (voir la remarque ci-dessous) et sa longueur, appel\u00e9e poids. Chaque n\u0153ud interm\u00e9diaire contient \u00e9galement un poids qui correspond \u00e0 la somme de toutes les feuilles de son sous-arbre gauche.<\/p>\n<p class=\"has-background\" style=\"background-color: #e8e8e8;\"><em><strong>Remarque&nbsp;:<\/strong> le texte utilis\u00e9 sur les feuilles est un simple exemple et n&#8217;est pas repr\u00e9sentatif de la r\u00e9partition r\u00e9elle du texte dans Fleet.<\/em><\/p>\n<p>Dans l&#8217;exemple ci-dessus, si nous prenons le n\u0153ud contenant les caract\u00e8res <em>fun<\/em>, le d\u00e9compte affich\u00e9 par le n\u0153ud est 3 parce que la cha\u00eene a 3 caract\u00e8res. En remontant vers le n\u0153ud parent, la valeur reste 3, car la somme de tous les poids \u00e0 sa gauche est \u00e9gale \u00e0 3. En revanche, son parent affiche 19 car il s&#8217;agit de la somme des feuilles \u00e0 sa gauche, 3 et 16.&nbsp;<\/p>\n<p>Des actions courantes, telles que la recherche, l&#8217;ajout, le retrait ou la division de cha\u00eenes, peuvent \u00eatre effectu\u00e9es avec un niveau de complexit\u00e9 O(log N), o\u00f9 N correspond \u00e0 la longueur de la cha\u00eene. Les op\u00e9rations commencent par traverser un arbre et, \u00e9tant donn\u00e9 les informations des n\u0153uds, cela est plus rapide. Par exemple, si nous devons trouver un caract\u00e8re \u00e0 la position <em>i =<\/em> 30, nous commen\u00e7ons par le n\u0153ud, et si 30 est inf\u00e9rieur au poids du n\u0153ud (nombre de caract\u00e8res), nous passons \u00e0 gauche pour soustraire la valeur du poids de i (voir la remarque ci-dessous). Par contre, si <em>i <\/em>est sup\u00e9rieur, nous passons \u00e0 droite. Au fur et \u00e0 mesure que nous descendons et que la valeur de <em>i <\/em>diminue, lorsque nous atteignons un n\u0153ud feuille, le caract\u00e8re \u00e0 la position <em>i <\/em>de la cha\u00eene contenue par le n\u0153ud est le caract\u00e8re recherch\u00e9.&nbsp;<\/p>\n<h4><span id=\"i\" class=\"ez-toc-section\"><\/span>&nbsp;<\/h4>\n<p class=\"has-background\" style=\"background-color: #e8e8e8;\"><em><strong>Remarque&nbsp;: <\/strong>selon la mesure utilis\u00e9e, la soustraction peut ne pas \u00eatre l&#8217;op\u00e9ration requise. L&#8217;important est d&#8217;accumuler les mesures en suivant l&#8217;arbre vers le bas jusqu&#8217;au n\u0153ud voulu et de les comparer \u00e0 la cl\u00e9 que nous recherchons.&nbsp;<\/em><\/p>\n<p>Lors de l&#8217;insertion ou de la suppression de n\u0153uds dans la structure de corde de Fleet, nous utilisons un <a href=\"https:\/\/en.wikipedia.org\/wiki\/B-tree\" target=\"_blank\" rel=\"noopener\">arbre B<\/a> \u00e0 \u00e9quilibrage automatique. Nous commen\u00e7ons par lire des blocs de 64&nbsp;caract\u00e8res, et lorsque nous arrivons \u00e0 des blocs de 32 caract\u00e8res, nous cr\u00e9ons un n\u0153ud et commen\u00e7ons \u00e0 collecter des blocs pour un deuxi\u00e8me n\u0153ud. Chaque n\u0153ud a deux nombres&nbsp;: en plus du poids, nous stockons \u00e9galement le nombre de lignes (la combinaison des deux correspond \u00e0 ce que nous appelons <em>mesures<\/em>).&nbsp;<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231346\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/2_diagram-2x.png\" alt=\"\" width=\"1600\" height=\"528\"><\/figure>\n<p>En stockant le nombre de lignes, nous pouvons acc\u00e9der plus rapidement \u00e0 des positions sp\u00e9cifiques. Une autre caract\u00e9ristique de l&#8217;arborescence dans Fleet est que nous privil\u00e9gions la largeur \u00e0 la profondeur.&nbsp;<\/p>\n<h3 id=\"interval-trees-for-widgets-et-al\"><span id=\"Interval_trees_for_widgets_et_al\" class=\"ez-toc-section\"><\/span>Arbres d&#8217;intervalle pour les widgets et autres.&nbsp;<\/h3>\n<p>Comme nous l&#8217;avons vu plus haut, un fragment de code peut non seulement contenir du texte, mais aussi des \u00e9l\u00e9ments additionnels comme des <em>utilisations<\/em>.&nbsp;<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231015\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/image-8.png\" alt=\"\" width=\"1126\" height=\"154\"><\/figure>\n<p>Nous appelons cela des widgets, et il peut s&#8217;agir de widgets interlignes, tels que les widgets <em>Find Usages<\/em> ou <em>Run<\/em>, postlignes (par exemple, d\u00e9bogage des informations apparaissant apr\u00e8s la ligne de code) ou incrust\u00e9e (par exemple, suggestions de types pour les variables et les lambdas).&nbsp;<\/p>\n<p>Un widget en soi est simplement un \u00e9l\u00e9ment de balisage, et la structure de donn\u00e9es qui le contient est une variante des <a href=\"https:\/\/www.geeksforgeeks.org\/interval-tree\/\" target=\"_blank\" rel=\"noopener\">arbres d&#8217;intervalle<\/a>, dont la structure est comparable \u00e0 celle d&#8217;une corde. Dans les arbres d&#8217;intervalle, les n\u0153uds contiennent une plage et le poids correspond \u00e0 la valeur maximale des plages du sous-arbre.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231358\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/3_diagram-2x.png\" alt=\"\" width=\"1600\" height=\"704\"><\/figure>\n<p>Dans Fleet, chaque n\u0153ud contient un d\u00e9but et une fin relatifs des n\u0153uds enfants. Les feuilles, quant \u00e0 elles, contiennent un widget. Lors de l&#8217;\u00e9x\u00e9cution de requ\u00eates pour voir si un widget donn\u00e9 doit s&#8217;afficher en fonction de coordonn\u00e9es sp\u00e9cifiques, nous traversons l&#8217;arbre jusqu&#8217;\u00e0 ce que la plage croise celle que nous recherchons.&nbsp;<\/p>\n<p>Chose importante : les feuilles contiennent \u00e9galement l&#8217;ID du widget. Cela signifie qu&#8217;en suppl\u00e9ment des requ\u00eates portant sur les intersections d&#8217;une plage sp\u00e9cifique, il est \u00e9galement possible de d\u00e9terminer son emplacement quel que soit le widget.&nbsp;<\/p>\n<p>Une diff\u00e9rence par rapport \u00e0 un arbre d&#8217;intervalle standard est que Fleet permet aux n\u0153uds de se superposer. Cela peut rendre les recherches un peu moins efficaces, mais a pour avantage de cr\u00e9er des arbres \u00e9quilibr\u00e9s et d&#8217;avoir la possibilit\u00e9 de les mettre \u00e0 jour pendant la saisie.&nbsp;<\/p>\n<p>En compl\u00e9ment des widgets, les arbres d&#8217;intervalle de Fleet permettent \u00e9galement de suivre les carets, de mettre le texte en \u00e9vidence, et de cr\u00e9er des emplacements <em>\u00e9pingl\u00e9s<\/em> dans le texte que nous appelons des ancres.<\/p>\n<h3 id=\"ropes-for-tokens-and-the-abstract-syntax-tree\"><span id=\"Ropes_for_Tokens_and_the_Abstract_Syntax_Tree\" class=\"ez-toc-section\"><\/span>Cordes pour les jetons et Arbre de syntaxe abstrait<\/h3>\n<p>Lorsqu&#8217;on travaille sur du code source, on utilise normalement un arbre de syntaxe abstrait (AST), qu&#8217;il s&#8217;agisse d&#8217;un compilateur ou d&#8217;un \u00e9diteur. Un module analyse le code source et cr\u00e9e une s\u00e9rie de jetons. Ces jetons servent ensuite \u00e0 construire l&#8217;AST.&nbsp;<\/p>\n<p>Prenons le code suivant :<\/p>\n<p><code>fun compileBundles(ship: JpsModule, model: JpsModel, src: SrcBundles): DstBundles<\/code><\/p>\n<p>Il serait divis\u00e9 pour obtenir les jetons suivants :<\/p>\n<p><code>[fun][ ][compileBundles][(][ship][:][ ][JpsModule][,][ ][model][:][ ][JpsModel][,][ ][src][:][ ][SrcBundles][)][:][ ][DstBundles]<\/code><\/p>\n<p>o\u00f9 chaque jeton est repr\u00e9sent\u00e9 par des crochets (il est \u00e0 noter que les espaces vides sont \u00e9galement des jetons). Ces jetons servent ensuite \u00e0 cr\u00e9er l&#8217;AST correspondant.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231369\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/4_diagram-2x.png\" alt=\"\" width=\"1600\" height=\"608\"><\/figure>\n<p>L&#8217;AST est ensuite utilis\u00e9 dans diff\u00e9rents types d&#8217;op\u00e9rations, comme la mise en \u00e9vidence des \u00e9l\u00e9ments de syntaxe, l&#8217;analyse statique, etc. C&#8217;est une partie importante de l&#8217;IDE.&nbsp;<\/p>\n<p><em>\u00c0 ce sujet, si vous souhaitez voir comment du code peut \u00eatre converti en AST, essayez cet <\/em><a href=\"https:\/\/astexplorer.net\/\" target=\"_blank\" rel=\"noopener\"><em>explorateur d&#8217;AST en ligne<\/em><\/a><em> (qui est utilisable avec diff\u00e9rents langages).&nbsp;<\/em><\/p>\n<p>Au fur et \u00e0 mesure de la saisie dans l&#8217;\u00e9diteur, le texte change, ce qui signifie que les jetons changent aussi, et un nouvel AST doit \u00eatre cr\u00e9\u00e9 pour fournir les fonctionnalit\u00e9s ci-dessus.&nbsp;<\/p>\n<p>Dans Fleet, pour \u00e9viter de mettre \u00e0 jour l&#8217;AST directement, nous utilisons une structure de corde pour stocker les jetons dans des feuilles (en fait, seules les longueurs sont stock\u00e9es). Pour donner un exemple, la liste de jetons ci-dessus pourrait \u00eatre repr\u00e9sent\u00e9e par l&#8217;arborescence suivante :<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231380\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/5_diagram-2x.png\" alt=\"\" width=\"1600\" height=\"432\"><\/figure>\n<p>Lorsque l&#8217;utilisateur saisit quelque chose, par exemple un espace, l&#8217;arbre est mis \u00e0 jour (la longueur 1 est ajout\u00e9e sur la feuille la plus \u00e0 gauche, ce qui augmente d&#8217;autant le total sur ce chemin).<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-231391\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/02\/6_diagram-2x.png\" alt=\"\" width=\"1600\" height=\"432\"><\/figure>\n<p>La longueur du nouveau jeton s&#8217;ajoute sur la feuille concern\u00e9e, ce qui en retour met \u00e0 jour certains n\u0153uds de l&#8217;arbre pour ajuster le poids. L&#8217;analyseur re\u00e7oit ensuite une notification qui le force \u00e0 se mettre \u00e0 jour et \u00e0 analyser de nouveau l&#8217;AST. Ainsi, l&#8217;AST risque de ne pas \u00eatre enti\u00e8rement correct pendant une fraction de seconde, mais l&#8217;exp\u00e9rience utilisateur en termes d&#8217;\u00e9dition est bien meilleure car il y a tr\u00e8s peu de choses \u00e0 mettre \u00e0 jour.&nbsp;<\/p>\n<h3 id=\"ropes-for-rendering\"><span id=\"Ropes_for_Rendering\" class=\"ez-toc-section\"><\/span>Cordes pour le rendu&nbsp;<\/h3>\n<p>L&#8217;image ci-dessous est un autre exemple tir\u00e9 de l&#8217;\u00e9diteur, mais cette fois avec quelques \u00e9l\u00e9ments suppl\u00e9mentaires, notamment le widget des utilisations \u00e9tendu pour afficher les utilisations, les retours \u00e0 la ligne, et d&#8217;autres \u00e9l\u00e9ments comme les lignes verticales color\u00e9es dans la barre de d\u00e9filement.<\/p>\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/wXqgUrNtxzOqdwxikmtI_bYmCybYTHy3_yDB6rYyckmXk70lC5rvTul8_67JxxxqsWaS90CYaofSXdWtRgkJ3AFXgJL3NSEf7IToek3oVUtVHOUpMMuO5WMz5Dnk8OCng7pbGXxj-1.png\" alt=\"\"><\/figure>\n<p>Le rendu ci-dessus n\u00e9cessite non seulement de savoir quelle ligne sera affich\u00e9e pour une coordonn\u00e9e <em>Y<\/em> donn\u00e9e, mais aussi de prendre en compte tous les widgets et retours \u00e0 la ligne.&nbsp;<\/p>\n<p class=\"has-background\" style=\"background-color: #e8e8e8;\"><em><strong>Anecdote&nbsp;:<\/strong> l&#8217;\u00e9diteur rendu dans le widget des utilisations utilise les m\u00eames structures de donn\u00e9es sous-jacentes que celles que nous pr\u00e9sentons dans cet article. Pour les utilisations dans le m\u00eame fichier, les m\u00eames cordes sont utilis\u00e9es pour cr\u00e9er et restituer cet \u00e9diteur.<\/em><\/p>\n<p>Les informations sur le widget et les retours \u00e0 la ligne sont \u00e9galement stock\u00e9es dans une structure de type corde. Alors qu&#8217;avant les feuilles de l&#8217;arborescence contenaient la cha\u00eene et sa longueur, dans ce cas, les feuilles contiennent des objets <em>SoftLine<\/em>. Il s&#8217;agit de blocs de texte accompagn\u00e9s par les hauteurs qui sont consid\u00e9r\u00e9es comme des lignes visuelles. Dans ce cas, le poids des n\u0153uds (que nous appelons mesures) correspond \u00e0 la hauteur et la longueur des <em>SoftLine<\/em>. La hauteur est stock\u00e9e de fa\u00e7on \u00e0 pouvoir prendre en charge les requ\u00eates de la fen\u00eatre d&#8217;affichage. Cette hauteur est affect\u00e9e par les interlignes qu&#8217;elle contient. De plus, lorsque les retours \u00e0 la ligne sont activ\u00e9s, <em>SoftLines<\/em> n&#8217;\u00e9tablit pas une correspondance exacte ligne \u00e0 ligne et peut correspondre \u00e0 une plage de lignes.&nbsp;<\/p>\n<h2 id=\"a-note-on-immutability\"><span id=\"A_note_on_immutability\" class=\"ez-toc-section\"><\/span>Remarque sur l&#8217;immutabilit\u00e9<\/h2>\n<p>Il est important de signaler que Fleet a adopt\u00e9 l&#8217;immutabilit\u00e9. L&#8217;utilisation de fonctions pures et d&#8217;objets immuables offre de nombreux avantages. Les fonctions pures nous permettent non seulement de mieux raisonner sur le code, mais \u00e9galement de savoir que l&#8217;appel d&#8217;une fonction ne g\u00e9n\u00e9rera pas de modification impr\u00e9vue ou d&#8217;effet secondaire dans le reste du syst\u00e8me. En termes de donn\u00e9es, savoir qu&#8217;un objet est immuable signifie qu&#8217;il ne posera pas de probl\u00e8me au niveau des threads et qu&#8217;il n&#8217;y aura pas de situation de comp\u00e9tition en cas de tentative de mise \u00e0 jour. Pour les environnements multi-thread, cela pr\u00e9sente des avantages consid\u00e9rables.&nbsp;<\/p>\n<p>Ce principe d&#8217;immutabilit\u00e9 est \u00e9galement central pour les op\u00e9rations qui utilisent des structures de corde. Plus haut, nous avons vu comment mettre \u00e0 jour les n\u0153uds et les feuilles de l&#8217;arbre. Tout cela se fait de fa\u00e7on immuable&nbsp;: toute op\u00e9ration sur l&#8217;arbre produit une copie de l&#8217;arbre qui partage sa structure avec le pr\u00e9c\u00e9dent, \u00e0 l&#8217;exception de la racine du n\u0153ud qui doit \u00eatre modifi\u00e9e. Dans la mesure o\u00f9 les arbres sont g\u00e9n\u00e9ralement larges et peu profonds, les chemins sont tr\u00e8s courts. Si l&#8217;op\u00e9ration m\u00e8ne \u00e0 des n\u0153uds non r\u00e9f\u00e9renc\u00e9s, ces derniers sont nettoy\u00e9s de la m\u00e9moire.<\/p>\n<p>Cette approche est assez diff\u00e9rente de celle de la plateforme IntelliJ, pour laquelle nous utilisons des m\u00e9canismes de verrouillage de lecture-\u00e9criture pour la r\u00e9alisation de modifications.&nbsp;<\/p>\n<h1 id=\"summary\"><span id=\"Summary\" class=\"ez-toc-section\"><\/span>En r\u00e9sum\u00e9<\/h1>\n<p>Comme nous l&#8217;avons vu dans ce deuxi\u00e8me volet sur la conception de Fleet, un outil aussi simple qu&#8217;un \u00e9diteur servant \u00e0 saisir et \u00e0 lire du code peut s&#8217;av\u00e9rer \u00eatre une agr\u00e9gation complexe de diff\u00e9rentes structures de donn\u00e9es sous-jacentes, dont la plupart sont des cordes. Si vous souhaitez en apprendre plus sur les cordes, nous vous recommandons de lire la s\u00e9rie d&#8217;articles <a href=\"https:\/\/xi-editor.io\/docs\/rope_science_00.html\" target=\"_blank\" rel=\"noopener\">Rope Science<\/a>, qui a fortement influenc\u00e9 notre travail pour la conception de Fleet.&nbsp;<\/p>\n\n\n<p><em>Auteur de l&#8217;article original en anglais<\/em> :<\/p>\n\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/secure.gravatar.com\/avatar\/?s=200&#038;r=g\" width=\"200\" height=\"200\" alt=\"\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":813,"featured_media":231142,"comment_status":"closed","ping_status":"closed","template":"","categories":[89],"tags":[],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/fleet\/235183"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/fleet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/types\/fleet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/users\/813"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/comments?post=235183"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/fleet\/235183\/revisions"}],"predecessor-version":[{"id":633647,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/fleet\/235183\/revisions\/633647"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media\/231142"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/media?parent=235183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/categories?post=235183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/tags?post=235183"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/fr\/wp-json\/wp\/v2\/cross-post-tag?post=235183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}