# Outils d'édition avancée

## Commenter / Décommenter

Les commandes Commenter et Décommenter, disponibles dans le menu Outils, permettent d'ajouter ou de supprimer des indicateurs de commentaires à la sélection ou à la ligne actuelle, s'il n'y a pas de texte sélectionné et si le format du texte qu'on modifie prend en charge les commentaires.

Les règles qui régissent la façon de créer des commentaires étant établies dans les définitions de syntaxe, l'ajout/la suppression de commentaires n'est pas possible si la coloration syntaxique n'est pas activée.

Certains formats définissent des indicateurs de commentaire sur une seule ligne, d'autres sur plusieurs lignes et d'autres encore, les deux. Si les indicateurs sur plusieurs lignes ne sont pas disponibles, il n'est pas possible de commenter une sélection qui ne contient pas la totalité de sa dernière ligne.

Si un indicateur de commentaire sur une seule ligne est disponible, le commentaire ligne par ligne aura la préférence là où il est applicable, car ce comportement contribue à éviter des problèmes avec les commentaires imbriqués.

Lorsqu'on supprime des indicateurs de commentaire, il ne faut pas sélectionner de texte non commenté. Lorsqu'on supprime des indicateurs de commentaire sur plusieurs lignes d'une sélection, tout espace en dehors des indicateurs de commentaire est ignoré.

Pour placer des indicateurs de commentaire, cliquez sur la ligne de menu Outils Commenter ou le raccourci clavier correspondant, par défaut &Ctrl;#.

Pour supprimer des indicateurs de commentaire, cliquez sur la ligne de menu Outils Décommenter ou le raccourci clavier correspondant, par défaut &Ctrl;&Maj;#.

## La ligne de commande du composant éditeur

Le composant éditeur de &kate; offre une ligne de commande interne permettant d'effectuer diverses actions à partir d'une interface graphique minimale. La ligne de commande est un élément de texte situé au bas de la zone d'édition. Pour la voir, cliquez sur Affichage Afficher la ligne de commande ou utilisez le raccourci clavier (par défaut, F7). L'éditeur fournit un ensemble de commandes comme décrit ci-dessous. Des commandes additionnelles peuvent être fournies par des modules externes.

Pour exécuter une commande, saisissez cette dernière, puis appuyez sur la touche Entrée. La ligne de commande indique si elle a abouti et affiche éventuellement un message. Si vous avez saisi la ligne de commande en appuyant sur F7, elle disparaît automatiquement au bout de quelques secondes. Pour effacer le message et saisir une nouvelle commande, appuyez sur F7 à nouveau.

La ligne de commande est dotée d'un système d'aide intégré : exécutez la commande `help` pour démarrer. Pour afficher une liste de toutes les commandes disponibles, saisissez `help list`. Pour afficher l'aide concernant une commande donnée, saisissez `help `commande``.

Comme la ligne de commande comporte un historique intégré, vous pouvez réutiliser les commandes déjà saisies. Pour parcourir l'historique, utilisez les touches Haut et Bas. Lorsque vous affichez l'historique des commandes, la partie argument de la commande est sélectionnée, ce qui permet d'écraser aisément les arguments.

### Commandes standard de la ligne de commande

#### Commandes pour configurer l'éditeur

Ces commandes sont fournies par le composant éditeur et permettent de configurer le document actif et son affichage uniquement. Ce comportement est pratique si vous voulez employer un autre paramètre que ceux par défaut, par exemple pour l'indentation.

#### Types d'arguments

BOOLÉEN

- On emploie cet argument avec les commandes qui servent à (dés)activer tel ou tel élément. Les valeurs admises sont `on`, `off`, `true`, `false`, `1` ou `0`

ENTIER

- Un nombre entier

CHAÎNE

- Une chaîne de caractères

    set-tab-widthENTIER largeur

- Associe la largeur de tabulation au nombre `largeur`

    set-indent-widthENTIER largeur

- Associe la largeur d'indentation au nombre `largeur`. Utilisé seulement si vous indentez avec des espaces.

    set-word-wrap-columnENTIER largeur

- Associe la largeur de ligne pour le retour à la ligne forcé à `largeur`. Utilisé si vous avez choisi le retour à la ligne automatique pour votre texte.

    set-icon-borderBOOLÉEN activer

- Définit la visibilité de la bordure d'icônes.

    set-folding-markersBOOLÉEN activer

- Définit la visibilité de la bordure des indicateurs de pliage.

    set-line-numbersBOOLÉEN activer

- Définit la visibilité du panneau des numéros de ligne.

    set-replace-tabsBOOLÉEN activer

- Si cette option est cochée, les tabulations sont remplacées par des espaces au fur et à mesure que vous saisissez au clavier.

    set-remove-trailing-spaceBOOLÉEN activer

- Si cette option est cochée, les espaces de fin sont supprimés chaque fois que le curseur change de ligne.

    set-show-tabsBOOLÉEN activer

- Si cette option est cochée, les caractères de tabulation et l'espace de fin de ligne seront représentés par un petit point.

    set-indent-spacesBOOLÉEN activer

- Si cette option est cochée, l'éditeur indente avec des espaces `indentation-largeur` pour chaque niveau d'indentation plutôt qu'avec un caractère de tabulation.

    set-mixed-indentBOOLÉEN activer

- Si cette option est cochée, &kate; utilise un mélange de tabulations et d'espaces pour l'indentation. Chaque niveau d'indentation aura une largeur `indentation-largeur` et d'autres niveaux d'indentation seront optimisés pour pouvoir utiliser autant de caractères de tabulation que possible.

  Lorsqu'elle est exécutée, cette commande définit en outre l'indentation avec des espaces activée et, si la largeur d'indentation n'est pas spécifiée, elle est définie à la moitié de la `tab-width` du document au moment de l'exécution.

    set-word-wrapBOOLÉEN largeur

- Active le retour à la ligne dynamique en fonction de `activer`

    set-replace-tabs-saveBOOLÉEN activer

- Si cette option est cochée, les tabulations sont remplacées par un blanc à chaque fois que le document est enregistré.

    set-remove-trailing-space-saveBOOLÉEN activer

