Cameleon2: Frequently Asked Questions

make opt install
make opt.opt install
Nothing's wrong, these warnings are due to some cross-reference links which could not be made and some tags used by other ocamldoc generators, not recognized by the one used to produce the HTML documentation.
This means that you can fully customize Chamo with pieces of OCaml code,
the same way you can customize Emacs with lisp code. There are multiple ways to do so.
For example, you can place some code in your file ~/.cameleon2/chamo.init.ml.
This file is evaluated when chamo.byte is launched. In this file, you can access any part of Chamo.
Refer to the reference documentation
for information about the API of the available modules.
For example, to display the "about box" at launch time, simply add to chamo.init.ml the following code:
Ed_window.show_about_dialog ();;
The same effect could be achieved by calling the command "about" with no arguments. To do so from OCaml code, you can use the function Cam_commands.eval_command:
Cam_commands.eval_command "about";;
Another way to evaluate OCaml code to add your own command or whatever you want is to call the "eval" command. When called without argument, this command prompts the user for OCaml code to evaluate. If an argument is given, it is evaluated as OCaml code. See here for details on commands. So, putting the following code in your file chamo.init.ml:
Cam_command.eval_command "eval \"let x = 1;;\"";;
is the same as simply putting
let x = 1;;
Another way to perform some customization is to use the --use command line option to indicate a file containing OCaml code to evaluate at launch time.
From a technical point of view, the chamo.byte executable includes the toplevellib.cma OCaml library which offers functions to evaluate OCaml code. Then, some initializations are done by the module Ed_eval to make the interpreter look for modules interfaces in the cameleon2 and lablgtk2 directories detected during configuration. This is done by evaluating some #directory directives.
All the answer above is true for the bytecode version of Chamo (chamo.byte). It is false for the native code version (chamo.x).
Commands are functions associated to a name. The name is a string. See here about how to define a command. The commands can take parameters, which are strings too. The call to a command is then a string of the form: command arg1 arg2 .... Arguments are optional. Some commands require arguments, some don't. Some commands will prompt the user for missing arguments.
By default, the A-x (Alt-x) keys are bound to the "prompt_command" command which uses the minibuffer of the active window to make the user type in a command (name and arguments). Then the text entered is given to the "command" command which parses its first argument to separate the command name from arguments and really launches the command. Quoting of arguments works the same way as in the shell (with simple or double quotes).
Commands are defined in OCaml using the functions in module Cam_commands. They are composed of a name, a list of parameter names, an optional description for remaining parameters and the OCaml function which is called when the command is launched. This function is of type string array -> unit. The parameters of the command are passed in the string array. The indications about parameters names can be used by higher level functions to prompt the user for missing parameters, with the names of the parameters, so that the user knows what to enter.
Here is an example of the creation of a command which displays the message in the first argument, or "Alert!" if there is no 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;;
It is useful to name and make visible the function associated to the command, so that it is also directly available in OCaml code, rather than calling
Cam_commands.eval_command "alert_message my_message";;
or
Cam_commands.launch_command "alert_message" [|"my_message"|];;
Of course, calling directly the function which was first associated to the command "alert_message" will short-circuit any redefinition of the command.
It is also possible to complete existing commands, by adding some code to execute before or after the original code of a command. This is done with the functions Cam_commands.register_before and Cam_commands.register_after. For example, if we want alert messages to be logged, we could use something like
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);;
The list of available command names can be obtained with Cam_commands.available_command_names (). Then it is easy to obtain, for each command, the names of its parameters:
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());;
A naming convention is needed to get some consistency in command names. By now, general commands are not prefixed. The commands relative to a sourceview mode (for example the "ocaml" mode of the "sourceview" view) should be prefixed by the mode name (e.g. "ocaml_"). The commands relative to a view (like "sourceview" or "odoc") should be prefixed by the view name (e.g. "sourceview_" or "odoc_"). The convention is to separate words in command names by "_" and not "-".
The user's global configuration files of Chamo are stored in the ~/.cameleon2/ directory and are prefixed with "chamo.". The files are created if they don't exist. They are human readable with an OCaml-like syntax.
There are also "local" configuration files, that is files stored in the directory where Chamo was launched. By now, we can find:
Indeed. But don't panic, there's a logical organisation.
Views in Chamo are different ways to edit or display files. The most commonly used view in the "sourceview" view, which allows the edition of any text file. It is based on GtkSourceView and can highlight syntax elements. Other views are available for some kinds of files:
Views define also their own description of menus and key bindings. When a view has the input focus, the menus it describes are available in the menubar of the parent window of the view, and the key bindings it defines are handled, in addition to the key bindings common to all Chamo windows.
Chamo has no way to guess the view you want to use to edit a file. You have to give some indications. This is done in the file ~/.cameleon2/chamo.views, in option view_from_filename_patterns, by giving pairs (regular expression, view name). The regular expressions are tried in the given order to match the name of the file to open. When a regular expression matches, Chamo uses the view with the associated name to open the file. A default view is used when none of the regular expressions match the file name. The default view name can be set with option default_view. The default value of default_view is "sourceview".
This file is read at launch time, so you must restart Chamo if you modified it, or evaluate the following OCaml code to reload the values of options:
Ed_view_rc.read();;
Values of options can also be set using OCaml code. Refer to the documentation of the Config_file library
to manipulate the options.
For example, to add a new association between a filename pattern and a view name, use the
following OCaml code (here we add a pattern so that files with ".ocamldoc" extension are
open with the "odoc" view):
let l = Ed_view_rc.filename_view_patterns#get in
Ed_view_rc.filename_view_patterns#set (("\\.*ocamldoc$", "odoc") :: l) ;;It is also possible to store the values of options, this way:
Ed_view_rc.write ();;
This view can be used to edit any text file. It is based on the GtkSourceView
Gtk2 library.
As in Emacs, this view separates the buffers from the views on the screen. So a buffer
can be displayed in various views, and some buffers can be present but not visible.
There cannot be two different buffers on the same file. Since Gtk2 buffers uses UTF-8
strings, the contents of the edited files must be converted to UTF-8 when used in
a buffer and converted back to the file encoding when the file is saved. The default
encoding used is the one associated to the "LOCALE" environment variable, then if
it fails, the default_charset option of the user's ~/.cameleon2/chamo.core file is used. If it still fails, the user is prompted to choose an encoding among the ones
found on the system at configuration and compilation time.
Prompting the user to choose an encoding when the default ones fail is not yet implemented.
Common manipulations of text are allowed through commands and are bound to keys. Check your ~/.cameleon2/chamo.sourceview file for what commands are bound. Sourceview specific commands begin with "sourceview_".
Syntax highlighting in a buffer is made by the GtkSourceView library according to the language associated to the buffer. Check the language_mime_from_filename_patterns option of your file ~/.cameleon2/chamo.sourceview: these are the associations between filename patterns and mime types. Then, the mime type is used to retrieve the language specification defining syntax elements. Since Chamo uses the module Gtksv_utils, the styles of the elements of each language are shared with the other applications using this module (for example Topcameleon). Styles of the "sourceview" views and syntax highlighting can be modified using the "Preferences" box accessible from the menu "File/Preferences". The syntax mode of the buffer in a view is displayed between square brackets below the view, next to the buffer name and the line and column numbers.
Chamo sourceview buffers can also have an associated mode. A mode is composed of a name, a description of the menus to display and the keyboard bindings to handle when the view of the buffer has the input focus. Associations between filename patterns and mode names are defined in option mode_from_filename_patterns of the user's file ~/.cameleon2/chamo.sourceview. This means that commands "specific to a mode" are available even on buffers with another mode associated; it is just a matter of key bindings and menus which give direct access to commands. Options of modes, like key bindings, are stored (by convention) in a configuration file specific to the mode. For example, the configuration options of the "ocaml" mode are stored in the user's file ~/.cameleon2/chamo.sourceview.mode.ocaml.
This is done with some OCaml code. Modes are represented by objects of class type Ed_sourceview.mode.
Then, an instance of your mode class must be registered with Ed_sourceview.register_mode.
Then, add some association between a filename
pattern and your mode name and it's ok. Have a look at the code of another mode, e.g. the ocaml mode
(implementation is here
,
implementation of the management of the configuration file is here
).
By now, there are not a lot of modes. Here is a list of the available modes, with the commands it provides through a key binding indicated between parenthesis:
Contributions (new modes or new commands) are very welcome !
Sourceviews in Chamo are based on GtkSourceView
,
which uses language-specs files to know what to highlight (keywords, comments, ...).
GtkSourceView installation does not include such a description file for Objective Caml.
So you must put a language-specs file for Objective-Caml in your directory ~/.gnome2/gtksourceview-1.0/language-specs/.
Such a file is available in the distribution of LablGtkSourceView or here: ocaml.lang.
Cameleon2: Frequently Asked Questions
