Tips and Tricks
Tips on using SPIDER.
Commands
Right-click inside a Prolog editor brings up a menu with commands;
right-click in the its left margin will bring up a different set of
commands, e.g. related to breakpoints. Additional commands are
available from the menu bar.
It is possible to add key bindings for commands. This is an Eclipse
feature, available from the Preferences. This way you can add a key
binding for e.g. the “Consult Prolog Source” command, if
desired.
The following summarizes some especially useful or powerful commands.
Navigation
- Go to definition
-
CTRL-mouse click (⌘-mouse click on macOS)
on a predicate name will go to its definition. This also works for
symbolic paths, e.g. the first argument to use_module/2
and variables. Alternatively, you can use the F3 keyboard
command.
- Open predicate
-
CTRL-O (⌘-O on macOS) opens a dialog
where the name of a predicate can be entered and its definition
opened.
- Select enclosing clause
-
CTRL-SHIFT-A (⌘-SHIFT-A on macOS) will
select the enclosing clause or directive. Repeated application selects
successively larger units (associated comments, predicate, etc.).
There are many other Prolog-specific commands for expanding the
selection in the “Edit” menu.
- Go to caller
-
CTRL-ALT-SHIFT-H when in a clause will go to the closest
caller of the current predicate. Repeated invocations thus navigate
backward through the call hierarchy.
- Open Call Hierarchy
-
CTRL-ALT-H will open a tree of callers and other references
to the predicate. This also works for symbolic paths and will tell you
who loads a particular file, and which predicates in a file are used
from outside the file.
- Prolog Search
-
CTRL-^ searches for terms subsumed by a pattern. For
instance, foo(_,_) would search for all occurences of a
compound term with name foo and two arguments (in this
example it would also find occurrences where the source code uses
infix notation like a foo 42 ).
Refactoring and Code Formatting
- Correct Indentation
-
CTRL-I will adjust the indent of the current line.
- Format Element
-
CTRL-SHIFT-F (⌘-SHIFT-F on macOS) will
format all lines of the enclosing clause or directive. If there is a
selection, it will only format the selection.
In the settings you can change some details of how code is
formatted.
Some formatting settings are also read from any -*-
... -*- line at the start of the the Prolog file.
To see the supported variables, use the “New Prolog File”
wizard; it will create a file with all supported Emacs variables
filled in from the settings. The “New Prolog File” wizard
can be accessed from the File menu, under New/Other/Prolog/Prolog
File.
SPIDER reads Emacs-style Per-Directory
Local Variables. This makes it easy to ensure consistent
formatting between developers, regardless of whether they use Emacs or
SPIDER, without modifying any source files.
A file, named .dir-locals.el in the same (or an
ancestor-) directory as a Prolog file will be used for settings that
are not present as a -*- ... -*- line in the Prolog file.
E.g.
;; This should go in a .dir-locals.el file
(
(prolog-mode .
(
;; These correspond to the SPIDER defaults
(indent-tabs-mode . nil)
(tab-width . 8)
(prolog-indent-width . 8)
(prolog-paren-indent . 4)
(comment-column . 32)
))
)
- Rename Predicate/Variable
-
CTRL-ALT-R when the cursor is on a goal or a variable
brings up a dialog where a new name can be entered. When a predicate
is renamed, all references in the project, not just those in the
current file, will be updated by default.
- Change Predicate Signature
-
CTRL-ALT-C when the cursor is on a predicate name brings up
a dialog where arguments can be reordered, and arguments can be added
or removed. When a predicate is changed, all references in the
project, not just those in the current file, will be updated by
default.
- Introduce Predicate
-
CTRL-ALT-M (⌘-⌥-M on macOS) when one
or more goals in a clause body are selected, will replace the selected
goals with a call to a new predicate defined using the selected
goals. Inline, when the cursor is at a call to a
predicate, will do the reverse, i.e. replace the call with the body of
the called predicate.
- Introduce Variable
-
CTRL-ALT-V (⌘-⌥-V on macOS) will
replace a selected term with a variable bound to the
term. Inline, when the cursor is at a variable,
will do the reverse, i.e. replace a variable with its value.
- Inline Predicate/Variable
-
CTRL-ALT-I (⌘-⌥-I macOS) when
the cursor is at a call to a predicate, or at a variable, will do the
reverse of Introduce Predicate
or Introduce Variable, depending on
what is at the cursor, i.e. replace the call with the body of the
predicate, or the variable with its value.
- Renumber Variables
-
Renumbers the selected variable and other similarly named
(Var , Var47 , …) to be numbered
consecutively. As an example,
foo(a, p(X42), X3) :-
body(a, X, X).
would become:
foo(a, p(X1), X) :-
body(a, X2, X2).
- Linearize Arguments
-
Ensures that each argument position is a variable that does not occur
elsewhere in the clause head. As an example,
foo(a, p(X1), X) :-
body(a, X2, X2).
would become:
foo(A, A1, X) :-
A = a,
A1 = p(X1),
body(a, X2, X2).
- Introduce Module Directive
-
will convert a non-module file to a module by inserting
a module/2 directive in the file. The module directive
will have an export list containing suitable predicates.
Prolog Top Level
- Compile Prolog Source
-
ALT-K will ask to save any modified files and then compile
the edited file in the running SICStus.
- Open Prolog Toplevel
-
CTRL-ALT-Q C (also available from the “SICStus”
menu) will open the SICStus top level view.
- Restart Prolog
-
To start or re-start SICStus in the Toplevel view, click on the the
“Restart Prolog” () button.
- Top level menu
-
The top level view has some useful commands in the "view menu",
available under the view menu () button. Among other things, you
can change the working directory of the running Prolog instance.
- Top level completion
-
In the top level view Word Completion
(ALT-/, CTRL-.) will complete the current word,
like in the Prolog editor. Word completion is based on the text in the
top level and the open Prolog editors. Predicate Completion
(CTRL-SPACE) will complete predicate names, like in the
Prolog editor. The history navigation History Previous
(CTRL+SHIFT+UP-ARROW) and History Next
(CTRL+SHIFT+DOWN-ARROW) will only show history entries that
match the already typed text.
Debugging and Profiling
- Create break point
-
Double-clicking in the left margin will create a spypoint or a line
breakpoint. Adding a breakpoint to the first line of a predicate will
create a spypoint.
Note that line breakpoints only work if source info is enabled,
i.e. with set_prolog_flag(source_info, on) .
Breakpoints are persisted and automatically installed in any Prolog
started from within SPIDER. You can temporarily disable all
breakpoints from the Breakpoints view.
- Open Profile
-
“Open Profile”, available from the “SICStus”
menu, will open the Profile view showing
profiling info. Use set_prolog_flag(profiling, on) in
Prolog to make Prolog collect profiling information.
- Open Coverage
-
“Open Coverage”, available from the “SICStus”
menu, will open the Coverage view showing
source code coverage information. Source code coverage information is
collected whenever profiling information is collected,
i.e. when set_prolog_flag(profiling, on) is in
effect. When SPIDER presents source code coverage in the Coverage view
it will also show coverage information in the left margin of any
affected source files.
Code Structure
SPIDER should be able to do a god job for any SICStus-compatible
source code (and probably also for code written using other Prolog
dialects). However, it will work best if some conventions are
followed, as outlined below.
-
SPIDER works best when each file defines a module and where no module
spans multiple files.
-
SPIDER works best with self-contained code. That is, code that defines
one module per file and that brings in all its dependencies using
use_module/[1,2] etc.
-
SPIDER cannot expand code with goal_expansion or
term_expansion except for special cases like Definite Clause
Grammars.
-
Avoid conjunctions of directives, e.g. do not use:
:- op(foo,xfy,800), op(bar, fx, 10).
instead use separate directives, like:
:- op(foo,xfy,800).
:- op(bar, fx, 10).
This is required also for ISO compliance.
-
SPIDER knows about conditional compilation directives but has limited
knowledge about whether a condition is true or not. It will warn if it
encounters a condition it is unable to evaluate. In the context of a
conditional directive the Prolog editor will handle at least the
following goals:
-
current_prolog_flag(dialect, spider) is treated as
true. This can be used to wrap code that should only be seen by the
Prolog editor since this will never be true at runtime.
-
current_prolog_flag(dialect, sicstus) is treated as true.
Other atomic values than spider and sicstus for the
second argument are considered false.
-
In addition, SPIDER handles true , false and
some other simple built-ins and control structures. It also handles
calls to user-defined, one-clause, zero-argument predicates that only
call things SPIDER can handle.
Note that this restricted language is only used by SPIDER, whereas
SICStus itself uses the full Prolog language when evaluating
conditional directives.
The following example shows how conditional compilation can be used to
supply SPIDER with special definitions of predicates etc.
:- if(current_prolog_flag(dialect,spider)).
%% Dummy definitions for SPIDER. SICStus will not see these.
foo(_,_).
bar(_,_).
:- elif(current_prolog_flag(dialect,sicstus)).
%% SICStus, but not SPIDER, will see this code
foo(X,Y) :- some_goal(X,Y).
%% include some code that is not available in SPIDER
%% Presumably it defines bar/2.
:- include(generated_code).
:- else.
%% This code is for Prolog dialects other than SICStus.
foo(X,Y) :- throw(unsupported(foo(X,Y))).
bar(X,Y) :- throw(unsupported(bar(X,Y))).
:- endif.
The Indexer
The automatic source code indexer will by default process all files in
the project(s). This can lead to unneeded work and irrelevant warnings
if there are files that should not be processed, e.g. data files or
files written for other dialects of Prolog.
You can select a file, folder, or Project in the Eclipse Project
Explorer and select Properties from the context menu. There is a
Prolog properties page with the following choices:
- Index
-
If you uncheck it then the Indexer will not process the file
or the folder contents except for files loaded by indexed files.
It may be worthwhile to uncheck this for some example folders in the
SICStus library tree.
Note that the Indexer will skip non-Prolog files even if Index is
checked so you do not need to uncheck this option for non-Prolog
files.
- Preferred
-
Marks a file as the preferred root in a tree of load
dependencies. This is useful when the load dependencies form a graph
without a unique root. Typically you do not need to explicitly use
this as the Indexer will figure out the load tree automatically.
- Ignore
-
Try to avoid processing the file or folder contents.
It is possible to put these properties in a file located with the
affected files. This ensures the properties are set whenever a new
project is created and allows version control etc. The details are
currently not documented and may change without notice. The curious
can deduce the file format from the .spider_data files
present below the SICStus Prolog library folder.
There are also some Indexer-related preferences:
- Suppress problem reporting for reference projects
-
default
checked. This avoids some work and distractions from computing
warnings for the SICStus libraries.
- Source Indexing
-
turn on or off the Indexer completely. Please
report if you ever feel the need to turn off the indexer.
- Show problems while editing
-
some problems are expensive to
detect. Unchecking this option will postpone expensive problem
detection until files are saved.
|