Foire Aux Questions
Installation depuis les sources
La compilation se termine avec le message d'erreur "Cannot find file lablglade.cmxa". Qu'est-ce qui ne va pas ?
La version native de la bibliothèque LablGtk n'est pas installée. Vérifiez que vous avez aussi installé la version native quand vous avez installé LablGtk: dans le répertoire des sources de LablGtk, tapez
make opt install
La compilation se termine avec le message d'erreur "Cannot find file odoc_info.cmxa". Quel est le problème ?
La version native de la bibliothèque OCamldoc n'est pas installée. Vérifiez que vous l'avez installée quand vous avez installé OCaml: dans le répertoire des sources d'OCaml, tapez
make opt.opt install
Après la compilation et l'installation, il y a deux fichiers pour chaque outil, par exemple cameleon2.byte et cameleon2.opt. Quelle est la différence ?
Les fichiers .x sont les versions natives des outils, tandis que les fichiers .byte sont les versions bytecode.
A la fin de la commande "make", plusieurs avertissements sont affichés, comme "Warning: ... not found" ou encore "Warning: Tag ... not handled by this generator". C'est grave, docteur ?

Ce n'est pas grave, il s'agit de liens qui n'ont pu être faits dans la doc ou bien de tags dans les commentaires de doc qui sont utilisés dans d'autres générateurs ocamldoc mais non reconnus par celui utilisé pour la documentation HTML.

Pendant la compilation, l'erreur suivante survient: Unbound module Parsetree. Quelle en est la raison ?
Cette erreur survient quand l'option --with-ocaml-src-dir=directory a été passée au script configure. Cette option est utilisée pour indiquer où se trouvent les sources compilées d'OCaml. Ce répertoire n'est pas le répertoire où OCaml est installé, mais le répertoire où les sources d'OCaml on été décompressées et compilées. En particulier, si OCaml a été installé par un paquetage d'une distribution Linux, cette option ne peut pas être utilisée.
Chamo
Voici quelques questions et réponses à propos de Chamo et de son utilisation.
Utiliser du code OCaml et des commandes dans Chamo
On peut faire des scripts en OCaml pour Chamo (Chamo est "OCaml-scriptable"). Qu'est-ce que cela signifie ?

Cela signifie que vous pouvez configurer entièrement Chamo avec des bouts de code OCaml, de la même façon qu'il est possible de configurer Emacs avec du code Lisp. Il y a plusieurs façons de le faire. Par exemple, vous pouvez placer du code OCaml dans votre fichier ~/.cameleon2/chamo_init.ml. Ce fichier est évalué quand chamo.byte est lancé. Dans ce fichier, vous pouvez accéder à n'importe quelle partie de Chamo. Consulter la documentation de référence pour de l'information à propos de l'interface de programmation des modules disponibles.

Par exemple, pour afficher la boîte "à propos" au lancement, ajoutez simplement au fichier chamo_init.ml le code suivant:

Ed_window.show_about_dialog ();;

Le même effet peut être obtenu en appelant la commande "about" sans arguments. Pour faire cela depuis du code OCaml, vous pouvez utiliser la fonction Cam_commands.eval_command:

Cam_commands.eval_command "about";;

Une autre façon d'évaluer du code OCaml pour ajouter vos propres commandes ou n'importe quelle autre fonctionnalité est d'appeler la commande "eval". Quand elle est appelée sans argument, cette commande demande à l'utilisateur le code OCaml à évaluer. Si un argument est indiqué, il est évalué comme étant du code OCaml. Voir ici pour les détails à propos des commandes. Ainsi, mettre le code suivant dans votre fichier chamo_init.ml:

Cam_command.eval_command "eval \"let x = 1;;\"";;

a le même effet que mettre

let x = 1;;

Une autre façon d'apporter des modifications est d'utiliser l'option --use de la ligne de commande, pour indiquer un fichier contenant du code OCaml à évaluer au lancement de l'éditeur.

