View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org/projects/xpce/
    6    Copyright (c)  2011-2020, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9    All rights reserved.
   10
   11    Redistribution and use in source and binary forms, with or without
   12    modification, are permitted provided that the following conditions
   13    are met:
   14
   15    1. Redistributions of source code must retain the above copyright
   16       notice, this list of conditions and the following disclaimer.
   17
   18    2. Redistributions in binary form must reproduce the above copyright
   19       notice, this list of conditions and the following disclaimer in
   20       the documentation and/or other materials provided with the
   21       distribution.
   22
   23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   26    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   27    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   28    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   29    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   31    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   33    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34    POSSIBILITY OF SUCH DAMAGE.
   35*/
   36
   37:- module(prolog_colour,
   38          [ prolog_colourise_stream/3,  % +Stream, +SourceID, :ColourItem
   39            prolog_colourise_stream/4,  % +Stream, +SourceID, :ColourItem, +Opts
   40            prolog_colourise_term/4,    % +Stream, +SourceID, :ColourItem, +Opts
   41            prolog_colourise_query/3,   % +String, +SourceID, :ColourItem
   42            syntax_colour/2,            % +Class, -Attributes
   43            syntax_message//1           % +Class
   44          ]).   45:- use_module(library(record),[(record)/1, op(_,_,record)]).   46:- autoload(library(apply),[maplist/3]).   47:- autoload(library(debug),[debug/3]).   48:- autoload(library(error),[is_of_type/2]).   49:- autoload(library(lists),[member/2,append/3]).   50:- autoload(library(operators),
   51	    [push_operators/1,pop_operators/0,push_op/3]).   52:- autoload(library(option),[option/3]).   53:- autoload(library(predicate_options),
   54	    [current_option_arg/2,current_predicate_options/3]).   55:- autoload(library(prolog_clause),[predicate_name/2]).   56:- autoload(library(prolog_source),
   57	    [ load_quasi_quotation_syntax/2,
   58	      read_source_term_at_location/3,
   59	      prolog_canonical_source/2
   60	    ]).   61:- autoload(library(prolog_xref),
   62	    [ xref_option/2,
   63	      xref_public_list/3,
   64	      xref_op/2,
   65	      xref_prolog_flag/4,
   66	      xref_module/2,
   67	      xref_meta/3,
   68	      xref_source_file/4,
   69	      xref_defined/3,
   70	      xref_called/3,
   71	      xref_defined_class/3,
   72	      xref_exported/2,
   73	      xref_hook/1
   74	    ]).   75
   76:- meta_predicate
   77    prolog_colourise_stream(+, +, 3),
   78    prolog_colourise_stream(+, +, 3, +),
   79    prolog_colourise_query(+, +, 3),
   80    prolog_colourise_term(+, +, 3, +).   81
   82:- predicate_options(prolog_colourise_term/4, 4,
   83                     [ subterm_positions(-any)
   84                     ]).   85:- predicate_options(prolog_colourise_stream/4, 4,
   86                     [ operators(list(any))
   87                     ]).

Prolog syntax colouring support.

This module defines reusable code to colourise Prolog source.

To be done
- : The one-term version */
   97:- multifile
   98    style/2,                        % +ColourClass, -Attributes
   99    message//1,                     % +ColourClass
  100    term_colours/2,                 % +SourceTerm, -ColourSpec
  101    goal_colours/2,                 % +Goal, -ColourSpec
  102    goal_colours/3,                 % +Goal, +Class, -ColourSpec
  103    directive_colours/2,            % +Goal, -ColourSpec
  104    goal_classification/2,          % +Goal, -Class
  105    vararg_goal_classification/3.   % +Name, +Arity, -Class
  106
  107
  108:- record
  109    colour_state(source_id_list,
  110                 module,
  111                 stream,
  112                 closure,
  113                 singletons).  114
  115colour_state_source_id(State, SourceID) :-
  116    colour_state_source_id_list(State, SourceIDList),
  117    member(SourceID, SourceIDList).
 prolog_colourise_stream(+Stream, +SourceID, :ColourItem) is det
 prolog_colourise_stream(+Stream, +SourceID, :ColourItem, +Opts) is det
Determine colour fragments for the data on Stream. SourceID is the canonical identifier of the input as known to the cross-referencer, i.e., as created using xref_source(SourceID).

ColourItem is a closure that is called for each identified fragment with three additional arguments:

Options

