4.4 Listing and Editor Interface

SWI-Prolog offers an extensible interface which allows the user to edit objects of the program: predicates, modules, files, etc. The editor interface is implemented by edit/1 and consists of three parts: locating, selecting and starting the editor.

Any of these parts may be extended or redefined by adding clauses to various multi-file (see multifile/1) predicates defined in the module prolog_edit.

The built-in edit specifications for edit/1 (see prolog_edit:locate/3) are described below.

Fully specified objects
<Module>:<Name>/<Arity> Refers a predicate
module(<Module>)Refers to a module
file(<Path>)Refers to a file
source_file(<Path>)Refers to a loaded source-file
Ambiguous specifications
<Name>/<Arity> Refers this predicate in any module
<Name>Refers to (1) named predicate in any module with any arity, (2) a (source) file or (3) a module.
First exploits prolog_edit:locate/3 to translate Specification into a list of Locations. If there is more than one `hit', the user is asked to select from the locations found. Finally, prolog_edit:edit_source/1 is used to invoke the user's preferred editor. Typically, edit/1 can be handed the name of a predicate, module, basename of a file, XPCE class, XPCE method, etc.
Edit the `default' file using edit/1. The default file is the file loaded with the command-line option -s or, in windows, the file loaded by double-clicking from the Windows shell.
prolog_edit:locate(+Spec, -FullSpec, -Location)
Where Spec is the specification provided through edit/1. This multifile predicate is used to enumerate locations at with an object satisfying the given Spec can be found. FullSpec is unified with the complete specification for the object. This distinction is used to allow for ambiguous specifications. For example, if Spec is an atom, which appears as the base-name of a loaded file and as the name of a predicate, FullSpec will be bound to file(Path) or Name/Arity.

Location is a list of attributes of the location. Normally, this list will contain the term file(File) and ---if available--- the term line(Line).

prolog_edit:locate(+Spec, -Location)
Same as prolog_edit:locate/3, but only deals with fully-specified objects.
Start editor on Location. See prolog_edit:locate/3 for the format of a location term. This multi-file predicate is normally not defined. If it succeeds, edit/1 assumes the editor is started.

If it fails, edit/1 uses its internal defaults, which are defined by the Prolog flag editor and/or the environment variable EDITOR. The following rules apply. If the Prolog flag editor is of the format $<name>, the editor is determined by the environment variable <name>. Else, if this flag is pce_emacs or built_in and XPCE is loaded or can be loaded, the built-in Emacs clone is used. Else, if the environment EDITOR is set, this editor is used. Finally, vi is used as default on Unix systems and notepad on Windows.

See the default user preferences file dotfiles/dotplrc for examples.

prolog_edit:edit_command(+Editor, -Command)
Determines how Editor is to be invoked using shell/1. Editor is the determined editor (see edit_source/1), without the full path specification, and without possible (exe) extension. Command is an atom describing the command. The pattern %f is replaced by the full file-name of the location, and %d by the line number. If the editor can deal with starting at a specified line, two clauses should be provided, one holding only the %f pattern, and one holding both patterns.

The default contains definitions for vi, emacs, emacsclient, vim and notepad (latter without line-number version).

Please contribute your specifications to jan@swi.psy.uva.nl.

Normally not-defined multifile predicate. This predicate may be defined to provide loading hooks for user-extensions to the edit module. For example, XPCE provides the code below to load library(swi_edit), containing definitions to locate classes and methods as well as to bind this package to the PceEmacs built-in editor.
:- multifile prolog_edit:load/0.

prolog_edit:load :-
List specified predicates (when an atom is given all predicates with this name will be listed). The listing is produced on the basis of the internal representation, thus losing user's layout and variable name information. See also portray_clause/1.
List all predicates of the database using listing/1.
Pretty print a clause. A clause should be specified as a term `<Head> :- <Body>'. Facts are represented as `<Head> :- true' or simply <Head>. Variables in the clause are written as A, B, ... . Singleton variables are written as _. See also portray_clause/2.
portray_clause(+Stream, +Clause)
Pretty print a clause to Stream. See portray_clause/1 for details.