Du point de vue technique, l'exécutable chamo.byte inclut la bibliothèque OCaml toplevellib.cma qui offre les fonctions pour évaluer du code OCaml. Ensuite, quelques initialisations sont faites par le module Ed_eval pour indiquer à l'interprète de chercher les interfaces de modules dans les répertoires d'installation de cameleon2 et lablgtk2. Ceci est réalisé avec des directives #directory.

Toute la réponse ci-dessus est valable pour la version bytecode de Chamo (chamo.byte). Cela ne l'est pas pour la version native (chamo.x).

Que sont les commandes ?

Les commandes sont des fonctions associées à un nom. Le nom est une chaîne de caractères. Voir ici pour la façon de définir une commande. Les commandes peuvent accepter des paramètres qui sont également des chaînes de caractères. L'appel à une commande est donc une chaine de la forme command arg1 arg2 .... Les arguments sont optionnels. Certaines commandes demandent des arguments, d'autres non. Certaines commandes demandent elles-mêmes à l'utilisateur les arguments manquants.

Par défaut, les touches A-x (Alt-x) sont liées à la commande "prompt_command" qui utilise le minibuffer de la fenêtre active pour faire saisir à l'utilisateur une commande (nom et arguments). Le texte saisi est ensuite donné en paramètre à la commande "command" qui analyse son premier argument pour séparer le nom de la commande de ses arguments et lancer réellement la commande. La citation des arguments fonctionne de la même façon que dans le shell (avec des simples ou doubles guillemets).

Comment définir de nouvelles commandes ?

Les commandes sont définies en OCaml en utilisant les fonctions du module Cam_commands. Elles consistent en un nom, une liste de noms de paramètres, une description optionnelle pour le reste des paramètres et une fonction OCaml qui est appelée quand la commande est lancée. La fonction est du type string array -> unit. Les paramètres de la commande sont passés dans le tableau de chaînes. Les indications sur les noms des paramètres peuvent être utilisées par des fonctions de plus haut niveau pour demander à l'utilisateur les paramètres manquants, avec les noms de ces derniers pour que l'utilisateur sache quoi indiquer.

Voici un exemple de création d'une commande qui affiche le message indiqué par le premier argument, ou "Alert!" s'il n'y a pas d'argument:

let alert_message args =
  let message =
    if Array.length args < 1 then
      "Alert!"
    else
      Ed_misc.to_utf8 args.(0)
   in
   GToolbox.message_box "Alert message" message;;
let com = Cam_commands.create_com
   "alert_message" [| "Message to display" |] alert_message;;
Cam_commands.register com;;

Il est utile de nommer et rendre visible la fonction associée à la commande, de façon à pouvoir l'appeler directement dans du code OCaml, plutôt que d'appeler

Cam_commands.eval_command "alert_message my_message";;

ou

Cam_commands.launch_command "alert_message" [|"my_message"|];;

Bien sûr, appeler directement la fonction qui a été associée à la commande "alert_message" court-circuite la redéfinition éventuelle de la commande.

Il est également possible de compléter des commandes existantes, en ajoutant du code à exécuter avant ou après le code original d'une commande. Ceci se fait à l'aide des fonctions Cam_commands.register_before et Cam_commands.register_after. Par exemple, si nous voulons journaliser les messages d'alerte, nous pouvons utiliser un code comme

let log_message args =
  (* log the message(s) in the arguments *)
  ...
;;
Cam_commands.register_before
  (Cam_commands.create_com
     "alert_message" [|"Message to display"|] log_message);;
Quelles commandes sont disponibles ?

La liste des noms des commandes disponibles peut être obtenue avec Cam_commands.available_command_names (). Il est donc facile ensuite d'obtenir, pour chaque commande, les noms de ses paramètres:

let f name =
  let com = Cam_commands.get_com_or_fail name in
  print_string com.Cam_commands.com_name;
  Array.iter (fun s -> Printf.printf " (%s)" s) com.Cam_commands.com_args;
  (match com.Cam_commands.com_more_args with
     None -> ()
   | Some s -> Printf.printf " (%s...)" s
  );
  print_newline ()