operators(+Ops)
Provide an initial list of additional operators.
  138prolog_colourise_stream(Fd, SourceId, ColourItem) :-
  139    prolog_colourise_stream(Fd, SourceId, ColourItem, []).
  140prolog_colourise_stream(Fd, SourceId, ColourItem, Options) :-
  141    to_list(SourceId, SourceIdList),
  142    make_colour_state([ source_id_list(SourceIdList),
  143                        stream(Fd),
  144                        closure(ColourItem)
  145                      ],
  146                      TB),
  147    option(operators(Ops), Options, []),
  148    setup_call_cleanup(
  149        save_settings(TB, Ops, State),
  150        colourise_stream(Fd, TB),
  151        restore_settings(State)).
  152
  153to_list(List, List) :-
  154    is_list(List),
  155    !.
  156to_list(One, [One]).
  157
  158
  159colourise_stream(Fd, TB) :-
  160    (   peek_char(Fd, #)            % skip #! script line
  161    ->  skip(Fd, 10)
  162    ;   true
  163    ),
  164    repeat,
  165        colour_state_module(TB, SM),
  166        character_count(Fd, Start),
  167        catch(read_term(Fd, Term,
  168                        [ subterm_positions(TermPos),
  169                          singletons(Singletons0),
  170                          module(SM),
  171                          comments(Comments)
  172                        ]),
  173              E,
  174              read_error(E, TB, Start, Fd)),
  175        fix_operators(Term, SM, TB),
  176        warnable_singletons(Singletons0, Singletons),
  177        colour_state_singletons(TB, Singletons),
  178        (   colourise_term(Term, TB, TermPos, Comments)
  179        ->  true
  180        ;   arg(1, TermPos, From),
  181            print_message(warning,
  182                          format('Failed to colourise ~p at index ~d~n',
  183                                 [Term, From]))
  184        ),
  185        Term == end_of_file,
  186    !.
  187
  188save_settings(TB, Ops, state(Style, Flags, OSM, Xref)) :-
  189    (   source_module(TB, SM)
  190    ->  true
  191    ;   SM = prolog_colour_ops
  192    ),
  193    set_xref(Xref, true),
  194    '$set_source_module'(OSM, SM),
  195    colour_state_module(TB, SM),
  196    maplist(qualify_op(SM), Ops, QOps),
  197    push_operators(QOps),
  198    syntax_flags(Flags),
  199    '$style_check'(Style, Style).
  200
  201qualify_op(M, op(P,T,N), op(P,T,M:N)) :-
  202    atom(N), !.
  203qualify_op(M, op(P,T,L), op(P,T,QL)) :-
  204    is_list(L), !,
  205    maplist(qualify_op_name(M), L, QL).
  206qualify_op(_, Op, Op).
  207
  208qualify_op_name(M, N, M:N) :-
  209    atom(N),
  210    !.
  211qualify_op_name(_, N, N).
  212
  213restore_settings(state(Style, Flags, OSM, Xref)) :-
  214    restore_syntax_flags(Flags),
  215    '$style_check'(_, Style),
  216    pop_operators,
  217    '$set_source_module'(OSM),
  218    set_xref(_, Xref).
  219
  220set_xref(Old, New) :-
  221    current_prolog_flag(xref, Old),
  222    !,
  223    set_prolog_flag(xref, New).
  224set_xref(false, New) :-
  225    set_prolog_flag(xref, New).
  226
  227
  228syntax_flags(Pairs) :-
  229    findall(set_prolog_flag(Flag, Value),
  230            syntax_flag(Flag, Value),
  231            Pairs).
  232
  233syntax_flag(Flag, Value) :-
  234    syntax_flag(Flag),
  235    current_prolog_flag(Flag, Value).
  236
  237restore_syntax_flags([]).
  238restore_syntax_flags([set_prolog_flag(Flag, Value)|T]) :-
  239    set_prolog_flag(Flag, Value),
  240    restore_syntax_flags(T).
 source_module(+State, -Module) is semidet
True when Module is the module context into which the file is loaded. This is the module of the file if File is a module file, or the load context of File if File is not included or the module context of the file into which the file was included.
  249source_module(TB, Module) :-
  250    colour_state_source_id_list(TB, []),
  251    !,
  252    colour_state_module(TB, Module).
  253source_module(TB, Module) :-
  254    colour_state_source_id(TB, SourceId),
  255    xref_option(SourceId, module(Module)),
  256    !.
  257source_module(TB, Module) :-
  258    (   colour_state_source_id(TB, File),
  259        atom(File)
  260    ;   colour_state_stream(TB, Fd),
  261        is_stream(Fd),
  262        stream_property(Fd, file_name(File))
  263    ),
  264    module_context(File, [], Module).
  265
  266module_context(File, _, Module) :-
  267    source_file_property(File, module(Module)),
  268    !.
  269module_context(File, Seen, Module) :-
  270    source_file_property(File, included_in(File2, _Line)),
  271    \+ memberchk(File, Seen),
  272    !,
  273    module_context(File2, [File|Seen], Module).
  274module_context(File, _, Module) :-
  275    source_file_property(File, load_context(Module, _, _)).
 read_error(+Error, +TB, +Start, +Stream) is failure
If this is a syntax error, create a syntax-error fragment.
  282read_error(Error, TB, Start, EndSpec) :-
  283    (   syntax_error(Error, Id, CharNo)
  284    ->  message_to_string(error(syntax_error(Id), _), Msg),
  285        (   integer(EndSpec)
  286        ->  End = EndSpec
  287        ;   character_count(EndSpec, End)
  288        ),
  289        show_syntax_error(TB, CharNo:Msg, Start-End),
  290        fail
  291    ;   throw(Error)
  292    ).
  293
  294syntax_error(error(syntax_error(Id), stream(_S, _Line, _LinePos, CharNo)),
  295             Id, CharNo).
  296syntax_error(error(syntax_error(Id), file(_S, _Line, _LinePos, CharNo)),
  297             Id, CharNo).
  298syntax_error(error(syntax_error(Id), string(_Text, CharNo)),
  299             Id, CharNo).
 warnable_singletons(+Singletons, -Warn) is det
Warn is the subset of the singletons that we warn about.
  305warnable_singletons([], []).
  306warnable_singletons([H|T0], List) :-
  307    H = (Name=_Var),
  308    (   '$is_named_var'(Name)
  309    ->  List = [H|T]
  310    ;   List = T
  311    ),
  312    warnable_singletons(T0, T).
 colour_item(+Class, +TB, +Pos) is det
  316colour_item(Class, TB, Pos) :-
  317    arg(1, Pos, Start),
  318    arg(2, Pos, End),
  319    Len is End - Start,
  320    colour_state_closure(TB, Closure),
  321    call(Closure, Class, Start, Len).
 safe_push_op(+Prec, +Type, :Name, +State)
Define operators into the default source module and register them to be undone by pop_operators/0.
  329safe_push_op(P, T, N0, State) :-
  330    colour_state_module(State, CM),
  331    strip_module(CM:N0, M, N),
  332    (   is_list(N),
  333        N \== []                                % define list as operator
  334    ->  acyclic_term(N),
  335        forall(member(Name, N),
  336               safe_push_op(P, T, M:Name, State))
  337    ;   push_op(P, T, M:N)
  338    ),
  339    debug(colour, ':- ~w.', [op(P,T,M:N)]).
 fix_operators(+Term, +Module, +State) is det
Fix flags that affect the syntax, such as operators and some style checking options. Src is the canonical source as required by the cross-referencer.
  347fix_operators((:- Directive), M, Src) :-
  348    ground(Directive),
  349    catch(process_directive(Directive, M, Src), _, true),
  350    !.
  351fix_operators(_, _, _).
  352
  353process_directive(style_check(X), _, _) :-
  354    !,
  355    style_check(X).
  356process_directive(set_prolog_flag(Flag, Value), M, _) :-
  357    syntax_flag(Flag),
  358    !,
  359    set_prolog_flag(M:Flag, Value).
  360process_directive(M:op(P,T,N), _, Src) :-
  361    !,
  362    process_directive(op(P,T,N), M, Src).
  363process_directive(op(P,T,N), M, Src) :-
  364    !,
  365    safe_push_op(P, T, M:N, Src).
  366process_directive(module(_Name, Export), M, Src) :-
  367    !,
  368    forall(member(op(P,A,N), Export),
  369           safe_push_op(P,A,M:N, Src)).
  370process_directive(use_module(Spec), _, Src) :-
  371    !,
  372    catch(process_use_module1(Spec, Src), _, true).
  373process_directive(use_module(Spec, Imports), _, Src) :-
  374    !,
  375    catch(process_use_module2(Spec, Imports, Src), _, true).
  376process_directive(Directive, _, Src) :-
  377    prolog_source:expand((:-Directive), Src, _).
  378
  379syntax_flag(character_escapes).
  380syntax_flag(var_prefix).
  381syntax_flag(allow_variable_name_as_functor).
  382syntax_flag(allow_dot_in_atom).
 process_use_module1(+Imports, +Src)
Get the exported operators from the referenced files.
  388process_use_module1([], _) :- !.
  389process_use_module1([H|T], Src) :-
  390    !,
  391    process_use_module1(H, Src),
  392    process_use_module1(T, Src).
  393process_use_module1(File, Src) :-
  394    (   xref_public_list(File, Src,
  395                         [ exports(Exports),
  396                           silent(true),
  397                           path(Path)
  398                         ])
  399    ->  forall(member(op(P,T,N), Exports),
  400               safe_push_op(P,T,N,Src)),
  401        colour_state_module(Src, SM),
  402        (   member(Syntax/4, Exports),
  403            load_quasi_quotation_syntax(SM:Path, Syntax),
  404            fail
  405        ;   true
  406        )
  407    ;   true
  408    ).
  409
  410process_use_module2(File, Imports, Src) :-
  411    (   xref_public_list(File, Src,
  412                         [ exports(Exports),
  413                           silent(true),
  414                           path(Path)
  415                         ])
  416    ->  forall(( member(op(P,T,N), Exports),
  417                 member(op(P,T,N), Imports)),
  418               safe_push_op(P,T,N,Src)),
  419        colour_state_module(Src, SM),
  420        (   member(Syntax/4, Exports),
  421            member(Syntax/4, Imports),
  422            load_quasi_quotation_syntax(SM:Path, Syntax),
  423            fail
  424        ;   true
  425        )
  426    ;   true
  427    ).
 prolog_colourise_query(+Query:string, +SourceId, :ColourItem)
Colourise a query, to be executed in the context of SourceId.
Arguments:
SourceId- Execute Query in the context of the cross-referenced environment SourceID.
  436prolog_colourise_query(QueryString, SourceID, ColourItem) :-
  437    query_colour_state(SourceID, ColourItem, TB),
  438    setup_call_cleanup(
  439        save_settings(TB, [], State),
  440        colourise_query(QueryString, TB),
  441        restore_settings(State)).
  442
  443query_colour_state(module(Module), ColourItem, TB) :-
  444    !,
  445    make_colour_state([ source_id_list([]),
  446                        module(Module),
  447                        closure(ColourItem)
  448                      ],
  449                      TB).
  450query_colour_state(SourceID, ColourItem, TB) :-
  451    to_list(SourceID, SourceIDList),
  452    make_colour_state([ source_id_list(SourceIDList),
  453                        closure(ColourItem)
  454                      ],
  455                      TB).
  456
  457
  458colourise_query(QueryString, TB) :-
  459    colour_state_module(TB, SM),
  460    string_length(QueryString, End),
  461    (   catch(term_string(Query, QueryString,
  462                          [ subterm_positions(TermPos),
  463                            singletons(Singletons0),
  464                            module(SM),
  465                            comments(Comments)
  466                          ]),
  467              E,
  468              read_error(E, TB, 0, End))
  469    ->  warnable_singletons(Singletons0, Singletons),
  470        colour_state_singletons(TB, Singletons),
  471        colourise_comments(Comments, TB),
  472        (   Query == end_of_file
  473        ->  true
  474        ;   colourise_body(Query, TB, TermPos)
  475        )
  476    ;   true                        % only a syntax error
  477    ).
 prolog_colourise_term(+Stream, +SourceID, :ColourItem, +Options)
Colourise the next term on Stream. Unlike prolog_colourise_stream/3, this predicate assumes it is reading a single term rather than the entire stream. This implies that it cannot adjust syntax according to directives that precede it.

Options:

subterm_positions(-TermPos)
Return complete term-layout. If an error is read, this is a term error_position(StartClause, EndClause, ErrorPos)
  492prolog_colourise_term(Stream, SourceId, ColourItem, Options) :-
  493    to_list(SourceId, SourceIdList),
  494    make_colour_state([ source_id_list(SourceIdList),
  495                        stream(Stream),
  496                        closure(ColourItem)
  497                      ],
  498                      TB),
  499    option(subterm_positions(TermPos), Options, _),
  500    findall(Op, xref_op(SourceId, Op), Ops),
  501    debug(colour, 'Ops from ~p: ~p', [SourceId, Ops]),
  502    findall(Opt, xref_flag_option(SourceId, Opt), Opts),
  503    character_count(Stream, Start),
  504    (   source_module(TB, Module)
  505    ->  true
  506    ;   Module = prolog_colour_ops
  507    ),
  508    read_source_term_at_location(
  509        Stream, Term,
  510        [ module(Module),
  511          operators(Ops),
  512          error(Error),
  513          subterm_positions(TermPos),
  514          singletons(Singletons0),
  515          comments(Comments)
  516        | Opts
  517        ]),
  518    (   var(Error)
  519    ->  warnable_singletons(Singletons0, Singletons),
  520        colour_state_singletons(TB, Singletons),
  521        colour_item(range, TB, TermPos),            % Call to allow clearing
  522        colourise_term(Term, TB, TermPos, Comments)
  523    ;   character_count(Stream, End),
  524        TermPos = error_position(Start, End, Pos),
  525        colour_item(range, TB, TermPos),
  526        show_syntax_error(TB, Error, Start-End),
  527        Error = Pos:_Message
  528    ).
  529
  530xref_flag_option(TB, var_prefix(Bool)) :-
  531    xref_prolog_flag(TB, var_prefix, Bool, _Line).
  532
  533show_syntax_error(TB, Pos:Message, Range) :-
  534    integer(Pos),
  535    !,
  536    End is Pos + 1,
  537    colour_item(syntax_error(Message, Range), TB, Pos-End).
  538show_syntax_error(TB, _:Message, Range) :-
  539    colour_item(syntax_error(Message, Range), TB, Range).
  540
  541
  542singleton(Var, TB) :-
  543    colour_state_singletons(TB, Singletons),
  544    member_var(Var, Singletons).
  545
  546member_var(V, [_=V2|_]) :-
  547    V == V2,
  548    !.
  549member_var(V, [_|T]) :-
  550    member_var(V, T).
 colourise_term(+Term, +TB, +Termpos, +Comments)
Colourise the next Term.
bug
- The colour spec is closed with fullstop, but the position information does not include the full stop location, so all we can do is assume it is behind the term.
  561colourise_term(Term, TB, TermPos, Comments) :-
  562    colourise_comments(Comments, TB),
  563    (   Term == end_of_file
  564    ->  true
  565    ;   colourise_term(Term, TB, TermPos),
  566        colourise_fullstop(TB, TermPos)
  567    ).
  568
  569colourise_fullstop(TB, TermPos) :-
  570    arg(2, TermPos, EndTerm),
  571    Start is EndTerm,
  572    End is Start+1,
  573    colour_item(fullstop, TB, Start-End).
  574
  575colourise_comments(-, _).
  576colourise_comments([], _).
  577colourise_comments([H|T], TB) :-
  578    colourise_comment(H, TB),
  579    colourise_comments(T, TB).
  580
  581colourise_comment((-)-_, _) :- !.
  582colourise_comment(Pos-Comment, TB) :-
  583    comment_style(Comment, Style),
  584    stream_position_data(char_count, Pos, Start),
  585    string_length(Comment, Len),
  586    End is Start + Len + 1,
  587    colour_item(comment(Style), TB, Start-End).
  588
  589comment_style(Comment, structured) :-           % Starts %%, %! or /**
  590    structured_comment_start(Start),
  591    sub_string(Comment, 0, Len, _, Start),
  592    Next is Len+1,
  593    string_code(Next, Comment, NextCode),
  594    code_type(NextCode, space),
  595    !.
  596comment_style(Comment, line) :-                 % Starts %
  597    sub_string(Comment, 0, _, _, '%'),
  598    !.
  599comment_style(_, block).                        % Starts /*
 structured_comment_start(-Start)
Copied from library(pldoc/doc_process). Unfortunate, but we do not want to force loading pldoc.
  606structured_comment_start('%%').
  607structured_comment_start('%!').
  608structured_comment_start('/**').
 colourise_term(+Term, +TB, +Pos)
Colorise a file toplevel term.
  614colourise_term(Var, TB, Start-End) :-
  615    var(Var),
  616    !,
  617    colour_item(instantiation_error, TB, Start-End).
  618colourise_term(_, _, Pos) :-
  619    var(Pos),
  620    !.
  621colourise_term(Term, TB, parentheses_term_position(PO,PC,Pos)) :-
  622    !,
  623    colour_item(parentheses, TB, PO-PC),
  624    colourise_term(Term, TB, Pos).
  625colourise_term(Term, TB, Pos) :-
  626    term_colours(Term, FuncSpec-ArgSpecs),
  627    !,
  628    Pos = term_position(F,T,FF,FT,ArgPos),
  629    colour_item(term, TB, F-T),     % TBD: Allow specifying by term_colours/2?
  630    specified_item(FuncSpec, Term, TB, FF-FT),
  631    specified_items(ArgSpecs, Term, TB, ArgPos).
  632colourise_term((Head :- Body), TB,
  633               term_position(F,T,FF,FT,[HP,BP])) :-
  634    !,
  635    colour_item(clause,         TB, F-T),
  636    colour_item(neck(clause),   TB, FF-FT),
  637    colourise_clause_head(Head, TB, HP),
  638    colourise_body(Body, Head,  TB, BP).
  639colourise_term(((Head,RHC) --> Body), TB,
  640               term_position(F,T,FF,FT,
  641                             [ term_position(_,_,_,_,[HP,RHCP]),
  642                               BP
  643                             ])) :-
  644    !,
  645    colour_item(grammar_rule,       TB, F-T),
  646    colour_item(dcg_right_hand_ctx, TB, RHCP),
  647    colourise_term_arg(RHC, TB, RHCP),
  648    colour_item(neck(grammar_rule), TB, FF-FT),
  649    colourise_extended_head(Head, 2, TB, HP),
  650    colourise_dcg(Body, Head,       TB, BP).
  651colourise_term((Head --> Body), TB,                     % TBD: expansion!
  652               term_position(F,T,FF,FT,[HP,BP])) :-
  653    !,
  654    colour_item(grammar_rule,       TB, F-T),
  655    colour_item(neck(grammar_rule), TB, FF-FT),
  656    colourise_extended_head(Head, 2, TB, HP),
  657    colourise_dcg(Body, Head,       TB, BP).
  658colourise_term(:->(Head, Body), TB,
  659               term_position(F,T,FF,FT,[HP,BP])) :-
  660    !,
  661    colour_item(method,             TB, F-T),
  662    colour_item(neck(method(send)), TB, FF-FT),
  663    colour_method_head(send(Head),  TB, HP),
  664    colourise_method_body(Body,     TB, BP).
  665colourise_term(:<-(Head, Body), TB,
  666               term_position(F,T,FF,FT,[HP,BP])) :-
  667    !,
  668    colour_item(method,            TB, F-T),
  669    colour_item(neck(method(get)), TB, FF-FT),
  670    colour_method_head(get(Head),  TB, HP),
  671    colourise_method_body(Body,    TB, BP).
  672colourise_term((:- Directive), TB, Pos) :-
  673    !,
  674    colour_item(directive, TB, Pos),
  675    Pos = term_position(_F,_T,FF,FT,[ArgPos]),
  676    colour_item(neck(directive), TB, FF-FT),
  677    colourise_directive(Directive, TB, ArgPos).
  678colourise_term((?- Directive), TB, Pos) :-
  679    !,
  680    colourise_term((:- Directive), TB, Pos).
  681colourise_term(end_of_file, _, _) :- !.
  682colourise_term(Fact, TB, Pos) :-
  683    !,
  684    colour_item(clause, TB, Pos),
  685    colourise_clause_head(Fact, TB, Pos).
 colourise_extended_head(+Head, +ExtraArgs, +TB, +Pos) is det
Colourise a clause-head that is extended by term_expansion, getting ExtraArgs more arguments (e.g., DCGs add two more arguments.
  693colourise_extended_head(Head, N, TB, Pos) :-
  694    extend(Head, N, TheHead),
  695    colourise_clause_head(TheHead, TB, Pos).
  696
  697extend(M:Head, N, M:ExtHead) :-
  698    nonvar(Head),
  699    !,
  700    extend(Head, N, ExtHead).
  701extend(Head, N, ExtHead) :-
  702    compound(Head),
  703    !,
  704    compound_name_arguments(Head, Name, Args),
  705    length(Extra, N),
  706    append(Args, Extra, NArgs),
  707    compound_name_arguments(ExtHead, Name, NArgs).
  708extend(Head, N, ExtHead) :-
  709    atom(Head),
  710    !,
  711    length(Extra, N),
  712    compound_name_arguments(ExtHead, Head, Extra).
  713extend(Head, _, Head).
  714
  715
  716colourise_clause_head(_, _, Pos) :-
  717    var(Pos),
  718    !.
  719colourise_clause_head(Head, TB, parentheses_term_position(PO,PC,Pos)) :-
  720    colour_item(parentheses, TB, PO-PC),
  721    colourise_clause_head(Head, TB, Pos).
  722colourise_clause_head(M:Head, TB, QHeadPos) :-
  723    QHeadPos = term_position(_,_,QF,QT,[MPos,HeadPos]),
  724    head_colours(M:Head, meta-[_, ClassSpec-ArgSpecs]),
  725    !,
  726    colourise_module(M, TB, MPos),
  727    colour_item(functor, TB, QF-QT),
  728    functor_position(HeadPos, FPos, ArgPos),
  729    (   ClassSpec == classify
  730    ->  classify_head(TB, Head, Class)
  731    ;   Class = ClassSpec
  732    ),
  733    colour_item(head_term(Class, Head), TB, QHeadPos),
  734    colour_item(head(Class, Head), TB, FPos),
  735    specified_items(ArgSpecs, Head, TB, ArgPos).
  736colourise_clause_head(Head, TB, Pos) :-
  737    head_colours(Head, ClassSpec-ArgSpecs),
  738    !,
  739    functor_position(Pos, FPos, ArgPos),
  740    (   ClassSpec == classify
  741    ->  classify_head(TB, Head, Class)
  742    ;   Class = ClassSpec
  743    ),
  744    colour_item(head_term(Class, Head), TB, Pos),
  745    colour_item(head(Class, Head), TB, FPos),
  746    specified_items(ArgSpecs, Head, TB, ArgPos).
  747colourise_clause_head(:=(Eval, Ret), TB,
  748                      term_position(_,_,AF,AT,
  749                                    [ term_position(_,_,SF,ST,
  750                                                    [ SelfPos,
  751                                                      FuncPos
  752                                                    ]),
  753                                      RetPos
  754                                    ])) :-
  755    Eval =.. [.,M,Func],
  756    FuncPos = term_position(_,_,FF,FT,_),
  757    !,
  758    colourise_term_arg(M, TB, SelfPos),
  759    colour_item(func_dot, TB, SF-ST),               % .
  760    colour_item(dict_function(Func), TB, FF-FT),
  761    colourise_term_args(Func, TB, FuncPos),
  762    colour_item(dict_return_op, TB, AF-AT),         % :=
  763    colourise_term_arg(Ret, TB, RetPos).
  764colourise_clause_head(Head, TB, Pos) :-
  765    functor_position(Pos, FPos, _),
  766    classify_head(TB, Head, Class),
  767    colour_item(head_term(Class, Head), TB, Pos),
  768    colour_item(head(Class, Head), TB, FPos),
  769    colourise_term_args(Head, TB, Pos).
 colourise_extern_head(+Head, +Module, +TB, +Pos)
Colourise the head specified as Module:Head. Normally used for adding clauses to multifile predicates in other modules.
  776colourise_extern_head(Head, M, TB, Pos) :-
  777    functor_position(Pos, FPos, _),
  778    colour_item(head(extern(M), Head), TB, FPos),
  779    colourise_term_args(Head, TB, Pos).
  780
  781colour_method_head(SGHead, TB, Pos) :-
  782    arg(1, SGHead, Head),
  783    functor_name(SGHead, SG),
  784    functor_position(Pos, FPos, _),
  785    colour_item(method(SG), TB, FPos),
  786    colourise_term_args(Head, TB, Pos).
 functor_position(+Term, -FunctorPos, -ArgPosList)
Get the position of a functor and its argument. Unfortunately this goes wrong for lists, who have two `functor-positions'.
  793functor_position(term_position(_,_,FF,FT,ArgPos), FF-FT, ArgPos) :- !.
  794functor_position(list_position(F,_T,Elms,none), F-FT, Elms) :-
  795    !,
  796    FT is F + 1.
  797functor_position(dict_position(_,_,FF,FT,KVPos), FF-FT, KVPos) :- !.
  798functor_position(brace_term_position(F,T,Arg), F-T, [Arg]) :- !.
  799functor_position(Pos, Pos, []).
  800
  801colourise_module(Term, TB, Pos) :-
  802    (   var(Term)
  803    ;   atom(Term)
  804    ),
  805    !,
  806    colour_item(module(Term), TB, Pos).
  807colourise_module(_, TB, Pos) :-
  808    colour_item(type_error(module), TB, Pos).
 colourise_directive(+Body, +TB, +Pos)
Colourise the body of a directive.
  814colourise_directive(_,_,Pos) :-
  815    var(Pos),
  816    !.
  817colourise_directive(Dir, TB, parentheses_term_position(PO,PC,Pos)) :-
  818    !,
  819    colour_item(parentheses, TB, PO-PC),
  820    colourise_directive(Dir, TB, Pos).
  821colourise_directive((A,B), TB, term_position(_,_,_,_,[PA,PB])) :-
  822    !,
  823    colourise_directive(A, TB, PA),
  824    colourise_directive(B, TB, PB).
  825colourise_directive(Body, TB, Pos) :-
  826    nonvar(Body),
  827    directive_colours(Body, ClassSpec-ArgSpecs),   % specified
  828    !,
  829    functor_position(Pos, FPos, ArgPos),
  830    (   ClassSpec == classify
  831    ->  goal_classification(TB, Body, [], Class)
  832    ;   Class = ClassSpec
  833    ),
  834    colour_item(goal(Class, Body), TB, FPos),
  835    specified_items(ArgSpecs, Body, TB, ArgPos).
  836colourise_directive(Body, TB, Pos) :-
  837    colourise_body(Body, TB, Pos).
  838
  839
  840%       colourise_body(+Body, +TB, +Pos)
  841%
  842%       Breaks down to colourise_goal/3.
  843
  844colourise_body(Body, TB, Pos) :-
  845    colourise_body(Body, [], TB, Pos).
  846
  847colourise_body(Body, Origin, TB, Pos) :-
  848    colour_item(body, TB, Pos),
  849    colourise_goals(Body, Origin, TB, Pos).
 colourise_method_body(+MethodBody, +TB, +Pos)
Colourise the optional "comment":: as pce(comment) and proceed with the body.
To be done
- Get this handled by a hook.
  858colourise_method_body(_, _, Pos) :-
  859    var(Pos),
  860    !.
  861colourise_method_body(Body, TB, parentheses_term_position(PO,PC,Pos)) :-
  862    !,
  863    colour_item(parentheses, TB, PO-PC),
  864    colourise_method_body(Body, TB, Pos).
  865colourise_method_body(::(_Comment,Body), TB,
  866                      term_position(_F,_T,_FF,_FT,[CP,BP])) :-
  867    !,
  868    colour_item(comment(string), TB, CP),
  869    colourise_body(Body, TB, BP).
  870colourise_method_body(Body, TB, Pos) :-         % deal with pri(::) < 1000
  871    Body =.. [F,A,B],
  872    control_op(F),
  873    !,
  874    Pos = term_position(_F,_T,FF,FT,
  875                        [ AP,
  876                          BP
  877                        ]),
  878    colour_item(control, TB, FF-FT),
  879    colourise_method_body(A, TB, AP),
  880    colourise_body(B, TB, BP).
  881colourise_method_body(Body, TB, Pos) :-
  882    colourise_body(Body, TB, Pos).
  883
  884control_op(',').
  885control_op((;)).
  886control_op((->)).
  887control_op((*->)).
 colourise_goals(+Body, +Origin, +TB, +Pos)
Colourise the goals in a body.
  893colourise_goals(_, _, _, Pos) :-
  894    var(Pos),
  895    !.
  896colourise_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  897    !,
  898    colour_item(parentheses, TB, PO-PC),
  899    colourise_goals(Body, Origin, TB, Pos).
  900colourise_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  901    body_compiled(Body),
  902    !,
  903    colour_item(control, TB, FF-FT),
  904    colourise_subgoals(ArgPos, 1, Body, Origin, TB).
  905colourise_goals(Goal, Origin, TB, Pos) :-
  906    colourise_goal(Goal, Origin, TB, Pos).
  907
  908colourise_subgoals([], _, _, _, _).
  909colourise_subgoals([Pos|T], N, Body, Origin, TB) :-
  910    arg(N, Body, Arg),
  911    colourise_goals(Arg, Origin, TB, Pos),
  912    NN is N + 1,
  913    colourise_subgoals(T, NN, Body, Origin, TB).
 colourise_dcg(+Body, +Head, +TB, +Pos)
Breaks down to colourise_dcg_goal/3.
  919colourise_dcg(Body, Head, TB, Pos) :-
  920    colour_item(dcg, TB, Pos),
  921    (   dcg_extend(Head, Origin)
  922    ->  true
  923    ;   Origin = Head
  924    ),
  925    colourise_dcg_goals(Body, Origin, TB, Pos).
  926
  927colourise_dcg_goals(Var, _, TB, Pos) :-
  928    var(Var),
  929    !,
  930    colour_item(goal(meta,Var), TB, Pos).
  931colourise_dcg_goals(_, _, _, Pos) :-
  932    var(Pos),
  933    !.
  934colourise_dcg_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  935    !,
  936    colour_item(parentheses, TB, PO-PC),
  937    colourise_dcg_goals(Body, Origin, TB, Pos).
  938colourise_dcg_goals({Body}, Origin, TB, brace_term_position(F,T,Arg)) :-
  939    !,
  940    colour_item(dcg(plain), TB, F-T),
  941    colourise_goals(Body, Origin, TB, Arg).
  942colourise_dcg_goals([], _, TB, Pos) :-
  943    !,
  944    colour_item(dcg(terminal), TB, Pos).
  945colourise_dcg_goals(List, _, TB, list_position(F,T,Elms,Tail)) :-
  946    List = [_|_],
  947    !,
  948    colour_item(dcg(terminal), TB, F-T),
  949    colourise_list_args(Elms, Tail, List, TB, classify).
  950colourise_dcg_goals(_, _, TB, string_position(F,T)) :-
  951    integer(F),
  952    !,
  953    colour_item(dcg(string), TB, F-T).
  954colourise_dcg_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  955    dcg_body_compiled(Body),       % control structures
  956    !,
  957    colour_item(control, TB, FF-FT),
  958    colourise_dcg_subgoals(ArgPos, 1, Body, Origin, TB).
  959colourise_dcg_goals(Goal, Origin, TB, Pos) :-
  960    colourise_dcg_goal(Goal, Origin, TB, Pos).
  961
  962colourise_dcg_subgoals([], _, _, _, _).
  963colourise_dcg_subgoals([Pos|T], N, Body, Origin, TB) :-
  964    arg(N, Body, Arg),
  965    colourise_dcg_goals(Arg, Origin, TB, Pos),
  966    NN is N + 1,
  967    colourise_dcg_subgoals(T, NN, Body, Origin, TB).
  968
  969dcg_extend(Term, _) :-
  970    var(Term), !, fail.
  971dcg_extend(M:Term, M:Goal) :-
  972    dcg_extend(Term, Goal).
  973dcg_extend(Term, Goal) :-
  974    compound(Term),
  975    !,
  976    compound_name_arguments(Term, Name, Args),
  977    append(Args, [_,_], NArgs),
  978    compound_name_arguments(Goal, Name, NArgs).
  979dcg_extend(Term, Goal) :-
  980    atom(Term),
  981    !,
  982    compound_name_arguments(Goal, Term, [_,_]).
  983
  984dcg_body_compiled(G) :-
  985    body_compiled(G),
  986    !.
  987dcg_body_compiled((_|_)).
  988
  989%       colourise_dcg_goal(+Goal, +Origin, +TB, +Pos).
  990
  991colourise_dcg_goal(!, Origin, TB, TermPos) :-
  992    !,
  993    colourise_goal(!, Origin, TB, TermPos).
  994colourise_dcg_goal(Goal, Origin, TB, TermPos) :-
  995    dcg_extend(Goal, TheGoal),
  996    !,
  997    colourise_goal(TheGoal, Origin, TB, TermPos).
  998colourise_dcg_goal(Goal, _, TB, Pos) :-
  999    colourise_term_args(Goal, TB, Pos).
 colourise_goal(+Goal, +Origin, +TB, +Pos)
Colourise access to a single goal.
To be done
- Quasi Quotations are coloured as a general term argument. Possibly we should do something with the goal information it refers to, in particular if this goal is not defined.
 1010                                        % Deal with list as goal (consult)
 1011colourise_goal(_,_,_,Pos) :-
 1012    var(Pos),
 1013    !.
 1014colourise_goal(Goal, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
 1015    !,
 1016    colour_item(parentheses, TB, PO-PC),
 1017    colourise_goal(Goal, Origin, TB, Pos).
 1018colourise_goal(Goal, _, TB, Pos) :-
 1019    Pos = list_position(F,T,Elms,TailPos),
 1020    Goal = [_|_],
 1021    !,
 1022    FT is F + 1,
 1023    AT is T - 1,
 1024    colour_item(goal_term(built_in, Goal), TB, Pos),
 1025    colour_item(goal(built_in, Goal), TB, F-FT),
 1026    colour_item(goal(built_in, Goal), TB, AT-T),
 1027    colourise_file_list(Goal, TB, Elms, TailPos, any).
 1028colourise_goal(Goal, Origin, TB, Pos) :-
 1029    Pos = list_position(F,T,Elms,Tail),
 1030    callable(Goal),
 1031    Goal =.. [_,GH,GT|_],
 1032    !,
 1033    goal_classification(TB, Goal, Origin, Class),
 1034    FT is F + 1,
 1035    AT is T - 1,
 1036    colour_item(goal_term(Class, Goal), TB, Pos),
 1037    colour_item(goal(Class, Goal), TB, F-FT),
 1038    colour_item(goal(Class, Goal), TB, AT-T),
 1039    colourise_list_args(Elms, Tail, [GH|GT], TB, classify).
 1040colourise_goal(Goal, _Origin, TB, Pos) :-
 1041    Pos = quasi_quotation_position(_F,_T,_QQType,_QQTypePos,_CPos),
 1042    !,
 1043    colourise_term_arg(Goal, TB, Pos).
 1044colourise_goal(Goal, Origin, TB, Pos) :-
 1045    strip_module(Goal, _, PGoal),
 1046    nonvar(PGoal),
 1047    (   goal_classification(TB, Goal, Origin, ClassInferred),
 1048        call_goal_colours(Goal, ClassInferred, ClassSpec-ArgSpecs)
 1049    ->  true
 1050    ;   call_goal_colours(Goal, ClassSpec-ArgSpecs)
 1051    ),
 1052    !,                                          % specified
 1053    functor_position(Pos, FPos, ArgPos),
 1054    (   ClassSpec == classify
 1055    ->  goal_classification(TB, Goal, Origin, Class)
 1056    ;   Class = ClassSpec
 1057    ),
 1058    colour_item(goal_term(Class, Goal), TB, Pos),
 1059    colour_item(goal(Class, Goal), TB, FPos),
 1060    colour_dict_braces(TB, Pos),
 1061    specified_items(ArgSpecs, Goal, TB, ArgPos).
 1062colourise_goal(Module:Goal, _Origin, TB, QGoalPos) :-
 1063    QGoalPos = term_position(_,_,QF,QT,[PM,PG]),
 1064    !,
 1065    colourise_module(Module, TB, PM),
 1066    colour_item(functor, TB, QF-QT),
 1067    (   PG = term_position(_,_,FF,FT,_)
 1068    ->  FP = FF-FT
 1069    ;   FP = PG
 1070    ),
 1071    (   callable(Goal)
 1072    ->  qualified_goal_classification(Module:Goal, TB, Class),
 1073        colour_item(goal_term(Class, Goal), TB, QGoalPos),
 1074        colour_item(goal(Class, Goal), TB, FP),
 1075        colourise_goal_args(Goal, Module, TB, PG)
 1076    ;   var(Goal)
 1077    ->  colourise_term_arg(Goal, TB, PG)
 1078    ;   colour_item(type_error(callable), TB, PG)
 1079    ).
 1080colourise_goal(Op, _Origin, TB, Pos) :-
 1081    nonvar(Op),
 1082    Op = op(_,_,_),
 1083    !,
 1084    colourise_op_declaration(Op, TB, Pos).
 1085colourise_goal(Goal, Origin, TB, Pos) :-
 1086    goal_classification(TB, Goal, Origin, Class),
 1087    (   Pos = term_position(_,_,FF,FT,_ArgPos)
 1088    ->  FPos = FF-FT
 1089    ;   FPos = Pos
 1090    ),
 1091    colour_item(goal_term(Class, Goal), TB, Pos),
 1092    colour_item(goal(Class, Goal), TB, FPos),
 1093    colourise_goal_args(Goal, TB, Pos).
 1094
 1095% make sure to emit a fragment for the braces of tag{k:v, ...} or
 1096% {...} that is mapped to something else.
 1097
 1098colour_dict_braces(TB, dict_position(_F,T,_TF,TT,_KVPos)) :-
 1099    !,
 1100    BStart is TT+1,
 1101    colour_item(dict_content, TB, BStart-T).
 1102colour_dict_braces(TB, brace_term_position(F,T,_Arg)) :-
 1103    !,
 1104    colour_item(brace_term, TB, F-T).
 1105colour_dict_braces(_, _).
 colourise_goal_args(+Goal, +TB, +Pos)
Colourise the arguments to a goal. This predicate deals with meta- and database-access predicates.
 1112colourise_goal_args(Goal, TB, Pos) :-
 1113    colourization_module(TB, Module),
 1114    colourise_goal_args(Goal, Module, TB, Pos).
 1115
 1116colourization_module(TB, Module) :-
 1117    (   colour_state_source_id(TB, SourceId),
 1118        xref_module(SourceId, Module)
 1119    ->  true
 1120    ;   Module = user
 1121    ).
 1122
 1123colourise_goal_args(Goal, M, TB, term_position(_,_,_,_,ArgPos)) :-
 1124    !,
 1125    (   meta_args(Goal, TB, MetaArgs)
 1126    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, ArgPos)
 1127    ;   colourise_goal_args(1, Goal, M, TB, ArgPos)
 1128    ).
 1129colourise_goal_args(Goal, M, TB, brace_term_position(_,_,ArgPos)) :-
 1130    !,
 1131    (   meta_args(Goal, TB, MetaArgs)
 1132    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, [ArgPos])
 1133    ;   colourise_goal_args(1, Goal, M, TB, [ArgPos])
 1134    ).
 1135colourise_goal_args(_, _, _, _).                % no arguments
 1136
 1137colourise_goal_args(_, _, _, _, []) :- !.
 1138colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1139    colourise_option_arg(Goal, Module, N, TB, P0),
 1140    !,
 1141    NN is N + 1,
 1142    colourise_goal_args(NN, Goal, Module, TB, PT).
 1143colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1144    arg(N, Goal, Arg),
 1145    colourise_term_arg(Arg, TB, P0),
 1146    NN is N + 1,
 1147    colourise_goal_args(NN, Goal, Module, TB, PT).
 1148
 1149
 1150colourise_meta_args(_, _, _, _, _, []) :- !.
 1151colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1152    colourise_option_arg(Goal, Module, N, TB, P0),
 1153    !,
 1154    NN is N + 1,
 1155    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1156colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1157    arg(N, Goal, Arg),
 1158    arg(N, MetaArgs, MetaSpec),
 1159    colourise_meta_arg(MetaSpec, Arg, TB, P0),
 1160    NN is N + 1,
 1161    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1162
 1163colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1164    nonvar(Arg),
 1165    expand_meta(MetaSpec, Arg, Expanded),
 1166    !,
 1167    colourise_goal(Expanded, [], TB, Pos). % TBD: recursion
 1168colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1169    nonvar(Arg),
 1170    MetaSpec == //,
 1171    !,
 1172    colourise_dcg_goals(Arg, //, TB, Pos).
 1173colourise_meta_arg(_, Arg, TB, Pos) :-
 1174    colourise_term_arg(Arg, TB, Pos).
 meta_args(+Goal, +TB, -ArgSpec) is semidet
Return a copy of Goal, where each meta-argument is an integer representing the number of extra arguments or the atom // for indicating a DCG body. The non-meta arguments are unbound variables.

E.g. meta_args(maplist(foo,x,y), X) --> X = maplist(2,_,_)

NOTE: this could be cached if performance becomes an issue.

 1187meta_args(Goal, TB, VarGoal) :-
 1188    colour_state_source_id(TB, SourceId),
 1189    xref_meta(SourceId, Goal, _),
 1190    !,
 1191    compound_name_arity(Goal, Name, Arity),
 1192    compound_name_arity(VarGoal, Name, Arity),
 1193    xref_meta(SourceId, VarGoal, MetaArgs),
 1194    instantiate_meta(MetaArgs).
 1195
 1196instantiate_meta([]).
 1197instantiate_meta([H|T]) :-
 1198    (   var(H)
 1199    ->  H = 0
 1200    ;   H = V+N
 1201    ->  V = N
 1202    ;   H = //(V)
 1203    ->  V = (//)
 1204    ),
 1205    instantiate_meta(T).
 expand_meta(+MetaSpec, +Goal, -Expanded) is semidet
Add extra arguments to the goal if the meta-specifier is an integer (see above).
 1212expand_meta(MetaSpec, Goal, Goal) :-
 1213    MetaSpec == 0.
 1214expand_meta(MetaSpec, M:Goal, M:Expanded) :-
 1215    atom(M),
 1216    !,
 1217    expand_meta(MetaSpec, Goal, Expanded).
 1218expand_meta(MetaSpec, Goal, Expanded) :-
 1219    integer(MetaSpec),
 1220    MetaSpec > 0,
 1221    (   atom(Goal)
 1222    ->  functor(Expanded, Goal, MetaSpec)
 1223    ;   compound(Goal)
 1224    ->  compound_name_arguments(Goal, Name, Args0),
 1225        length(Extra, MetaSpec),
 1226        append(Args0, Extra, Args),
 1227        compound_name_arguments(Expanded, Name, Args)
 1228    ).
 colourise_setof(+Term, +TB, +Pos)
Colourise the 2nd argument of setof/bagof
 1234colourise_setof(Var^G, TB, term_position(_,_,FF,FT,[VP,GP])) :-
 1235    !,
 1236    colourise_term_arg(Var, TB, VP),
 1237    colour_item(ext_quant, TB, FF-FT),
 1238    colourise_setof(G, TB, GP).
 1239colourise_setof(Term, TB, Pos) :-
 1240    colourise_goal(Term, [], TB, Pos).
 1241
 1242%       colourise_db(+Arg, +TB, +Pos)
 1243%
 1244%       Colourise database modification calls (assert/1, retract/1 and
 1245%       friends.
 1246
 1247colourise_db((Head:-_Body), TB, term_position(_,_,_,_,[HP,_])) :-
 1248    !,
 1249    colourise_db(Head, TB, HP).
 1250colourise_db(Module:Head, TB, term_position(_,_,QF,QT,[MP,HP])) :-
 1251    !,
 1252    colourise_module(Module, TB, MP),
 1253    colour_item(functor, TB, QF-QT),
 1254    (   atom(Module),
 1255        colour_state_source_id(TB, SourceId),
 1256        xref_module(SourceId, Module)
 1257    ->  colourise_db(Head, TB, HP)
 1258    ;   colourise_db(Head, TB, HP)
 1259    ).
 1260colourise_db(Head, TB, Pos) :-
 1261    colourise_goal(Head, '<db-change>', TB, Pos).
 colourise_option_args(+Goal, +Module, +Arg:integer, +TB, +ArgPos) is semidet
Colourise predicate options for the Arg-th argument of Module:Goal
 1270colourise_option_arg(Goal, Module, Arg, TB, ArgPos) :-
 1271    goal_name_arity(Goal, Name, Arity),
 1272    current_option_arg(Module:Name/Arity, Arg),
 1273    current_predicate_options(Module:Name/Arity, Arg, OptionDecl),
 1274    debug(emacs, 'Colouring option-arg ~w of ~p',
 1275          [Arg, Module:Name/Arity]),
 1276    arg(Arg, Goal, Options),
 1277    colourise_option(Options, Module, Goal, Arg, OptionDecl, TB, ArgPos).
 1278
 1279colourise_option(Options0, Module, Goal, Arg, OptionDecl, TB, Pos0) :-
 1280    strip_option_module_qualifier(Goal, Module, Arg, TB,
 1281                                  Options0, Pos0, Options, Pos),
 1282    (   Pos = list_position(F, T, ElmPos, TailPos)
 1283    ->  colour_item(list, TB, F-T),
 1284        colourise_option_list(Options, OptionDecl, TB, ElmPos, TailPos)
 1285    ;   (   var(Options)
 1286        ;   Options == []
 1287        )
 1288    ->  colourise_term_arg(Options, TB, Pos)
 1289    ;   colour_item(type_error(list), TB, Pos)
 1290    ).
 1291
 1292strip_option_module_qualifier(Goal, Module, Arg, TB,
 1293                              M:Options, term_position(_,_,_,_,[MP,Pos]),
 1294                              Options, Pos) :-
 1295    predicate_property(Module:Goal, meta_predicate(Head)),
 1296    arg(Arg, Head, :),
 1297    !,
 1298    colourise_module(M, TB, MP).
 1299strip_option_module_qualifier(_, _, _, _,
 1300                              Options, Pos, Options, Pos).
 1301
 1302
 1303colourise_option_list(_, _, _, [], none) :- !.
 1304colourise_option_list(Tail, _, TB, [], TailPos) :-
 1305    !,
 1306    colourise_term_arg(Tail, TB, TailPos).
 1307colourise_option_list([H|T], OptionDecl, TB, [HPos|TPos], TailPos) :-
 1308    colourise_option(H, OptionDecl, TB, HPos),
 1309    colourise_option_list(T, OptionDecl, TB, TPos, TailPos).
 1310
 1311colourise_option(Opt, _, TB, Pos) :-
 1312    var(Opt),
 1313    !,
 1314    colourise_term_arg(Opt, TB, Pos).
 1315colourise_option(Opt, OptionDecl, TB, term_position(_,_,FF,FT,ValPosList)) :-
 1316    !,
 1317    generalise_term(Opt, GenOpt),
 1318    (   memberchk(GenOpt, OptionDecl)
 1319    ->  colour_item(option_name, TB, FF-FT),
 1320        Opt =.. [Name|Values],
 1321        GenOpt =.. [Name|Types],
 1322        colour_option_values(Values, Types, TB, ValPosList)
 1323    ;   colour_item(no_option_name, TB, FF-FT),
 1324        colourise_term_args(ValPosList, 1, Opt, TB)
 1325    ).
 1326colourise_option(_, _, TB, Pos) :-
 1327    colour_item(type_error(option), TB, Pos).
 1328
 1329colour_option_values([], [], _, _).
 1330colour_option_values([V0|TV], [T0|TT], TB, [P0|TP]) :-
 1331    (   (   var(V0)
 1332        ;   is_of_type(T0, V0)
 1333        ;   T0 = list(_),
 1334            member(E, V0),
 1335            var(E)
 1336        ;   functor(V0, '.', 2),
 1337            V0 \= [_|_]
 1338        )
 1339    ->  colourise_term_arg(V0, TB, P0)
 1340    ;   callable(V0),
 1341        (   T0 = callable
 1342        ->  N = 0
 1343        ;   T0 = (callable+N)
 1344        )
 1345    ->  colourise_meta_arg(N, V0, TB, P0)
 1346    ;   colour_item(type_error(T0), TB, P0)
 1347    ),
 1348    colour_option_values(TV, TT, TB, TP).
 colourise_files(+Arg, +TB, +Pos, +Why)
Colourise the argument list of one of the file-loading predicates.
Arguments:
Why- is one of any or imported
 1357colourise_files(List, TB, list_position(F,T,Elms,TailPos), Why) :-
 1358    !,
 1359    colour_item(list, TB, F-T),
 1360    colourise_file_list(List, TB, Elms, TailPos, Why).
 1361colourise_files(M:Spec, TB, term_position(_,_,_,_,[MP,SP]), Why) :-
 1362    !,
 1363    colourise_module(M, TB, MP),
 1364    colourise_files(Spec, TB, SP, Why).
 1365colourise_files(Var, TB, P, _) :-
 1366    var(Var),
 1367    !,
 1368    colour_item(var, TB, P).
 1369colourise_files(Spec0, TB, Pos, Why) :-
 1370    strip_module(Spec0, _, Spec),
 1371    (   colour_state_source_id(TB, Source),
 1372        prolog_canonical_source(Source, SourceId),
 1373        catch(xref_source_file(Spec, Path, SourceId, [silent(true)]),
 1374              _, fail)
 1375    ->  (   Why = imported,
 1376            \+ resolves_anything(TB, Path),
 1377            exports_something(TB, Path)
 1378        ->  colour_item(file_no_depend(Path), TB, Pos)
 1379        ;   colour_item(file(Path), TB, Pos)
 1380        )
 1381    ;   colour_item(nofile, TB, Pos)
 1382    ).
 colourise_file_list(+Files, +TB, +ElmPos, +TailPos, +Why)
 1386colourise_file_list([], _, [], none, _).
 1387colourise_file_list(Last, TB, [], TailPos, _Why) :-
 1388    (   var(Last)
 1389    ->  colourise_term(Last, TB, TailPos)
 1390    ;   colour_item(type_error(list), TB, TailPos)
 1391    ).
 1392colourise_file_list([H|T], TB, [PH|PT], TailPos, Why) :-
 1393    colourise_files(H, TB, PH, Why),
 1394    colourise_file_list(T, TB, PT, TailPos, Why).
 1395
 1396resolves_anything(TB, Path) :-
 1397    colour_state_source_id(TB, SourceId),
 1398    xref_defined(SourceId, Head, imported(Path)),
 1399    xref_called(SourceId, Head, _),
 1400    !.
 1401
 1402exports_something(TB, Path) :-
 1403    colour_state_source_id(TB, SourceId),
 1404    xref_defined(SourceId, _, imported(Path)),
 1405    !.
 colourise_directory(+Arg, +TB, +Pos)
Colourise argument that should be an existing directory.
 1411colourise_directory(Spec, TB, Pos) :-
 1412    (   colour_state_source_id(TB, SourceId),
 1413        catch(xref_source_file(Spec, Path, SourceId,
 1414                               [ file_type(directory),
 1415                                 silent(true)
 1416                               ]),
 1417              _, fail)
 1418    ->  colour_item(directory(Path), TB, Pos)
 1419    ;   colour_item(nofile, TB, Pos)
 1420    ).
 colourise_langoptions(+Term, +TB, +Pos) is det
Colourise the 3th argument of module/3
 1426colourise_langoptions([], _, _) :- !.
 1427colourise_langoptions([H|T], TB, list_position(PF,PT,[HP|TP],_)) :-
 1428    !,
 1429    colour_item(list, TB, PF-PT),
 1430    colourise_langoptions(H, TB, HP),
 1431    colourise_langoptions(T, TB, TP).
 1432colourise_langoptions(Spec, TB, Pos) :-
 1433    colourise_files(library(dialect/Spec), TB, Pos, imported).
 colourise_class(ClassName, TB, Pos)
Colourise an XPCE class.
 1439colourise_class(ClassName, TB, Pos) :-
 1440    colour_state_source_id(TB, SourceId),
 1441    classify_class(SourceId, ClassName, Classification),
 1442    colour_item(class(Classification, ClassName), TB, Pos).
 classify_class(+SourceId, +ClassName, -Classification)
Classify an XPCE class. As long as this code is in this module rather than using hooks, we do not want to load xpce unless it is already loaded.
 1450classify_class(SourceId, Name, Class) :-
 1451    xref_defined_class(SourceId, Name, Class),
 1452    !.
 1453classify_class(_SourceId, Name, Class) :-
 1454    current_predicate(pce:send_class/3),
 1455    (   current_predicate(classify_class/2)
 1456    ->  true
 1457    ;   use_module(library(pce_meta), [classify_class/2])
 1458    ),
 1459    member(G, [classify_class(Name, Class)]),
 1460    call(G).
 colourise_term_args(+Term, +TB, +Pos)
colourise head/body principal terms.
 1466colourise_term_args(Term, TB,
 1467                    term_position(_,_,_,_,ArgPos)) :-
 1468    !,
 1469    colourise_term_args(ArgPos, 1, Term, TB).
 1470colourise_term_args(_, _, _).
 1471
 1472colourise_term_args([], _, _, _).
 1473colourise_term_args([Pos|T], N, Term, TB) :-
 1474    arg(N, Term, Arg),
 1475    colourise_term_arg(Arg, TB, Pos),
 1476    NN is N + 1,
 1477    colourise_term_args(T, NN, Term, TB).
 1478
 1479colourise_term_arg(_, _, Pos) :-
 1480    var(Pos),
 1481    !.
 1482colourise_term_arg(Arg, TB, parentheses_term_position(PO,PC,Pos)) :-
 1483    !,
 1484    colour_item(parentheses, TB, PO-PC),
 1485    colourise_term_arg(Arg, TB, Pos).
 1486colourise_term_arg(Var, TB, Pos) :-                     % variable
 1487    var(Var), Pos = _-_,
 1488    !,
 1489    (   singleton(Var, TB)
 1490    ->  colour_item(singleton, TB, Pos)
 1491    ;   colour_item(var, TB, Pos)
 1492    ).
 1493colourise_term_arg(List, TB, list_position(F, T, Elms, Tail)) :-
 1494    !,
 1495    colour_item(list, TB, F-T),
 1496    colourise_list_args(Elms, Tail, List, TB, classify).    % list
 1497colourise_term_arg(String, TB, string_position(F, T)) :-       % string
 1498    !,
 1499    (   string(String)
 1500    ->  colour_item(string, TB, F-T)
 1501    ;   String = [H|_]
 1502    ->  (   integer(H)
 1503        ->  colour_item(codes, TB, F-T)
 1504        ;   colour_item(chars, TB, F-T)
 1505        )
 1506    ;   String == []
 1507    ->  colour_item(codes, TB, F-T)
 1508    ).
 1509colourise_term_arg(_, TB,
 1510                   quasi_quotation_position(F,T,QQType,QQTypePos,CPos)) :-
 1511    !,
 1512    colourise_qq_type(QQType, TB, QQTypePos),
 1513    functor_name(QQType, Type),
 1514    colour_item(qq_content(Type), TB, CPos),
 1515    arg(1, CPos, SE),
 1516    SS is SE-2,
 1517    FE is F+2,
 1518    TS is T-2,
 1519    colour_item(qq(open),  TB, F-FE),
 1520    colour_item(qq(sep),   TB, SS-SE),
 1521    colour_item(qq(close), TB, TS-T).
 1522colourise_term_arg({Term}, TB, brace_term_position(F,T,Arg)) :-
 1523    !,
 1524    colour_item(brace_term, TB, F-T),
 1525    colourise_term_arg(Term, TB, Arg).
 1526colourise_term_arg(Map, TB, dict_position(F,T,TF,TT,KVPos)) :-
 1527    !,
 1528    is_dict(Map, Tag),
 1529    colour_item(dict, TB, F-T),
 1530    TagPos = TF-TT,
 1531    (   var(Tag)
 1532    ->  (   singleton(Tag, TB)
 1533        ->  colour_item(singleton, TB, TagPos)
 1534        ;   colour_item(var, TB, TagPos)
 1535        )
 1536    ;   colour_item(dict_tag, TB, TagPos)
 1537    ),
 1538    BStart is TT+1,
 1539    colour_item(dict_content, TB, BStart-T),
 1540    colourise_dict_kv(Map, TB, KVPos).
 1541colourise_term_arg([](List,Term), TB,                   % [] as operator
 1542                   term_position(_,_,0,0,[ListPos,ArgPos])) :-
 1543    !,
 1544    colourise_term_arg(List, TB, ListPos),
 1545    colourise_term_arg(Term, TB, ArgPos).
 1546colourise_term_arg(Compound, TB, Pos) :-                % compound
 1547    compound(Compound),
 1548    !,
 1549    (   Pos = term_position(_F,_T,FF,FT,_ArgPos)
 1550    ->  colour_item(functor, TB, FF-FT)             % TBD: Infix/Postfix?
 1551    ;   true                                        % TBD: When is this
 1552    ),
 1553    colourise_term_args(Compound, TB, Pos).
 1554colourise_term_arg(EmptyList, TB, Pos) :-
 1555    EmptyList == [],
 1556    !,
 1557    colour_item(empty_list, TB, Pos).
 1558colourise_term_arg(Atom, TB, Pos) :-
 1559    atom(Atom),
 1560    !,
 1561    colour_item(atom, TB, Pos).
 1562colourise_term_arg(Integer, TB, Pos) :-
 1563    integer(Integer),
 1564    !,
 1565    colour_item(int, TB, Pos).
 1566colourise_term_arg(Rational, TB, Pos) :-
 1567    rational(Rational),
 1568    !,
 1569    colour_item(rational(Rational), TB, Pos).
 1570colourise_term_arg(Float, TB, Pos) :-
 1571    float(Float),
 1572    !,
 1573    colour_item(float, TB, Pos).
 1574colourise_term_arg(_Arg, _TB, _Pos) :-
 1575    true.
 1576
 1577colourise_list_args([HP|TP], Tail, [H|T], TB, How) :-
 1578    specified_item(How, H, TB, HP),
 1579    colourise_list_args(TP, Tail, T, TB, How).
 1580colourise_list_args([], none, _, _, _) :- !.
 1581colourise_list_args([], TP, T, TB, How) :-
 1582    specified_item(How, T, TB, TP).
 colourise_qq_type(+QQType, +TB, +QQTypePos)
Colouring the type part of a quasi quoted term
 1588colourise_qq_type(QQType, TB, QQTypePos) :-
 1589    functor_position(QQTypePos, FPos, _),
 1590    colour_item(qq_type, TB, FPos),
 1591    colourise_term_args(QQType, TB, QQTypePos).
 1592
 1593qq_position(quasi_quotation_position(_,_,_,_,_)).
 colourise_dict_kv(+Dict, +TB, +KVPosList)
Colourise the name-value pairs in the dict
 1599colourise_dict_kv(_, _, []) :- !.
 1600colourise_dict_kv(Dict, TB, [key_value_position(_F,_T,SF,ST,K,KP,VP)|KV]) :-
 1601    colour_item(dict_key, TB, KP),
 1602    colour_item(dict_sep, TB, SF-ST),
 1603    get_dict(K, Dict, V),
 1604    colourise_term_arg(V, TB, VP),
 1605    colourise_dict_kv(Dict, TB, KV).
 colourise_exports(+List, +TB, +Pos)
Colourise the module export-list (or any other list holding terms of the form Name/Arity referring to predicates).
 1613colourise_exports([], TB, Pos) :- !,
 1614    colourise_term_arg([], TB, Pos).
 1615colourise_exports(List, TB, list_position(F,T,ElmPos,Tail)) :-
 1616    !,
 1617    colour_item(list, TB, F-T),
 1618    (   Tail == none
 1619    ->  true
 1620    ;   colour_item(type_error(list), TB, Tail)
 1621    ),
 1622    colourise_exports2(List, TB, ElmPos).
 1623colourise_exports(_, TB, Pos) :-
 1624    colour_item(type_error(list), TB, Pos).
 1625
 1626colourise_exports2([G0|GT], TB, [P0|PT]) :-
 1627    !,
 1628    colourise_declaration(G0, export, TB, P0),
 1629    colourise_exports2(GT, TB, PT).
 1630colourise_exports2(_, _, _).
 colourise_imports(+List, +File, +TB, +Pos)
Colourise import list from use_module/2, importing from File.
 1637colourise_imports(List, File, TB, Pos) :-
 1638    (   colour_state_source_id(TB, SourceId),
 1639        ground(File),
 1640        catch(xref_public_list(File, SourceId,
 1641                               [ path(Path),
 1642                                 public(Public),
 1643                                 silent(true)
 1644                               ] ), _, fail)
 1645    ->  true
 1646    ;   Public = [],
 1647        Path = (-)
 1648    ),
 1649    colourise_imports(List, Path, Public, TB, Pos).
 1650
 1651colourise_imports([], _, _, TB, Pos) :-
 1652    !,
 1653    colour_item(empty_list, TB, Pos).
 1654colourise_imports(List, File, Public, TB, list_position(F,T,ElmPos,Tail)) :-
 1655    !,
 1656    colour_item(list, TB, F-T),
 1657    (   Tail == none
 1658    ->  true
 1659    ;   colour_item(type_error(list), TB, Tail)
 1660    ),
 1661    colourise_imports2(List, File, Public, TB, ElmPos).
 1662colourise_imports(except(Except), File, Public, TB,
 1663                  term_position(_,_,FF,FT,[LP])) :-
 1664    !,
 1665    colour_item(keyword(except), TB, FF-FT),
 1666    colourise_imports(Except, File, Public, TB, LP).
 1667colourise_imports(_, _, _, TB, Pos) :-
 1668    colour_item(type_error(list), TB, Pos).
 1669
 1670colourise_imports2([G0|GT], File, Public, TB, [P0|PT]) :-
 1671    !,
 1672    colourise_import(G0, File, TB, P0),
 1673    colourise_imports2(GT, File, Public, TB, PT).
 1674colourise_imports2(_, _, _, _, _).
 1675
 1676
 1677colourise_import(PI as Name, File, TB, term_position(_,_,FF,FT,[PP,NP])) :-
 1678    pi_to_term(PI, Goal),
 1679    !,
 1680    colour_item(goal(imported(File), Goal), TB, PP),
 1681    rename_goal(Goal, Name, NewGoal),
 1682    goal_classification(TB, NewGoal, [], Class),
 1683    colour_item(goal(Class, NewGoal), TB, NP),
 1684    colour_item(keyword(as), TB, FF-FT).
 1685colourise_import(PI, File, TB, Pos) :-
 1686    pi_to_term(PI, Goal),
 1687    colour_state_source_id(TB, SourceID),
 1688    (   \+ xref_defined(SourceID, Goal, imported(File))
 1689    ->  colour_item(undefined_import, TB, Pos)
 1690    ;   \+ xref_called(SourceID, Goal, _)
 1691    ->  colour_item(unused_import, TB, Pos)
 1692    ),
 1693    !.
 1694colourise_import(PI, _, TB, Pos) :-
 1695    colourise_declaration(PI, import, TB, Pos).
 colourise_declaration(+Decl, ?Which, +TB, +Pos) is det
Colourise declaration sequences as used by module/2, dynamic/1, etc.
 1702colourise_declaration(PI, _, TB, term_position(F,T,FF,FT,[NamePos,ArityPos])) :-
 1703    pi_to_term(PI, Goal),
 1704    !,
 1705    goal_classification(TB, Goal, [], Class),
 1706    colour_item(predicate_indicator(Class, Goal), TB, F-T),
 1707    colour_item(goal(Class, Goal), TB, NamePos),
 1708    colour_item(predicate_indicator, TB, FF-FT),
 1709    colour_item(arity, TB, ArityPos).
 1710colourise_declaration(Module:PI, _, TB,
 1711                      term_position(_,_,QF,QT,[PM,PG])) :-
 1712    atom(Module), pi_to_term(PI, Goal),
 1713    !,
 1714    colourise_module(M, TB, PM),
 1715    colour_item(functor, TB, QF-QT),
 1716    colour_item(predicate_indicator(extern(M), Goal), TB, PG),
 1717    PG = term_position(_,_,FF,FT,[NamePos,ArityPos]),
 1718    colour_item(goal(extern(M), Goal), TB, NamePos),
 1719    colour_item(predicate_indicator, TB, FF-FT),
 1720    colour_item(arity, TB, ArityPos).
 1721colourise_declaration(Module:PI, _, TB,
 1722                      term_position(_,_,QF,QT,[PM,PG])) :-
 1723    atom(Module), nonvar(PI), PI = Name/Arity,
 1724    !,                                  % partial predicate indicators
 1725    colourise_module(Module, TB, PM),
 1726    colour_item(functor, TB, QF-QT),
 1727    (   (var(Name) ; atom(Name)),
 1728        (var(Arity) ; integer(Arity), Arity >= 0)
 1729    ->  colourise_term_arg(PI, TB, PG)
 1730    ;   colour_item(type_error(predicate_indicator), TB, PG)
 1731    ).
 1732colourise_declaration(op(N,T,P), Which, TB, Pos) :-
 1733    (   Which == export
 1734    ;   Which == import
 1735    ),
 1736    !,
 1737    colour_item(exported_operator, TB, Pos),
 1738    colourise_op_declaration(op(N,T,P), TB, Pos).
 1739colourise_declaration(Module:Goal, table, TB,
 1740                      term_position(_,_,QF,QT,
 1741                                    [PM,term_position(_F,_T,FF,FT,ArgPos)])) :-
 1742    atom(Module), callable(Goal),
 1743    !,
 1744    colourise_module(Module, TB, PM),
 1745    colour_item(functor, TB, QF-QT),
 1746    goal_classification(TB, Module:Goal, [], Class),
 1747    compound_name_arguments(Goal, _, Args),
 1748    colour_item(goal(Class, Goal), TB, FF-FT),
 1749    colourise_table_modes(Args, TB, ArgPos).
 1750colourise_declaration(Goal, table, TB, term_position(_F,_T,FF,FT,ArgPos)) :-
 1751    callable(Goal),
 1752    !,
 1753    compound_name_arguments(Goal, _, Args),
 1754    goal_classification(TB, Goal, [], Class),
 1755    colour_item(goal(Class, Goal), TB, FF-FT),
 1756    colourise_table_modes(Args, TB, ArgPos).
 1757colourise_declaration(Goal, table, TB, Pos) :-
 1758    atom(Goal),
 1759    !,
 1760    goal_classification(TB, Goal, [], Class),
 1761    colour_item(goal(Class, Goal), TB, Pos).
 1762colourise_declaration(Partial, _Which, TB, Pos) :-
 1763    compatible_with_pi(Partial),
 1764    !,
 1765    colourise_term_arg(Partial, TB, Pos).
 1766colourise_declaration(_, Which, TB, Pos) :-
 1767    colour_item(type_error(declaration(Which)), TB, Pos).
 1768
 1769compatible_with_pi(Term) :-
 1770    var(Term),
 1771    !.
 1772compatible_with_pi(Name/Arity) :-
 1773    !,
 1774    var_or_atom(Name),
 1775    var_or_nonneg(Arity).
 1776compatible_with_pi(Name//Arity) :-
 1777    !,
 1778    var_or_atom(Name),
 1779    var_or_nonneg(Arity).
 1780compatible_with_pi(M:T) :-
 1781    var_or_atom(M),
 1782    compatible_with_pi(T).
 1783
 1784var_or_atom(X) :- var(X), !.
 1785var_or_atom(X) :- atom(X).
 1786var_or_nonneg(X) :- var(X), !.
 1787var_or_nonneg(X) :- integer(X), X >= 0, !.
 1788
 1789pi_to_term(Name/Arity, Term) :-
 1790    (atom(Name)->true;Name==[]), integer(Arity), Arity >= 0,
 1791    !,
 1792    functor(Term, Name, Arity).
 1793pi_to_term(Name//Arity0, Term) :-
 1794    atom(Name), integer(Arity0), Arity0 >= 0,
 1795    !,
 1796    Arity is Arity0 + 2,
 1797    functor(Term, Name, Arity).
 1798
 1799colourise_meta_declarations((Head,Tail), Extra, TB,
 1800                            term_position(_,_,_,_,[PH,PT])) :-
 1801    !,
 1802    colourise_meta_declaration(Head, Extra, TB, PH),
 1803    colourise_meta_declarations(Tail, Extra, TB, PT).
 1804colourise_meta_declarations(Last, Extra, TB, Pos) :-
 1805    colourise_meta_declaration(Last, Extra, TB, Pos).
 1806
 1807colourise_meta_declaration(M:Head, Extra, TB,
 1808                           term_position(_,_,QF,QT,
 1809                                         [ MP,
 1810                                           term_position(_,_,FF,FT,ArgPos)
 1811                                         ])) :-
 1812    compound(Head),
 1813    !,
 1814    colourise_module(M, TB, MP),
 1815    colour_item(functor, TB, QF-QT),
 1816    colour_item(goal(extern(M),Head), TB, FF-FT),
 1817    compound_name_arguments(Head, _, Args),
 1818    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1819colourise_meta_declaration(Head, Extra, TB, term_position(_,_,FF,FT,ArgPos)) :-
 1820    compound(Head),
 1821    !,
 1822    goal_classification(TB, Head, [], Class),
 1823    colour_item(goal(Class, Head), TB, FF-FT),
 1824    compound_name_arguments(Head, _, Args),
 1825    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1826colourise_meta_declaration([H|T], Extra, TB, list_position(LF,LT,[HP],TP)) :-
 1827    !,
 1828    colour_item(list, TB, LF-LT),
 1829    colourise_meta_decls([H,T], Extra, TB, [HP,TP]).
 1830colourise_meta_declaration(_, _, TB, Pos) :-
 1831    !,
 1832    colour_item(type_error(compound), TB, Pos).
 1833
 1834colourise_meta_decls([], _, _, []).
 1835colourise_meta_decls([Arg|ArgT], Extra, TB, [PosH|PosT]) :-
 1836    colourise_meta_decl(Arg, Extra, TB, PosH),
 1837    colourise_meta_decls(ArgT, Extra, TB, PosT).
 1838
 1839colourise_meta_decl(Arg, Extra, TB, Pos) :-
 1840    nonvar(Arg),
 1841    (   valid_meta_decl(Arg)
 1842    ->  true
 1843    ;   memberchk(Arg, Extra)
 1844    ),
 1845    colour_item(meta(Arg), TB, Pos).
 1846colourise_meta_decl(_, _, TB, Pos) :-
 1847    colour_item(error, TB, Pos).
 1848
 1849valid_meta_decl(:).
 1850valid_meta_decl(*).
 1851valid_meta_decl(//).
 1852valid_meta_decl(^).
 1853valid_meta_decl(?).
 1854valid_meta_decl(+).
 1855valid_meta_decl(-).
 1856valid_meta_decl(I) :- integer(I), between(0,9,I).
 colourise_declarations(+Term, +Which, +TB, +Pos)
Colourise specification for dynamic/1, table/1, etc. Includes processing options such as :- dynamic p/1 as incremental..
 1863colourise_declarations(List, Which, TB, list_position(F,T,Elms,none)) :-
 1864    !,
 1865    colour_item(list, TB, F-T),
 1866    colourise_list_declarations(List, Which, TB, Elms).
 1867colourise_declarations(Term, Which, TB, parentheses_term_position(PO,PC,Pos)) :-
 1868    !,
 1869    colour_item(parentheses, TB, PO-PC),
 1870    colourise_declarations(Term, Which, TB, Pos).
 1871colourise_declarations((Head,Tail), Which, TB,
 1872                             term_position(_,_,_,_,[PH,PT])) :-
 1873    !,
 1874    colourise_declarations(Head, Which, TB, PH),
 1875    colourise_declarations(Tail, Which, TB, PT).
 1876colourise_declarations(as(Spec, Options), Which, TB,
 1877                             term_position(_,_,FF,FT,[PH,PT])) :-
 1878    !,
 1879    colour_item(keyword(as), TB, FF-FT),
 1880    colourise_declarations(Spec, Which, TB, PH),
 1881    colourise_decl_options(Options, Which, TB, PT).
 1882colourise_declarations(PI, Which, TB, Pos) :-
 1883    colourise_declaration(PI, Which, TB, Pos).
 1884
 1885colourise_list_declarations([], _, _, []).
 1886colourise_list_declarations([H|T], Which, TB, [HP|TP]) :-
 1887    colourise_declaration(H, Which, TB, HP),
 1888    colourise_list_declarations(T, Which, TB, TP).
 1889
 1890
 1891colourise_table_modes([], _, _).
 1892colourise_table_modes([H|T], TB, [PH|PT]) :-
 1893    colourise_table_mode(H, TB, PH),
 1894    colourise_table_modes(T, TB, PT).
 1895
 1896colourise_table_mode(H, TB, Pos) :-
 1897    table_mode(H, Mode),
 1898    !,
 1899    colour_item(table_mode(Mode), TB, Pos).
 1900colourise_table_mode(lattice(Spec), TB, term_position(_F,_T,FF,FT,[ArgPos])) :-
 1901    !,
 1902    colour_item(table_mode(lattice), TB, FF-FT),
 1903    table_moded_call(Spec, 3, TB, ArgPos).
 1904colourise_table_mode(po(Spec), TB, term_position(_F,_T,FF,FT,[ArgPos])) :-
 1905    !,
 1906    colour_item(table_mode(po), TB, FF-FT),
 1907    table_moded_call(Spec, 2, TB, ArgPos).
 1908colourise_table_mode(_, TB, Pos) :-
 1909    colour_item(type_error(table_mode), TB, Pos).
 1910
 1911table_mode(Var, index) :-
 1912    var(Var),
 1913    !.
 1914table_mode(+, index).
 1915table_mode(index, index).
 1916table_mode(-, first).
 1917table_mode(first, first).
 1918table_mode(last, last).
 1919table_mode(min, min).
 1920table_mode(max, max).
 1921table_mode(sum, sum).
 1922
 1923table_moded_call(Atom, Arity, TB, Pos) :-
 1924    atom(Atom),
 1925    functor(Head, Atom, Arity),
 1926    goal_classification(TB, Head, [], Class),
 1927    colour_item(goal(Class, Head), TB, Pos).
 1928table_moded_call(Atom/Arity, Arity, TB,
 1929                 term_position(_,_,FF,FT,[NP,AP])) :-
 1930    atom(Atom),
 1931    !,
 1932    functor(Head, Atom, Arity),
 1933    goal_classification(TB, Head, [], Class),
 1934    colour_item(goal(Class, Head), TB, NP),
 1935    colour_item(predicate_indicator, TB, FF-FT),
 1936    colour_item(arity, TB, AP).
 1937table_moded_call(Head, Arity, TB, Pos) :-
 1938    Pos = term_position(_,_,FF,FT,_),
 1939    compound(Head),
 1940    !,
 1941    compound_name_arity(Head, _Name, Arity),
 1942    goal_classification(TB, Head, [], Class),
 1943    colour_item(goal(Class, Head), TB, FF-FT),
 1944    colourise_term_args(Head, TB, Pos).
 1945table_moded_call(_, _, TB, Pos) :-
 1946    colour_item(type_error(predicate_name_or_indicator), TB, Pos).
 1947
 1948colourise_decl_options(Options, Which, TB,
 1949                       parentheses_term_position(_,_,Pos)) :-
 1950    !,
 1951    colourise_decl_options(Options, Which, TB, Pos).
 1952colourise_decl_options((Head,Tail), Which, TB,
 1953                        term_position(_,_,_,_,[PH,PT])) :-
 1954    !,
 1955    colourise_decl_options(Head, Which, TB, PH),
 1956    colourise_decl_options(Tail, Which, TB, PT).
 1957colourise_decl_options(Option, Which, TB, Pos) :-
 1958    ground(Option),
 1959    valid_decl_option(Option, Which),
 1960    !,
 1961    functor(Option, Name, _),
 1962    (   Pos = term_position(_,_,FF,FT,[ArgPos])
 1963    ->  colour_item(decl_option(Name), TB, FF-FT),
 1964        (   arg(1, Option, Value),
 1965            nonneg_or_false(Value)
 1966        ->  colourise_term_arg(Value, TB, ArgPos)
 1967        ;   colour_item(type_error(decl_option_value(Which)), TB, ArgPos)
 1968        )
 1969    ;   colour_item(decl_option(Name), TB, Pos)
 1970    ).
 1971colourise_decl_options(_, Which, TB, Pos) :-
 1972    colour_item(type_error(decl_option(Which)), TB, Pos).
 1973
 1974valid_decl_option(subsumptive,         table).
 1975valid_decl_option(variant,             table).
 1976valid_decl_option(incremental,         table).
 1977valid_decl_option(monotonic,           table).
 1978valid_decl_option(opaque,              table).
 1979valid_decl_option(lazy,                table).
 1980valid_decl_option(monotonic,           dynamic).
 1981valid_decl_option(incremental,         dynamic).
 1982valid_decl_option(abstract(_),         dynamic).
 1983valid_decl_option(opaque,              dynamic).
 1984valid_decl_option(shared,              table).
 1985valid_decl_option(private,             table).
 1986valid_decl_option(subgoal_abstract(_), table).
 1987valid_decl_option(answer_abstract(_),  table).
 1988valid_decl_option(max_answers(_),      table).
 1989valid_decl_option(shared,              dynamic).
 1990valid_decl_option(private,             dynamic).
 1991valid_decl_option(local,               dynamic).
 1992valid_decl_option(multifile,           _).
 1993valid_decl_option(discontiguous,       _).
 1994valid_decl_option(volatile,            _).
 1995
 1996nonneg_or_false(Value) :-
 1997    var(Value),
 1998    !.
 1999nonneg_or_false(Value) :-
 2000    integer(Value), Value >= 0,
 2001    !.
 2002nonneg_or_false(off).
 2003nonneg_or_false(false).
 colourise_op_declaration(Op, TB, Pos) is det
 2007colourise_op_declaration(op(P,T,N), TB, term_position(_,_,FF,FT,[PP,TP,NP])) :-
 2008    colour_item(goal(built_in, op(N,T,P)), TB, FF-FT),
 2009    colour_op_priority(P, TB, PP),
 2010    colour_op_type(T, TB, TP),
 2011    colour_op_name(N, TB, NP).
 2012
 2013colour_op_name(_, _, Pos) :-
 2014    var(Pos),
 2015    !.
 2016colour_op_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 2017    !,
 2018    colour_item(parentheses, TB, PO-PC),
 2019    colour_op_name(Name, TB, Pos).
 2020colour_op_name(Name, TB, Pos) :-
 2021    var(Name),
 2022    !,
 2023    colour_item(var, TB, Pos).
 2024colour_op_name(Name, TB, Pos) :-
 2025    (atom(Name) ; Name == []),
 2026    !,
 2027    colour_item(identifier, TB, Pos).
 2028colour_op_name(Module:Name, TB, term_position(_F,_T,QF,QT,[MP,NP])) :-
 2029    !,
 2030    colourise_module(Module, TB, MP),
 2031    colour_item(functor, TB, QF-QT),
 2032    colour_op_name(Name, TB, NP).
 2033colour_op_name(List, TB, list_position(F,T,Elems,none)) :-
 2034    !,
 2035    colour_item(list, TB, F-T),
 2036    colour_op_names(List, TB, Elems).
 2037colour_op_name(_, TB, Pos) :-
 2038    colour_item(error, TB, Pos).
 2039
 2040colour_op_names([], _, []).
 2041colour_op_names([H|T], TB, [HP|TP]) :-
 2042    colour_op_name(H, TB, HP),
 2043    colour_op_names(T, TB, TP).
 2044
 2045colour_op_type(Type, TB, Pos) :-
 2046    var(Type),
 2047    !,
 2048    colour_item(var, TB, Pos).
 2049colour_op_type(Type, TB, Pos) :-
 2050    op_type(Type),
 2051    !,
 2052    colour_item(op_type(Type), TB, Pos).
 2053colour_op_type(_, TB, Pos) :-
 2054    colour_item(error, TB, Pos).
 2055
 2056colour_op_priority(Priority, TB, Pos) :-
 2057    var(Priority), colour_item(var, TB, Pos).
 2058colour_op_priority(Priority, TB, Pos) :-
 2059    integer(Priority),
 2060    between(0, 1200, Priority),
 2061    !,
 2062    colour_item(int, TB, Pos).
 2063colour_op_priority(_, TB, Pos) :-
 2064    colour_item(error, TB, Pos).
 2065
 2066op_type(fx).
 2067op_type(fy).
 2068op_type(xf).
 2069op_type(yf).
 2070op_type(xfy).
 2071op_type(xfx).
 2072op_type(yfx).
 colourise_prolog_flag_name(+Name, +TB, +Pos)
Colourise the name of a Prolog flag
 2079colourise_prolog_flag_name(_, _, Pos) :-
 2080    var(Pos),
 2081    !.
 2082colourise_prolog_flag_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 2083    !,
 2084    colour_item(parentheses, TB, PO-PC),
 2085    colourise_prolog_flag_name(Name, TB, Pos).
 2086colourise_prolog_flag_name(Name, TB, Pos) :-
 2087    atom(Name),
 2088    !,
 2089    (   current_prolog_flag(Name, _)
 2090    ->  colour_item(flag_name(Name), TB, Pos)
 2091    ;   colour_item(no_flag_name(Name), TB, Pos)
 2092    ).
 2093colourise_prolog_flag_name(Name, TB, Pos) :-
 2094    colourise_term(Name, TB, Pos).
 2095
 2096
 2097                 /*******************************
 2098                 *        CONFIGURATION         *
 2099                 *******************************/
 2100
 2101%       body_compiled(+Term)
 2102%
 2103%       Succeeds if term is a construct handled by the compiler.
 2104
 2105body_compiled((_,_)).
 2106body_compiled((_->_)).
 2107body_compiled((_*->_)).
 2108body_compiled((_;_)).
 2109body_compiled(\+_).
 goal_classification(+TB, +Goal, +Origin, -Class)
Classify Goal appearing in TB and called from a clause with head Origin. For directives, Origin is [].
 2116goal_classification(_, QGoal, _, Class) :-
 2117    strip_module(QGoal, _, Goal),
 2118    (   var(Goal)
 2119    ->  !, Class = meta
 2120    ;   \+ callable(Goal)
 2121    ->  !, Class = not_callable
 2122    ).
 2123goal_classification(_, Goal, Origin, recursion) :-
 2124    callable(Origin),
 2125    generalise_term(Goal, Origin),
 2126    !.
 2127goal_classification(TB, Goal, _, How) :-
 2128    colour_state_source_id(TB, SourceId),
 2129    xref_defined(SourceId, Goal, How),
 2130    How \= public(_),
 2131    !.
 2132goal_classification(TB, Goal, _, Class) :-
 2133    (   colour_state_source_id(TB, SourceId),
 2134        xref_module(SourceId, Module)
 2135    ->  true
 2136    ;   Module = user
 2137    ),
 2138    call_goal_classification(Goal, Module, Class),
 2139    !.
 2140goal_classification(TB, Goal, _, How) :-
 2141    colour_state_module(TB, Module),
 2142    atom(Module),
 2143    Module \== prolog_colour_ops,
 2144    predicate_property(Module:Goal, imported_from(From)),
 2145    !,
 2146    How = imported(From).
 2147goal_classification(_TB, _Goal, _, undefined).
 goal_classification(+Goal, +Module, -Class)
Multifile hookable classification for non-local goals.
 2153call_goal_classification(Goal, Module, Class) :-
 2154    catch(global_goal_classification(Goal, Module, Class), _,
 2155          Class = type_error(callable)).
 2156
 2157global_goal_classification(Goal, _, built_in) :-
 2158    built_in_predicate(Goal),
 2159    !.
 2160global_goal_classification(Goal, _, autoload(From)) :-  % SWI-Prolog
 2161    predicate_property(Goal, autoload(From)).
 2162global_goal_classification(Goal, Module, Class) :-      % SWI-Prolog
 2163    strip_module(Goal, _, PGoal),
 2164    current_predicate(_, user:PGoal),
 2165    !,
 2166    (   Module == user
 2167    ->  Class = global(GClass, Location),
 2168        global_location(user:Goal, Location),
 2169        global_class(user:Goal, GClass)
 2170    ;   Class = global
 2171    ).
 2172global_goal_classification(Goal, _, Class) :-
 2173    compound(Goal),
 2174    compound_name_arity(Goal, Name, Arity),
 2175    vararg_goal_classification(Name, Arity, Class).
 2176
 2177global_location(Goal, File:Line) :-
 2178    predicate_property(Goal, file(File)),
 2179    predicate_property(Goal, line_count(Line)),
 2180    !.
 2181global_location(_, -).
 2182
 2183global_class(Goal, dynamic)   :- predicate_property(Goal, dynamic), !.
 2184global_class(Goal, multifile) :- predicate_property(Goal, multifile), !.
 2185global_class(Goal, tabled)    :- predicate_property(Goal, tabled), !.
 2186global_class(_,    static).
 vararg_goal_classification(+Name, +Arity, -Class) is semidet
Multifile hookable classification for vararg predicates.
 2193vararg_goal_classification(call, Arity, built_in) :-
 2194    Arity >= 1.
 2195vararg_goal_classification(send_super, Arity, expanded) :- % XPCE (TBD)
 2196    Arity >= 2.
 2197vararg_goal_classification(get_super, Arity, expanded) :-  % XPCE (TBD)
 2198    Arity >= 3.
 qualified_goal_classification(:Goal, +TB, -Class)
Classify an explicitly qualified goal.
 2204qualified_goal_classification(Goal, TB, Class) :-
 2205    goal_classification(TB, Goal, [], Class),
 2206    Class \== undefined,
 2207    !.
 2208qualified_goal_classification(Module:Goal, _, extern(Module, How)) :-
 2209    predicate_property(Module:Goal, visible),
 2210    !,
 2211    (   (   predicate_property(Module:Goal, public)
 2212        ;   predicate_property(Module:Goal, exported)
 2213        )
 2214    ->  How = (public)
 2215    ;   How = (private)
 2216    ).
 2217qualified_goal_classification(Module:_, _, extern(Module, unknown)).
 classify_head(+TB, +Head, -Class)
Classify a clause head
 2223classify_head(TB, Goal, exported) :-
 2224    colour_state_source_id(TB, SourceId),
 2225    xref_exported(SourceId, Goal),
 2226    !.
 2227classify_head(_TB, Goal, hook) :-
 2228    xref_hook(Goal),
 2229    !.
 2230classify_head(TB, Goal, hook) :-
 2231    colour_state_source_id(TB, SourceId),
 2232    xref_module(SourceId, M),
 2233    xref_hook(M:Goal),
 2234    !.
 2235classify_head(TB, Goal, Class) :-
 2236    built_in_predicate(Goal),
 2237    (   system_module(TB)
 2238    ->  (   predicate_property(system:Goal, iso)
 2239        ->  Class = def_iso
 2240        ;   goal_name(Goal, Name),
 2241            \+ sub_atom(Name, 0, _, _, $)
 2242        ->  Class = def_swi
 2243        )
 2244    ;   (   predicate_property(system:Goal, iso)
 2245        ->  Class = iso
 2246        ;   Class = built_in
 2247        )
 2248    ).
 2249classify_head(TB, Goal, unreferenced) :-
 2250    colour_state_source_id(TB, SourceId),
 2251    \+ (xref_called(SourceId, Goal, By), By \= Goal),
 2252    !.
 2253classify_head(TB, Goal, How) :-
 2254    colour_state_source_id(TB, SourceId),
 2255    (   xref_defined(SourceId, Goal, imported(From))
 2256    ->  How = imported(From)
 2257    ;   xref_defined(SourceId, Goal, How)
 2258    ),
 2259    !.
 2260classify_head(_TB, _Goal, undefined).
 2261
 2262built_in_predicate(Goal) :-
 2263    predicate_property(system:Goal, built_in),
 2264    !.
 2265built_in_predicate(module(_, _)).       % reserved expanded constructs
 2266built_in_predicate(module(_, _, _)).
 2267built_in_predicate(if(_)).
 2268built_in_predicate(elif(_)).
 2269built_in_predicate(else).
 2270built_in_predicate(endif).
 2271
 2272goal_name(_:G, Name) :- nonvar(G), !, goal_name(G, Name).
 2273goal_name(G, Name) :- callable(G), functor_name(G, Name).
 2274
 2275system_module(TB) :-
 2276    colour_state_source_id(TB, SourceId),
 2277    xref_module(SourceId, M),
 2278    module_property(M, class(system)).
 2279
 2280generalise_term(Specific, General) :-
 2281    (   compound(Specific)
 2282    ->  compound_name_arity(Specific, Name, Arity),
 2283        compound_name_arity(General0, Name, Arity),
 2284        General = General0
 2285    ;   General = Specific
 2286    ).
 2287
 2288rename_goal(Goal0, Name, Goal) :-
 2289    (   compound(Goal0)
 2290    ->  compound_name_arity(Goal0, _, Arity),
 2291        compound_name_arity(Goal, Name, Arity)
 2292    ;   Goal = Name
 2293    ).
 2294
 2295functor_name(Term, Name) :-
 2296    (   compound(Term)
 2297    ->  compound_name_arity(Term, Name, _)
 2298    ;   atom(Term)
 2299    ->  Name = Term
 2300    ).
 2301
 2302goal_name_arity(Goal, Name, Arity) :-
 2303    (   compound(Goal)
 2304    ->  compound_name_arity(Goal, Name, Arity)
 2305    ;   atom(Goal)
 2306    ->  Name = Goal, Arity = 0
 2307    ).
 2308
 2309
 2310call_goal_colours(Term, Colours) :-
 2311    goal_colours(Term, Colours),
 2312    !.
 2313call_goal_colours(Term, Colours) :-
 2314    def_goal_colours(Term, Colours).
 2315
 2316call_goal_colours(Term, Class, Colours) :-
 2317    goal_colours(Term, Class, Colours),
 2318    !.
 2319%call_goal_colours(Term, Class, Colours) :-
 2320%    def_goal_colours(Term, Class, Colours).
 2321
 2322
 2323%       Specify colours for individual goals.
 2324
 2325def_goal_colours(module(_,_),            built_in-[identifier,exports]).
 2326def_goal_colours(module(_,_,_),          built_in-[identifier,exports,langoptions]).
 2327def_goal_colours(use_module(_),          built_in-[imported_file]).
 2328def_goal_colours(use_module(File,_),     built_in-[file,imports(File)]).
 2329def_goal_colours(autoload(_),            built_in-[imported_file]).
 2330def_goal_colours(autoload(File,_),       built_in-[file,imports(File)]).
 2331def_goal_colours(reexport(_),            built_in-[file]).
 2332def_goal_colours(reexport(File,_),       built_in-[file,imports(File)]).
 2333def_goal_colours(dynamic(_),             built_in-[declarations(dynamic)]).
 2334def_goal_colours(thread_local(_),        built_in-[declarations(thread_local)]).
 2335def_goal_colours(module_transparent(_),  built_in-[declarations(module_transparent)]).
 2336def_goal_colours(discontiguous(_),       built_in-[declarations(discontiguous)]).
 2337def_goal_colours(multifile(_),           built_in-[declarations(multifile)]).
 2338def_goal_colours(volatile(_),            built_in-[declarations(volatile)]).
 2339def_goal_colours(public(_),              built_in-[declarations(public)]).
 2340def_goal_colours(table(_),               built_in-[declarations(table)]).
 2341def_goal_colours(meta_predicate(_),      built_in-[meta_declarations]).
 2342def_goal_colours(consult(_),             built_in-[file]).
 2343def_goal_colours(include(_),             built_in-[file]).
 2344def_goal_colours(ensure_loaded(_),       built_in-[file]).
 2345def_goal_colours(load_files(_),          built_in-[file]).
 2346def_goal_colours(load_files(_,_),        built_in-[file,options]).
 2347def_goal_colours(setof(_,_,_),           built_in-[classify,setof,classify]).
 2348def_goal_colours(bagof(_,_,_),           built_in-[classify,setof,classify]).
 2349def_goal_colours(predicate_options(_,_,_), built_in-[predicate,classify,classify]).
 2350% Database access
 2351def_goal_colours(assert(_),              built_in-[db]).
 2352def_goal_colours(asserta(_),             built_in-[db]).
 2353def_goal_colours(assertz(_),             built_in-[db]).
 2354def_goal_colours(assert(_,_),            built_in-[db,classify]).
 2355def_goal_colours(asserta(_,_),           built_in-[db,classify]).
 2356def_goal_colours(assertz(_,_),           built_in-[db,classify]).
 2357def_goal_colours(retract(_),             built_in-[db]).
 2358def_goal_colours(retractall(_),          built_in-[db]).
 2359def_goal_colours(clause(_,_),            built_in-[db,classify]).
 2360def_goal_colours(clause(_,_,_),          built_in-[db,classify,classify]).
 2361% misc
 2362def_goal_colours(set_prolog_flag(_,_),   built_in-[prolog_flag_name,classify]).
 2363def_goal_colours(current_prolog_flag(_,_), built_in-[prolog_flag_name,classify]).
 2364% XPCE stuff
 2365def_goal_colours(pce_autoload(_,_),      classify-[classify,file]).
 2366def_goal_colours(pce_image_directory(_), classify-[directory]).
 2367def_goal_colours(new(_, _),              built_in-[classify,pce_new]).
 2368def_goal_colours(send_list(_,_,_),       built_in-pce_arg_list).
 2369def_goal_colours(send(_,_),              built_in-[pce_arg,pce_selector]).
 2370def_goal_colours(get(_,_,_),             built_in-[pce_arg,pce_selector,pce_arg]).
 2371def_goal_colours(send_super(_,_),        built_in-[pce_arg,pce_selector]).
 2372def_goal_colours(get_super(_,_),         built_in-[pce_arg,pce_selector,pce_arg]).
 2373def_goal_colours(get_chain(_,_,_),       built_in-[pce_arg,pce_selector,pce_arg]).
 2374def_goal_colours(Pce,                    built_in-pce_arg) :-
 2375    compound(Pce),
 2376    functor_name(Pce, Functor),
 2377    pce_functor(Functor).
 2378
 2379pce_functor(send).
 2380pce_functor(get).
 2381pce_functor(send_super).
 2382pce_functor(get_super).
 2383
 2384
 2385                 /*******************************
 2386                 *        SPECIFIC HEADS        *
 2387                 *******************************/
 2388
 2389head_colours(file_search_path(_,_), hook-[identifier,classify]).
 2390head_colours(library_directory(_),  hook-[file]).
 2391head_colours(resource(_,_),         hook-[identifier,file]).
 2392head_colours(resource(_,_,_),       hook-[identifier,file,classify]).
 2393
 2394head_colours(Var, _) :-
 2395    var(Var),
 2396    !,
 2397    fail.
 2398head_colours(M:H, Colours) :-
 2399    M == user,
 2400    head_colours(H, HC),
 2401    HC = hook - _,
 2402    !,
 2403    Colours = meta-[module(user), HC ].
 2404head_colours(M:H, Colours) :-
 2405    atom(M), callable(H),
 2406    xref_hook(M:H),
 2407    !,
 2408    Colours = meta-[module(M), hook-classify ].
 2409head_colours(M:_, meta-[module(M),extern(M)]).
 2410
 2411
 2412                 /*******************************
 2413                 *             STYLES           *
 2414                 *******************************/
 def_style(+Pattern, -Style)
Define the style used for the given pattern. Definitions here can be overruled by defining rules for style/2
 2422def_style(goal(built_in,_),        [colour(blue)]).
 2423def_style(goal(imported(_),_),     [colour(blue)]).
 2424def_style(goal(autoload(_),_),     [colour(navy_blue)]).
 2425def_style(goal(global,_),          [colour(navy_blue)]).
 2426def_style(goal(global(dynamic,_),_), [colour(magenta)]).
 2427def_style(goal(global(_,_),_),     [colour(navy_blue)]).
 2428def_style(goal(undefined,_),       [colour(red)]).
 2429def_style(goal(thread_local(_),_), [colour(magenta), underline(true)]).
 2430def_style(goal(dynamic(_),_),      [colour(magenta)]).
 2431def_style(goal(multifile(_),_),    [colour(navy_blue)]).
 2432def_style(goal(expanded,_),        [colour(blue), underline(true)]).
 2433def_style(goal(extern(_),_),       [colour(blue), underline(true)]).
 2434def_style(goal(extern(_,private),_), [colour(red)]).
 2435def_style(goal(extern(_,public),_), [colour(blue)]).
 2436def_style(goal(recursion,_),       [underline(true)]).
 2437def_style(goal(meta,_),            [colour(red4)]).
 2438def_style(goal(foreign(_),_),      [colour(darkturquoise)]).
 2439def_style(goal(local(_),_),        []).
 2440def_style(goal(constraint(_),_),   [colour(darkcyan)]).
 2441def_style(goal(not_callable,_),    [background(orange)]).
 2442
 2443def_style(option_name,             [colour('#3434ba')]).
 2444def_style(no_option_name,          [colour(red)]).
 2445
 2446def_style(head(exported,_),        [colour(blue), bold(true)]).
 2447def_style(head(public(_),_),       [colour('#016300'), bold(true)]).
 2448def_style(head(extern(_),_),       [colour(blue), bold(true)]).
 2449def_style(head(dynamic,_),         [colour(magenta), bold(true)]).
 2450def_style(head(multifile,_),       [colour(navy_blue), bold(true)]).
 2451def_style(head(unreferenced,_),    [colour(red), bold(true)]).
 2452def_style(head(hook,_),            [colour(blue), underline(true)]).
 2453def_style(head(meta,_),            []).
 2454def_style(head(constraint(_),_),   [colour(darkcyan), bold(true)]).
 2455def_style(head(imported(_),_),     [colour(darkgoldenrod4), bold(true)]).
 2456def_style(head(built_in,_),        [background(orange), bold(true)]).
 2457def_style(head(iso,_),             [background(orange), bold(true)]).
 2458def_style(head(def_iso,_),         [colour(blue), bold(true)]).
 2459def_style(head(def_swi,_),         [colour(blue), bold(true)]).
 2460def_style(head(_,_),               [bold(true)]).
 2461
 2462def_style(module(_),               [colour(dark_slate_blue)]).
 2463def_style(comment(_),              [colour(dark_green)]).
 2464
 2465def_style(directive,               [background(grey90)]).
 2466def_style(method(_),               [bold(true)]).
 2467
 2468def_style(var,                     [colour(red4)]).
 2469def_style(singleton,               [bold(true), colour(red4)]).
 2470def_style(unbound,                 [colour(red), bold(true)]).
 2471def_style(quoted_atom,             [colour(navy_blue)]).
 2472def_style(string,                  [colour(navy_blue)]).
 2473def_style(rational(_),		   [colour(steel_blue)]).
 2474def_style(codes,                   [colour(navy_blue)]).
 2475def_style(chars,                   [colour(navy_blue)]).
 2476def_style(nofile,                  [colour(red)]).
 2477def_style(file(_),                 [colour(blue), underline(true)]).
 2478def_style(file_no_depend(_),       [colour(blue), underline(true), background(pink)]).
 2479def_style(directory(_),            [colour(blue)]).
 2480def_style(class(built_in,_),       [colour(blue), underline(true)]).
 2481def_style(class(library(_),_),     [colour(navy_blue), underline(true)]).
 2482def_style(class(local(_,_,_),_),   [underline(true)]).
 2483def_style(class(user(_),_),        [underline(true)]).
 2484def_style(class(user,_),           [underline(true)]).
 2485def_style(class(undefined,_),      [colour(red), underline(true)]).
 2486def_style(prolog_data,             [colour(blue), underline(true)]).
 2487def_style(flag_name(_),            [colour(blue)]).
 2488def_style(no_flag_name(_),         [colour(red)]).
 2489def_style(unused_import,           [colour(blue), background(pink)]).
 2490def_style(undefined_import,        [colour(red)]).
 2491
 2492def_style(constraint(_),           [colour(darkcyan)]).
 2493
 2494def_style(keyword(_),              [colour(blue)]).
 2495def_style(identifier,              [bold(true)]).
 2496def_style(delimiter,               [bold(true)]).
 2497def_style(expanded,                [colour(blue), underline(true)]).
 2498def_style(hook(_),                 [colour(blue), underline(true)]).
 2499def_style(op_type(_),              [colour(blue)]).
 2500
 2501def_style(qq_type,                 [bold(true)]).
 2502def_style(qq(_),                   [colour(blue), bold(true)]).
 2503def_style(qq_content(_),           [colour(red4)]).
 2504
 2505def_style(dict_tag,                [bold(true)]).
 2506def_style(dict_key,                [bold(true)]).
 2507def_style(dict_function(_),        [colour(navy_blue)]).
 2508def_style(dict_return_op,          [colour(blue)]).
 2509
 2510def_style(hook,                    [colour(blue), underline(true)]).
 2511def_style(dcg_right_hand_ctx,      [background('#d4ffe3')]).
 2512
 2513def_style(error,                   [background(orange)]).
 2514def_style(type_error(_),           [background(orange)]).
 2515def_style(syntax_error(_,_),       [background(orange)]).
 2516def_style(instantiation_error,     [background(orange)]).
 2517
 2518def_style(decl_option(_),	   [bold(true)]).
 2519def_style(table_mode(_),	   [bold(true)]).
 syntax_colour(?Class, ?Attributes) is nondet
True when a range classified Class must be coloured using Attributes. Attributes is a list of:

Attributes may be the empty list. This is used for cases where -for example- a menu is associated with the fragment. If syntax_colour/2 fails, no fragment is created for the region.

 2535syntax_colour(Class, Attributes) :-
 2536    (   style(Class, Attributes)            % user hook
 2537    ;   def_style(Class, Attributes)        % system default
 2538    ).
 term_colours(+Term, -FunctorColour, -ArgColours)
Define colourisation for specific terms.
 2545term_colours((?- Directive), Colours) :-
 2546    term_colours((:- Directive), Colours).
 2547term_colours((prolog:Head --> _),
 2548             neck(grammar_rule) - [ expanded - [ module(prolog),
 2549                                                 hook(message) - [ identifier
 2550                                                                 ]
 2551                                               ],
 2552                                    dcg_body(prolog:Head)
 2553                                  ]) :-
 2554    prolog_message_hook(Head).
 2555
 2556prolog_message_hook(message(_)).
 2557prolog_message_hook(deprecated(_)).
 2558prolog_message_hook(error_message(_)).
 2559prolog_message_hook(message_context(_)).
 2560prolog_message_hook(message_location(_)).
 2561
 2562%       XPCE rules
 2563
 2564term_colours(variable(_, _, _, _),
 2565             expanded - [ identifier,
 2566                          classify,
 2567                          classify,
 2568                          comment(string)
 2569                        ]).
 2570term_colours(variable(_, _, _),
 2571             expanded - [ identifier,
 2572                          classify,
 2573                          atom
 2574                        ]).
 2575term_colours(handle(_, _, _),
 2576             expanded - [ classify,
 2577                          classify,
 2578                          classify
 2579                        ]).
 2580term_colours(handle(_, _, _, _),
 2581             expanded - [ classify,
 2582                          classify,
 2583                          classify,
 2584                          classify
 2585                        ]).
 2586term_colours(class_variable(_,_,_,_),
 2587             expanded - [ identifier,
 2588                          pce(type),
 2589                          pce(default),
 2590                          comment(string)
 2591                        ]).
 2592term_colours(class_variable(_,_,_),
 2593             expanded - [ identifier,
 2594                          pce(type),
 2595                          pce(default)
 2596                        ]).
 2597term_colours(delegate_to(_),
 2598             expanded - [ classify
 2599                        ]).
 2600term_colours((:- encoding(_)),
 2601             expanded - [ expanded - [ classify
 2602                                     ]
 2603                        ]).
 2604term_colours((:- pce_begin_class(_, _, _)),
 2605             expanded - [ expanded - [ identifier,
 2606                                       pce_new,
 2607                                       comment(string)
 2608                                     ]
 2609                        ]).
 2610term_colours((:- pce_begin_class(_, _)),
 2611             expanded - [ expanded - [ identifier,
 2612                                       pce_new
 2613                                     ]
 2614                        ]).
 2615term_colours((:- pce_extend_class(_)),
 2616             expanded - [ expanded - [ identifier
 2617                                     ]
 2618                        ]).
 2619term_colours((:- pce_end_class),
 2620             expanded - [ expanded
 2621                        ]).
 2622term_colours((:- pce_end_class(_)),
 2623             expanded - [ expanded - [ identifier
 2624                                     ]
 2625                        ]).
 2626term_colours((:- use_class_template(_)),
 2627             expanded - [ expanded - [ pce_new
 2628                                     ]
 2629                        ]).
 2630term_colours((:- emacs_begin_mode(_,_,_,_,_)),
 2631             expanded - [ expanded - [ identifier,
 2632                                       classify,
 2633                                       classify,
 2634                                       classify,
 2635                                       classify
 2636                                     ]
 2637                        ]).
 2638term_colours((:- emacs_extend_mode(_,_)),
 2639             expanded - [ expanded - [ identifier,
 2640                                       classify
 2641                                     ]
 2642                        ]).
 2643term_colours((:- pce_group(_)),
 2644             expanded - [ expanded - [ identifier
 2645                                     ]
 2646                        ]).
 2647term_colours((:- pce_global(_, new(_))),
 2648             expanded - [ expanded - [ identifier,
 2649                                       pce_arg
 2650                                     ]
 2651                        ]).
 2652term_colours((:- emacs_end_mode),
 2653             expanded - [ expanded
 2654                        ]).
 2655term_colours(pce_ifhostproperty(_,_),
 2656             expanded - [ classify,
 2657                          classify
 2658                        ]).
 2659term_colours((_,_),
 2660             error - [ classify,
 2661                       classify
 2662                     ]).
 specified_item(+Specified, +Term, +TB, +TermPosition) is det
Colourise an item that is explicitly classified by the user using term_colours/2 or goal_colours/2.
 2669specified_item(_Class, _Term, _TB, Pos) :-
 2670    var(Pos),
 2671    !.
 2672specified_item(Class, Term, TB, parentheses_term_position(PO,PC,Pos)) :-
 2673    !,
 2674    colour_item(parentheses, TB, PO-PC),
 2675    specified_item(Class, Term, TB, Pos).
 2676specified_item(_, Var, TB, Pos) :-
 2677    (   var(Var)
 2678    ;   qq_position(Pos)
 2679    ),
 2680    !,
 2681    colourise_term_arg(Var, TB, Pos).
 2682                                        % generic classification
 2683specified_item(classify, Term, TB, Pos) :-
 2684    !,
 2685    colourise_term_arg(Term, TB, Pos).
 2686                                        % classify as head
 2687specified_item(head, Term, TB, Pos) :-
 2688    !,
 2689    colourise_clause_head(Term, TB, Pos).
 2690                                        % expanded head (DCG=2, ...)
 2691specified_item(head(+N), Term, TB, Pos) :-
 2692    !,
 2693    colourise_extended_head(Term, N, TB, Pos).
 2694                                        % M:Head
 2695specified_item(extern(M), Term, TB, Pos) :-
 2696    !,
 2697    colourise_extern_head(Term, M, TB, Pos).
 2698                                        % classify as body
 2699specified_item(body, Term, TB, Pos) :-
 2700    !,
 2701    colourise_body(Term, TB, Pos).
 2702specified_item(body(Goal), _Term0, TB, Pos) :-
 2703    !,
 2704    colourise_body(Goal, TB, Pos).
 2705specified_item(dcg_body(Head), Term, TB, Pos) :-
 2706    !,
 2707    colourise_dcg(Term, Head, TB, Pos).
 2708specified_item(setof, Term, TB, Pos) :-
 2709    !,
 2710    colourise_setof(Term, TB, Pos).
 2711specified_item(meta(MetaSpec), Term, TB, Pos) :-
 2712    !,
 2713    colourise_meta_arg(MetaSpec, Term, TB, Pos).
 2714                                        % DCG goal in body
 2715specified_item(dcg, Term, TB, Pos) :-
 2716    !,
 2717    colourise_dcg(Term, [], TB, Pos).
 2718                                        % assert/retract arguments
 2719specified_item(db, Term, TB, Pos) :-
 2720    !,
 2721    colourise_db(Term, TB, Pos).
 2722                                        % error(Error)
 2723specified_item(error(Error), _Term, TB, Pos) :-
 2724    colour_item(Error, TB, Pos).
 2725                                        % files
 2726specified_item(file(Path), _Term, TB, Pos) :-
 2727    !,
 2728    colour_item(file(Path), TB, Pos).
 2729specified_item(file, Term, TB, Pos) :-
 2730    !,
 2731    colourise_files(Term, TB, Pos, any).
 2732specified_item(imported_file, Term, TB, Pos) :-
 2733    !,
 2734    colourise_files(Term, TB, Pos, imported).
 2735specified_item(langoptions, Term, TB, Pos) :-
 2736    !,
 2737    colourise_langoptions(Term, TB, Pos).
 2738
 2739                                        % directory
 2740specified_item(directory, Term, TB, Pos) :-
 2741    !,
 2742    colourise_directory(Term, TB, Pos).
 2743                                        % [Name/Arity, ...]
 2744specified_item(exports, Term, TB, Pos) :-
 2745    !,
 2746    colourise_exports(Term, TB, Pos).
 2747                                        % [Name/Arity, ...]
 2748specified_item(imports(File), Term, TB, Pos) :-
 2749    !,
 2750    colourise_imports(Term, File, TB, Pos).
 2751                                        % Name/Arity
 2752specified_item(import(File), Term, TB, Pos) :-
 2753    !,
 2754    colourise_import(Term, File, TB, Pos).
 2755                                        % Name/Arity, ...
 2756specified_item(predicates, Term, TB, Pos) :-
 2757    !,
 2758    colourise_declarations(Term, predicate_indicator, TB, Pos).
 2759                                        % Name/Arity
 2760specified_item(predicate, Term, TB, Pos) :-
 2761    !,
 2762    colourise_declaration(Term, predicate_indicator, TB, Pos).
 2763                                        % head(Arg, ...)
 2764specified_item(meta_declarations, Term, TB, Pos) :-
 2765    !,
 2766    colourise_meta_declarations(Term, [], TB, Pos).
 2767specified_item(meta_declarations(Extra), Term, TB, Pos) :-
 2768    !,
 2769    colourise_meta_declarations(Term, Extra, TB, Pos).
 2770specified_item(declarations(Which), Term, TB, Pos) :-
 2771    !,
 2772    colourise_declarations(Term, Which, TB, Pos).
 2773                                        % set_prolog_flag(Name, _)
 2774specified_item(prolog_flag_name, Term, TB, Pos) :-
 2775    !,
 2776    colourise_prolog_flag_name(Term, TB, Pos).
 2777                                        % XPCE new argument
 2778specified_item(pce_new, Term, TB, Pos) :-
 2779    !,
 2780    (   atom(Term)
 2781    ->  colourise_class(Term, TB, Pos)
 2782    ;   compound(Term)
 2783    ->  functor_name(Term, Class),
 2784        Pos = term_position(_,_,FF, FT, ArgPos),
 2785        colourise_class(Class, TB, FF-FT),
 2786        specified_items(pce_arg, Term, TB, ArgPos)
 2787    ;   colourise_term_arg(Term, TB, Pos)
 2788    ).
 2789                                        % Generic XPCE arguments
 2790specified_item(pce_arg, new(X), TB,
 2791               term_position(_,_,_,_,[ArgPos])) :-
 2792    !,
 2793    specified_item(pce_new, X, TB, ArgPos).
 2794specified_item(pce_arg, new(X, T), TB,
 2795               term_position(_,_,_,_,[P1, P2])) :-
 2796    !,
 2797    colourise_term_arg(X, TB, P1),
 2798    specified_item(pce_new, T, TB, P2).
 2799specified_item(pce_arg, @(Ref), TB, Pos) :-
 2800    !,
 2801    colourise_term_arg(@(Ref), TB, Pos).
 2802specified_item(pce_arg, prolog(Term), TB,
 2803               term_position(_,_,FF,FT,[ArgPos])) :-
 2804    !,
 2805    colour_item(prolog_data, TB, FF-FT),
 2806    colourise_term_arg(Term, TB, ArgPos).
 2807specified_item(pce_arg, Term, TB, Pos) :-
 2808    compound(Term),
 2809    Term \= [_|_],
 2810    !,
 2811    specified_item(pce_new, Term, TB, Pos).
 2812specified_item(pce_arg, Term, TB, Pos) :-
 2813    !,
 2814    colourise_term_arg(Term, TB, Pos).
 2815                                        % List of XPCE arguments
 2816specified_item(pce_arg_list, List, TB, list_position(F,T,Elms,Tail)) :-
 2817    !,
 2818    colour_item(list, TB, F-T),
 2819    colourise_list_args(Elms, Tail, List, TB, pce_arg).
 2820specified_item(pce_arg_list, Term, TB, Pos) :-
 2821    !,
 2822    specified_item(pce_arg, Term, TB, Pos).
 2823                                        % XPCE selector
 2824specified_item(pce_selector, Term, TB,
 2825               term_position(_,_,_,_,ArgPos)) :-
 2826    !,
 2827    specified_items(pce_arg, Term, TB, ArgPos).
 2828specified_item(pce_selector, Term, TB, Pos) :-
 2829    colourise_term_arg(Term, TB, Pos).
 2830                                        % Nested specification
 2831specified_item(FuncSpec-ArgSpecs, Term, TB,
 2832               term_position(_,_,FF,FT,ArgPos)) :-
 2833    !,
 2834    specified_item(FuncSpec, Term, TB, FF-FT),
 2835    specified_items(ArgSpecs, Term, TB, ArgPos).
 2836                                        % Nested for {...}
 2837specified_item(FuncSpec-[ArgSpec], {Term}, TB,
 2838               brace_term_position(F,T,ArgPos)) :-
 2839    !,
 2840    specified_item(FuncSpec, {Term}, TB, F-T),
 2841    specified_item(ArgSpec, Term, TB, ArgPos).
 2842                                        % Specified
 2843specified_item(FuncSpec-ElmSpec, List, TB,
 2844               list_position(F,T,ElmPos,TailPos)) :-
 2845    !,
 2846    colour_item(FuncSpec, TB, F-T),
 2847    specified_list(ElmSpec, List, TB, ElmPos, TailPos).
 2848specified_item(Class, _, TB, Pos) :-
 2849    colour_item(Class, TB, Pos).
 specified_items(+Spec, +Term, +TB, +PosList)
 2853specified_items(Specs, Term, TB, PosList) :-
 2854    is_dict(Term),
 2855    !,
 2856    specified_dict_kv(PosList, Term, TB, Specs).
 2857specified_items(Specs, Term, TB, PosList) :-
 2858    is_list(Specs),
 2859    !,
 2860    specified_arglist(Specs, 1, Term, TB, PosList).
 2861specified_items(Spec, Term, TB, PosList) :-
 2862    specified_argspec(PosList, Spec, 1, Term, TB).
 2863
 2864
 2865specified_arglist([], _, _, _, _).
 2866specified_arglist(_, _, _, _, []) :- !.         % Excess specification args
 2867specified_arglist([S0|ST], N, T, TB, [P0|PT]) :-
 2868    (   S0 == options,
 2869        colourization_module(TB, Module),
 2870        colourise_option_arg(T, Module, N, TB, P0)
 2871    ->  true
 2872    ;   arg(N, T, Term),
 2873        specified_item(S0, Term, TB, P0)
 2874    ),
 2875    NN is N + 1,
 2876    specified_arglist(ST, NN, T, TB, PT).
 2877
 2878specified_argspec([], _, _, _, _).
 2879specified_argspec([P0|PT], Spec, N, T, TB) :-
 2880    arg(N, T, Term),
 2881    specified_item(Spec, Term, TB, P0),
 2882    NN is N + 1,
 2883    specified_argspec(PT, Spec, NN, T, TB).
 2884
 2885
 2886%       specified_list(+Spec, +List, +TB, +PosList, TailPos)
 2887
 2888specified_list([], [], _, [], _).
 2889specified_list([HS|TS], [H|T], TB, [HP|TP], TailPos) :-
 2890    !,
 2891    specified_item(HS, H, TB, HP),
 2892    specified_list(TS, T, TB, TP, TailPos).
 2893specified_list(Spec, [H|T], TB, [HP|TP], TailPos) :-
 2894    specified_item(Spec, H, TB, HP),
 2895    specified_list(Spec, T, TB, TP, TailPos).
 2896specified_list(_, _, _, [], none) :- !.
 2897specified_list(Spec, Tail, TB, [], TailPos) :-
 2898    specified_item(Spec, Tail, TB, TailPos).
 specified_dict_kv(+PosList, +Term, +TB, +Specs)
Arguments:
Specs- is a list of dict_kv(+Key, +KeySpec, +ArgSpec)
 2904specified_dict_kv([], _, _, _).
 2905specified_dict_kv([key_value_position(_F,_T,SF,ST,K,KP,VP)|Pos],
 2906                  Dict, TB, Specs) :-
 2907    specified_dict_kv1(K, Specs, KeySpec, ValueSpec),
 2908    colour_item(KeySpec, TB, KP),
 2909    colour_item(dict_sep, TB, SF-ST),
 2910    get_dict(K, Dict, V),
 2911    specified_item(ValueSpec, V, TB, VP),
 2912    specified_dict_kv(Pos, Dict, TB, Specs).
 2913
 2914specified_dict_kv1(Key, Specs, KeySpec, ValueSpec) :-
 2915    Specs = [_|_],
 2916    memberchk(dict_kv(Key, KeySpec, ValueSpec), Specs),
 2917    !.
 2918specified_dict_kv1(Key, dict_kv(Key2, KeySpec, ValueSpec), KeySpec, ValueSpec) :-
 2919    \+ Key \= Key2,
 2920    !.              % do not bind Key2
 2921specified_dict_kv1(_, _, dict_key, classify).
 2922
 2923
 2924                 /*******************************
 2925                 *         DESCRIPTIONS         *
 2926                 *******************************/
 2927
 2928syntax_message(Class) -->
 2929    message(Class),
 2930    !.
 2931syntax_message(qq(_)) -->
 2932    [ 'Quasi quote delimiter' ].
 2933syntax_message(qq_type) -->
 2934    [ 'Quasi quote type term' ].
 2935syntax_message(qq_content(Type)) -->
 2936    [ 'Quasi quote content (~w syntax)'-[Type] ].
 2937syntax_message(goal(Class, Goal)) -->
 2938    !,
 2939    goal_message(Class, Goal).
 2940syntax_message(class(Type, Class)) -->
 2941    !,
 2942    xpce_class_message(Type, Class).
 2943syntax_message(dict_return_op) -->
 2944    !,
 2945    [ ':= separates function from return value' ].
 2946syntax_message(dict_function) -->
 2947    !,
 2948    [ 'Function on a dict' ].
 2949syntax_message(ext_quant) -->
 2950    !,
 2951    [ 'Existential quantification operator' ].
 2952syntax_message(hook(message)) -->
 2953    [ 'Rule for print_message/2' ].
 2954syntax_message(module(Module)) -->
 2955    (   { current_module(Module) }
 2956    ->  (   { module_property(Module, file(File)) }
 2957        ->  [ 'Module ~w defined in ~w'-[Module,File] ]
 2958        ;   [ 'Module ~w'-[Module] ]
 2959        )
 2960    ;   [ 'Module ~w (not loaded)'-[Module] ]
 2961    ).
 2962syntax_message(decl_option(incremental)) -->
 2963    [ 'Keep affected tables consistent' ].
 2964syntax_message(decl_option(abstract)) -->
 2965    [ 'Add abstracted goal to table dependency graph' ].
 2966syntax_message(decl_option(volatile)) -->
 2967    [ 'Do not include predicate in a saved program' ].
 2968syntax_message(decl_option(multifile)) -->
 2969    [ 'Clauses are spread over multiple files' ].
 2970syntax_message(decl_option(discontiguous)) -->
 2971    [ 'Clauses are not contiguous' ].
 2972syntax_message(decl_option(private)) -->
 2973    [ 'Tables or clauses are private to a thread' ].
 2974syntax_message(decl_option(local)) -->
 2975    [ 'Tables or clauses are private to a thread' ].
 2976syntax_message(decl_option(shared)) -->
 2977    [ 'Tables or clauses are shared between threads' ].
 2978syntax_message(decl_option(_Opt)) -->
 2979    [ 'Predicate property' ].
 2980syntax_message(rational(Value)) -->
 2981    [ 'Rational number ~w'-[Value] ].
 2982
 2983goal_message(meta, _) -->
 2984    [ 'Meta call' ].
 2985goal_message(not_callable, _) -->
 2986    [ 'Goal is not callable (type error)' ].
 2987goal_message(expanded, _) -->
 2988    [ 'Expanded goal' ].
 2989goal_message(Class, Goal) -->
 2990    { predicate_name(Goal, PI) },
 2991    [ 'Call to ~q'-PI ],
 2992    goal_class(Class).
 2993
 2994goal_class(recursion) -->
 2995    [ ' (recursive call)' ].
 2996goal_class(undefined) -->
 2997    [ ' (undefined)' ].
 2998goal_class(global) -->
 2999    [ ' (Auto-imported from module user)' ].
 3000goal_class(global(Class, File:Line)) -->
 3001    [ ' (~w in user module from ~w:~w)'-[Class, File, Line] ].
 3002goal_class(global(Class, source_location(File,Line))) -->
 3003    [ ' (~w in user module from ~w:~w)'-[Class, File, Line] ].
 3004goal_class(global(Class, -)) -->
 3005    [ ' (~w in user module)'-[Class] ].
 3006goal_class(imported(From)) -->
 3007    [ ' (imported from ~q)'-[From] ].
 3008goal_class(extern(_, private)) -->
 3009    [ ' (WARNING: private predicate)' ].
 3010goal_class(extern(_, public)) -->
 3011    [ ' (public predicate)' ].
 3012goal_class(extern(_)) -->
 3013    [ ' (cross-module call)' ].
 3014goal_class(Class) -->
 3015    [ ' (~p)'-[Class] ].
 3016
 3017xpce_class_message(Type, Class) -->
 3018    [ 'XPCE ~w class ~q'-[Type, Class] ]