- Lorsque cette option est cochée, l'espace de fin est supprimé de chaque ligne à chaque fois que le document est enregistré.

    set-indent-modenom

- Définit le mode d'indentation automatique à `nom`. Si `nom` n'est pas connu, le mode est associé à « none ». Les modes autorisés sont « cstyle », « csands », « xml », « python », « varindent » et « none ».

    set-highlightcoloration syntaxique

- Définit le système de coloration syntaxique pour le document. L'argument doit être un nom de coloration syntaxique autorisé, comme on le voit dans le menu Outils Coloration syntaxique. Cette commande fournit une liste de complétement automatique pour son argument.

#### Commandes d'édition

Ces commandes modifient le document actuel.

    indent

- Indente les lignes sélectionnées ou la ligne actuelle.

    unindent

- Désindente les lignes sélectionnées ou la ligne actuelle.

    cleanindent

- Nettoie l'indentation des lignes sélectionnées ou de la ligne actuelle en fonction des paramètres d'indentation du document.

    comment

- Insère des indicateurs de commentaire pour créer sur la sélection, les lignes sélectionnées ou la ligne actuelle, un commentaire en fonction du format du texte, comme défini par la coloration syntaxique concernant le document.

    uncomment

- Supprime les indicateurs de commentaires de la sélection, des lignes sélectionnées ou de la ligne actuelle en fonction du format du texte, comme défini par la définition de la coloration syntaxique concernant le document.

    kill-line

- Supprime la ligne actuelle.

    replacemotifremplacement

- Remplace le texte correspondant au `motif` par `remplacement`. Si vous voulez ajouter un blanc dans le `motif`, vous devez entourer d'apostrophes ou de guillemets à la fois le `motif` et le `remplacement`. Si les arguments n'ont pas de guillemets, le premier mot sert de `motif` et le reste de `remplacement`. Si `remplacement` est vide, chaque occurrence de `motif` est supprimée.

  Vous pouvez définir des drapeaux pour configurer la recherche, en ajoutant un caractère « : » (deux points), suivi d'une ou plusieurs lettres représentant une configuration, ce qui donne la forme `replace:options motif remplacement`. Les options disponibles sont les suivantes :

  `b`

- Recherche arrière.

`c`

- Recherche à partir de la position du curseur.

`e`

- Recherche dans la sélection uniquement.

`r`

- Recherche sur des expressions rationnelles. Si défini, vous pouvez utiliser `\N`, où N est un nombre représentant des captures dans la chaîne de remplacement.

`s`

- Recherche sensible à la casse.

`p`

- Invite de permission pour remplacer la prochaine occurrence.

`w`

- Correspondance de mots entiers uniquement.

    dateformat

- Insère une chaîne date/heure comme défini par le format spécifié `format` ou le format « aaaa-MM-jj hh:mm:ss », si aucun n'est indiqué. Les traductions suivantes sont effectuées lors de l'interprétation de `format` :

  `d` | Le jour sous la forme d'un nombre sans zéro de début (1-31).
  `dd` | Le jour sous la forme d'un nombre avec un zéro de début (01-31).
  `ddd` | Le nom abrégé du jour localisé (par exemple 'Lun'..'Dim').
  `dddd` | Le nom entier du jour localisé (par exemple 'Lundi'..'Dimanche').
  `M` | Le mois sous la forme d'un nombre sans zéro de début (1-12).
  `MM` | Le mois sous la forme d'un nombre avec un zéro de début (01-12).
  `MMM` | Le nom abrégé du mois localisé (par exemple 'Jan'..'Déc').
  `aa` | L'année sous la forme d'un nombre à deux chiffres (00-99).
  `aaaa` | L'année sous la forme d'un nombre à quatre chiffres (1752-8000).
  `h` | L'heure sans zéro de début (0..23 ou 1..12 en cas d'affichage AM/PM).
  `hh` | L'heure avec un zéro de début (00..23 ou 01..12 en cas d'affichage AM/PM).
  `m` | La minute sans zéro de début (0..59).
  `mm` | La minute avec un zéro de début (00..59).
  `s` | La seconde sans zéro de début (0..59).
  `ss` | La seconde avec un zéro de début (00..59).
  `z` | Les millisecondes sans zéro de début (0..999).
  `zzz` | Les millisecondes avec des zéros de début (000..999).
  `AP` | Utiliser l'affichage AM/PM. AP sera remplacé soit par « AM », soit par « PM ».
  `ap` | Utiliser l'affichage. ap sera remplacé soit par « am », soit par « pm ».

    charidentifiant

- Cette commande permet d'insérer des caractères spéciaux par leur identifiant numérique, sous forme décimale, octale ou hexadécimale. Pour l'utiliser, ouvrez la boîte de dialogue Commandes d'édition, et saisissez `char: [numéro]` dans la zone de saisie, puis cliquez sur Ok.

  ##### Exemples avec `char`

  Entrée : `char:234`

  Sortie : `ê`

  Entrée : `char:0x1234`

  Sortie : `ሴ`

`s///[ig]` `%s///[ig]`