;;
List.iter f (Cam_commands.available_command_names());;

Une convention de nommage est nécessaire pour garantir une certaine cohérence dans les noms de commandes. Pour l'instant, les noms des commandes générales ne sont pas préfixés. Les commandes relatives à un mode de la vue "sourceview" (par exemple le mode "ocaml") devraient être préfixées par le nom du mode (i.e. "ocaml_"). Les commandes relatives à une vue (comme "sourceview" ou "odoc") devraient être préfixées par le nom de la vue (i.e. "sourceview_" ou "odoc_"). La convention est de séparer les mots dans les noms de commandes par "_" et non "-".

Fichiers de configuration
Où sont stockés les fichiers de configuration de Chamo ?

Les fichiers de configuration globale de Chamo de chaque utilisateur sont stockés dans son répertoire ~/.cameleon2/ et leur nom commence par "chamo.". Les fichiers sont créés s'ils n'existent pas. Ils sont "lisibles par l'humain" avec une syntaxe à la OCaml.

Il y a également des fichiers de configuration "locaux", c'est-à-dire stockés dans le répertoire dans lequel Chamo a été lancé. Pour l'instant, on trouve:

  • Le fichier .chamo.sourceview.buffers qui contient la liste des fichiers ouverts dans la vue "sourceview", et la position du curseur dans chacun d'eux.
  • .chamo.layout.xml qui contient la description de l'arrangement de toutes les fenêtres ouvertes. Ce fichier est créé à la demande par la commande "store_layout". Quand Chamo est lancé et que ce fichier existe dans le répertoire courant, il est lu et les fenêtres et vues correspondantes sont recréées; de cette façon, vous pouvez restaurer les fenêtres et vues telles qu'elles étaient lors de la sauvegarde de l'état.
  • .chamo_init.ml qui est évalué par chamo.byte au lancement, après le fichier ~/.cameleon2/chamo_init.ml de l'utilisateur; il peut être utilisé pour ajouter des fonctionnalités ou modifier la configuration relativement à un répertoire particulier.
Wahou ! Il y a beaucoup de fichiers de configuration dans ~/.cameleon2/ !

En effet. Mais pas de panique, il y a une organisation logique à tout ça.

  • Dans chamo.core, vous trouverez quelques valeurs utilisées en interne par Chamo, comme l'encodage de caractères utilisé par défaut lors de la lecture et l'écriture des fichiers et la conversion depuis et vers UTF-8 (Gtk2 utilises UTF-8).
  • chamo.gui contient des options communes à toutes les fenêtres de Chamo, comme les raccourcis clavier.
  • chamo_init.ml est évalué quand chamo.byte est lancé; il contient du code source OCaml. C'est l'équivalent du fichier ~/.emacs d'Emacs.
  • chamo.views définit des options pour la gestion des vues, en particulier les associations entre noms de fichiers et vues à utiliser, ainsi que la vue à utiliser par défaut lors de l'ouverture d'un fichier.
  • chamo.odoc, chamo.sourceview et chamo.tdl contiennent respectivement les options des vues "odoc", "sourceview" et "tdl". Le nom standard du fichier de configuration d'une vue est donc chamo.<nom de la vue>.
  • Chaque mode disponible dans la vue "sourceview" a son propre fichier de configuration nommé chamo.sourceview.mode.<nom du mode>, par exemple chamo.sourceview.mode.ocaml ou chamo.sourceview.mode.changelog.
Vues
Que sont les vues ?

