13. Édition interactive des entrées et substitution d’historique
****************************************************************

Certaines versions de l’interpréteur Python prennent en charge
l’édition de la ligne d’entrée courante et la substitution
d’historique, similaires aux facilités que l’on trouve dans le shell
Korn et dans le shell GNU Bash. C’est implémenté en utilisant la
bibliothèque GNU Readline, qui supporte l’édition en style Emacs et en
style Vi. La bibliothèque a sa propre documentation qui ne va pas être
dupliquée ici ; toutefois, les bases seront expliquées rapidement.
L’éditeur interactif et la gestion d’historique décrits ici sont
disponibles en option sous les versions Unix et Cygwin de
l’interpréteur.

Ce chapitre *ne décrit pas* les possibilités d’édition du paquet
PythonWin de Mark Hammond ou de l’environnement basé sur Tk, IDLE,
distribué avec Python. Le rappel d’historique des lignes de commandes
qui fonctionne dans des fenêtres DOS sous NT ou d’autres variétés de
Windows est encore une autre histoire.


13.1. Édition de ligne
======================

Si elle est supportée, l’édition de la ligne d’entrée est active
lorsque l’interpréteur affiche une invite primaire ou secondaire. La
ligne courante peut être éditée en utilisant les caractères de
contrôles traditionnels d’Emacs. Les plus importants d’entre eux sont
: "C-A" (Contrôle-A) déplace le curseur au début de la ligne, "C-E" à
la fin, "C-B" d’un caractère vers la gauche, "C-F" d’un caractère vers
la droite. La touche retour arrière efface le caractère à la gauche du
curseur, "C-D" le caractère à sa droite. "C-K" supprime le reste de la
ligne à la droite du curseur, "C-Y" rappelle la dernière chaîne
supprimée. "C-tiret bas" annule la dernière modification ; cette
commande peut être répétée pour cumuler ses effets.


13.2. Substitution d’historique
===============================

La substitution d’historique fonctionne comme ceci. Toutes les lignes
non vides reçues sont enregistrées dans un tampon d’historique et, à
chaque fois qu’une invite est affichée, vous êtes positionné sur une
nouvelle ligne à la fin de ce tampon. "C-P" remonte d’une ligne (en
arrière) dans ce tampon, "C-N" descend d’une ligne. Chaque ligne
présente dans le tampon d’historique peut être éditée ; un astérisque
apparaît en face de l’invite pour indiquer qu’une ligne a été
modifiée. Presser la touche "Entrée" envoie la ligne en cours à
l’interpréteur. "C-R" démarre une recherche incrémentale en arrière ;
"C-S" démarre une recherche en avant.


13.3. Raccourcis clavier
========================

Les raccourcis clavier ainsi que d’autres paramètres de la
bibliothèque Readline peuvent être personnalisés en inscrivant des
commandes dans un fichier d’initialisation appelé "~/.inputrc". Les
raccourcis sont de la forme

   key-name: function-name

ou :

   "string": function-name

et les options peuvent être définies avec

   set option-name value

Par exemple :

   # I prefer vi-style editing:
   set editing-mode vi

   # Edit using a single line:
   set horizontal-scroll-mode On

   # Rebind some keys:
   Meta-h: backward-kill-word
   "\C-u": universal-argument
   "\C-x\C-r": re-read-init-file

Notez que le raccourci par défaut pour la touche "Tab" en Python est
d’insérer un caractère de tabulation au lieu de la fonction par défaut
de complétion des noms de fichiers de la bibliothèque Readline. Si
vous y tenez, vous pouvez surcharger ce comportement en indiquant

   Tab: complete

dans votre fichier "~/.inputrc" (bien sûr, avec cela il devient plus
difficile d’entrer des lignes de continuation indentées si vous êtes
habitué à utiliser "Tab" dans ce but).

La complétude automatique des noms de variables et de modules est
disponible de manière optionnelle. Pour l’activer dans le mode
interactif de l’interpréteur, ajoutez les lignes suivantes à votre
fichier de démarrage : [1]

   import rlcompleter, readline
   readline.parse_and_bind('tab: complete')

Ceci lie la touche "Tab" à la fonction de complétude, donc taper la
touche "Tab" deux fois de suite suggère les options disponibles ; la
recherche s’effectue dans les noms d’instructions Python, les noms des
variables locales et les noms de modules disponibles. Pour les
expressions pointées telles que "string.a", l’expression est évaluée
jusqu’au dernier "'.'" avant de suggérer les options disponibles à
partir des attributs de l’objet résultant de cette évaluation. Notez
bien que ceci peut exécuter une partie du code de l’application si un
objet disposant d’une méthode "__getattr__()" fait partie de
l’expression.

Un fichier de démarrage plus complet peut ressembler à cet exemple.
Notez que celui-ci supprime les noms qu’il crée dès qu’ils ne sont
plus nécessaires ; ceci est possible car le fichier de démarrage est
exécuté dans le même espace de noms que les commandes interactives, et
supprimer les noms évite de générer des effets de bord dans
l’environnement interactif. Vous pouvez trouver pratique de conserver
certains des modules importés, tels que "os", qui s’avère nécessaire
dans la plupart des sessions avec l’interpréteur.

   # Add auto-completion and a stored history file of commands to your Python
   # interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
   # bound to the Esc key by default (you can change it - see readline docs).
   #
   # Store the file in ~/.pystartup, and set an environment variable to point
   # to it:  "export PYTHONSTARTUP=~/.pystartup" in bash.

   import atexit
   import os
   import readline
   import rlcompleter

   historyPath = os.path.expanduser("~/.pyhistory")

   def save_history(historyPath=historyPath):
       import readline
       readline.write_history_file(historyPath)

   if os.path.exists(historyPath):
       readline.read_history_file(historyPath)

   atexit.register(save_history)
   del os, atexit, readline, rlcompleter, save_history, historyPath


13.4. Alternatives à l’interpréteur interactif
==============================================

Cette facilité constitue un énorme pas en avant comparé aux versions
précédentes de l’interpréteur. Toutefois, il reste des fonctions à
implémenter comme l’indentation correcte sur les lignes de
continuation (l’analyseur sait si une indentation doit suivre) ; le
mécanisme de complétion devrait utiliser la table de symboles de
l’interpréteur. Une commande pour vérifier (ou même suggérer) les
correspondances de parenthèses, de guillemets…, serait également
utile.

Une alternative améliorée de l’interpréteur interactif est développée
depuis maintenant quelques temps : IPython. Il fournit la complétion,
l’exploration d’objets et une gestion avancée de l’historique. Il peut
également être personnalisé en profondeur et embarqué dans d’autres
applications. Un autre environnement interactif amélioré similaire est
bpython.

-[ Notes ]-

[1] Python exécute le contenu d’un fichier identifié par la
    variable d’environnement "PYTHONSTARTUP" lorsque vous démarrez un
    interpréteur interactif. Pour personnaliser Python y compris en
    mode non interactif, consultez Modules de personnalisation.