- Cette commande effectue une opération de recherche / remplacement comme sed dans la ligne actuelle, ou dans tout le fichier (`%s///`).

  En bref, on recherche dans le texte une expression qui correspond au texte recherché, l'expression rationnelle entre la première et la deuxième barre oblique. Lorsqu'une correspondance est trouvée, la partie de texte correspondant est remplacée par l'expression située entre la partie du milieu et la dernière partie de la chaîne. Les parenthèses dans le motif de recherche créent des références arrière, c'est-à-dire que la commande se souvient quelle partie du motif correspondait dans les parenthèses ; ces chaînes peuvent être réutilisées dans le motif de remplacement, référencées par `\1` pour la première paire de parenthèses, `\2` pour la deuxième, etc.

  Pour rechercher une `(` ou une `)`, vous devez la faire précéder d'une barre oblique inverse, qui joue le rôle de caractère d'échappement : `\(\)`

  Si vous placez un `i` à la fin de l'expression, l'expression correspondante sera insensible à la casse. Si vous placez un `g` à la fin, toutes les occurrences du motif seront remplacées, sinon seule la première occurrence est remplacée.

  ##### Remplacer du texte dans la ligne actuelle

  Votre compilateur préféré vient de s'arrêter en vous indiquant que la classe `maClasse` mentionnée à la ligne 3902 de votre fichier source n'est pas définie.

  Il s'agit évidemment de `MaClasse` ! Allez à la ligne 3902 et, au lieu d'essayer de trouver le mot dans le texte, ouvrez la boîte de dialogue Commande d'édition, saisissez `s/maClasse/MaClasse/i`, cliquez sur le bouton Ok, enregistrez le fichier et compilez – avec succès, sans l'erreur.

  ##### Remplacer du texte dans le fichier entier

  Imaginez que vous avez un fichier dans lequel vous mentionnez plusieurs fois « Mlle Dupont » lorsque quelqu'un vient vous informer qu'elle vient de se marier avec « M. Martin ». Vous voulez, bien évidemment, remplacer chaque occurrence de « Mlle Dupont » par « Mme Martin ».

  Sur la ligne de commande, saisissez `%s/Melle Dupont/Mme Martin/` et appuyez sur Entrée. Vous avez terminé.

  ##### Un exemple plus avancé

  Cet exemple utilise les références arrière ainsi qu'une classe de caractères (si vous ne savez pas de quoi il s'agit, consultez la documentation relative à ce sujet mentionnée ci-dessous).

  Supposons que vous ayez la ligne suivante :

      void MyClass::DoStringOps( String      &foo, String &bar String *p, int  &a, int &b )

  Maintenant, vous vous rendez compte que ces lignes ne donnent pas du code élégant et que vous voulez utiliser le mot clé `const` pour tous les arguments « adresse de », ceux caractérisés par l'opérateur & avant le nom d'argument. Vous voulez aussi simplifier les espaces,pour qu'il n'y ait qu'un caractère d'espacement entre les mots.

  Ouvrez la boîte de dialogue « Commande d'édition » et saisissez : `s/\s+(\w+)\s+(&)/ const \1 \2/g`, puis cliquez sur le bouton Ok. Le `g` à la fin de l'expression fait recompiler l'expression rationnelle pour chaque occurrence, pour enregistrer les références arrière.

  Sortie : `void MyClass::DoStringOps( const String &foo, const String &bar String *p, const int &a, const int &b )`

  Mission réussie ! Mais que s'est-il passé ? Nous avons recherché des blancs (`\s+`), suivis d'un ou plusieurs caractères alphabétiques (`\w+`), eux-mêmes suivis d'un autre blanc (`\s+`) suivi d'une esperluette. Le processus a enregistré le fragment alphanumérique et l'esperluette pour le réutiliser lors de l'opération de remplacement. Puis, nous avons remplacé la partie correspondante de la ligne par un blanc suivi de « const », suivi d'un blanc, suivi de notre fragment alphanumérique enregistré (`\1`), lui-même suivi d'un blanc et de notre esperluette enregistrée (`\2`)

  Maintenant, comme dans certains cas, le fragment alphanumérique était « String » et dans d'autres « int », l'utilisation de la classe de caractères `//w` et du quantificateur `+` a été un grand avantage.

#### Commandes de navigation

    gotoENTIER ligne

- Cette commande permet d'aller jusqu'à la ligne spécifiée.

    findmotif

- Cette commande permet d'aller à la première occurrence de `motif`, en fonction de la configuration. Vous pouvez trouver les occurrences suivantes à l'aide de Édition Poursuivre la recherche (le raccourci par défaut est F3).

  Il est possible de configurer la commande Chercher en ajoutant à la fin un caractère « : », suivi d'une ou plusieurs options. La forme est `find:options motif`. Les options suivantes sont prises en charge :

  `b`

- Recherche arrière.

`c`

- Recherche à partir de la position du curseur.

`e`

- Recherche dans la sélection uniquement.

`r`

- Recherche sur des expressions rationnelles. Si défini, vous pouvez utiliser `\N`, où N est un nombre représentant des captures dans la chaîne de remplacement.

`s`

- Recherche sensible à la casse.

`w`

- Correspondance de mots entiers uniquement.

    ifindmotif

- Cette commande fournit une recherche au fur et à mesure de la saisie (« as-you-type »). On peut configurer le comportement ou la recherche en ajoutant à la fin un caractère « : », suivi d'une ou plusieurs options, comme suit : `ifind:options motif`. Les options autorisées sont

  `b`

- Recherche arrière.

`r`

- Effectue une recherche sur des expressions rationnelles.

`s`

- Recherche sensible à la casse.

`c`

- Recherche à partir de la position du curseur.

## Utiliser le pliage du code

Le pliage du code permet de cacher des parties d'un document dans l'éditeur, ce qui facilite l'affichage de la vue d'ensemble de documents volumineux. Dans &kate;, les régions pliables sont calculées à l'aide de règles définies dans les définitions de coloration syntaxique, et le pliage du code n'est donc disponible que dans certains formats - en général le code source du programme, le marquage XML et similaires. La plupart des définitions de coloration syntaxique prenant en charge le pliage du code permet également de définir manuellement des régions pliables, en général à l'aide des mots clés `DÉBUT` et `FIN`.

Pour utiliser la fonctionnalité de pliage du code, activez les marqueurs suivants à l'aide de l'élément de menu Affichage Afficher les indicateurs de pliage s'ils ne sont pas déjà visibles. Le panneau des indicateurs de pliage du côté gauche de l'écran affiche une vue graphique des régions pliables, avec des signes +/- pour indiquer l'opération possible sur une région donnée : un - signifie que la région est dépliée. Un clic sur - replie la région et sur + sera affiché à la place.

Quatre commandes sont prévues pour manipuler l'état des régions de pliage. Consultez la documentation du menu.

Si vous ne voulez pas employer la fonctionnalité de pliage du code, vous pouvez désactiver l'option Afficher les indicateurs de pliage (si disponible) dans la page Apparence de la configuration de l'éditeur.

## Étendre &kate; avec des scripts