Les vues dans Chamo sont différentes façons d'éditer ou d'afficher des fichiers. La vue la plus souvent utilisée est "sourceview", qui permet l'édition de n'importe quel fichier de texte. Elle est basée sur GtkSourceView et offre l'accentuation des mots clés et autres éléments de syntaxe. D'autres vues sont disponibles pour certains types de fichiers:

  • la vue "odoc" peut être utilisée pour afficher et parcourir le contenu d'un fichier de dump généré par OCamldoc. Les fichiers qui y sont référencés peuvent être directement ouverts au bon endroit, en double-cliquant sur les éléments (modules, fonctions, ...) ou en cliquant sur le bouton droit pour choisir entre l'ouverture du fichier d'interface ou d'implémentation.
  • la vue "tdl" est dédiée à l'édition de "todo lists" au format utilisé par la bibliothèque TDL. Les groupes et les items sont représentés dans un arbre.

Les vues définissent également leur propre description de menu et raccourcis clavier. Quand une vue a le focus, les menus qu'elle décrit sont accessibles dans la barre de menu de la fenêtre qui contient la vue, et les raccourcis clavier de la vue sont gérés, en plus de ceux communs à toutes les fenêtres de Chamo.

Comment choisir quelle vue est utilisée pour éditer un fichier ?

Chamo n'a aucun moyen de deviner quelle vue vous souhaitez utiliser pour éditer un fichier. Il faut lui donner quelques indications. Ceci se fait dans le fichier ~/.cameleon2/chamo.views, dans l'option view_from_filename_patterns, sous forme de paires (expression régulière, nom de la vue). Les expressions régulières sont essayées les unes après les autres dans l'ordre indiqué pour voir si elles correspondent au nom du fichier à ouvrir. Quand l'une d'entre elles correspond, Chamo utilise la vue dont le nom est associé à l'expression pour ouvrir le fichier. Une vue par défaut peut être fixée avec l'option default_view. La valeur par défaut de default_view est "sourceview".

Le fichier est lu au lancement, il faut donc relancer Chamo si vous le modifiez, ou bien évaluer le code OCaml suivant pour recharger les valeurs des options:

Ed_view_rc.read();;