Depuis la version 3.4 de &kate; présente dans KDE 4.4, on peut facilement étendre le composant éditeur de &kate; en écrivant des scripts. Le langage de scriptage utilisé est ECMAScript (bien connu sous le nom de JavaScript). &kate; prend en charge deux sortes de scripts : les scripts d'indentation et les scripts de ligne de commande.

### Scripts d'indentation

Scripts d'indentation - également appelés indenteurs - indentent automatiquement le code source au fil de la saisie du texte. À titre d'exemple, après avoir appuyé sur la touche Entrée, le niveau d'indentation augmente en principe.

Les sections suivantes décrivent étape par étape comment créer le squelette d'un indenteur simple. Premièrement, créez un nouveau fichier `*.js` appelé par exemple `javascript.js` dans votre dossier personnel local `$KDEHOME/share/apps/katepart/script`.

#### L'en-tête du script d'indentation

L'en-tête du fichier `javascript.js` est intégré dans un commentaire et se présente sous la forme suivante

    /* kate-script
     * name: JavaScript
     * author: Exemple de nom <exemple.nom@une.adresse.org>
     * license: BSD
     * revision: 1
     * kate-version: 3.4
     * type: indentation
     * required-syntax-style: javascript
     * indent-languages: javascript
     * priority: 0
     *
     * Une ligne sans « : » arrête l'analyse syntaxique de l'en-tête. On peut donc ajouter ici
     * du texte facultativement, comme une licence détaillée.
     */

Chaque ligne est expliquée en détail ci-après :

- `kate-script` [requis] : la chaîne de texte doit apparaître dans la première ligne du fichier `*.js`, sinon &kate; ignore le script.

- `name` [requis] : le nom de l'indenteur qui apparaît dans le menu Outils Indentation et dans la boîte de dialogue de configuration.

- `author` [optionnel] : le nom de l'auteur et les informations de contact.

- `license` [optionnel] : la forme abrégée de la licence, comme BSD ou LGPLv3.

- `revision` [requis] : la révision du script. Ce nombre devra être augmenté à chaque fois que le script est modifié.

- `kate-version` [requis] : version de &kate; minimale nécessaire.

- `type` [requis] : le type doit être `indentation`, sinon &kate; ignore ce script.

- `required-syntax-style` [optionnel] : liste séparée par une virgule des styles de coloration syntaxique requis. Ce paramètre est important pour les indenteurs qui s'appuient sur des informations de coloration syntaxique spécifique dans le document. Si un style de syntaxe requis est spécifié, l'indenteur est disponible uniquement quand l'outil de coloration syntaxique est actif. On empêche ainsi un comportement indéfini causé par l'emploi de l'indenteur sans le schéma de coloration syntaxique attendu. Par exemple, l'indenteur de Ruby l'utilise dans les fichiers `ruby.js` et `ruby.xml`.

- `indent-languages` [optionnel] : liste séparée par une virgule de styles de coloration syntaxique que l'indenteur peut indenter correctement, ex. : c++, java.

- `priority` [optionnel] : si plusieurs indenteurs sont adaptés pour un certain fichier mis en surbrillance, la priorité décide de l'indenteur choisi comme indenteur par défaut.

&kate; lit toutes les paires de la forme `clé`:`valeur` jusqu'à ce qu'il ne puisse plus trouver de « : ». Cette fonction implique que l'en-tête puisse contenir du texte arbitraire tel qu'une licence comme le montre l'exemple.

#### Le code source de l'indenteur

Après avoir spécifié l'en-tête, cette section explique comment fonctionne le scriptage d'indentation lui-même. Voici à quoi ressemble le squelette de base du corps :

    triggerCharacters = "{}/:;";
    function indent(line, indentWidth, ch)
    {
        // appelé pour chaque nouvelle ligne (ch == '\n') et tous les caractères spécifiés dans
        // la variable globale triggerCharacters. Lorsqu'on appelle OutilsAligner,
        // la variable ch est vide, c'est-à-dire ch == ''.
        //
        // voir également : API de scriptage
        return -2;
    }

La fonction `indent()` comporte trois paramètres :

- `line` : la ligne à indenter

- `indentWidth` : la largeur d'indentation dans la quantité d'espaces

- `ch` : soit un caractère de saut de ligne (`ch == '\n'`), le caractère déclencheur spécifié dans `triggerCharacters` ou vide si l'utilisateur a exécuté l'action Outils Aligner.

La valeur de retour de la fonction `indent()` spécifie de combien la ligne sera indentée. Si la valeur de retour est un nombre entier simple, il est interprété comme suit :

- valeur de retour `-2` : ne rien faire

- valeur de retour `-1` : conserver l'indentation (chercher s'il existe une ligne précédente non vide)

- valeur de retour `0` : les nombres >= 0 spécifient la profondeur d'indentation en espaces

Autrement, un tableau de deux éléments peut être retourné :

- `return [ indent, align ];`

Dans ce cas, le premier élément est la profondeur d'indentation comme ci-dessus, avec la même signification des valeurs spéciales. Cependant, le second élément est une valeur absolue représentant une colonne pour alignement. Si la valeur est supérieure à la valeur d'indentation, la différence représente un nombre d'espaces à ajouter après l'indentation du premier paramètre. Sinon, le second nombre est ignoré. L'utilisation de tabulations et d'espaces pour l'indentation est souvent dénommée mode mixte.

Voyons l'exemple suivant : supposons qu'on utilise des tabulations pour indenter et que la largeur des tabulations soit définie à 4. Ici, <tab> représente une tabulation et « . » un espace :

    1: <tab><tab>exemple("bonjour",
    2: <tab><tab>......."monde");

Lorsqu'on indente la ligne 2, la fonction `indent()` retourne [8, 15]. Par conséquent, deux tabulations sont insérées pour indenter dans la colonne 8, et 7 espaces sont ajoutés pour aligner le second paramètre sous le premier, pour qu'il reste aligné si le fichier est visualisé avec une largeur de tabulation différente.

Une installation KDE par défaut fournit &kate; avec plusieurs indenteurs. Le code source JavaScript correspondant se trouve dans `$KDRDIR/share/apps/katepart/script`.

Le développement d'un indenteur nécessite de recharger les scripts pour vérifier si les changements se comportent convenablement. Au lieu de redémarrer l'application, passez simplement sur la ligne de commande et exécutez la commande `reload-scripts`.

Si vous développez des scripts utiles, vous pourriez envisager de contribuer au Projet &kate; en contactant la liste de diffusion.

### Scripts de ligne de commande

Comme il est difficile de satisfaire les besoins de chacun, &kate; prend en charge de petits outils d'aide permettant une manipulation rapide du texte par le biais de la ligne de commande intégrée. Par exemple, la commande `sort` est implémentée comme script. Cette section explique comment créer des fichiers `*.js` pour étendre &kate; avec des scripts d'aide arbitraires.

Les scripts de ligne de commande se trouvent dans le même dossier que les scripts d'indentation. Ainsi, la première étape consiste à créer un nouveau fichier `*.js` appelé `myutils.js` dans le dossier personnel local `$KDEHOME/share/apps/katepart/script`.

#### L'en-tête du script de ligne de commande

L'en-tête de chaque script de ligne de commande est intégré dans un commentaire et se présente sous la forme suivante

    /* kate-script
     * author: Exemple de nom <exemple.nom@une.adresse.org>
     * license: BSD
     * revision: 1
     * kate-version: 3.4
     * type: commands
     * functions: sort, format-paragraph
     *
     * Une ligne sans « : » arrête l'analyse syntaxique de l'en-tête. On peut donc ajouter ici
     * du texte facultativement, comme une licence détaillée.
     */

Chaque ligne est expliquée en détail ci-après :

- `kate-script` [requis] : la chaîne de texte doit apparaître dans la première ligne du fichier `*.js`, sinon &kate; ignore le script.

- `author` [optionnel] : le nom de l'auteur et les informations de contact.

- `license` [optionnel] : la forme abrégée de la licence, comme BSD ou LGPLv3.

- `revision` [requis] : la révision du script. Ce nombre devra être augmenté à chaque fois que le script est modifié.

- `kate-version` [requis] : version de &kate; minimale nécessaire.

- `type` [requis] : le type doit être `commands`, sinon &kate; ignore ce script.

- `functions` [requis] : liste séparée par une virgule de commandes dans le script.

&kate; lit toutes les paires de la forme `clé`:`valeur` jusqu'à ce qu'il ne puisse plus trouver de « : ». Cette fonction implique que l'en-tête puisse contenir du texte arbitraire tel qu'une licence comme le montre l'exemple. La valeur des fonctions clés est une liste séparée par une virgule de commandes en ligne de commande. Cela signifie qu'un seul script contient une quantité arbitraire de commandes en ligne de commande. Chaque fonction est disponible par le biais de la ligne de commande intégrée de &kate;.

#### Le code source du script

Toutes les fonctions spécifiées dans l'en-tête doivent être implémentées dans le script. Par exemple, le fichier de script tiré de l'exemple ci-dessus doit implémenter les deux fonctions `sort` et `format-paragraph`. Toutes les fonctions ont la syntaxe suivante :

    function <name>(arg1, arg2, ...)
    {
        // ... implémentation, voir également : API de scriptage
    }

Les arguments dans la ligne de commande sont passés à la fonction sous la forme `arg1`, `arg2`, etc. Pour pouvoir fournir de la documentation pour chaque commande, implémentez simplement la fonction « `help` » comme suit :

    function help(cmd)
    {
        if (cmd == "sort") {
            return "Trier le texte sélectionné.";
        } else if (cmd == "...") {
            // ...
        }
    }

Exécuter `help sort` dans la ligne de commande appelle alors cette fonction d'aide avec l'argument `cmd` associé à la commande indiquée, c'est-à-dire `cmd == "sort"`. &kate; présente ensuite le texte obtenu sous forme de documentation à l'utilisateur.

Le développement d'un script de ligne de commande nécessite de recharger les scripts pour vérifier si les changements se comportent convenablement. Au lieu de redémarrer l'application passez simplement dans la ligne de commande et exécutez la commande `reload-scripts`.

Si vous développez des scripts utiles, vous pourriez envisager de contribuer au Projet &kate; en contactant la liste de diffusion.

### API de scriptage

L'API de scriptage présentée ici est disponible dans tous les scripts, c'est-à-dire l'indentation de scripts et les commandes en ligne de commande. Avant de charger le contenu d'un script, &kate; ajoute d'abord plusieurs prototypes et fonctions au contexte de scriptage. Cette API de commodité contient des prototypes comme les curseurs de texte ainsi que des plages de texte, et se trouve dans le dossier `$KDEDIR/share/apps/katepart/api`. Là, les noms des fichiers de chaque fichier JavaScript se conforme au schéma natif de nommage :

    <nombre>_<nom>.js

Le nombre comprend deux chiffres, et le nom est un nom arbitraire tel que `mesoutils`. Grâce à ce nombre, &kate; contrôle l'ordre d'exécution de l'API. Autrement dit, le fichier appelé `05_cursor.js` est appelé avant le fichier `10_range.js` (ce comportement est similaire à l'ordre de démarrage du système de niveau d'exécution/d'initialisation sous Linux).