Les valeurs des options peuvent également être modifiées en utilisant du code OCaml. Référez-vous à la documentation de la bibliothèque Config_file pour manipuler les options. Par exemple, pour ajouter une nouvelle association entre une expression régulière (décrivant un nom de fichier) et un nom de vue, utilisez le code OCaml suivant (ici nous faisons en sorte que les fichiers ayant l'extension ".ocamldoc" soient ouverts avec la vue "odoc"):

let l = Ed_view_rc.filename_view_patterns#get in
Ed_view_rc.filename_view_patterns#set (("\\.*ocamldoc$", "odoc") :: l) ;;

Il est également possible de sauvegarder les valeurs des options, de la façon suivante:

Ed_view_rc.write ();;
Puis-je avoir quelques détails à propos de la vue "sourceview" ?

Cette vue peut être utilisée pour éditer n'importe quel fichier texte. Elle est basée sur la bibliothèque Gtk2 GtkSourceView. Comme dans Emacs, cette vue sépare les buffers des vues à l'écran. Un buffer peut donc être affiché dans plusieurs vues, et des buffers peuvent être présents mais non visibles. Il ne peut y avoir plusieurs buffers différents sur le même fichier. Comme Gtk2 utilise des chaînes de caractères encodées en UTF-8, le contenu des fichiers édités doit être converti en UTF-8 pour être utilisé dans un buffer, et converti de UTF-8 vers l'encodage initial du fichier quand il faut le sauvegarder. L'encodage utilisé par défaut est celui associé à la variable d'environnement "LOCALE", et si la conversion échoue, l'option default_charset du fichier ~/.cameleon2/chamo.core de l'utilisateur est utilisée. Si la conversion échoue encore, l'utilisateur est invité à indiquer l'encodage à utiliser parmi ceux trouvés sur la machine lors de la compilation de Chamo.

Demander à l'utilisateur un encodage quand l'utilisation de ceux par défaut échoue n'est pas encore implémenté.

Les opérations habituelles sur le texte sont accessibles par des commandes associées à des raccourcis clavier. Regardez dans votre fichier ~/.cameleon2/chamo.sourceview pour voir quelles commandes sont associées. Les commandes spécifiques à la vue "sourceview" commencent par "sourceview_".

L'accentuation de la syntaxe dans un buffer est effectuée par la bibliothèque GtkSourceView d'après le langage associé au buffer. Référez-vous à l'option language_mime_from_filename_patterns de votre fichier ~/.cameleon2/chamo.sourceview: il s'agit des associations entre nom de fichier (sous forme d'expressions régulières) et type mime. Le type mime est utilisé pour récupérer la description du langage définissant les éléments de syntaxe. Comme Chamo utilise le module Gtksv_utils, les styles des éléments de chaque langage sont partagés avec les autres applications utilisant ce module (par exemple Topcameleon). Les styles de la vue "sourceview" et de l'accentuation de la syntaxe de chaque langage peuvent être modifiés en utilisant la boîte de dialogue "Preferences" accessible par le menu "File/Preferences". Le mode d'accentuation de syntaxe utilisé dans un buffer est indiqué sous la vue affichant le buffer, entre crochets, à côté du nom de buffer et de la position du curseur (ligne, colonne).

Les buffers de la vue "sourceview" de Chamo peuvent également avoir un mode associé. Un mode est composé d'un nom, d'une description des menus à afficher et des raccourcis clavier à gérer quand la vue a le focus. Les associations entre nom de fichier (sous forme d'expressions régulières) et nom de mode sont définies dans l'option mode_from_filename_patterns du fichier de l'utilisateur ~/.cameleon2/chamo.sourceview. Ainsi, les commandes spécifiques à un mode sont disponibles même dans les buffers auxquels un autre mode est associé; un mode ne fait qu'ajouter des menus et des raccourcis clavier donnant accès aux commandes utiles dans un mode. Les options des modes, comme les raccourcis clavier, sont stockés (par convention) dans un fichier de configuration spécifique à chaque mode. Par exemple, les options du mode "ocaml" sont stockées dans le fichier de l'utilisateur ~/.cameleon2/chamo.sourceview.mode.ocaml.

Comment définir un nouveau mode de la vue "sourceview" ?

Cela se fait avec du code OCaml. Les modes sont représentés par des objets du type Ed_sourceview.mode. Ensuite, une instance de votre classe de mode doit être enregistrée avec Ed_sourceview.register_mode. Enfin, ajoutez une ou plusieurs associations entre des noms de fichiers (sous forme d'expressions régulières) et le nom de votre mode. Vous pouvez regarder le code d'un mode existant comme par exemple le mode ocaml (l'implémentation est ici, l'implémentation de la gestion du fichier de configuration est ).

Quels modes sont disponibles ?

Pour l'instant, il n'y a pas beaucoup de modes. En voici une liste, avec les commandes qu'ils fournissent à travers un raccourci clavier indiqué entre prenthèses:

  • "ocaml": 'ocaml_indent_line' (Tab), 'ocaml_indent_buffer' (C-x C-Tab), 'ocaml_switch_file' (C-x C-a), 'ocaml_display_type_annot' (A-t),
  • "makefile": 'sourceview_insert "\t"' (Tab),
  • "changelog": 'changelog_new_day_entry' (C-x a), 'sourceview_insert "\t"' (Tab).

Les contributions (nouveaux modes ou nouvelles commandes) sont les bienvenues!

Raccourcis clavier
Comment/où sont définis les raccourcis clavier ?
Il existe plusieurs ensembles de raccourcis clavier:
  • les raccourcis globaux à Chamo, utilisables dans toutes les fenêtres d'édition de Chamo, quelle que soit la vue active; ces raccourcis sont définis dans le fichier ~/.cameleon2/chamo.gui.
  • les raccourcis spécifiques à chaque type de vue; ces raccourcis sont définis dans le fichier ~/.cameleon2/chamo.VV est le nom d'une vue. Ainsi, les raccourcis des vues "sourceview" seront définis dans le fichier ~/.cameleon2/chamo.sourceview. Les raccourcis associés à un type de vue ne sont actifs que lorsque la vue active est de ce type.
  • les raccourcis spécifiques à un mode, dans une vue "sourceview"; ils ne sont actifs que lorsque ce mode est sélectionné dans la vue active; ils sont définis dans un fichier ~/.cameleon2/chamo.sourceview.mode.MM est le nom du mode en question, comme "ocaml".

Tous ces fichiers sont créés avec des valeurs par défaut s'ils n'existent pas au lancement de Chamo.

L'ensemble des raccourcis actifs est l'union des raccourcis globaux et des raccourcis de la vue active (avec éventuellement ceux du mode actif).

J'aimerais définir mes propres raccourcis clavier, mais je ne sais pas comment spécifier certaines touches comme "page up". Où trouver cette information ?

Les identifiants de touches utilisables dans les fichiers de configuration se trouvent dans le fichier source src/configwin_ihm/configwin_keys.ml, dans la valeur keysym_to_name. Vous devriez pouvoir trouver la chaine correspondant à une clé; par exemple, la touche "page up" peut être indiquée par la chaîne "Page_Up".

Comment connaître la liste des commandes disponibles auxquelles je peux associer un raccourci clavier ?

La plupart des commandes prédéfinies sont déjà liées à des raccourcis clavier, donc vous pouvez tout d'abord regarder dans les fichiers de configuration si vous trouvez la commande que vous cherchez. Si ce n'est pas le cas, vous pouvez exécuter la commande suivante dans une version bytecode de Chamo:

eval "Cam_commands.available_command_names ()"

Cette commande évalue l'expression OCaml entre guillemets, qui retourne une liste des noms des commandes enregistrées. La liste est affichée dans la fenêtre de sortie des évaluations OCaml.

Problèmes courants
Il y a une colorisation syntaxique étrange quand j'ouvre des fichiers de code OCaml dans Chamo.

Les sourceviews dans Chamo sont basées sur GtkSourceView 2.X, qui utilise des fichiers "language-specs" pour savoir ce qui doit être mis en valeur (mots-clés, commentaires, ...). L'installation de GtkSourceView 2.X inclut un tel fichier de description pour Objective-Caml. Malheureusement, il peut être mal adapté à vos habitudes de style. Par exemple, vous préférez peut-être avoir des styles différents pour les mots-clés de définition et pour les mots-clés d'expressions, ou vouloir que les entiers dans vos identifiants n'apparaissent pas dans le style des constantes entières. Dans ce cas, vous pouvez copier les fichiers ci-dessous dans votre répertoire ~/.mlgtksourceview2/:

  • ocaml.lang est une description alternative des éléments de syntaxe OCaml. Cette description s'appelle "OCaml" et diffère du style "Objective Caml" venant avec l'installation de GtkSourceView 2.X,
  • scheme_chamo.xml est un style gtksourceview2 nommé "Chamo" adapté aux éléments de styles OCaml définis dans le fichier ocaml.lang; vous pouvez le modifier à votre convenance. Pour l'activer, utilisez le menu Files/Preferences.
Quand j'ouvre un fichier, certains caractères sont mal affichés, comme s'il s'agissait d'un problème d'encodage. Comment sont gérés les encodages des fichiers ?

Par défaut, Chamo considère que les fichiers sont encodés dans le jeu de caractères indiqué dans le fichier ~/.cameleon2/chamo.core (la valeur par défaut à la création de ce fichier est ISO8859-1). Quand un fichier est ouvert, Chamo convertit son contenu vers de l'UTF-8 pour un affichage correct dans les fenêtres Gtk. Si vous souhaitez ouvrir un fichier qui est dans un autre encodage, vous pouvez utiliser la commande open_file_with_encoding qui permet d'indiquer l'encodage du fichier à ouvrir. Il est également possible de changer l'encodage utilisé par défaut en modifiant la valeur dans le fichier ~/.cameleon2/chamo.core.