Pour étendre l'API de scriptage standard avec ses propres fonctions et prototypes, il suffit de créer un nouveau fichier dans le dossier de configuration local de KDE `$KDEHOME/share/apps/katepart/api` et de vérifier qu'il possède un nombre supérieur (ordre d'exécution) aux autres fichiers `*.js` dans le dossier global `$KDEDIR/share/apps/katepart/api`. &kate; cherche automatiquement les fichiers `*.js` dans les deux dossiers et les exécute dans l'ordre correct.

Pour étendre les prototypes existants comme `Cursor` ou `Range`, la méthode recommandée consiste à ne pas modifier les fichiers `*.js` globaux. À la place, créez un fichier `*.js` dans le dossier local, qui est exécuté plus tard que le `05_cursor.js` puis changez le prototype `Cursor` en JavaScript.

#### Curseurs et intervalles

Comme &kate; est un éditeur de texte, toute l'API de scriptage repose sur des curseurs et des intervalles dans la mesure du possible. Un curseur est un tuple `(line, column)` simple représentant une position du texte dans le document. Un intervalle étend du texte à partir de la position du curseur de début vers une position de curseur de fin. L'API est expliquée en détail dans les sections suivantes.

##### Le prototype de curseur

    Cursor();

- Constructeur. Retourne un curseur à la position `(0, 0)`.

  Exemple : `var cursor = new Cursor();`

    Curseur(int ligne, int colonne);

- Constructeur. Retourne un curseur à la position (ligne, colonne).

  Exemple : `var cursor = new Cursor(3, 42);`

    Cursor(Cursor autre);

- Constructeur de copie. Retourne une copie du curseur `autre`.

  Exemple : `var copy = new Cursor(autre);`

    Cursor Cursor.clone();

- Retourne un clone du curseur.

  Exemple : `var clone = cursor.clone();`

    bool Cursor.isValid();

- Vérifiez si le curseur est valable ou non. Le curseur n'est pas valable si la ligne et/ou la colonne sont associées à `-1`.

  Exemple : `var valid = cursor.isValid();`

    Cursor Cursor.invalid();

- Retourne un nouveau curseur non valable situé à `(-1, -1)`.

  Exemple : `var invalidCursor = cursor.invalid();`

    int Cursor.compareTo(Cursor autre);

- Compare ce curseur au curseur `autre`. Retourne

  - `-1`, si le curseur se trouve avant le curseur `autre`,

  - `0`, si les deux curseurs sont égaux et

  - `+1`, si ce curseur se trouve après le curseur `autre`.

    bool Cursor.equals(Cursor autre);

- Retourne `true`, si le curseur et le curseur `autre` sont égaux, sinon `false`.

    String Cursor.toString();

- Retourne le curseur ou une chaîne de la forme `Cursor(line, column)`.

##### Le prototype d'intervalle

    Range();

- Constructeur. Appeler `new Range()` retourne un intervalle à (0, 0) - (0, 0).

    Range(Cursor début, Cursor fin);

- Constructeur. Appeler `new Range(`début`, `fin`)` retourne l'intervalle (`début`, `fin`).

    Range(int ligneDébut, int colonneDébut, int ligneFin, int colonneFin);

- Constructeur. Appeler `new Range(`ligneDébut`, `colonneDébut`, `ligneFin`, `colonneFin`)` Retourne l'intervalle de (`ligneDébut`, `colonneDébut`) à (`ligneFin`, `colonneFin`).

    Range(Range autre);

- Constructeur de copie. Retourne une copie de l'intervalle Range `autre`.

    Range Range.clone();

- Retourne un clone de l'intervalle.

  Exemple : `var clone = range.clone();`

    bool Range.isValid();

- Retourne `true`, si les curseurs de début et de fin sont valables, sinon `false`.

  Exemple : `var valid = range.isValid();`

    bool Range.invalid();

- Retourne l'intervalle Range de (-1, -1) à (-1, -1).

    bool Range.contains(Cursor curseur);

- Retourne `true`, si cet intervalle contient la position du curseur, sinon `false`.

    bool Range.contains(Range autre);

- Retourne `true`, si l'intervalle contient l'intervalle Range contient `autre`, sinon `false`.

    bool Range.containsColumn(int colonne);

- Retourne `true`, si `colonne` est dans l'intervalle semi-ouvert `[start.column, end.column)`, sinon `false`.

    bool Range.containsLine(int ligne);

- Retourne `true`, si `ligne` est dans l'intervalle semi-ouvert `[start.line, end.line)`, sinon `false`.

    bool Range.overlaps(Range autre);

- Retourne `true`, si l'intervalle et l'intervalle `autre` partagent une région commune, sinon `false`.

    bool Range.overlapsLine(int ligne);

- Retourne `true`, si `ligne` est dans l'intervalle `[start.line, end.line]`, sinon `false`.

    bool Range.overlapsColumn(int colonne);

- Retourne `true`, si `colonne` est dans l'intervalle `[start.column, end.column]`, sinon `false`.

    bool Range.equals(Range autre);

- Retourne `true`, si cet intervalle et l'intervalle Range `autre` sont égaux, sinon `false`.

    String Range.toString();

- Retourne l'intervalle en tant que chaîne de la forme `Range(Cursor(line, column), Cursor(line, column))`.

#### Fonctions globales

    void debug(String texte);

- Affiche `texte` dans `stdout` dans la console lançant l'application.

#### L'API d'affichage

Dès l'instant où un script est exécuté, il existe une variable globale `view` représentant la vue de l'éditeur actif actuel. Voici une liste de toutes les fonctions View disponibles.

    Cursor view.cursorPosition()

- Retourne la position actuelle du curseur dans la vue.

    void view.setCursorPosition(int ligne, int colonne)
    void view.setCursorPosition(Cursor curseur)

- Retourne la position actuelle du curseur dans la vue.

    void view.setCursorPosition(int ligne, int colonne);
    void view.setCursorPosition(Cursor curseur);

- Associe la position actuelle du curseur soit à (ligne, colonne), soit au curseur donné.

    Cursor view.virtualCursorPosition();

- Retourne la position virtuelle du curseur avec chaque tabulation comptant la quantité correspondante d'espaces en fonction de la largeur de tabulation actuelle.

    void view.setVirtualCursorPosition(int ligne, int colonne);
    void view.setVirtualCursorPosition(Cursor curseur);

- Associe la position actuelle du curseur virtuel soit à (ligne, colonne), soit au curseur donné.

    String view.selectedText();

- Retourne le texte sélectionné. S'il n'y a pas de texte sélectionné, la chaîne retournée est vide.

    bool view.hasSelection();

- Retourne `true`, si la vue a sélectionné du texte, sinon `false`.

    Range view.selection();

- Retourne l'intervalle de texte sélectionné. L'intervalle retourné n'est pas valable s'il n'y a pas de texte sélectionné.

    void view.setSelection(Range intervalle);

- Associe le texte sélectionné à l'intervalle donné.

    void view.removeSelectedText();

- Supprime le texte sélectionné. Si la vue ne contient pas de texte sélectionné, ce paramètre ne fait rien.

    void view.selectAll();

- Sélectionne le texte entier dans le document.

    void view.clearSelection();

- Efface la sélection de texte sans supprimer le texte.

#### L'API du document

Dès l'instant où un script est exécuté, il existe une variable globale `document` représentant le dossier actif actuel. Voici une liste des fonctions Document disponibles.

    String document.fileName();

- Retourne le nom de fichier du document ou une chaîne vide pour les tampons de texte non enregistrés.

    String document.url();

- Retourne l'URL complet du document ou une chaîne vide pour les tampons de texte non enregistrés.

    String document.mimeType();

- Retourne le type MIME du document ou le type MIME `application/octet-stream` s'il est impossible de trouver un type MIME approprié.

    String document.encoding();

- Retourne l'encodage actuellement utilisé pour enregistrer le fichier.

    bool document.isModified();

- Retourne `true`, si le document contient des changements non enregistrés (modifiés), sinon `false`.

    String document.text();

- Retourne le contenu entier du document en une seule chaîne de texte. Les nouvelles lignes sont marquées avec le caractère de saut de ligne `\n`.

    String document.text(int ligneDébut, int colonneDepuis, int ligneVers, int colonneVers);
    String document.text(Cursor depuis, Cursor vers);
    String document.text(Range intervalle);

- Retourne le texte dans l'intervalle donné. Il est recommandé d'utiliser la version correspondant au curseur et à l'intervalle pour avoir une meilleure lisibilité du code source.

    String document.line(int ligne);

- Retourne la ligne de texte donnée sous la forme d'une chaîne. La chaîne est vide si la ligne demandée est en dehors de l'intervalle.

    String document.wordAt(int ligne, int colonne);
    String document.wordAt(Cursor curseur);

- Retourne le mot à la position donnée du curseur.

    String document.charAt(int ligne, int colonne);
    String document.charAt(Cursor curseur);

- Retourne le caractère la position donnée du curseur.

    String document.firstChar(int ligne);

- Retourne le premier caractère dans la `ligne` donnée, qui n'est pas un caractère d'espacement. Le premier caractère se trouve à la colonne 0. Si la ligne est vide ou ne contient que des caractères d'espacement, la chaîne retournée est vide.

    String document.lastChar(int ligne);

- Retourne le dernier caractère dans la `ligne` donnée, qui n'est pas un caractère d'espacement. Si la ligne est vide ou ne contient que des caractères d'espacement, la chaîne retournée est vide.

    bool document.isSpace(int ligne, int colonne);
    bool document.isSpace(Cursor curseur);

- Retourne `true`, si le caractère à la position donnée du curseur est un caractère d'espacement, sinon `false`.

    bool document.matchesAt(int ligne, int colonne, int ligne, String texte);
    bool document.matchesAt(Cursor curseur, String texte);

- Retourne `true`, si le `texte` donné concorde avec la position correspondante du curseur, sinon `false`.

    bool document.startsWith(int ligne, String texte, bool ignorerEspaces);

- Retourne `true`, si la ligne commence par `texte`, sinon `false`. L'argument `ignorerEspaces` contrôle si les caractères d'espacement de début sont ou non ignorés.

    bool document.endsWith(int ligne, String texte, bool ignorerEspaces);

- Retourne `true`, si la ligne se termine par `texte`, sinon `false`. L' argument `ignorerEspaces` contrôle si les caractères d'espacement sont ou non ignorés.

    bool document.setText(String texte);

- Définit le texte entier du document.

    bool document.clear();

- Supprime le texte entier dans le document.

    bool document.truncate(int ligne, int colonne);
    bool document.truncate(Cursor curseur);

- Tronque la ligne donnée à la colonne ou la position de curseur donnée. Retourne `true` en cas de succès ou `false`, si la ligne donnée ne fait pas partie de l'intervalle de document.

    bool document.insertText(int ligne, int colonne, int ligne, String texte);
    bool document.insertText(Cursor curseur, String texte);

- Insère le `texte` à la position donnée du curseur. Retourne `true` en cas de succès ou `false`, si le document est en mode lecture seule.

    bool document.removeText(int ligneDepuis, int colonneDepuis, int ligneVers, int colonneVers);
    bool document.removeText(Cursor depuis, Cursor vers);
    bool document.removeText(Range intervalle);

- Supprime le texte dans l'intervalle donné. Retourne `true` en cas de succès ou `false`, si le document est en mode lecture seule.

    bool document.insertLine(int ligne, String texte);

- Insère du texte dans la ligne donnée. Retourne `true` en cas de succès ou `false`, si le document est en mode lecture seule ou si la ligne n'est pas dans l'intervalle du document.

    bool document.removeLine(int ligne);

- Supprime la ligne de texte donnée. Retourne `true` en cas de succès ou `false`, si le document est en mode lecture seule ou si la ligne n'est pas dans l'intervalle du document.

    void document.joinLines(int ligneDébut, int ligneFin);

- Joint les lignes de `ligneDébut` à `ligneFin`. Deux lignes de texte consécutives sont toujours séparées par un seul espace.

    int document.lines();

- Retourne le nombre de lignes dans le document.

    int document.length();

- Retourne le nombre de caractères dans le document.

    int document.lineLength(int ligne);

- Retourna la longueur de la `ligne`.

    void document.editBegin();

- Démarre un groupe d'édition pour regrouper les opérations Annuler/Refaire. Veillez à toujours appeler `editEnd()` aussi souvent que vous appelez `editBegin()`. L'appel de `editBegin()` en interne utilise un compteur de référence, c'est-à-dire que cet appel peut être imbriqué.

    void document.editEnd();

- Termine un groupe d'édition. Le dernier appel de `editEnd()` (c'est-à-dire celui qui fait le pendant avec le premier appel de `editBegin()`) met fin à l'étape d'édition.

    int document.firstColumn(int ligne);

- Retourne la première colonne, contenant des caractères autres que des caractères d'espacement, dans la `ligne` donnée. S'il n'y a que des caractères d'espacement dans la ligne, la valeur de retour est `-1`.

    int document.lastColumn(int ligne);

- Retourne la dernière colonne, contenant des caractères autres que des caractères d'espacement, dans la `ligne` donnée. S'il n'y a que des caractères d'espacement dans la ligne, la valeur de retour est `-1`.

    int document.prevNonSpaceColumn(int ligne, int colonne);
    int document.prevNonSpaceColumn(Cursor curseur);

- Retourne la colonne, contenant des caractères autres que des caractères d'espacement, en commençant à la position donnée du curseur et en effectuant une recherche arrière.

    int document.nextNonSpaceColumn(int ligne, int colonne);
    int document.nextNonSpaceColumn(Cursor curseur);

- Retourne la colonne, contenant des caractères autres que des caractères d'espacement, en commençant à la position actuelle du curseur et en effectuant une recherche avant.

    int document.prevNonEmptyLine(int ligne);

- Retourne la prochaine ligne non vide, contenant des caractères autres que des caractères d'espacement, en effectuant une recherche arrière.

    int document.nextNonEmptyLine(int ligne);

- Retourne la prochaine ligne non vide, contenant des caractères autres que des caractères d'espacement, en effectuant une recherche avant.

    bool document.isInWord(String caractère, int attribut);

- Retourne `true`, si le `caractère` donné contenant l'`attribut` donné peuvent faire partie d'un mot, sinon `false`.

    bool document.canBreakAt(String caractère, int attribut);

- Retourne `true`, si le `caractère` donné contenant l'`attribut` donné est approprié pour encapsuler une ligne, sinon `false`.

    bool document.canComment(int attributDébut, int attributFin);

- Retourne `true`, si un intervalle commençant et se terminant par les attributs données est approprié pour être mis en commentaire, sinon `false`.

    String document.commentMarker(int attribut);

- Retourne l'indicateur de commentaires pour les commentaires à une seule ligne pour un `attribut` donné.

    String document.commentStart(int attribut);

- Retourne l'indicateur de commentaires pour le début des commentaires multilignes pour un `attribut` donné.

    String document.commentEnd(int attribut);

- Retourne l'indicateur de commentaires pour la fin des commentaires multilignes pour un `attribut` donné.

    int document.attribute(int ligne, int colonne);
    int document.attribute(Cursor curseur);

- Retourne l'attribut à la position donnée du curseur.

    bool document.isAttribute(int ligne, int colonne, int attribut);
    bool document.isAttribute(Cursor curseur, int attribut);

- Retourne `true`, si l'attribut à la position donnée du curseur est égal à `attribut`, sinon `false`.

    String document.attributeName(int ligne, int colonne);
    String document.attributeName(Cursor curseur);

- Retourne le nom de l'attribut sous la forme de texte lisible par l'utilisateur. Il est égal au nom `itemData` dans la fichier de coloration syntaxique.

    bool document.isAttributeName(int ligne, int colonne, String nom);
    bool document.isAttributeName(Cursor curseur, String nom);

- Retourne `true`, si le nom de l'attribut à une certaines position du curseur correspond au `nom` donné, sinon `false`.

    String document.variable(String clé);

- Retourne la valeur de la variable de document demandée `clé`. Si la variable de document n'existe pas, la valeur de retour est une chaîne vide.

    int document.firstVirtualColumn(int ligne);

- Retourne la colonne virtuelle du premier caractère autre qu'un caractère d'espacement dans la ligne donnée ou `-1`, si la ligne est vide ou ne contient que des caractères d'espacement.

    int document.lastVirtualColumn(int ligne);

- Retourne la colonne virtuelle du dernier caractère autre qu'un caractère d'espacement dans la ligne donnée ou `-1`, si la ligne est vide ou ne contient que des caractères d'espacement.

    int document.toVirtualColumn(int ligne, int colonne);
    int document.toVirtualColumn(Cursor curseur);

- Convertit la position de curseur réel donné à une position virtuelle de curseur.

    int document.fromVirtualColumn(int ligne, int colonneVirtuelle);
    int document.fromVirtualColumn(Cursor curseurVirtuel);

- Convertit la position de curseur virtuel donnée à une position de curseur réel.

    Cursor document.anchor(int ligne, int colonne, Char caractère);
    Cursor document.anchor(Cursor curseur, Char caractère);

- Cherche en arrière le caractère donné en commençant depuis le curseur donné. Par exemple, si « ( » est passée comme caractère, cette fonction retournera la position de la « ( » ouvrante. Ce compte de référence, c'est-à-dire les autres « (...) » est ignoré.

    Cursor document.rfind(int ligne, int colonne, String texte, int attribut = -1);
    Cursor document.rfind(Cursor curseur, String texte, int attribut = -1);

- Cherche en arrière le texte donné avec l'`attribut` approprié. L'argument `attribut` est ignoré s'il est associé à `-1`. Le curseur retourné n'est pas valable, s'il est impossible de trouver le texte.

    int document.defStyleNum(int ligne, int colonne);
    int document.defStyleNum(Cursor curseur);

- Retourne le style par défaut utilisé à la position donnée du curseur.

    bool document.isCode(int ligne, int colonne);
    bool document.isCode(Cursor curseur);

- Retourne `true`, si l'attribut à la position donnée du curseur n'est pas égale à tous les styles suivants : `dsComment`, `dsString`, `dsRegionMarker`, `dsChar`, `dsOthers`.

    bool document.isComment(int ligne, int colonne);
    bool document.isComment(Cursor curseur);

- Retourne `true`, si l'attribut du caractère à la position du curseur est `dsComment`, sinon `false`.

    bool document.isString(int ligne, int colonne);
    bool document.isString(Cursor curseur);

- Retourne `true`, si l'attribut du caractère à la position du curseur est `dsString`, sinon `false`.

    bool document.isRegionMarker(int ligne, int colonne);
    bool document.isRegionMarker(Cursor curseur);

- Retourne `true`, si l'attribut du caractère à la position du curseur est `dsRegionMarker`, sinon `false`.

    bool document.isChar(int ligne, int colonne);
    bool document.isChar(Cursor curseur);

- Retourne `true`, si l'attribut du caractère à la position du curseur est `dsChar`, sinon `false`.

    bool document.isOthers(int ligne, int colonne);
    bool document.isOthers(Cursor curseur);

- Retourne `true`, si l'attribut du caractère à la position du curseur est `dsOthers`, sinon `false`.