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

Prolog syntax colouring support.

This module defines reusable code to colourise Prolog source.

To be done
- : The one-term version */
   98:- multifile
   99    style/2,                        % +ColourClass, -Attributes
  100    message//1,                     % +ColourClass
  101    term_colours/2,                 % +SourceTerm, -ColourSpec
  102    goal_colours/2,                 % +Goal, -ColourSpec
  103    goal_colours/3,                 % +Goal, +Class, -ColourSpec
  104    directive_colours/2,            % +Goal, -ColourSpec
  105    goal_classification/2,          % +Goal, -Class
  106    vararg_goal_classification/3.   % +Name, +Arity, -Class
  107
  108
  109:- record
  110    colour_state(source_id_list,
  111                 module,
  112                 stream,
  113                 closure,
  114                 singletons).  115
  116colour_state_source_id(State, SourceID) :-
  117    colour_state_source_id_list(State, SourceIDList),
  118    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.
  139prolog_colourise_stream(Fd, SourceId, ColourItem) :-
  140    prolog_colourise_stream(Fd, SourceId, ColourItem, []).
  141prolog_colourise_stream(Fd, SourceId, ColourItem, Options) :-
  142    to_list(SourceId, SourceIdList),
  143    make_colour_state([ source_id_list(SourceIdList),
  144                        stream(Fd),
  145                        closure(ColourItem)
  146                      ],
  147                      TB),
  148    option(operators(Ops), Options, []),
  149    setup_call_cleanup(
  150        save_settings(TB, Ops, State),
  151        colourise_stream(Fd, TB),
  152        restore_settings(State)).
  153
  154to_list(List, List) :-
  155    is_list(List),
  156    !.
  157to_list(One, [One]).
  158
  159
  160colourise_stream(Fd, TB) :-
  161    (   peek_char(Fd, #)            % skip #! script line
  162    ->  skip(Fd, 10)
  163    ;   true
  164    ),
  165    repeat,
  166        colour_state_module(TB, SM),
  167        character_count(Fd, Start),
  168        catch(read_term(Fd, Term,
  169                        [ subterm_positions(TermPos),
  170                          singletons(Singletons0),
  171                          module(SM),
  172                          comments(Comments)
  173                        ]),
  174              E,
  175              read_error(E, TB, Start, Fd)),
  176        fix_operators(Term, SM, TB),
  177        warnable_singletons(Singletons0, Singletons),
  178        colour_state_singletons(TB, Singletons),
  179        (   colourise_term(Term, TB, TermPos, Comments)
  180        ->  true
  181        ;   arg(1, TermPos, From),
  182            print_message(warning,
  183                          format('Failed to colourise ~p at index ~d~n',
  184                                 [Term, From]))
  185        ),
  186        Term == end_of_file,
  187    !.
  188
  189save_settings(TB, Ops, state(Style, Flags, OSM, Xref)) :-
  190    (   source_module(TB, SM)
  191    ->  true
  192    ;   SM = prolog_colour_ops
  193    ),
  194    set_xref(Xref, true),
  195    '$set_source_module'(OSM, SM),
  196    colour_state_module(TB, SM),
  197    maplist(qualify_op(SM), Ops, QOps),
  198    push_operators(QOps),
  199    syntax_flags(Flags),
  200    '$style_check'(Style, Style).
  201
  202qualify_op(M, op(P,T,[]), Q)            => Q = op(P,T,M:[]).
  203qualify_op(M, op(P,T,N), Q), atom(N)    => Q = op(P,T,M:N).
  204qualify_op(M, op(P,T,L), Q), is_list(Q) =>
  205    Q = op(P, T, QL),
  206    maplist(qualify_op_name(M), L, QL).
  207qualify_op(_, Op, Q)			=> Q = Op.
  208
  209qualify_op_name(M, N,  Q), atom(N) => Q = M:N.
  210qualify_op_name(M, [], Q)          => Q = M:[].
  211qualify_op_name(_, V,  Q)          => Q = V.
  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
  353:- multifile
  354    prolog:xref_update_syntax/2.  355
  356process_directive(Directive, M, _Src) :-
  357    prolog:xref_update_syntax(Directive, M),
  358    !.
  359process_directive(style_check(X), _, _) :-
  360    !,
  361    style_check(X).
  362process_directive(set_prolog_flag(Flag, Value), M, _) :-
  363    syntax_flag(Flag),
  364    !,
  365    set_prolog_flag(M:Flag, Value).
  366process_directive(M:op(P,T,N), _, Src) :-
  367    !,
  368    process_directive(op(P,T,N), M, Src).
  369process_directive(op(P,T,N), M, Src) :-
  370    !,
  371    safe_push_op(P, T, M:N, Src).
  372process_directive(module(_Name, Export), M, Src) :-
  373    !,
  374    forall(member(op(P,A,N), Export),
  375           safe_push_op(P,A,M:N, Src)).
  376process_directive(use_module(Spec), _, Src) :-
  377    !,
  378    catch(process_use_module1(Spec, Src), _, true).
  379process_directive(use_module(Spec, Imports), _, Src) :-
  380    !,
  381    catch(process_use_module2(Spec, Imports, Src), _, true).
  382process_directive(Directive, _, Src) :-
  383    prolog_source:expand((:-Directive), Src, _).
  384
  385syntax_flag(character_escapes).
  386syntax_flag(var_prefix).
  387syntax_flag(allow_variable_name_as_functor).
  388syntax_flag(allow_dot_in_atom).
 process_use_module1(+Imports, +Src)
Get the exported operators from the referenced files.
  394process_use_module1([], _) :- !.
  395process_use_module1([H|T], Src) :-
  396    !,
  397    process_use_module1(H, Src),
  398    process_use_module1(T, Src).
  399process_use_module1(File, Src) :-
  400    (   xref_public_list(File, Src,
  401                         [ exports(Exports),
  402                           silent(true),
  403                           path(Path)
  404                         ])
  405    ->  forall(member(op(P,T,N), Exports),
  406               safe_push_op(P,T,N,Src)),
  407        colour_state_module(Src, SM),
  408        (   member(Syntax/4, Exports),
  409            load_quasi_quotation_syntax(SM:Path, Syntax),
  410            fail
  411        ;   true
  412        )
  413    ;   true
  414    ).
  415
  416process_use_module2(File, Imports, Src) :-
  417    (   xref_public_list(File, Src,
  418                         [ exports(Exports),
  419                           silent(true),
  420                           path(Path)
  421                         ])
  422    ->  forall(( member(op(P,T,N), Exports),
  423                 member(op(P,T,N), Imports)),
  424               safe_push_op(P,T,N,Src)),
  425        colour_state_module(Src, SM),
  426        (   member(Syntax/4, Exports),
  427            member(Syntax/4, Imports),
  428            load_quasi_quotation_syntax(SM:Path, Syntax),
  429            fail
  430        ;   true
  431        )
  432    ;   true
  433    ).
 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.
  442prolog_colourise_query(QueryString, SourceID, ColourItem) :-
  443    query_colour_state(SourceID, ColourItem, TB),
  444    setup_call_cleanup(
  445        save_settings(TB, [], State),
  446        colourise_query(QueryString, TB),
  447        restore_settings(State)).
  448
  449query_colour_state(module(Module), ColourItem, TB) :-
  450    !,
  451    make_colour_state([ source_id_list([]),
  452                        module(Module),
  453                        closure(ColourItem)
  454                      ],
  455                      TB).
  456query_colour_state(SourceID, ColourItem, TB) :-
  457    to_list(SourceID, SourceIDList),
  458    make_colour_state([ source_id_list(SourceIDList),
  459                        closure(ColourItem)
  460                      ],
  461                      TB).
  462
  463
  464colourise_query(QueryString, TB) :-
  465    colour_state_module(TB, SM),
  466    string_length(QueryString, End),
  467    (   catch(term_string(Query, QueryString,
  468                          [ subterm_positions(TermPos),
  469                            singletons(Singletons0),
  470                            module(SM),
  471                            comments(Comments)
  472                          ]),
  473              E,
  474              read_error(E, TB, 0, End))
  475    ->  warnable_singletons(Singletons0, Singletons),
  476        colour_state_singletons(TB, Singletons),
  477        colourise_comments(Comments, TB),
  478        (   Query == end_of_file
  479        ->  true
  480        ;   colourise_body(Query, TB, TermPos)
  481        )
  482    ;   true                        % only a syntax error
  483    ).
 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)
  498prolog_colourise_term(Stream, SourceId, ColourItem, Options) :-
  499    to_list(SourceId, SourceIdList),
  500    make_colour_state([ source_id_list(SourceIdList),
  501                        stream(Stream),
  502                        closure(ColourItem)
  503                      ],
  504                      TB),
  505    option(subterm_positions(TermPos), Options, _),
  506    findall(Op, xref_op(SourceId, Op), Ops),
  507    debug(colour, 'Ops from ~p: ~p', [SourceId, Ops]),
  508    findall(Opt, xref_flag_option(SourceId, Opt), Opts),
  509    character_count(Stream, Start),
  510    (   source_module(TB, Module)
  511    ->  true
  512    ;   Module = prolog_colour_ops
  513    ),
  514    read_source_term_at_location(
  515        Stream, Term,
  516        [ module(Module),
  517          operators(Ops),
  518          error(Error),
  519          subterm_positions(TermPos),
  520          singletons(Singletons0),
  521          comments(Comments)
  522        | Opts
  523        ]),
  524    (   var(Error)
  525    ->  warnable_singletons(Singletons0, Singletons),
  526        colour_state_singletons(TB, Singletons),
  527        colour_item(range, TB, TermPos),            % Call to allow clearing
  528        colourise_term(Term, TB, TermPos, Comments)
  529    ;   character_count(Stream, End),
  530        TermPos = error_position(Start, End, Pos),
  531        colour_item(range, TB, TermPos),
  532        show_syntax_error(TB, Error, Start-End),
  533        Error = Pos:_Message
  534    ).
  535
  536xref_flag_option(TB, var_prefix(Bool)) :-
  537    xref_prolog_flag(TB, var_prefix, Bool, _Line).
  538
  539show_syntax_error(TB, Pos:Message, Range) :-
  540    integer(Pos),
  541    !,
  542    End is Pos + 1,
  543    colour_item(syntax_error(Message, Range), TB, Pos-End).
  544show_syntax_error(TB, _:Message, Range) :-
  545    colour_item(syntax_error(Message, Range), TB, Range).
  546
  547
  548singleton(Var, TB) :-
  549    colour_state_singletons(TB, Singletons),
  550    member_var(Var, Singletons).
  551
  552member_var(V, [_=V2|_]) :-
  553    V == V2,
  554    !.
  555member_var(V, [_|T]) :-
  556    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.
  567colourise_term(Term, TB, TermPos, Comments) :-
  568    colourise_comments(Comments, TB),
  569    (   Term == end_of_file
  570    ->  true
  571    ;   colourise_term(Term, TB, TermPos),
  572        colourise_fullstop(TB, TermPos)
  573    ).
  574
  575colourise_fullstop(TB, TermPos) :-
  576    arg(2, TermPos, EndTerm),
  577    Start is EndTerm,
  578    End is Start+1,
  579    colour_item(fullstop, TB, Start-End).
  580
  581colourise_comments(-, _).
  582colourise_comments([], _).
  583colourise_comments([H|T], TB) :-
  584    colourise_comment(H, TB),
  585    colourise_comments(T, TB).
  586
  587colourise_comment((-)-_, _) :- !.
  588colourise_comment(Pos-Comment, TB) :-
  589    comment_style(Comment, Style),
  590    stream_position_data(char_count, Pos, Start),
  591    string_length(Comment, Len),
  592    End is Start + Len + 1,
  593    colour_item(comment(Style), TB, Start-End).
  594
  595comment_style(Comment, structured) :-           % Starts %%, %! or /**
  596    structured_comment_start(Start),
  597    sub_string(Comment, 0, Len, _, Start),
  598    Next is Len+1,
  599    string_code(Next, Comment, NextCode),
  600    code_type(NextCode, space),
  601    !.
  602comment_style(Comment, line) :-                 % Starts %
  603    sub_string(Comment, 0, _, _, '%'),
  604    !.
  605comment_style(_, block).                        % Starts /*
 structured_comment_start(-Start)
Copied from library(pldoc/doc_process). Unfortunate, but we do not want to force loading pldoc.
  612structured_comment_start('%%').
  613structured_comment_start('%!').
  614structured_comment_start('/**').
 colourise_term(+Term, +TB, +Pos)
Colorise a file toplevel term.
  620colourise_term(Var, TB, Start-End) :-
  621    var(Var),
  622    !,
  623    colour_item(instantiation_error, TB, Start-End).
  624colourise_term(_, _, Pos) :-
  625    var(Pos),
  626    !.
  627colourise_term(Term, TB, parentheses_term_position(PO,PC,Pos)) :-
  628    !,
  629    colour_item(parentheses, TB, PO-PC),
  630    colourise_term(Term, TB, Pos).
  631colourise_term(Term, TB, Pos) :-
  632    term_colours(Term, FuncSpec-ArgSpecs),
  633    !,
  634    Pos = term_position(F,T,FF,FT,ArgPos),
  635    colour_item(term, TB, F-T),     % TBD: Allow specifying by term_colours/2?
  636    specified_item(FuncSpec, Term, TB, FF-FT),
  637    specified_items(ArgSpecs, Term, TB, ArgPos).
  638colourise_term((Pre=>Body), TB,
  639               term_position(F,T,FF,FT,[PP,BP])) :-
  640    nonvar(Pre),
  641    Pre = (Head,Cond),
  642    PP = term_position(_HF,_HT,_HFF,_HFT,[HP,CP]),
  643    !,
  644    colour_item(clause,         TB, F-T),
  645    colour_item(neck(=>),       TB, FF-FT),
  646    colourise_clause_head(Head, TB, HP),
  647    colour_item(rule_condition, TB, CP),
  648    colourise_body(Cond, Head,  TB, CP),
  649    colourise_body(Body, Head,  TB, BP).
  650colourise_term(Term, TB,
  651               term_position(F,T,FF,FT,[HP,BP])) :-
  652    neck(Term, Head, Body, Neck),
  653    !,
  654    colour_item(clause,         TB, F-T),
  655    colour_item(neck(Neck),     TB, FF-FT),
  656    colourise_clause_head(Head, TB, HP),
  657    colourise_body(Body, Head,  TB, BP).
  658colourise_term(((Head,RHC) --> Body), TB,
  659               term_position(F,T,FF,FT,
  660                             [ term_position(_,_,_,_,[HP,RHCP]),
  661                               BP
  662                             ])) :-
  663    !,
  664    colour_item(grammar_rule,       TB, F-T),
  665    colour_item(dcg_right_hand_ctx, TB, RHCP),
  666    colourise_term_arg(RHC, TB, RHCP),
  667    colour_item(neck(-->),          TB, FF-FT),
  668    colourise_extended_head(Head, 2, TB, HP),
  669    colourise_dcg(Body, Head,       TB, BP).
  670colourise_term((Head --> Body), TB,                     % TBD: expansion!
  671               term_position(F,T,FF,FT,[HP,BP])) :-
  672    !,
  673    colour_item(grammar_rule,       TB, F-T),
  674    colour_item(neck(-->),          TB, FF-FT),
  675    colourise_extended_head(Head, 2, TB, HP),
  676    colourise_dcg(Body, Head,       TB, BP).
  677colourise_term(((Head,RHC) ==> Body), TB,
  678               term_position(F,T,FF,FT,
  679                             [ term_position(_,_,_,_,[HP,RHCP]),
  680                               BP
  681                             ])) :-
  682    !,
  683    extend(Head, 2, HeadEx),
  684    colour_item(grammar_rule,        TB, F-T),
  685    colour_item(rule_condition,      TB, RHCP),
  686    colourise_body(RHC, HeadEx,      TB, RHCP),
  687    colour_item(neck(==>),           TB, FF-FT),
  688    colourise_extended_head(Head, 2, TB, HP),
  689    colourise_dcg(Body, Head,        TB, BP).
  690colourise_term((Head ==> Body), TB,                     % TBD: expansion!
  691               term_position(F,T,FF,FT,[HP,BP])) :-
  692    !,
  693    colour_item(grammar_rule,       TB, F-T),
  694    colour_item(neck(==>),          TB, FF-FT),
  695    colourise_extended_head(Head, 2, TB, HP),
  696    colourise_dcg(Body, Head,       TB, BP).
  697colourise_term(:->(Head, Body), TB,
  698               term_position(F,T,FF,FT,[HP,BP])) :-
  699    !,
  700    colour_item(method,             TB, F-T),
  701    colour_item(neck(:->), TB, FF-FT),
  702    colour_method_head(send(Head),  TB, HP),
  703    colourise_method_body(Body,     TB, BP).
  704colourise_term(:<-(Head, Body), TB,
  705               term_position(F,T,FF,FT,[HP,BP])) :-
  706    !,
  707    colour_item(method,            TB, F-T),
  708    colour_item(neck(:<-), TB, FF-FT),
  709    colour_method_head(get(Head),  TB, HP),
  710    colourise_method_body(Body,    TB, BP).
  711colourise_term((:- Directive), TB, Pos) :-
  712    !,
  713    colour_item(directive, TB, Pos),
  714    Pos = term_position(_F,_T,FF,FT,[ArgPos]),
  715    colour_item(neck(directive), TB, FF-FT),
  716    colourise_directive(Directive, TB, ArgPos).
  717colourise_term((?- Directive), TB, Pos) :-
  718    !,
  719    colourise_term((:- Directive), TB, Pos).
  720colourise_term(end_of_file, _, _) :- !.
  721colourise_term(Fact, TB, Pos) :-
  722    !,
  723    colour_item(clause, TB, Pos),
  724    colourise_clause_head(Fact, TB, Pos).
  725
  726neck((Head  :- Body), Head, Body, :-).
  727neck((Head  => Body), Head, Body, =>).
  728neck(?=>(Head, Body), Head, Body, ?=>).
 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.
  736colourise_extended_head(Head, N, TB, Pos) :-
  737    extend(Head, N, TheHead),
  738    colourise_clause_head(TheHead, TB, Pos).
  739
  740extend(M:Head, N, M:ExtHead) :-
  741    nonvar(Head),
  742    !,
  743    extend(Head, N, ExtHead).
  744extend(Head, N, ExtHead) :-
  745    compound(Head),
  746    !,
  747    compound_name_arguments(Head, Name, Args),
  748    length(Extra, N),
  749    append(Args, Extra, NArgs),
  750    compound_name_arguments(ExtHead, Name, NArgs).
  751extend(Head, N, ExtHead) :-
  752    atom(Head),
  753    !,
  754    length(Extra, N),
  755    compound_name_arguments(ExtHead, Head, Extra).
  756extend(Head, _, Head).
  757
  758
  759colourise_clause_head(_, _, Pos) :-
  760    var(Pos),
  761    !.
  762colourise_clause_head(Head, TB, parentheses_term_position(PO,PC,Pos)) :-
  763    colour_item(parentheses, TB, PO-PC),
  764    colourise_clause_head(Head, TB, Pos).
  765colourise_clause_head(M:Head, TB, QHeadPos) :-
  766    QHeadPos = term_position(_,_,QF,QT,[MPos,HeadPos]),
  767    head_colours(M:Head, meta-[_, ClassSpec-ArgSpecs]),
  768    !,
  769    colourise_module(M, TB, MPos),
  770    colour_item(functor, TB, QF-QT),
  771    functor_position(HeadPos, FPos, ArgPos),
  772    (   ClassSpec == classify
  773    ->  classify_head(TB, Head, Class)
  774    ;   Class = ClassSpec
  775    ),
  776    colour_item(head_term(Class, Head), TB, QHeadPos),
  777    colour_item(head(Class, Head), TB, FPos),
  778    specified_items(ArgSpecs, Head, TB, ArgPos).
  779colourise_clause_head(#(Macro), TB, term_position(_,_,HF,HT,[MPos])) :-
  780    expand_macro(TB, Macro, Head),
  781    !,
  782    macro_term_string(Head, String),
  783    functor_position(MPos, FPos, _),
  784    classify_head(TB, Head, Class),
  785    colour_item(macro(String), TB, HF-HT),
  786    colour_item(head_term(Class, Head), TB, MPos),
  787    colour_item(head(Class, Head), TB, FPos),
  788    colourise_term_args(Macro, TB, MPos).
  789colourise_clause_head(Head, TB, Pos) :-
  790    head_colours(Head, ClassSpec-ArgSpecs),
  791    !,
  792    functor_position(Pos, FPos, ArgPos),
  793    (   ClassSpec == classify
  794    ->  classify_head(TB, Head, Class)
  795    ;   Class = ClassSpec
  796    ),
  797    colour_item(head_term(Class, Head), TB, Pos),
  798    colour_item(head(Class, Head), TB, FPos),
  799    specified_items(ArgSpecs, Head, TB, ArgPos).
  800colourise_clause_head(:=(Eval, Ret), TB,
  801                      term_position(_,_,AF,AT,
  802                                    [ term_position(_,_,SF,ST,
  803                                                    [ SelfPos,
  804                                                      FuncPos
  805                                                    ]),
  806                                      RetPos
  807                                    ])) :-
  808    Eval =.. [.,M,Func],
  809    FuncPos = term_position(_,_,FF,FT,_),
  810    !,
  811    colourise_term_arg(M, TB, SelfPos),
  812    colour_item(func_dot, TB, SF-ST),               % .
  813    colour_item(dict_function(Func), TB, FF-FT),
  814    colourise_term_args(Func, TB, FuncPos),
  815    colour_item(dict_return_op, TB, AF-AT),         % :=
  816    colourise_term_arg(Ret, TB, RetPos).
  817colourise_clause_head(Head, TB, Pos) :-
  818    functor_position(Pos, FPos, _),
  819    classify_head(TB, Head, Class),
  820    colour_item(head_term(Class, Head), TB, Pos),
  821    colour_item(head(Class, Head), TB, FPos),
  822    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.
  829colourise_extern_head(Head, M, TB, Pos) :-
  830    functor_position(Pos, FPos, _),
  831    colour_item(head(extern(M), Head), TB, FPos),
  832    colourise_term_args(Head, TB, Pos).
  833
  834colour_method_head(SGHead, TB, Pos) :-
  835    arg(1, SGHead, Head),
  836    functor_name(SGHead, SG),
  837    functor_position(Pos, FPos, _),
  838    colour_item(method(SG), TB, FPos),
  839    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'.
  846functor_position(term_position(_,_,FF,FT,ArgPos), FF-FT, ArgPos) :- !.
  847functor_position(list_position(F,_T,Elms,none), F-FT, Elms) :-
  848    !,
  849    FT is F + 1.
  850functor_position(dict_position(_,_,FF,FT,KVPos), FF-FT, KVPos) :- !.
  851functor_position(brace_term_position(F,T,Arg), F-T, [Arg]) :- !.
  852functor_position(Pos, Pos, []).
  853
  854colourise_module(Term, TB, Pos) :-
  855    (   var(Term)
  856    ;   atom(Term)
  857    ),
  858    !,
  859    colour_item(module(Term), TB, Pos).
  860colourise_module(_, TB, Pos) :-
  861    colour_item(type_error(module), TB, Pos).
 colourise_directive(+Body, +TB, +Pos)
Colourise the body of a directive.
  867colourise_directive(_,_,Pos) :-
  868    var(Pos),
  869    !.
  870colourise_directive(Dir, TB, parentheses_term_position(PO,PC,Pos)) :-
  871    !,
  872    colour_item(parentheses, TB, PO-PC),
  873    colourise_directive(Dir, TB, Pos).
  874colourise_directive((A,B), TB, term_position(_,_,_,_,[PA,PB])) :-
  875    !,
  876    colourise_directive(A, TB, PA),
  877    colourise_directive(B, TB, PB).
  878colourise_directive(Body, TB, Pos) :-
  879    nonvar(Body),
  880    directive_colours(Body, ClassSpec-ArgSpecs),   % specified
  881    !,
  882    functor_position(Pos, FPos, ArgPos),
  883    (   ClassSpec == classify
  884    ->  goal_classification(TB, Body, [], Class)
  885    ;   Class = ClassSpec
  886    ),
  887    colour_item(goal(Class, Body), TB, FPos),
  888    specified_items(ArgSpecs, Body, TB, ArgPos).
  889colourise_directive(Body, TB, Pos) :-
  890    colourise_body(Body, TB, Pos).
  891
  892
  893%       colourise_body(+Body, +TB, +Pos)
  894%
  895%       Breaks down to colourise_goal/3.
  896
  897colourise_body(Body, TB, Pos) :-
  898    colourise_body(Body, [], TB, Pos).
  899
  900colourise_body(Body, Origin, TB, Pos) :-
  901    colour_item(body, TB, Pos),
  902    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.
  911colourise_method_body(_, _, Pos) :-
  912    var(Pos),
  913    !.
  914colourise_method_body(Body, TB, parentheses_term_position(PO,PC,Pos)) :-
  915    !,
  916    colour_item(parentheses, TB, PO-PC),
  917    colourise_method_body(Body, TB, Pos).
  918colourise_method_body(::(_Comment,Body), TB,
  919                      term_position(_F,_T,_FF,_FT,[CP,BP])) :-
  920    !,
  921    colour_item(comment(string), TB, CP),
  922    colourise_body(Body, TB, BP).
  923colourise_method_body(Body, TB, Pos) :-         % deal with pri(::) < 1000
  924    Body =.. [F,A,B],
  925    control_op(F),
  926    !,
  927    Pos = term_position(_F,_T,FF,FT,
  928                        [ AP,
  929                          BP
  930                        ]),
  931    colour_item(control, TB, FF-FT),
  932    colourise_method_body(A, TB, AP),
  933    colourise_body(B, TB, BP).
  934colourise_method_body(Body, TB, Pos) :-
  935    colourise_body(Body, TB, Pos).
  936
  937control_op(',').
  938control_op((;)).
  939control_op((->)).
  940control_op((*->)).
 colourise_goals(+Body, +Origin, +TB, +Pos)
Colourise the goals in a body.
  946colourise_goals(_, _, _, Pos) :-
  947    var(Pos),
  948    !.
  949colourise_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  950    !,
  951    colour_item(parentheses, TB, PO-PC),
  952    colourise_goals(Body, Origin, TB, Pos).
  953colourise_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  954    body_compiled(Body),
  955    !,
  956    colour_item(control, TB, FF-FT),
  957    colourise_subgoals(ArgPos, 1, Body, Origin, TB).
  958colourise_goals(Goal, Origin, TB, Pos) :-
  959    colourise_goal(Goal, Origin, TB, Pos).
  960
  961colourise_subgoals([], _, _, _, _).
  962colourise_subgoals([Pos|T], N, Body, Origin, TB) :-
  963    arg(N, Body, Arg),
  964    colourise_goals(Arg, Origin, TB, Pos),
  965    NN is N + 1,
  966    colourise_subgoals(T, NN, Body, Origin, TB).
 colourise_dcg(+Body, +Head, +TB, +Pos)
Breaks down to colourise_dcg_goal/3.
  972colourise_dcg(Body, Head, TB, Pos) :-
  973    colour_item(dcg, TB, Pos),
  974    (   dcg_extend(Head, Origin)
  975    ->  true
  976    ;   Origin = Head
  977    ),
  978    colourise_dcg_goals(Body, Origin, TB, Pos).
  979
  980colourise_dcg_goals(Var, _, TB, Pos) :-
  981    var(Var),
  982    !,
  983    colour_item(goal(meta,Var), TB, Pos).
  984colourise_dcg_goals(_, _, _, Pos) :-
  985    var(Pos),
  986    !.
  987colourise_dcg_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  988    !,
  989    colour_item(parentheses, TB, PO-PC),
  990    colourise_dcg_goals(Body, Origin, TB, Pos).
  991colourise_dcg_goals({Body}, Origin, TB, brace_term_position(F,T,Arg)) :-
  992    !,
  993    colour_item(dcg(plain), TB, F-T),
  994    colourise_goals(Body, Origin, TB, Arg).
  995colourise_dcg_goals([], _, TB, Pos) :-
  996    !,
  997    colour_item(dcg(terminal), TB, Pos).
  998colourise_dcg_goals(List, _, TB, list_position(F,T,Elms,Tail)) :-
  999    List = [_|_],
 1000    !,
 1001    colour_item(dcg(terminal), TB, F-T),
 1002    colourise_list_args(Elms, Tail, List, TB, classify).
 1003colourise_dcg_goals(_, _, TB, string_position(F,T)) :-
 1004    integer(F),
 1005    !,
 1006    colour_item(dcg(string), TB, F-T).
 1007colourise_dcg_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
 1008    dcg_body_compiled(Body),       % control structures
 1009    !,
 1010    colour_item(control, TB, FF-FT),
 1011    colourise_dcg_subgoals(ArgPos, 1, Body, Origin, TB).
 1012colourise_dcg_goals(Goal, Origin, TB, Pos) :-
 1013    colourise_dcg_goal(Goal, Origin, TB, Pos).
 1014
 1015colourise_dcg_subgoals([], _, _, _, _).
 1016colourise_dcg_subgoals([Pos|T], N, Body, Origin, TB) :-
 1017    arg(N, Body, Arg),
 1018    colourise_dcg_goals(Arg, Origin, TB, Pos),
 1019    NN is N + 1,
 1020    colourise_dcg_subgoals(T, NN, Body, Origin, TB).
 1021
 1022dcg_extend(Term, _) :-
 1023    var(Term), !, fail.
 1024dcg_extend(M:Term, M:Goal) :-
 1025    dcg_extend(Term, Goal).
 1026dcg_extend(Term, Goal) :-
 1027    compound(Term),
 1028    !,
 1029    compound_name_arguments(Term, Name, Args),
 1030    append(Args, [_,_], NArgs),
 1031    compound_name_arguments(Goal, Name, NArgs).
 1032dcg_extend(Term, Goal) :-
 1033    atom(Term),
 1034    !,
 1035    compound_name_arguments(Goal, Term, [_,_]).
 1036
 1037dcg_body_compiled(G) :-
 1038    body_compiled(G),
 1039    !.
 1040dcg_body_compiled((_|_)).
 1041
 1042%       colourise_dcg_goal(+Goal, +Origin, +TB, +Pos).
 1043
 1044colourise_dcg_goal(!, Origin, TB, TermPos) :-
 1045    !,
 1046    colourise_goal(!, Origin, TB, TermPos).
 1047colourise_dcg_goal(Goal, Origin, TB, TermPos) :-
 1048    dcg_extend(Goal, TheGoal),
 1049    !,
 1050    colourise_goal(TheGoal, Origin, TB, TermPos).
 1051colourise_dcg_goal(Goal, _, TB, Pos) :-
 1052    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.
 1063                                        % Deal with list as goal (consult)
 1064colourise_goal(_,_,_,Pos) :-
 1065    var(Pos),
 1066    !.
 1067colourise_goal(Goal, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
 1068    !,
 1069    colour_item(parentheses, TB, PO-PC),
 1070    colourise_goal(Goal, Origin, TB, Pos).
 1071colourise_goal(Goal, _, TB, Pos) :-
 1072    Pos = list_position(F,T,Elms,TailPos),
 1073    Goal = [_|_],
 1074    !,
 1075    FT is F + 1,
 1076    AT is T - 1,
 1077    colour_item(goal_term(built_in, Goal), TB, Pos),
 1078    colour_item(goal(built_in, Goal), TB, F-FT),
 1079    colour_item(goal(built_in, Goal), TB, AT-T),
 1080    colourise_file_list(Goal, TB, Elms, TailPos, any).
 1081colourise_goal(Goal, Origin, TB, Pos) :-
 1082    Pos = list_position(F,T,Elms,Tail),
 1083    callable(Goal),
 1084    Goal =.. [_,GH,GT|_],
 1085    !,
 1086    goal_classification(TB, Goal, Origin, Class),
 1087    FT is F + 1,
 1088    AT is T - 1,
 1089    colour_item(goal_term(Class, Goal), TB, Pos),
 1090    colour_item(goal(Class, Goal), TB, F-FT),
 1091    colour_item(goal(Class, Goal), TB, AT-T),
 1092    colourise_list_args(Elms, Tail, [GH|GT], TB, classify).
 1093colourise_goal(Goal, _Origin, TB, Pos) :-
 1094    Pos = quasi_quotation_position(_F,_T,_QQType,_QQTypePos,_CPos),
 1095    !,
 1096    colourise_term_arg(Goal, TB, Pos).
 1097colourise_goal(#(Macro), Origin, TB, term_position(_,_,HF,HT,[MPos])) :-
 1098    expand_macro(TB, Macro, Goal),
 1099    !,
 1100    macro_term_string(Goal, String),
 1101    goal_classification(TB, Goal, Origin, Class),
 1102    (   MPos = term_position(_,_,FF,FT,_ArgPos)
 1103    ->  FPos = FF-FT
 1104    ;   FPos = MPos
 1105    ),
 1106    colour_item(macro(String), TB, HF-HT),
 1107    colour_item(goal_term(Class, Goal), TB, MPos),
 1108    colour_item(goal(Class, Goal), TB, FPos),
 1109    colourise_goal_args(Goal, TB, MPos).
 1110colourise_goal(Goal, Origin, TB, Pos) :-
 1111    strip_module(Goal, _, PGoal),
 1112    nonvar(PGoal),
 1113    (   goal_classification(TB, Goal, Origin, ClassInferred),
 1114        call_goal_colours(Goal, ClassInferred, ClassSpec-ArgSpecs)
 1115    ->  true
 1116    ;   call_goal_colours(Goal, ClassSpec-ArgSpecs)
 1117    ),
 1118    !,                                          % specified
 1119    functor_position(Pos, FPos, ArgPos),
 1120    (   ClassSpec == classify
 1121    ->  goal_classification(TB, Goal, Origin, Class)
 1122    ;   Class = ClassSpec
 1123    ),
 1124    colour_item(goal_term(Class, Goal), TB, Pos),
 1125    colour_item(goal(Class, Goal), TB, FPos),
 1126    colour_dict_braces(TB, Pos),
 1127    specified_items(ArgSpecs, Goal, TB, ArgPos).
 1128colourise_goal(Module:Goal, _Origin, TB, QGoalPos) :-
 1129    QGoalPos = term_position(_,_,QF,QT,[PM,PG]),
 1130    !,
 1131    colourise_module(Module, TB, PM),
 1132    colour_item(functor, TB, QF-QT),
 1133    (   PG = term_position(_,_,FF,FT,_)
 1134    ->  FP = FF-FT
 1135    ;   FP = PG
 1136    ),
 1137    (   callable(Goal)
 1138    ->  qualified_goal_classification(Module:Goal, TB, Class),
 1139        colour_item(goal_term(Class, Goal), TB, QGoalPos),
 1140        colour_item(goal(Class, Goal), TB, FP),
 1141        colourise_goal_args(Goal, Module, TB, PG)
 1142    ;   var(Goal)
 1143    ->  colourise_term_arg(Goal, TB, PG)
 1144    ;   colour_item(type_error(callable), TB, PG)
 1145    ).
 1146colourise_goal(Op, _Origin, TB, Pos) :-
 1147    nonvar(Op),
 1148    Op = op(_,_,_),
 1149    !,
 1150    colourise_op_declaration(Op, TB, Pos).
 1151colourise_goal(Goal, Origin, TB, Pos) :-
 1152    goal_classification(TB, Goal, Origin, Class),
 1153    (   Pos = term_position(_,_,FF,FT,_ArgPos)
 1154    ->  FPos = FF-FT
 1155    ;   FPos = Pos
 1156    ),
 1157    colour_item(goal_term(Class, Goal), TB, Pos),
 1158    colour_item(goal(Class, Goal), TB, FPos),
 1159    colourise_goal_args(Goal, TB, Pos).
 1160
 1161% make sure to emit a fragment for the braces of tag{k:v, ...} or
 1162% {...} that is mapped to something else.
 1163
 1164colour_dict_braces(TB, dict_position(_F,T,_TF,TT,_KVPos)) :-
 1165    !,
 1166    BStart is TT+1,
 1167    colour_item(dict_content, TB, BStart-T).
 1168colour_dict_braces(_, _).
 colourise_goal_args(+Goal, +TB, +Pos)
Colourise the arguments to a goal. This predicate deals with meta- and database-access predicates.
 1175colourise_goal_args(Goal, TB, Pos) :-
 1176    colourization_module(TB, Module),
 1177    colourise_goal_args(Goal, Module, TB, Pos).
 1178
 1179colourization_module(TB, Module) :-
 1180    (   colour_state_source_id(TB, SourceId),
 1181        xref_module(SourceId, Module)
 1182    ->  true
 1183    ;   Module = user
 1184    ).
 1185
 1186colourise_goal_args(Goal, M, TB, term_position(_,_,_,_,ArgPos)) :-
 1187    !,
 1188    (   meta_args(Goal, TB, MetaArgs)
 1189    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, ArgPos)
 1190    ;   colourise_goal_args(1, Goal, M, TB, ArgPos)
 1191    ).
 1192colourise_goal_args(Goal, M, TB, brace_term_position(_,_,ArgPos)) :-
 1193    !,
 1194    (   meta_args(Goal, TB, MetaArgs)
 1195    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, [ArgPos])
 1196    ;   colourise_goal_args(1, Goal, M, TB, [ArgPos])
 1197    ).
 1198colourise_goal_args(_, _, _, _).                % no arguments
 1199
 1200colourise_goal_args(_, _, _, _, []) :- !.
 1201colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1202    colourise_option_arg(Goal, Module, N, TB, P0),
 1203    !,
 1204    NN is N + 1,
 1205    colourise_goal_args(NN, Goal, Module, TB, PT).
 1206colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1207    arg(N, Goal, Arg),
 1208    colourise_term_arg(Arg, TB, P0),
 1209    NN is N + 1,
 1210    colourise_goal_args(NN, Goal, Module, TB, PT).
 1211
 1212
 1213colourise_meta_args(_, _, _, _, _, []) :- !.
 1214colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1215    colourise_option_arg(Goal, Module, N, TB, P0),
 1216    !,
 1217    NN is N + 1,
 1218    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1219colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1220    arg(N, Goal, Arg),
 1221    arg(N, MetaArgs, MetaSpec),
 1222    colourise_meta_arg(MetaSpec, Arg, TB, P0),
 1223    NN is N + 1,
 1224    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1225
 1226colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1227    nonvar(Arg),
 1228    expand_meta(MetaSpec, Arg, Expanded),
 1229    !,
 1230    colourise_goal(Expanded, [], TB, Pos). % TBD: recursion
 1231colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1232    nonvar(Arg),
 1233    MetaSpec == //,
 1234    !,
 1235    colourise_dcg_goals(Arg, //, TB, Pos).
 1236colourise_meta_arg(_, Arg, TB, Pos) :-
 1237    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.

 1250meta_args(Goal, TB, VarGoal) :-
 1251    colour_state_source_id(TB, SourceId),
 1252    xref_meta(SourceId, Goal, _),
 1253    !,
 1254    compound_name_arity(Goal, Name, Arity),
 1255    compound_name_arity(VarGoal, Name, Arity),
 1256    xref_meta(SourceId, VarGoal, MetaArgs),
 1257    instantiate_meta(MetaArgs).
 1258
 1259instantiate_meta([]).
 1260instantiate_meta([H|T]) :-
 1261    (   var(H)
 1262    ->  H = 0
 1263    ;   H = V+N
 1264    ->  V = N
 1265    ;   H = //(V)
 1266    ->  V = (//)
 1267    ),
 1268    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).
 1275expand_meta(MetaSpec, Goal, Goal) :-
 1276    MetaSpec == 0.
 1277expand_meta(MetaSpec, M:Goal, M:Expanded) :-
 1278    atom(M),
 1279    !,
 1280    expand_meta(MetaSpec, Goal, Expanded).
 1281expand_meta(MetaSpec, Goal, Expanded) :-
 1282    integer(MetaSpec),
 1283    MetaSpec > 0,
 1284    (   atom(Goal)
 1285    ->  functor(Expanded, Goal, MetaSpec)
 1286    ;   compound(Goal)
 1287    ->  compound_name_arguments(Goal, Name, Args0),
 1288        length(Extra, MetaSpec),
 1289        append(Args0, Extra, Args),
 1290        compound_name_arguments(Expanded, Name, Args)
 1291    ).
 colourise_setof(+Term, +TB, +Pos)
Colourise the 2nd argument of setof/bagof
 1297colourise_setof(Var^G, TB, term_position(_,_,FF,FT,[VP,GP])) :-
 1298    !,
 1299    colourise_term_arg(Var, TB, VP),
 1300    colour_item(ext_quant, TB, FF-FT),
 1301    colourise_setof(G, TB, GP).
 1302colourise_setof(Term, TB, Pos) :-
 1303    colourise_goal(Term, [], TB, Pos).
 1304
 1305%       colourise_db(+Arg, +TB, +Pos)
 1306%
 1307%       Colourise database modification calls (assert/1, retract/1 and
 1308%       friends.
 1309
 1310colourise_db((Head:-Body), TB, term_position(_,_,_,_,[HP,BP])) :-
 1311    !,
 1312    colourise_db(Head, TB, HP),
 1313    colourise_body(Body, Head, TB, BP).
 1314colourise_db(Module:Head, TB, term_position(_,_,QF,QT,[MP,HP])) :-
 1315    !,
 1316    colourise_module(Module, TB, MP),
 1317    colour_item(functor, TB, QF-QT),
 1318    (   atom(Module),
 1319        colour_state_source_id(TB, SourceId),
 1320        xref_module(SourceId, Module)
 1321    ->  colourise_db(Head, TB, HP)
 1322    ;   colourise_db(Head, TB, HP)
 1323    ).
 1324colourise_db(Head, TB, Pos) :-
 1325    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
 1334colourise_option_arg(Goal, Module, Arg, TB, ArgPos) :-
 1335    goal_name_arity(Goal, Name, Arity),
 1336    current_option_arg(Module:Name/Arity, Arg),
 1337    current_predicate_options(Module:Name/Arity, Arg, OptionDecl),
 1338    debug(emacs, 'Colouring option-arg ~w of ~p',
 1339          [Arg, Module:Name/Arity]),
 1340    arg(Arg, Goal, Options),
 1341    colourise_option(Options, Module, Goal, Arg, OptionDecl, TB, ArgPos).
 1342
 1343colourise_option(Options0, Module, Goal, Arg, OptionDecl, TB, Pos0) :-
 1344    strip_option_module_qualifier(Goal, Module, Arg, TB,
 1345                                  Options0, Pos0, Options, Pos),
 1346    (   Pos = list_position(F, T, ElmPos, TailPos)
 1347    ->  colour_item(list, TB, F-T),
 1348        colourise_option_list(Options, OptionDecl, TB, ElmPos, TailPos)
 1349    ;   (   var(Options)
 1350        ;   Options == []
 1351        )
 1352    ->  colourise_term_arg(Options, TB, Pos)
 1353    ;   colour_item(type_error(list), TB, Pos)
 1354    ).
 1355
 1356strip_option_module_qualifier(Goal, Module, Arg, TB,
 1357                              M:Options, term_position(_,_,_,_,[MP,Pos]),
 1358                              Options, Pos) :-
 1359    predicate_property(Module:Goal, meta_predicate(Head)),
 1360    arg(Arg, Head, :),
 1361    !,
 1362    colourise_module(M, TB, MP).
 1363strip_option_module_qualifier(_, _, _, _,
 1364                              Options, Pos, Options, Pos).
 1365
 1366
 1367colourise_option_list(_, _, _, [], none) :- !.
 1368colourise_option_list(Tail, _, TB, [], TailPos) :-
 1369    !,
 1370    colourise_term_arg(Tail, TB, TailPos).
 1371colourise_option_list([H|T], OptionDecl, TB, [HPos|TPos], TailPos) :-
 1372    colourise_option(H, OptionDecl, TB, HPos),
 1373    colourise_option_list(T, OptionDecl, TB, TPos, TailPos).
 1374
 1375colourise_option(Opt, _, TB, Pos) :-
 1376    var(Opt),
 1377    !,
 1378    colourise_term_arg(Opt, TB, Pos).
 1379colourise_option(Opt, OptionDecl, TB, term_position(_,_,FF,FT,ValPosList)) :-
 1380    !,
 1381    generalise_term(Opt, GenOpt),
 1382    (   memberchk(GenOpt, OptionDecl)
 1383    ->  colour_item(option_name, TB, FF-FT),
 1384        Opt =.. [Name|Values],
 1385        GenOpt =.. [Name|Types],
 1386        colour_option_values(Values, Types, TB, ValPosList)
 1387    ;   colour_item(no_option_name, TB, FF-FT),
 1388        colourise_term_args(ValPosList, 1, Opt, TB)
 1389    ).
 1390colourise_option(_, _, TB, Pos) :-
 1391    colour_item(type_error(option), TB, Pos).
 1392
 1393colour_option_values([], [], _, _).
 1394colour_option_values([V0|TV], [T0|TT], TB, [P0|TP]) :-
 1395    (   (   var(V0)
 1396        ;   is_of_type(T0, V0)
 1397        ;   T0 = list(_),
 1398            member(E, V0),
 1399            var(E)
 1400        ;   dict_field_extraction(V0)
 1401        )
 1402    ->  colourise_term_arg(V0, TB, P0)
 1403    ;   callable(V0),
 1404        (   T0 = callable
 1405        ->  N = 0
 1406        ;   T0 = (callable+N)
 1407        )
 1408    ->  colourise_meta_arg(N, V0, TB, P0)
 1409    ;   colour_item(type_error(T0), TB, P0)
 1410    ),
 1411    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
 1420colourise_files(List, TB, list_position(F,T,Elms,TailPos), Why) :-
 1421    !,
 1422    colour_item(list, TB, F-T),
 1423    colourise_file_list(List, TB, Elms, TailPos, Why).
 1424colourise_files(M:Spec, TB, term_position(_,_,_,_,[MP,SP]), Why) :-
 1425    !,
 1426    colourise_module(M, TB, MP),
 1427    colourise_files(Spec, TB, SP, Why).
 1428colourise_files(Var, TB, P, _) :-
 1429    var(Var),
 1430    !,
 1431    colour_item(var, TB, P).
 1432colourise_files(Spec0, TB, Pos, Why) :-
 1433    strip_module(Spec0, _, Spec),
 1434    (   colour_state_source_id(TB, Source),
 1435        prolog_canonical_source(Source, SourceId),
 1436        catch(xref_source_file(Spec, Path, SourceId, [silent(true)]),
 1437              _, fail)
 1438    ->  (   Why = imported,
 1439            \+ resolves_anything(TB, Path),
 1440            exports_something(TB, Path)
 1441        ->  colour_item(file_no_depend(Path), TB, Pos)
 1442        ;   colour_item(file(Path), TB, Pos)
 1443        )
 1444    ;   colour_item(nofile, TB, Pos)
 1445    ).
 colourise_file_list(+Files, +TB, +ElmPos, +TailPos, +Why)
 1449colourise_file_list([], _, [], none, _).
 1450colourise_file_list(Last, TB, [], TailPos, _Why) :-
 1451    (   var(Last)
 1452    ->  colourise_term(Last, TB, TailPos)
 1453    ;   colour_item(type_error(list), TB, TailPos)
 1454    ).
 1455colourise_file_list([H|T], TB, [PH|PT], TailPos, Why) :-
 1456    colourise_files(H, TB, PH, Why),
 1457    colourise_file_list(T, TB, PT, TailPos, Why).
 1458
 1459resolves_anything(TB, Path) :-
 1460    colour_state_source_id(TB, SourceId),
 1461    xref_defined(SourceId, Head, imported(Path)),
 1462    xref_called(SourceId, Head, _),
 1463    !.
 1464
 1465exports_something(TB, Path) :-
 1466    colour_state_source_id(TB, SourceId),
 1467    xref_defined(SourceId, _, imported(Path)),
 1468    !.
 colourise_directory(+Arg, +TB, +Pos)
Colourise argument that should be an existing directory.
 1474colourise_directory(Spec, TB, Pos) :-
 1475    (   colour_state_source_id(TB, SourceId),
 1476        catch(xref_source_file(Spec, Path, SourceId,
 1477                               [ file_type(directory),
 1478                                 silent(true)
 1479                               ]),
 1480              _, fail)
 1481    ->  colour_item(directory(Path), TB, Pos)
 1482    ;   colour_item(nofile, TB, Pos)
 1483    ).
 colourise_langoptions(+Term, +TB, +Pos) is det
Colourise the 3th argument of module/3
 1489colourise_langoptions([], _, _) :- !.
 1490colourise_langoptions([H|T], TB, list_position(PF,PT,[HP|TP],_)) :-
 1491    !,
 1492    colour_item(list, TB, PF-PT),
 1493    colourise_langoptions(H, TB, HP),
 1494    colourise_langoptions(T, TB, TP).
 1495colourise_langoptions(Spec, TB, Pos) :-
 1496    colourise_files(library(dialect/Spec), TB, Pos, imported).
 colourise_class(ClassName, TB, Pos)
Colourise an XPCE class.
 1502colourise_class(ClassName, TB, Pos) :-
 1503    colour_state_source_id(TB, SourceId),
 1504    classify_class(SourceId, ClassName, Classification),
 1505    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.
 1513classify_class(SourceId, Name, Class) :-
 1514    xref_defined_class(SourceId, Name, Class),
 1515    !.
 1516classify_class(_SourceId, Name, Class) :-
 1517    current_predicate(pce:send_class/3),
 1518    (   current_predicate(classify_class/2)
 1519    ->  true
 1520    ;   use_module(library(pce_meta), [classify_class/2])
 1521    ),
 1522    member(G, [classify_class(Name, Class)]),
 1523    call(G).
 colourise_term_args(+Term, +TB, +Pos)
colourise head/body principal terms.
 1529colourise_term_args(Term, TB,
 1530                    term_position(_,_,_,_,ArgPos)) :-
 1531    !,
 1532    colourise_term_args(ArgPos, 1, Term, TB).
 1533colourise_term_args(_, _, _).
 1534
 1535colourise_term_args([], _, _, _).
 1536colourise_term_args([Pos|T], N, Term, TB) :-
 1537    arg(N, Term, Arg),
 1538    colourise_term_arg(Arg, TB, Pos),
 1539    NN is N + 1,
 1540    colourise_term_args(T, NN, Term, TB).
 colourise_term_arg(+Term, +TB, +Pos)
Colourise an arbitrary Prolog term without context of its semantical role.
 1547colourise_term_arg(_, _, Pos) :-
 1548    var(Pos),
 1549    !.
 1550colourise_term_arg(Arg, TB, parentheses_term_position(PO,PC,Pos)) :-
 1551    !,
 1552    colour_item(parentheses, TB, PO-PC),
 1553    colourise_term_arg(Arg, TB, Pos).
 1554colourise_term_arg(Var, TB, Pos) :-                     % variable
 1555    var(Var), Pos = _-_,
 1556    !,
 1557    (   singleton(Var, TB)
 1558    ->  colour_item(singleton, TB, Pos)
 1559    ;   colour_item(var, TB, Pos)
 1560    ).
 1561colourise_term_arg(List, TB, list_position(F, T, Elms, Tail)) :-
 1562    !,
 1563    colour_item(list, TB, F-T),
 1564    colourise_list_args(Elms, Tail, List, TB, classify).    % list
 1565colourise_term_arg(String, TB, string_position(F, T)) :-    % string
 1566    !,
 1567    (   string(String)
 1568    ->  colour_item(string, TB, F-T)
 1569    ;   String = [H|_]
 1570    ->  (   integer(H)
 1571        ->  colour_item(codes, TB, F-T)
 1572        ;   colour_item(chars, TB, F-T)
 1573        )
 1574    ;   String == []
 1575    ->  colour_item(codes, TB, F-T)
 1576    ).
 1577colourise_term_arg(_, TB,
 1578                   quasi_quotation_position(F,T,QQType,QQTypePos,CPos)) :-
 1579    !,
 1580    colourise_qq_type(QQType, TB, QQTypePos),
 1581    functor_name(QQType, Type),
 1582    colour_item(qq_content(Type), TB, CPos),
 1583    arg(1, CPos, SE),
 1584    SS is SE-2,
 1585    FE is F+2,
 1586    TS is T-2,
 1587    colour_item(qq(open),  TB, F-FE),
 1588    colour_item(qq(sep),   TB, SS-SE),
 1589    colour_item(qq(close), TB, TS-T).
 1590colourise_term_arg({Term}, TB, brace_term_position(F,T,Arg)) :-
 1591    !,
 1592    colour_item(brace_term, TB, F-T),
 1593    colourise_term_arg(Term, TB, Arg).
 1594colourise_term_arg(Map, TB, dict_position(F,T,TF,TT,KVPos)) :-
 1595    !,
 1596    is_dict(Map, Tag),
 1597    colour_item(dict, TB, F-T),
 1598    TagPos = TF-TT,
 1599    (   var(Tag)
 1600    ->  (   singleton(Tag, TB)
 1601        ->  colour_item(singleton, TB, TagPos)
 1602        ;   colour_item(var, TB, TagPos)
 1603        )
 1604    ;   colour_item(dict_tag, TB, TagPos)
 1605    ),
 1606    BStart is TT+1,
 1607    colour_item(dict_content, TB, BStart-T),
 1608    colourise_dict_kv(Map, TB, KVPos).
 1609colourise_term_arg([](List,Term), TB,                   % [] as operator
 1610                   term_position(_,_,0,0,[ListPos,ArgPos])) :-
 1611    !,
 1612    colourise_term_arg(List, TB, ListPos),
 1613    colourise_term_arg(Term, TB, ArgPos).
 1614colourise_term_arg(#(Macro), TB, term_position(_,_,HF,HT,[MPos])) :-
 1615    expand_macro(TB, Macro, Term),
 1616    !,
 1617    macro_term_string(Term, String),
 1618    colour_item(macro(String), TB, HF-HT),
 1619    colourise_term_arg(Macro, TB, MPos).
 1620colourise_term_arg(Compound, TB, Pos) :-                % compound
 1621    compound(Compound),
 1622    !,
 1623    (   Pos = term_position(_F,_T,FF,FT,_ArgPos)
 1624    ->  colour_item(functor, TB, FF-FT)             % TBD: Infix/Postfix?
 1625    ;   true                                        % TBD: When is this
 1626    ),
 1627    colourise_term_args(Compound, TB, Pos).
 1628colourise_term_arg(EmptyList, TB, Pos) :-
 1629    EmptyList == [],
 1630    !,
 1631    colour_item(empty_list, TB, Pos).
 1632colourise_term_arg(Atom, TB, Pos) :-
 1633    atom(Atom),
 1634    !,
 1635    colour_item(atom, TB, Pos).
 1636colourise_term_arg(Integer, TB, Pos) :-
 1637    integer(Integer),
 1638    !,
 1639    colour_item(int, TB, Pos).
 1640colourise_term_arg(Rational, TB, Pos) :-
 1641    rational(Rational),
 1642    !,
 1643    colour_item(rational(Rational), TB, Pos).
 1644colourise_term_arg(Float, TB, Pos) :-
 1645    float(Float),
 1646    !,
 1647    colour_item(float, TB, Pos).
 1648colourise_term_arg(_Arg, _TB, _Pos) :-
 1649    true.
 1650
 1651colourise_list_args([HP|TP], Tail, [H|T], TB, How) :-
 1652    specified_item(How, H, TB, HP),
 1653    colourise_list_args(TP, Tail, T, TB, How).
 1654colourise_list_args([], none, _, _, _) :- !.
 1655colourise_list_args([], TP, T, TB, How) :-
 1656    specified_item(How, T, TB, TP).
 colourise_expression(+Term, +TB, +Pos)
colourise arithmetic expressions.
 1663colourise_expression(_, _, Pos) :-
 1664    var(Pos),
 1665    !.
 1666colourise_expression(Arg, TB, parentheses_term_position(PO,PC,Pos)) :-
 1667    !,
 1668    colour_item(parentheses, TB, PO-PC),
 1669    colourise_expression(Arg, TB, Pos).
 1670colourise_expression(Compound, TB, Pos) :-
 1671    compound(Compound), Pos = term_position(_F,_T,FF,FT,_ArgPos),
 1672    !,
 1673    (   dict_field_extraction(Compound)
 1674    ->  colourise_term_arg(Compound, TB, Pos)
 1675    ;   current_arithmetic_function(Compound)
 1676    ->  colour_item(function, TB, FF-FT)
 1677    ;   colour_item(no_function, TB, FF-FT)
 1678    ),
 1679    colourise_expression_args(Compound, TB, Pos).
 1680colourise_expression(Atom, TB, Pos) :-
 1681    atom(Atom),
 1682    !,
 1683    (   current_arithmetic_function(Atom)
 1684    ->  colour_item(function, TB, Pos)
 1685    ;   colour_item(no_function, TB, Pos)
 1686    ).
 1687colourise_expression(NumOrVar, TB, Pos) :-
 1688    Pos = _-_,
 1689    !,
 1690    colourise_term_arg(NumOrVar, TB, Pos).
 1691colourise_expression(_Arg, TB, Pos) :-
 1692    colour_item(type_error(evaluable), TB, Pos).
 1693
 1694dict_field_extraction(Term) :-
 1695    compound(Term),
 1696    compound_name_arity(Term, '.', 2),
 1697    Term \= [_|_].                        % traditional mode
 1698
 1699
 1700colourise_expression_args(roundtoward(Expr, Mode), TB,
 1701                          term_position(_,_,_,_,[ExprPos, ModePos])) :-
 1702    !,
 1703    colourise_expression(Expr, TB, ExprPos),
 1704    colourise_round_mode(Mode, TB, ModePos).
 1705colourise_expression_args(Term, TB,
 1706                          term_position(_,_,_,_,ArgPos)) :-
 1707    !,
 1708    colourise_expression_args(ArgPos, 1, Term, TB).
 1709colourise_expression_args(_, _, _).
 1710
 1711colourise_expression_args([], _, _, _).
 1712colourise_expression_args([Pos|T], N, Term, TB) :-
 1713    arg(N, Term, Arg),
 1714    colourise_expression(Arg, TB, Pos),
 1715    NN is N + 1,
 1716    colourise_expression_args(T, NN, Term, TB).
 1717
 1718colourise_round_mode(Mode, TB, Pos) :-
 1719    var(Mode),
 1720    !,
 1721    colourise_term_arg(Mode, TB, Pos).
 1722colourise_round_mode(Mode, TB, Pos) :-
 1723    round_mode(Mode),
 1724    !,
 1725    colour_item(identifier, TB, Pos).
 1726colourise_round_mode(_Mode, TB, Pos) :-
 1727    colour_item(domain_error(rounding_mode), TB, Pos).
 1728
 1729round_mode(to_nearest).
 1730round_mode(to_positive).
 1731round_mode(to_negative).
 1732round_mode(to_zero).
 colourise_qq_type(+QQType, +TB, +QQTypePos)
Colouring the type part of a quasi quoted term
 1738colourise_qq_type(QQType, TB, QQTypePos) :-
 1739    functor_position(QQTypePos, FPos, _),
 1740    colour_item(qq_type, TB, FPos),
 1741    colourise_term_args(QQType, TB, QQTypePos).
 1742
 1743qq_position(quasi_quotation_position(_,_,_,_,_)).
 colourise_dict_kv(+Dict, +TB, +KVPosList)
Colourise the name-value pairs in the dict
 1749colourise_dict_kv(_, _, []) :- !.
 1750colourise_dict_kv(Dict, TB, [key_value_position(_F,_T,SF,ST,K,KP,VP)|KV]) :-
 1751    colour_item(dict_key, TB, KP),
 1752    colour_item(dict_sep, TB, SF-ST),
 1753    get_dict(K, Dict, V),
 1754    colourise_term_arg(V, TB, VP),
 1755    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).
 1763colourise_exports([], TB, Pos) :- !,
 1764    colourise_term_arg([], TB, Pos).
 1765colourise_exports(List, TB, list_position(F,T,ElmPos,Tail)) :-
 1766    !,
 1767    colour_item(list, TB, F-T),
 1768    (   Tail == none
 1769    ->  true
 1770    ;   colour_item(type_error(list), TB, Tail)
 1771    ),
 1772    colourise_exports2(List, TB, ElmPos).
 1773colourise_exports(_, TB, Pos) :-
 1774    colour_item(type_error(list), TB, Pos).
 1775
 1776colourise_exports2([G0|GT], TB, [P0|PT]) :-
 1777    !,
 1778    colourise_declaration(G0, export, TB, P0),
 1779    colourise_exports2(GT, TB, PT).
 1780colourise_exports2(_, _, _).
 colourise_imports(+List, +File, +TB, +Pos)
Colourise import list from use_module/2, importing from File.
 1787colourise_imports(List, File, TB, Pos) :-
 1788    (   colour_state_source_id(TB, SourceId),
 1789        ground(File),
 1790        catch(xref_public_list(File, SourceId,
 1791                               [ path(Path),
 1792                                 public(Public),
 1793                                 silent(true)
 1794                               ] ), _, fail)
 1795    ->  true
 1796    ;   Public = [],
 1797        Path = (-)
 1798    ),
 1799    colourise_imports(List, Path, Public, TB, Pos).
 1800
 1801colourise_imports([], _, _, TB, Pos) :-
 1802    !,
 1803    colour_item(empty_list, TB, Pos).
 1804colourise_imports(List, File, Public, TB, list_position(F,T,ElmPos,Tail)) :-
 1805    !,
 1806    colour_item(list, TB, F-T),
 1807    (   Tail == none
 1808    ->  true
 1809    ;   colour_item(type_error(list), TB, Tail)
 1810    ),
 1811    colourise_imports2(List, File, Public, TB, ElmPos).
 1812colourise_imports(except(Except), File, Public, TB,
 1813                  term_position(_,_,FF,FT,[LP])) :-
 1814    !,
 1815    colour_item(keyword(except), TB, FF-FT),
 1816    colourise_imports(Except, File, Public, TB, LP).
 1817colourise_imports(_, _, _, TB, Pos) :-
 1818    colour_item(type_error(list), TB, Pos).
 1819
 1820colourise_imports2([G0|GT], File, Public, TB, [P0|PT]) :-
 1821    !,
 1822    colourise_import(G0, File, TB, P0),
 1823    colourise_imports2(GT, File, Public, TB, PT).
 1824colourise_imports2(_, _, _, _, _).
 1825
 1826
 1827colourise_import(PI as Name, File, TB, term_position(_,_,FF,FT,[PP,NP])) :-
 1828    pi_to_term(PI, Goal),
 1829    !,
 1830    colour_item(goal(imported(File), Goal), TB, PP),
 1831    rename_goal(Goal, Name, NewGoal),
 1832    goal_classification(TB, NewGoal, [], Class),
 1833    colour_item(goal(Class, NewGoal), TB, NP),
 1834    colour_item(keyword(as), TB, FF-FT).
 1835colourise_import(PI, File, TB, Pos) :-
 1836    pi_to_term(PI, Goal),
 1837    colour_state_source_id(TB, SourceID),
 1838    (   \+ xref_defined(SourceID, Goal, imported(File))
 1839    ->  colour_item(undefined_import, TB, Pos)
 1840    ;   \+ xref_called(SourceID, Goal, _)
 1841    ->  colour_item(unused_import, TB, Pos)
 1842    ),
 1843    !.
 1844colourise_import(PI, _, TB, Pos) :-
 1845    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.
 1852colourise_declaration(PI, _, TB, term_position(F,T,FF,FT,[NamePos,ArityPos])) :-
 1853    pi_to_term(PI, Goal),
 1854    !,
 1855    goal_classification(TB, Goal, [], Class),
 1856    colour_item(predicate_indicator(Class, Goal), TB, F-T),
 1857    colour_item(goal(Class, Goal), TB, NamePos),
 1858    colour_item(predicate_indicator, TB, FF-FT),
 1859    colour_item(arity, TB, ArityPos).
 1860colourise_declaration(Module:PI, _, TB,
 1861                      term_position(_,_,QF,QT,[PM,PG])) :-
 1862    atom(Module), pi_to_term(PI, Goal),
 1863    !,
 1864    colourise_module(M, TB, PM),
 1865    colour_item(functor, TB, QF-QT),
 1866    colour_item(predicate_indicator(extern(M), Goal), TB, PG),
 1867    PG = term_position(_,_,FF,FT,[NamePos,ArityPos]),
 1868    colour_item(goal(extern(M), Goal), TB, NamePos),
 1869    colour_item(predicate_indicator, TB, FF-FT),
 1870    colour_item(arity, TB, ArityPos).
 1871colourise_declaration(Module:PI, _, TB,
 1872                      term_position(_,_,QF,QT,[PM,PG])) :-
 1873    atom(Module), nonvar(PI), PI = Name/Arity,
 1874    !,                                  % partial predicate indicators
 1875    colourise_module(Module, TB, PM),
 1876    colour_item(functor, TB, QF-QT),
 1877    (   (var(Name) ; atom(Name)),
 1878        (var(Arity) ; integer(Arity), Arity >= 0)
 1879    ->  colourise_term_arg(PI, TB, PG)
 1880    ;   colour_item(type_error(predicate_indicator), TB, PG)
 1881    ).
 1882colourise_declaration(op(N,T,P), Which, TB, Pos) :-
 1883    (   Which == export
 1884    ;   Which == import
 1885    ),
 1886    !,
 1887    colour_item(exported_operator, TB, Pos),
 1888    colourise_op_declaration(op(N,T,P), TB, Pos).
 1889colourise_declaration(Module:Goal, table, TB,
 1890                      term_position(_,_,QF,QT,
 1891                                    [PM,term_position(_F,_T,FF,FT,ArgPos)])) :-
 1892    atom(Module), callable(Goal),
 1893    !,
 1894    colourise_module(Module, TB, PM),
 1895    colour_item(functor, TB, QF-QT),
 1896    goal_classification(TB, Module:Goal, [], Class),
 1897    compound_name_arguments(Goal, _, Args),
 1898    colour_item(goal(Class, Goal), TB, FF-FT),
 1899    colourise_table_modes(Args, TB, ArgPos).
 1900colourise_declaration(Goal, table, TB, term_position(_F,_T,FF,FT,ArgPos)) :-
 1901    callable(Goal),
 1902    !,
 1903    compound_name_arguments(Goal, _, Args),
 1904    goal_classification(TB, Goal, [], Class),
 1905    colour_item(goal(Class, Goal), TB, FF-FT),
 1906    colourise_table_modes(Args, TB, ArgPos).
 1907colourise_declaration(Goal, table, TB, Pos) :-
 1908    atom(Goal),
 1909    !,
 1910    goal_classification(TB, Goal, [], Class),
 1911    colour_item(goal(Class, Goal), TB, Pos).
 1912colourise_declaration(Partial, _Which, TB, Pos) :-
 1913    compatible_with_pi(Partial),
 1914    !,
 1915    colourise_term_arg(Partial, TB, Pos).
 1916colourise_declaration(_, Which, TB, Pos) :-
 1917    colour_item(type_error(declaration(Which)), TB, Pos).
 1918
 1919compatible_with_pi(Term) :-
 1920    var(Term),
 1921    !.
 1922compatible_with_pi(Name/Arity) :-
 1923    !,
 1924    var_or_atom(Name),
 1925    var_or_nonneg(Arity).
 1926compatible_with_pi(Name//Arity) :-
 1927    !,
 1928    var_or_atom(Name),
 1929    var_or_nonneg(Arity).
 1930compatible_with_pi(M:T) :-
 1931    var_or_atom(M),
 1932    compatible_with_pi(T).
 1933
 1934var_or_atom(X) :- var(X), !.
 1935var_or_atom(X) :- atom(X).
 1936var_or_nonneg(X) :- var(X), !.
 1937var_or_nonneg(X) :- integer(X), X >= 0, !.
 1938
 1939pi_to_term(Name/Arity, Term) :-
 1940    (atom(Name)->true;Name==[]), integer(Arity), Arity >= 0,
 1941    !,
 1942    functor(Term, Name, Arity).
 1943pi_to_term(Name//Arity0, Term) :-
 1944    atom(Name), integer(Arity0), Arity0 >= 0,
 1945    !,
 1946    Arity is Arity0 + 2,
 1947    functor(Term, Name, Arity).
 1948
 1949colourise_meta_declarations((Head,Tail), Extra, TB,
 1950                            term_position(_,_,_,_,[PH,PT])) :-
 1951    !,
 1952    colourise_meta_declaration(Head, Extra, TB, PH),
 1953    colourise_meta_declarations(Tail, Extra, TB, PT).
 1954colourise_meta_declarations(Last, Extra, TB, Pos) :-
 1955    colourise_meta_declaration(Last, Extra, TB, Pos).
 1956
 1957colourise_meta_declaration(M:Head, Extra, TB,
 1958                           term_position(_,_,QF,QT,
 1959                                         [ MP,
 1960                                           term_position(_,_,FF,FT,ArgPos)
 1961                                         ])) :-
 1962    compound(Head),
 1963    !,
 1964    colourise_module(M, TB, MP),
 1965    colour_item(functor, TB, QF-QT),
 1966    colour_item(goal(extern(M),Head), TB, FF-FT),
 1967    compound_name_arguments(Head, _, Args),
 1968    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1969colourise_meta_declaration(Head, Extra, TB, term_position(_,_,FF,FT,ArgPos)) :-
 1970    compound(Head),
 1971    !,
 1972    goal_classification(TB, Head, [], Class),
 1973    colour_item(goal(Class, Head), TB, FF-FT),
 1974    compound_name_arguments(Head, _, Args),
 1975    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1976colourise_meta_declaration([H|T], Extra, TB, list_position(LF,LT,[HP],TP)) :-
 1977    !,
 1978    colour_item(list, TB, LF-LT),
 1979    colourise_meta_decls([H,T], Extra, TB, [HP,TP]).
 1980colourise_meta_declaration(_, _, TB, Pos) :-
 1981    !,
 1982    colour_item(type_error(compound), TB, Pos).
 1983
 1984colourise_meta_decls([], _, _, []).
 1985colourise_meta_decls([Arg|ArgT], Extra, TB, [PosH|PosT]) :-
 1986    colourise_meta_decl(Arg, Extra, TB, PosH),
 1987    colourise_meta_decls(ArgT, Extra, TB, PosT).
 1988
 1989colourise_meta_decl(Arg, Extra, TB, Pos) :-
 1990    nonvar(Arg),
 1991    (   valid_meta_decl(Arg)
 1992    ->  true
 1993    ;   memberchk(Arg, Extra)
 1994    ),
 1995    colour_item(meta(Arg), TB, Pos).
 1996colourise_meta_decl(_, _, TB, Pos) :-
 1997    colour_item(error, TB, Pos).
 1998
 1999valid_meta_decl(:).
 2000valid_meta_decl(*).
 2001valid_meta_decl(//).
 2002valid_meta_decl(^).
 2003valid_meta_decl(?).
 2004valid_meta_decl(+).
 2005valid_meta_decl(-).
 2006valid_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..
 2013colourise_declarations(List, Which, TB, list_position(F,T,Elms,none)) :-
 2014    !,
 2015    colour_item(list, TB, F-T),
 2016    colourise_list_declarations(List, Which, TB, Elms).
 2017colourise_declarations(Term, Which, TB, parentheses_term_position(PO,PC,Pos)) :-
 2018    !,
 2019    colour_item(parentheses, TB, PO-PC),
 2020    colourise_declarations(Term, Which, TB, Pos).
 2021colourise_declarations((Head,Tail), Which, TB,
 2022                             term_position(_,_,_,_,[PH,PT])) :-
 2023    !,
 2024    colourise_declarations(Head, Which, TB, PH),
 2025    colourise_declarations(Tail, Which, TB, PT).
 2026colourise_declarations(as(Spec, Options), Which, TB,
 2027                             term_position(_,_,FF,FT,[PH,PT])) :-
 2028    !,
 2029    colour_item(keyword(as), TB, FF-FT),
 2030    colourise_declarations(Spec, Which, TB, PH),
 2031    colourise_decl_options(Options, Which, TB, PT).
 2032colourise_declarations(PI, Which, TB, Pos) :-
 2033    colourise_declaration(PI, Which, TB, Pos).
 2034
 2035colourise_list_declarations([], _, _, []).
 2036colourise_list_declarations([H|T], Which, TB, [HP|TP]) :-
 2037    colourise_declaration(H, Which, TB, HP),
 2038    colourise_list_declarations(T, Which, TB, TP).
 2039
 2040
 2041colourise_table_modes([], _, _).
 2042colourise_table_modes([H|T], TB, [PH|PT]) :-
 2043    colourise_table_mode(H, TB, PH),
 2044    colourise_table_modes(T, TB, PT).
 2045
 2046colourise_table_mode(H, TB, Pos) :-
 2047    table_mode(H, Mode),
 2048    !,
 2049    colour_item(table_mode(Mode), TB, Pos).
 2050colourise_table_mode(lattice(Spec), TB, term_position(_F,_T,FF,FT,[ArgPos])) :-
 2051    !,
 2052    colour_item(table_mode(lattice), TB, FF-FT),
 2053    table_moded_call(Spec, 3, TB, ArgPos).
 2054colourise_table_mode(po(Spec), TB, term_position(_F,_T,FF,FT,[ArgPos])) :-
 2055    !,
 2056    colour_item(table_mode(po), TB, FF-FT),
 2057    table_moded_call(Spec, 2, TB, ArgPos).
 2058colourise_table_mode(_, TB, Pos) :-
 2059    colour_item(type_error(table_mode), TB, Pos).
 2060
 2061table_mode(Var, index) :-
 2062    var(Var),
 2063    !.
 2064table_mode(+, index).
 2065table_mode(index, index).
 2066table_mode(-, first).
 2067table_mode(first, first).
 2068table_mode(last, last).
 2069table_mode(min, min).
 2070table_mode(max, max).
 2071table_mode(sum, sum).
 2072
 2073table_moded_call(Atom, Arity, TB, Pos) :-
 2074    atom(Atom),
 2075    functor(Head, Atom, Arity),
 2076    goal_classification(TB, Head, [], Class),
 2077    colour_item(goal(Class, Head), TB, Pos).
 2078table_moded_call(Atom/Arity, Arity, TB,
 2079                 term_position(_,_,FF,FT,[NP,AP])) :-
 2080    atom(Atom),
 2081    !,
 2082    functor(Head, Atom, Arity),
 2083    goal_classification(TB, Head, [], Class),
 2084    colour_item(goal(Class, Head), TB, NP),
 2085    colour_item(predicate_indicator, TB, FF-FT),
 2086    colour_item(arity, TB, AP).
 2087table_moded_call(Head, Arity, TB, Pos) :-
 2088    Pos = term_position(_,_,FF,FT,_),
 2089    compound(Head),
 2090    !,
 2091    compound_name_arity(Head, _Name, Arity),
 2092    goal_classification(TB, Head, [], Class),
 2093    colour_item(goal(Class, Head), TB, FF-FT),
 2094    colourise_term_args(Head, TB, Pos).
 2095table_moded_call(_, _, TB, Pos) :-
 2096    colour_item(type_error(predicate_name_or_indicator), TB, Pos).
 2097
 2098colourise_decl_options(Options, Which, TB,
 2099                       parentheses_term_position(_,_,Pos)) :-
 2100    !,
 2101    colourise_decl_options(Options, Which, TB, Pos).
 2102colourise_decl_options((Head,Tail), Which, TB,
 2103                        term_position(_,_,_,_,[PH,PT])) :-
 2104    !,
 2105    colourise_decl_options(Head, Which, TB, PH),
 2106    colourise_decl_options(Tail, Which, TB, PT).
 2107colourise_decl_options(Option, Which, TB, Pos) :-
 2108    ground(Option),
 2109    valid_decl_option(Option, Which),
 2110    !,
 2111    functor(Option, Name, _),
 2112    (   Pos = term_position(_,_,FF,FT,[ArgPos])
 2113    ->  colour_item(decl_option(Name), TB, FF-FT),
 2114        (   arg(1, Option, Value),
 2115            nonneg_or_false(Value)
 2116        ->  colourise_term_arg(Value, TB, ArgPos)
 2117        ;   colour_item(type_error(decl_option_value(Which)), TB, ArgPos)
 2118        )
 2119    ;   colour_item(decl_option(Name), TB, Pos)
 2120    ).
 2121colourise_decl_options(_, Which, TB, Pos) :-
 2122    colour_item(type_error(decl_option(Which)), TB, Pos).
 2123
 2124valid_decl_option(subsumptive,         table).
 2125valid_decl_option(variant,             table).
 2126valid_decl_option(incremental,         table).
 2127valid_decl_option(monotonic,           table).
 2128valid_decl_option(opaque,              table).
 2129valid_decl_option(lazy,                table).
 2130valid_decl_option(monotonic,           dynamic).
 2131valid_decl_option(incremental,         dynamic).
 2132valid_decl_option(abstract(_),         dynamic).
 2133valid_decl_option(opaque,              dynamic).
 2134valid_decl_option(shared,              table).
 2135valid_decl_option(private,             table).
 2136valid_decl_option(subgoal_abstract(_), table).
 2137valid_decl_option(answer_abstract(_),  table).
 2138valid_decl_option(max_answers(_),      table).
 2139valid_decl_option(shared,              dynamic).
 2140valid_decl_option(private,             dynamic).
 2141valid_decl_option(local,               dynamic).
 2142valid_decl_option(multifile,           _).
 2143valid_decl_option(discontiguous,       _).
 2144valid_decl_option(volatile,            _).
 2145
 2146nonneg_or_false(Value) :-
 2147    var(Value),
 2148    !.
 2149nonneg_or_false(Value) :-
 2150    integer(Value), Value >= 0,
 2151    !.
 2152nonneg_or_false(off).
 2153nonneg_or_false(false).
 colourise_op_declaration(Op, TB, Pos) is det
 2157colourise_op_declaration(op(P,T,N), TB, term_position(_,_,FF,FT,[PP,TP,NP])) :-
 2158    colour_item(goal(built_in, op(N,T,P)), TB, FF-FT),
 2159    colour_op_priority(P, TB, PP),
 2160    colour_op_type(T, TB, TP),
 2161    colour_op_name(N, TB, NP).
 2162
 2163colour_op_name(_, _, Pos) :-
 2164    var(Pos),
 2165    !.
 2166colour_op_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 2167    !,
 2168    colour_item(parentheses, TB, PO-PC),
 2169    colour_op_name(Name, TB, Pos).
 2170colour_op_name(Name, TB, Pos) :-
 2171    var(Name),
 2172    !,
 2173    colour_item(var, TB, Pos).
 2174colour_op_name(Name, TB, Pos) :-
 2175    (atom(Name) ; Name == []),
 2176    !,
 2177    colour_item(identifier, TB, Pos).
 2178colour_op_name(Module:Name, TB, term_position(_F,_T,QF,QT,[MP,NP])) :-
 2179    !,
 2180    colourise_module(Module, TB, MP),
 2181    colour_item(functor, TB, QF-QT),
 2182    colour_op_name(Name, TB, NP).
 2183colour_op_name(List, TB, list_position(F,T,Elems,none)) :-
 2184    !,
 2185    colour_item(list, TB, F-T),
 2186    colour_op_names(List, TB, Elems).
 2187colour_op_name(_, TB, Pos) :-
 2188    colour_item(error, TB, Pos).
 2189
 2190colour_op_names([], _, []).
 2191colour_op_names([H|T], TB, [HP|TP]) :-
 2192    colour_op_name(H, TB, HP),
 2193    colour_op_names(T, TB, TP).
 2194
 2195colour_op_type(Type, TB, Pos) :-
 2196    var(Type),
 2197    !,
 2198    colour_item(var, TB, Pos).
 2199colour_op_type(Type, TB, Pos) :-
 2200    op_type(Type),
 2201    !,
 2202    colour_item(op_type(Type), TB, Pos).
 2203colour_op_type(_, TB, Pos) :-
 2204    colour_item(error, TB, Pos).
 2205
 2206colour_op_priority(Priority, TB, Pos) :-
 2207    var(Priority), colour_item(var, TB, Pos).
 2208colour_op_priority(Priority, TB, Pos) :-
 2209    integer(Priority),
 2210    between(0, 1200, Priority),
 2211    !,
 2212    colour_item(int, TB, Pos).
 2213colour_op_priority(_, TB, Pos) :-
 2214    colour_item(error, TB, Pos).
 2215
 2216op_type(fx).
 2217op_type(fy).
 2218op_type(xf).
 2219op_type(yf).
 2220op_type(xfy).
 2221op_type(xfx).
 2222op_type(yfx).
 colourise_prolog_flag_name(+Name, +TB, +Pos)
Colourise the name of a Prolog flag
 2229colourise_prolog_flag_name(_, _, Pos) :-
 2230    var(Pos),
 2231    !.
 2232colourise_prolog_flag_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 2233    !,
 2234    colour_item(parentheses, TB, PO-PC),
 2235    colourise_prolog_flag_name(Name, TB, Pos).
 2236colourise_prolog_flag_name(Name, TB, Pos) :-
 2237    atom(Name),
 2238    !,
 2239    (   current_prolog_flag(Name, _)
 2240    ->  colour_item(flag_name(Name), TB, Pos)
 2241    ;   known_flag(Name)
 2242    ->  colour_item(known_flag_name(Name), TB, Pos)
 2243    ;   colour_item(no_flag_name(Name), TB, Pos)
 2244    ).
 2245colourise_prolog_flag_name(Name, TB, Pos) :-
 2246    colourise_term(Name, TB, Pos).
 2247
 2248% Some flags are know, but can be unset.
 2249known_flag(android).
 2250known_flag(android_api).
 2251known_flag(apple).
 2252known_flag(asan).
 2253known_flag(break_level).
 2254known_flag(conda).
 2255known_flag(dde).
 2256known_flag(emscripten).
 2257known_flag(executable_format).
 2258known_flag(gc_thread).
 2259known_flag(gmp_version).
 2260known_flag(gui).
 2261known_flag(max_rational_size).
 2262known_flag(mitigate_spectre).
 2263known_flag(msys2).
 2264known_flag(pid).
 2265known_flag(pipe).
 2266known_flag(posix_shell).
 2267known_flag(shared_home).
 2268known_flag(shared_table_space).
 2269known_flag(system_thread_id).
 2270known_flag(threads).
 2271known_flag(unix).
 2272known_flag(windows).
 2273known_flag(wine_version).
 2274known_flag(xpce).
 2275known_flag(bundle).
 2276known_flag(apple_universal_binary).
 2277
 2278		 /*******************************
 2279		 *             MACROS		*
 2280		 *******************************/
 expand_macro(+TB, +Macro, -Expanded) is semidet
To be done
- This only works if the code is compiled. Ideally we'd also make this work for not compiled code.
 2287expand_macro(TB, Macro, Expanded) :-
 2288    colour_state_source_id(TB, SourceId),
 2289    (   xref_module(SourceId, M)
 2290    ->  true
 2291    ;   M = user
 2292    ),
 2293    current_predicate(M:'$macro'/2),
 2294    catch(M:'$macro'(Macro, Expanded),
 2295          error(_, _),
 2296          fail),
 2297    !.
 2298
 2299macro_term_string(Term, String) :-
 2300    copy_term_nat(Term, Copy),
 2301    numbervars(Copy, 0, _, [singletons(true)]),
 2302    term_string(Copy, String,
 2303                [ portray(true),
 2304                  max_depth(2),
 2305                  numbervars(true)
 2306                ]).
 2307
 2308
 2309                 /*******************************
 2310                 *        CONFIGURATION         *
 2311                 *******************************/
 2312
 2313%       body_compiled(+Term)
 2314%
 2315%       Succeeds if term is a construct handled by the compiler.
 2316
 2317body_compiled((_,_)).
 2318body_compiled((_->_)).
 2319body_compiled((_*->_)).
 2320body_compiled((_;_)).
 2321body_compiled(\+_).
 goal_classification(+TB, +Goal, +Origin, -Class)
Classify Goal appearing in TB and called from a clause with head Origin. For directives, Origin is [].
 2328goal_classification(_, QGoal, _, Class) :-
 2329    strip_module(QGoal, _, Goal),
 2330    (   var(Goal)
 2331    ->  !, Class = meta
 2332    ;   \+ callable(Goal)
 2333    ->  !, Class = not_callable
 2334    ).
 2335goal_classification(_, Goal, Origin, recursion) :-
 2336    callable(Origin),
 2337    generalise_term(Goal, Origin),
 2338    !.
 2339goal_classification(TB, Goal, _, How) :-
 2340    colour_state_source_id(TB, SourceId),
 2341    xref_defined(SourceId, Goal, How),
 2342    How \= public(_),
 2343    !.
 2344goal_classification(TB, Goal, _, Class) :-
 2345    (   colour_state_source_id(TB, SourceId),
 2346        xref_module(SourceId, Module)
 2347    ->  true
 2348    ;   Module = user
 2349    ),
 2350    call_goal_classification(Goal, Module, Class),
 2351    !.
 2352goal_classification(TB, Goal, _, How) :-
 2353    colour_state_module(TB, Module),
 2354    atom(Module),
 2355    Module \== prolog_colour_ops,
 2356    predicate_property(Module:Goal, imported_from(From)),
 2357    !,
 2358    How = imported(From).
 2359goal_classification(_TB, _Goal, _, undefined).
 goal_classification(+Goal, +Module, -Class)
Multifile hookable classification for non-local goals.
 2365call_goal_classification(Goal, Module, Class) :-
 2366    catch(global_goal_classification(Goal, Module, Class), _,
 2367          Class = type_error(callable)).
 2368
 2369global_goal_classification(Goal, _, built_in) :-
 2370    built_in_predicate(Goal),
 2371    !.
 2372global_goal_classification(Goal, _, autoload(From)) :-  % SWI-Prolog
 2373    predicate_property(Goal, autoload(From)).
 2374global_goal_classification(Goal, Module, Class) :-      % SWI-Prolog
 2375    strip_module(Goal, _, PGoal),
 2376    current_predicate(_, user:PGoal),
 2377    !,
 2378    (   Module == user
 2379    ->  Class = global(GClass, Location),
 2380        global_location(user:Goal, Location),
 2381        global_class(user:Goal, GClass)
 2382    ;   Class = global
 2383    ).
 2384global_goal_classification(Goal, _, Class) :-
 2385    compound(Goal),
 2386    compound_name_arity(Goal, Name, Arity),
 2387    vararg_goal_classification(Name, Arity, Class).
 2388
 2389global_location(Goal, File:Line) :-
 2390    predicate_property(Goal, file(File)),
 2391    predicate_property(Goal, line_count(Line)),
 2392    !.
 2393global_location(_, -).
 2394
 2395global_class(Goal, dynamic)   :- predicate_property(Goal, dynamic), !.
 2396global_class(Goal, multifile) :- predicate_property(Goal, multifile), !.
 2397global_class(Goal, tabled)    :- predicate_property(Goal, tabled), !.
 2398global_class(_,    static).
 vararg_goal_classification(+Name, +Arity, -Class) is semidet
Multifile hookable classification for vararg predicates.
 2405vararg_goal_classification(call, Arity, built_in) :-
 2406    Arity >= 1.
 2407vararg_goal_classification(send_super, Arity, expanded) :- % XPCE (TBD)
 2408    Arity >= 2.
 2409vararg_goal_classification(get_super, Arity, expanded) :-  % XPCE (TBD)
 2410    Arity >= 3.
 qualified_goal_classification(:Goal, +TB, -Class)
Classify an explicitly qualified goal.
 2416qualified_goal_classification(Goal, TB, Class) :-
 2417    goal_classification(TB, Goal, [], Class),
 2418    Class \== undefined,
 2419    !.
 2420qualified_goal_classification(Module:Goal, _, extern(Module, How)) :-
 2421    predicate_property(Module:Goal, visible),
 2422    !,
 2423    (   (   predicate_property(Module:Goal, public)
 2424        ;   predicate_property(Module:Goal, exported)
 2425        )
 2426    ->  How = (public)
 2427    ;   How = (private)
 2428    ).
 2429qualified_goal_classification(Module:_, _, extern(Module, unknown)).
 classify_head(+TB, +Head, -Class)
Classify a clause head
 2435classify_head(TB, Goal, exported) :-
 2436    colour_state_source_id(TB, SourceId),
 2437    xref_exported(SourceId, Goal),
 2438    !.
 2439classify_head(_TB, Goal, hook) :-
 2440    xref_hook(Goal),
 2441    !.
 2442classify_head(TB, Goal, hook) :-
 2443    colour_state_source_id(TB, SourceId),
 2444    xref_module(SourceId, M),
 2445    xref_hook(M:Goal),
 2446    !.
 2447classify_head(TB, Goal, Class) :-
 2448    built_in_predicate(Goal),
 2449    (   system_module(TB)
 2450    ->  (   predicate_property(system:Goal, iso)
 2451        ->  Class = def_iso
 2452        ;   goal_name(Goal, Name),
 2453            \+ sub_atom(Name, 0, _, _, $)
 2454        ->  Class = def_swi
 2455        )
 2456    ;   (   predicate_property(system:Goal, iso)
 2457        ->  Class = iso
 2458        ;   Class = built_in
 2459        )
 2460    ).
 2461classify_head(TB, Goal, unreferenced) :-
 2462    colour_state_source_id(TB, SourceId),
 2463    \+ (xref_called(SourceId, Goal, By), By \= Goal),
 2464    !.
 2465classify_head(TB, Goal, test) :-
 2466    Goal = test(_),
 2467    colour_state_source_id(TB, SourceId),
 2468    xref_called(SourceId, Goal, '<test_unit>'(_Unit)),
 2469    !.
 2470classify_head(TB, Goal, test) :-
 2471    Goal = test(_, _),
 2472    colour_state_source_id(TB, SourceId),
 2473    xref_called(SourceId, Goal, '<test_unit>'(_Unit)),
 2474    !.
 2475classify_head(TB, Goal, How) :-
 2476    colour_state_source_id(TB, SourceId),
 2477    (   xref_defined(SourceId, Goal, imported(From))
 2478    ->  How = imported(From)
 2479    ;   xref_defined(SourceId, Goal, How)
 2480    ),
 2481    !.
 2482classify_head(_TB, _Goal, undefined).
 2483
 2484built_in_predicate(Goal) :-
 2485    predicate_property(system:Goal, built_in),
 2486    !.
 2487built_in_predicate(module(_, _)).       % reserved expanded constructs
 2488built_in_predicate(module(_, _, _)).
 2489built_in_predicate(if(_)).
 2490built_in_predicate(elif(_)).
 2491built_in_predicate(else).
 2492built_in_predicate(endif).
 2493
 2494goal_name(_:G, Name) :- nonvar(G), !, goal_name(G, Name).
 2495goal_name(G, Name) :- callable(G), functor_name(G, Name).
 2496
 2497system_module(TB) :-
 2498    colour_state_source_id(TB, SourceId),
 2499    xref_module(SourceId, M),
 2500    module_property(M, class(system)).
 2501
 2502generalise_term(Specific, General) :-
 2503    (   compound(Specific)
 2504    ->  compound_name_arity(Specific, Name, Arity),
 2505        compound_name_arity(General0, Name, Arity),
 2506        General = General0
 2507    ;   General = Specific
 2508    ).
 2509
 2510rename_goal(Goal0, Name, Goal) :-
 2511    (   compound(Goal0)
 2512    ->  compound_name_arity(Goal0, _, Arity),
 2513        compound_name_arity(Goal, Name, Arity)
 2514    ;   Goal = Name
 2515    ).
 2516
 2517functor_name(Term, Name) :-
 2518    (   compound(Term)
 2519    ->  compound_name_arity(Term, Name, _)
 2520    ;   atom(Term)
 2521    ->  Name = Term
 2522    ).
 2523
 2524goal_name_arity(Goal, Name, Arity) :-
 2525    (   compound(Goal)
 2526    ->  compound_name_arity(Goal, Name, Arity)
 2527    ;   atom(Goal)
 2528    ->  Name = Goal, Arity = 0
 2529    ).
 2530
 2531
 2532call_goal_colours(Term, Colours) :-
 2533    goal_colours(Term, Colours),
 2534    !.
 2535call_goal_colours(Term, Colours) :-
 2536    def_goal_colours(Term, Colours).
 2537
 2538call_goal_colours(Term, Class, Colours) :-
 2539    goal_colours(Term, Class, Colours),
 2540    !.
 2541%call_goal_colours(Term, Class, Colours) :-
 2542%    def_goal_colours(Term, Class, Colours).
 2543
 2544
 2545%       Specify colours for individual goals.
 2546
 2547def_goal_colours(_ is _,                 built_in-[classify,expression]).
 2548def_goal_colours(_ < _,                  built_in-[expression,expression]).
 2549def_goal_colours(_ > _,                  built_in-[expression,expression]).
 2550def_goal_colours(_ =< _,                 built_in-[expression,expression]).
 2551def_goal_colours(_ >= _,                 built_in-[expression,expression]).
 2552def_goal_colours(_ =\= _,                built_in-[expression,expression]).
 2553def_goal_colours(_ =:= _,                built_in-[expression,expression]).
 2554def_goal_colours(module(_,_),            built_in-[identifier,exports]).
 2555def_goal_colours(module(_,_,_),          built_in-[identifier,exports,langoptions]).
 2556def_goal_colours(use_module(_),          built_in-[imported_file]).
 2557def_goal_colours(use_module(File,_),     built_in-[file,imports(File)]).
 2558def_goal_colours(autoload(_),            built_in-[imported_file]).
 2559def_goal_colours(autoload(File,_),       built_in-[file,imports(File)]).
 2560def_goal_colours(reexport(_),            built_in-[file]).
 2561def_goal_colours(reexport(File,_),       built_in-[file,imports(File)]).
 2562def_goal_colours(dynamic(_),             built_in-[declarations(dynamic)]).
 2563def_goal_colours(thread_local(_),        built_in-[declarations(thread_local)]).
 2564def_goal_colours(module_transparent(_),  built_in-[declarations(module_transparent)]).
 2565def_goal_colours(discontiguous(_),       built_in-[declarations(discontiguous)]).
 2566def_goal_colours(multifile(_),           built_in-[declarations(multifile)]).
 2567def_goal_colours(volatile(_),            built_in-[declarations(volatile)]).
 2568def_goal_colours(public(_),              built_in-[declarations(public)]).
 2569def_goal_colours(det(_),                 built_in-[declarations(det)]).
 2570def_goal_colours(table(_),               built_in-[declarations(table)]).
 2571def_goal_colours(meta_predicate(_),      built_in-[meta_declarations]).
 2572def_goal_colours(consult(_),             built_in-[file]).
 2573def_goal_colours(include(_),             built_in-[file]).
 2574def_goal_colours(ensure_loaded(_),       built_in-[file]).
 2575def_goal_colours(load_files(_),          built_in-[file]).
 2576def_goal_colours(load_files(_,_),        built_in-[file,options]).
 2577def_goal_colours(setof(_,_,_),           built_in-[classify,setof,classify]).
 2578def_goal_colours(bagof(_,_,_),           built_in-[classify,setof,classify]).
 2579def_goal_colours(predicate_options(_,_,_), built_in-[predicate,classify,classify]).
 2580% Database access
 2581def_goal_colours(assert(_),              built_in-[db]).
 2582def_goal_colours(asserta(_),             built_in-[db]).
 2583def_goal_colours(assertz(_),             built_in-[db]).
 2584def_goal_colours(assert(_,_),            built_in-[db,classify]).
 2585def_goal_colours(asserta(_,_),           built_in-[db,classify]).
 2586def_goal_colours(assertz(_,_),           built_in-[db,classify]).
 2587def_goal_colours(retract(_),             built_in-[db]).
 2588def_goal_colours(retractall(_),          built_in-[db]).
 2589def_goal_colours(clause(_,_),            built_in-[db,classify]).
 2590def_goal_colours(clause(_,_,_),          built_in-[db,classify,classify]).
 2591% misc
 2592def_goal_colours(set_prolog_flag(_,_),   built_in-[prolog_flag_name,classify]).
 2593def_goal_colours(current_prolog_flag(_,_), built_in-[prolog_flag_name,classify]).
 2594% XPCE stuff
 2595def_goal_colours(pce_autoload(_,_),      classify-[classify,file]).
 2596def_goal_colours(pce_image_directory(_), classify-[directory]).
 2597def_goal_colours(new(_, _),              built_in-[classify,pce_new]).
 2598def_goal_colours(send_list(_,_,_),       built_in-pce_arg_list).
 2599def_goal_colours(send(_,_),              built_in-[pce_arg,pce_selector]).
 2600def_goal_colours(get(_,_,_),             built_in-[pce_arg,pce_selector,pce_arg]).
 2601def_goal_colours(send_super(_,_),        built_in-[pce_arg,pce_selector]).
 2602def_goal_colours(get_super(_,_),         built_in-[pce_arg,pce_selector,pce_arg]).
 2603def_goal_colours(get_chain(_,_,_),       built_in-[pce_arg,pce_selector,pce_arg]).
 2604def_goal_colours(Pce,                    built_in-pce_arg) :-
 2605    compound(Pce),
 2606    functor_name(Pce, Functor),
 2607    pce_functor(Functor).
 2608
 2609pce_functor(send).
 2610pce_functor(get).
 2611pce_functor(send_super).
 2612pce_functor(get_super).
 2613
 2614
 2615                 /*******************************
 2616                 *        SPECIFIC HEADS        *
 2617                 *******************************/
 2618
 2619head_colours(file_search_path(_,_), hook-[identifier,classify]).
 2620head_colours(library_directory(_),  hook-[file]).
 2621head_colours(resource(_,_),         hook-[identifier,file]).
 2622head_colours(resource(_,_,_),       hook-[identifier,file,classify]).
 2623
 2624head_colours(Var, _) :-
 2625    var(Var),
 2626    !,
 2627    fail.
 2628head_colours(M:H, Colours) :-
 2629    M == user,
 2630    head_colours(H, HC),
 2631    HC = hook - _,
 2632    !,
 2633    Colours = meta-[module(user), HC ].
 2634head_colours(M:H, Colours) :-
 2635    atom(M), callable(H),
 2636    xref_hook(M:H),
 2637    !,
 2638    Colours = meta-[module(M), hook-classify ].
 2639head_colours(M:_, meta-[module(M),extern(M)]).
 2640
 2641
 2642                 /*******************************
 2643                 *             STYLES           *
 2644                 *******************************/
 def_style(+Pattern, -Style)
Define the style used for the given pattern. Definitions here can be overruled by defining rules for style/2
 2652def_style(goal(built_in,_),        [colour(blue)]).
 2653def_style(goal(imported(_),_),     [colour(blue)]).
 2654def_style(goal(autoload(_),_),     [colour(navy_blue)]).
 2655def_style(goal(global,_),          [colour(navy_blue)]).
 2656def_style(goal(global(dynamic,_),_), [colour(magenta)]).
 2657def_style(goal(global(_,_),_),     [colour(navy_blue)]).
 2658def_style(goal(undefined,_),       [colour(red)]).
 2659def_style(goal(thread_local(_),_), [colour(magenta), underline(true)]).
 2660def_style(goal(dynamic(_),_),      [colour(magenta)]).
 2661def_style(goal(multifile(_),_),    [colour(navy_blue)]).
 2662def_style(goal(expanded,_),        [colour(blue), underline(true)]).
 2663def_style(goal(extern(_),_),       [colour(blue), underline(true)]).
 2664def_style(goal(extern(_,private),_), [colour(red)]).
 2665def_style(goal(extern(_,public),_), [colour(blue)]).
 2666def_style(goal(recursion,_),       [underline(true)]).
 2667def_style(goal(meta,_),            [colour(red4)]).
 2668def_style(goal(foreign(_),_),      [colour(darkturquoise)]).
 2669def_style(goal(local(_),_),        []).
 2670def_style(goal(constraint(_),_),   [colour(darkcyan)]).
 2671def_style(goal(not_callable,_),    [background(orange)]).
 2672
 2673def_style(function,                [colour(blue)]).
 2674def_style(no_function,             [colour(red)]).
 2675
 2676def_style(option_name,             [colour('#3434ba')]).
 2677def_style(no_option_name,          [colour(red)]).
 2678
 2679def_style(neck(_),		   [bold(true)]).
 2680
 2681def_style(head(exported,_),        [colour(blue), bold(true)]).
 2682def_style(head(public(_),_),       [colour('#016300'), bold(true)]).
 2683def_style(head(extern(_),_),       [colour(blue), bold(true)]).
 2684def_style(head(dynamic,_),         [colour(magenta), bold(true)]).
 2685def_style(head(multifile,_),       [colour(navy_blue), bold(true)]).
 2686def_style(head(unreferenced,_),    [colour(red), bold(true)]).
 2687def_style(head(hook,_),            [colour(blue), underline(true)]).
 2688def_style(head(meta,_),            []).
 2689def_style(head(constraint(_),_),   [colour(darkcyan), bold(true)]).
 2690def_style(head(imported(_),_),     [colour(darkgoldenrod4), bold(true)]).
 2691def_style(head(built_in,_),        [background(orange), bold(true)]).
 2692def_style(head(iso,_),             [background(orange), bold(true)]).
 2693def_style(head(def_iso,_),         [colour(blue), bold(true)]).
 2694def_style(head(def_swi,_),         [colour(blue), bold(true)]).
 2695def_style(head(test,_),            [colour('#01bdbd'), bold(true)]).
 2696def_style(head(_,_),               [bold(true)]).
 2697def_style(rule_condition,	   [background('#d4ffe3')]).
 2698
 2699def_style(module(_),               [colour(dark_slate_blue)]).
 2700def_style(comment(_),              [colour(dark_green)]).
 2701
 2702def_style(directive,               [background(grey90)]).
 2703def_style(method(_),               [bold(true)]).
 2704
 2705def_style(var,                     [colour(red4)]).
 2706def_style(singleton,               [bold(true), colour(red4)]).
 2707def_style(unbound,                 [colour(red), bold(true)]).
 2708def_style(quoted_atom,             [colour(navy_blue)]).
 2709def_style(string,                  [colour(navy_blue)]).
 2710def_style(rational(_),		   [colour(steel_blue)]).
 2711def_style(codes,                   [colour(navy_blue)]).
 2712def_style(chars,                   [colour(navy_blue)]).
 2713def_style(nofile,                  [colour(red)]).
 2714def_style(file(_),                 [colour(blue), underline(true)]).
 2715def_style(file_no_depend(_),       [colour(blue), underline(true), background(pink)]).
 2716def_style(directory(_),            [colour(blue)]).
 2717def_style(class(built_in,_),       [colour(blue), underline(true)]).
 2718def_style(class(library(_),_),     [colour(navy_blue), underline(true)]).
 2719def_style(class(local(_,_,_),_),   [underline(true)]).
 2720def_style(class(user(_),_),        [underline(true)]).
 2721def_style(class(user,_),           [underline(true)]).
 2722def_style(class(undefined,_),      [colour(red), underline(true)]).
 2723def_style(prolog_data,             [colour(blue), underline(true)]).
 2724def_style(flag_name(_),            [colour(blue)]).
 2725def_style(known_flag_name(_),      [colour(blue), background(pink)]).
 2726def_style(no_flag_name(_),         [colour(red)]).
 2727def_style(unused_import,           [colour(blue), background(pink)]).
 2728def_style(undefined_import,        [colour(red)]).
 2729
 2730def_style(constraint(_),           [colour(darkcyan)]).
 2731
 2732def_style(keyword(_),              [colour(blue)]).
 2733def_style(identifier,              [bold(true)]).
 2734def_style(delimiter,               [bold(true)]).
 2735def_style(expanded,                [colour(blue), underline(true)]).
 2736def_style(hook(_),                 [colour(blue), underline(true)]).
 2737def_style(op_type(_),              [colour(blue)]).
 2738
 2739def_style(qq_type,                 [bold(true)]).
 2740def_style(qq(_),                   [colour(blue), bold(true)]).
 2741def_style(qq_content(_),           [colour(red4)]).
 2742
 2743def_style(dict_tag,                [bold(true)]).
 2744def_style(dict_key,                [bold(true)]).
 2745def_style(dict_function(_),        [colour(navy_blue)]).
 2746def_style(dict_return_op,          [colour(blue)]).
 2747
 2748def_style(hook,                    [colour(blue), underline(true)]).
 2749def_style(dcg_right_hand_ctx,      [background('#d4ffe3')]).
 2750
 2751def_style(error,                   [background(orange)]).
 2752def_style(type_error(_),           [background(orange)]).
 2753def_style(domain_error(_),         [background(orange)]).
 2754def_style(syntax_error(_,_),       [background(orange)]).
 2755def_style(instantiation_error,     [background(orange)]).
 2756
 2757def_style(decl_option(_),	   [bold(true)]).
 2758def_style(table_mode(_),	   [bold(true)]).
 2759
 2760def_style(macro(_),                [colour(blue), underline(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.

 2776syntax_colour(Class, Attributes) :-
 2777    (   style(Class, Attributes)            % user hook
 2778    ;   def_style(Class, Attributes)        % system default
 2779    ).
 term_colours(+Term, -FunctorColour, -ArgColours)
Define colourisation for specific terms.
 2786term_colours((?- Directive), Colours) :-
 2787    term_colours((:- Directive), Colours).
 2788term_colours((prolog:Head --> _),
 2789             neck(-->) - [ expanded - [ module(prolog),
 2790                                        hook(message) - [ identifier
 2791                                                        ]
 2792                                      ],
 2793                           dcg_body(prolog:Head)
 2794                         ]) :-
 2795    prolog_message_hook(Head).
 2796
 2797prolog_message_hook(message(_)).
 2798prolog_message_hook(deprecated(_)).
 2799prolog_message_hook(error_message(_)).
 2800prolog_message_hook(message_context(_)).
 2801prolog_message_hook(message_location(_)).
 2802
 2803%       XPCE rules
 2804
 2805term_colours(variable(_, _, _, _),
 2806             expanded - [ identifier,
 2807                          classify,
 2808                          classify,
 2809                          comment(string)
 2810                        ]).
 2811term_colours(variable(_, _, _),
 2812             expanded - [ identifier,
 2813                          classify,
 2814                          atom
 2815                        ]).
 2816term_colours(handle(_, _, _),
 2817             expanded - [ classify,
 2818                          classify,
 2819                          classify
 2820                        ]).
 2821term_colours(handle(_, _, _, _),
 2822             expanded - [ classify,
 2823                          classify,
 2824                          classify,
 2825                          classify
 2826                        ]).
 2827term_colours(class_variable(_,_,_,_),
 2828             expanded - [ identifier,
 2829                          pce(type),
 2830                          pce(default),
 2831                          comment(string)
 2832                        ]).
 2833term_colours(class_variable(_,_,_),
 2834             expanded - [ identifier,
 2835                          pce(type),
 2836                          pce(default)
 2837                        ]).
 2838term_colours(delegate_to(_),
 2839             expanded - [ classify
 2840                        ]).
 2841term_colours((:- encoding(_)),
 2842             expanded - [ expanded - [ classify
 2843                                     ]
 2844                        ]).
 2845term_colours((:- pce_begin_class(_, _, _)),
 2846             expanded - [ expanded - [ identifier,
 2847                                       pce_new,
 2848                                       comment(string)
 2849                                     ]
 2850                        ]).
 2851term_colours((:- pce_begin_class(_, _)),
 2852             expanded - [ expanded - [ identifier,
 2853                                       pce_new
 2854                                     ]
 2855                        ]).
 2856term_colours((:- pce_extend_class(_)),
 2857             expanded - [ expanded - [ identifier
 2858                                     ]
 2859                        ]).
 2860term_colours((:- pce_end_class),
 2861             expanded - [ expanded
 2862                        ]).
 2863term_colours((:- pce_end_class(_)),
 2864             expanded - [ expanded - [ identifier
 2865                                     ]
 2866                        ]).
 2867term_colours((:- use_class_template(_)),
 2868             expanded - [ expanded - [ pce_new
 2869                                     ]
 2870                        ]).
 2871term_colours((:- emacs_begin_mode(_,_,_,_,_)),
 2872             expanded - [ expanded - [ identifier,
 2873                                       classify,
 2874                                       classify,
 2875                                       classify,
 2876                                       classify
 2877                                     ]
 2878                        ]).
 2879term_colours((:- emacs_extend_mode(_,_)),
 2880             expanded - [ expanded - [ identifier,
 2881                                       classify
 2882                                     ]
 2883                        ]).
 2884term_colours((:- pce_group(_)),
 2885             expanded - [ expanded - [ identifier
 2886                                     ]
 2887                        ]).
 2888term_colours((:- pce_global(_, new(_))),
 2889             expanded - [ expanded - [ identifier,
 2890                                       pce_arg
 2891                                     ]
 2892                        ]).
 2893term_colours((:- emacs_end_mode),
 2894             expanded - [ expanded
 2895                        ]).
 2896term_colours(pce_ifhostproperty(_,_),
 2897             expanded - [ classify,
 2898                          classify
 2899                        ]).
 2900term_colours((_,_),
 2901             error - [ classify,
 2902                       classify
 2903                     ]).
 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.
 2910specified_item(_Class, _Term, _TB, Pos) :-
 2911    var(Pos),
 2912    !.
 2913specified_item(Class, Term, TB, parentheses_term_position(PO,PC,Pos)) :-
 2914    !,
 2915    colour_item(parentheses, TB, PO-PC),
 2916    specified_item(Class, Term, TB, Pos).
 2917specified_item(_, Var, TB, Pos) :-
 2918    (   var(Var)
 2919    ;   qq_position(Pos)
 2920    ),
 2921    !,
 2922    colourise_term_arg(Var, TB, Pos).
 2923                                        % generic classification
 2924specified_item(classify, Term, TB, Pos) :-
 2925    !,
 2926    colourise_term_arg(Term, TB, Pos).
 2927                                        % classify as head
 2928specified_item(head, Term, TB, Pos) :-
 2929    !,
 2930    colourise_clause_head(Term, TB, Pos).
 2931                                        % expanded head (DCG=2, ...)
 2932specified_item(head(+N), Term, TB, Pos) :-
 2933    !,
 2934    colourise_extended_head(Term, N, TB, Pos).
 2935                                        % M:Head
 2936specified_item(extern(M), Term, TB, Pos) :-
 2937    !,
 2938    colourise_extern_head(Term, M, TB, Pos).
 2939                                        % classify as body
 2940specified_item(body, Term, TB, Pos) :-
 2941    !,
 2942    colourise_body(Term, TB, Pos).
 2943specified_item(body(Goal), _Term0, TB, Pos) :-
 2944    !,
 2945    colourise_body(Goal, TB, Pos).
 2946specified_item(dcg_body(Head), Term, TB, Pos) :-
 2947    !,
 2948    colourise_dcg(Term, Head, TB, Pos).
 2949specified_item(setof, Term, TB, Pos) :-
 2950    !,
 2951    colourise_setof(Term, TB, Pos).
 2952specified_item(meta(MetaSpec), Term, TB, Pos) :-
 2953    !,
 2954    colourise_meta_arg(MetaSpec, Term, TB, Pos).
 2955                                        % DCG goal in body
 2956specified_item(dcg, Term, TB, Pos) :-
 2957    !,
 2958    colourise_dcg(Term, [], TB, Pos).
 2959                                        % assert/retract arguments
 2960specified_item(db, Term, TB, Pos) :-
 2961    !,
 2962    colourise_db(Term, TB, Pos).
 2963                                        % error(Error)
 2964specified_item(error(Error), _Term, TB, Pos) :-
 2965    colour_item(Error, TB, Pos).
 2966                                        % files
 2967specified_item(file(Path), _Term, TB, Pos) :-
 2968    !,
 2969    colour_item(file(Path), TB, Pos).
 2970specified_item(file, Term, TB, Pos) :-
 2971    !,
 2972    colourise_files(Term, TB, Pos, any).
 2973specified_item(imported_file, Term, TB, Pos) :-
 2974    !,
 2975    colourise_files(Term, TB, Pos, imported).
 2976specified_item(langoptions, Term, TB, Pos) :-
 2977    !,
 2978    colourise_langoptions(Term, TB, Pos).
 2979specified_item(expression, Term, TB, Pos) :-
 2980    !,
 2981    colourise_expression(Term, TB, Pos).
 2982                                        % directory
 2983specified_item(directory, Term, TB, Pos) :-
 2984    !,
 2985    colourise_directory(Term, TB, Pos).
 2986                                        % [Name/Arity, ...]
 2987specified_item(exports, Term, TB, Pos) :-
 2988    !,
 2989    colourise_exports(Term, TB, Pos).
 2990                                        % [Name/Arity, ...]
 2991specified_item(imports(File), Term, TB, Pos) :-
 2992    !,
 2993    colourise_imports(Term, File, TB, Pos).
 2994                                        % Name/Arity
 2995specified_item(import(File), Term, TB, Pos) :-
 2996    !,
 2997    colourise_import(Term, File, TB, Pos).
 2998                                        % Name/Arity, ...
 2999specified_item(predicates, Term, TB, Pos) :-
 3000    !,
 3001    colourise_declarations(Term, predicate_indicator, TB, Pos).
 3002                                        % Name/Arity
 3003specified_item(predicate, Term, TB, Pos) :-
 3004    !,
 3005    colourise_declaration(Term, predicate_indicator, TB, Pos).
 3006                                        % head(Arg, ...)
 3007specified_item(meta_declarations, Term, TB, Pos) :-
 3008    !,
 3009    colourise_meta_declarations(Term, [], TB, Pos).
 3010specified_item(meta_declarations(Extra), Term, TB, Pos) :-
 3011    !,
 3012    colourise_meta_declarations(Term, Extra, TB, Pos).
 3013specified_item(declarations(Which), Term, TB, Pos) :-
 3014    !,
 3015    colourise_declarations(Term, Which, TB, Pos).
 3016                                        % set_prolog_flag(Name, _)
 3017specified_item(prolog_flag_name, Term, TB, Pos) :-
 3018    !,
 3019    colourise_prolog_flag_name(Term, TB, Pos).
 3020                                        % XPCE new argument
 3021specified_item(pce_new, Term, TB, Pos) :-
 3022    !,
 3023    (   atom(Term)
 3024    ->  colourise_class(Term, TB, Pos)
 3025    ;   compound(Term)
 3026    ->  functor_name(Term, Class),
 3027        Pos = term_position(_,_,FF, FT, ArgPos),
 3028        colourise_class(Class, TB, FF-FT),
 3029        specified_items(pce_arg, Term, TB, ArgPos)
 3030    ;   colourise_term_arg(Term, TB, Pos)
 3031    ).
 3032                                        % Generic XPCE arguments
 3033specified_item(pce_arg, new(X), TB,
 3034               term_position(_,_,_,_,[ArgPos])) :-
 3035    !,
 3036    specified_item(pce_new, X, TB, ArgPos).
 3037specified_item(pce_arg, new(X, T), TB,
 3038               term_position(_,_,_,_,[P1, P2])) :-
 3039    !,
 3040    colourise_term_arg(X, TB, P1),
 3041    specified_item(pce_new, T, TB, P2).
 3042specified_item(pce_arg, @(Ref), TB, Pos) :-
 3043    !,
 3044    colourise_term_arg(@(Ref), TB, Pos).
 3045specified_item(pce_arg, prolog(Term), TB,
 3046               term_position(_,_,FF,FT,[ArgPos])) :-
 3047    !,
 3048    colour_item(prolog_data, TB, FF-FT),
 3049    colourise_term_arg(Term, TB, ArgPos).
 3050specified_item(pce_arg, Term, TB, Pos) :-
 3051    compound(Term),
 3052    Term \= [_|_],
 3053    \+ is_dict(Term),
 3054    !,
 3055    specified_item(pce_new, Term, TB, Pos).
 3056specified_item(pce_arg, Term, TB, Pos) :-
 3057    !,
 3058    colourise_term_arg(Term, TB, Pos).
 3059                                        % List of XPCE arguments
 3060specified_item(pce_arg_list, List, TB, list_position(F,T,Elms,Tail)) :-
 3061    !,
 3062    colour_item(list, TB, F-T),
 3063    colourise_list_args(Elms, Tail, List, TB, pce_arg).
 3064specified_item(pce_arg_list, Term, TB, Pos) :-
 3065    !,
 3066    specified_item(pce_arg, Term, TB, Pos).
 3067                                        % XPCE selector
 3068specified_item(pce_selector, Term, TB,
 3069               term_position(_,_,_,_,ArgPos)) :-
 3070    !,
 3071    specified_items(pce_arg, Term, TB, ArgPos).
 3072specified_item(pce_selector, Term, TB, Pos) :-
 3073    colourise_term_arg(Term, TB, Pos).
 3074                                        % Nested specification
 3075specified_item(FuncSpec-ArgSpecs, Term, TB,
 3076               term_position(_,_,FF,FT,ArgPos)) :-
 3077    !,
 3078    specified_item(FuncSpec, Term, TB, FF-FT),
 3079    specified_items(ArgSpecs, Term, TB, ArgPos).
 3080                                        % Nested for {...}
 3081specified_item(FuncSpec-[ArgSpec], {Term}, TB,
 3082               brace_term_position(F,T,ArgPos)) :-
 3083    !,
 3084    specified_item(FuncSpec, {Term}, TB, F-T),
 3085    specified_item(ArgSpec, Term, TB, ArgPos).
 3086                                        % Specified
 3087specified_item(FuncSpec-ElmSpec, List, TB,
 3088               list_position(F,T,ElmPos,TailPos)) :-
 3089    !,
 3090    colour_item(FuncSpec, TB, F-T),
 3091    specified_list(ElmSpec, List, TB, ElmPos, TailPos).
 3092specified_item(Class, _, TB, Pos) :-
 3093    colour_item(Class, TB, Pos).
 specified_items(+Spec, +Term, +TB, +PosList)
 3097specified_items(Specs, Term, TB, PosList) :-
 3098    is_dict(Term),
 3099    !,
 3100    specified_dict_kv(PosList, Term, TB, Specs).
 3101specified_items(Specs, Term, TB, PosList) :-
 3102    is_list(Specs),
 3103    !,
 3104    specified_arglist(Specs, 1, Term, TB, PosList).
 3105specified_items(Spec, Term, TB, PosList) :-
 3106    specified_argspec(PosList, Spec, 1, Term, TB).
 3107
 3108
 3109specified_arglist([], _, _, _, _).
 3110specified_arglist(_, _, _, _, []) :- !.         % Excess specification args
 3111specified_arglist([S0|ST], N, T, TB, [P0|PT]) :-
 3112    (   S0 == options,
 3113        colourization_module(TB, Module),
 3114        colourise_option_arg(T, Module, N, TB, P0)
 3115    ->  true
 3116    ;   arg(N, T, Term),
 3117        specified_item(S0, Term, TB, P0)
 3118    ),
 3119    NN is N + 1,
 3120    specified_arglist(ST, NN, T, TB, PT).
 3121
 3122specified_argspec([], _, _, _, _).
 3123specified_argspec([P0|PT], Spec, N, T, TB) :-
 3124    arg(N, T, Term),
 3125    specified_item(Spec, Term, TB, P0),
 3126    NN is N + 1,
 3127    specified_argspec(PT, Spec, NN, T, TB).
 3128
 3129
 3130%       specified_list(+Spec, +List, +TB, +PosList, TailPos)
 3131
 3132specified_list([], [], _, [], _).
 3133specified_list([HS|TS], [H|T], TB, [HP|TP], TailPos) :-
 3134    !,
 3135    specified_item(HS, H, TB, HP),
 3136    specified_list(TS, T, TB, TP, TailPos).
 3137specified_list(Spec, [H|T], TB, [HP|TP], TailPos) :-
 3138    specified_item(Spec, H, TB, HP),
 3139    specified_list(Spec, T, TB, TP, TailPos).
 3140specified_list(_, _, _, [], none) :- !.
 3141specified_list(Spec, Tail, TB, [], TailPos) :-
 3142    specified_item(Spec, Tail, TB, TailPos).
 specified_dict_kv(+PosList, +Term, +TB, +Specs)
Arguments:
Specs- is a list of dict_kv(+Key, +KeySpec, +ArgSpec)
 3148specified_dict_kv([], _, _, _).
 3149specified_dict_kv([key_value_position(_F,_T,SF,ST,K,KP,VP)|Pos],
 3150                  Dict, TB, Specs) :-
 3151    specified_dict_kv1(K, Specs, KeySpec, ValueSpec),
 3152    colour_item(KeySpec, TB, KP),
 3153    colour_item(dict_sep, TB, SF-ST),
 3154    get_dict(K, Dict, V),
 3155    specified_item(ValueSpec, V, TB, VP),
 3156    specified_dict_kv(Pos, Dict, TB, Specs).
 3157
 3158specified_dict_kv1(Key, Specs, KeySpec, ValueSpec) :-
 3159    Specs = [_|_],
 3160    memberchk(dict_kv(Key, KeySpec, ValueSpec), Specs),
 3161    !.
 3162specified_dict_kv1(Key, dict_kv(Key2, KeySpec, ValueSpec), KeySpec, ValueSpec) :-
 3163    \+ Key \= Key2,
 3164    !.              % do not bind Key2
 3165specified_dict_kv1(_, _, dict_key, classify).
 3166
 3167
 3168                 /*******************************
 3169                 *         DESCRIPTIONS         *
 3170                 *******************************/
 3171
 3172syntax_message(Class) -->
 3173    message(Class),
 3174    !.
 3175syntax_message(qq(_)) -->
 3176    [ 'Quasi quote delimiter' ].
 3177syntax_message(qq_type) -->
 3178    [ 'Quasi quote type term' ].
 3179syntax_message(qq_content(Type)) -->
 3180    [ 'Quasi quote content (~w syntax)'-[Type] ].
 3181syntax_message(goal(Class, Goal)) -->
 3182    !,
 3183    goal_message(Class, Goal).
 3184syntax_message(class(Type, Class)) -->
 3185    !,
 3186    xpce_class_message(Type, Class).
 3187syntax_message(dict_return_op) -->
 3188    !,
 3189    [ ':= separates function from return value' ].
 3190syntax_message(dict_function) -->
 3191    !,
 3192    [ 'Function on a dict' ].
 3193syntax_message(ext_quant) -->
 3194    !,
 3195    [ 'Existential quantification operator' ].
 3196syntax_message(hook(message)) -->
 3197    [ 'Rule for print_message/2' ].
 3198syntax_message(module(Module)) -->
 3199    (   { current_module(Module) }
 3200    ->  (   { module_property(Module, file(File)) }
 3201        ->  [ 'Module ~w defined in ~w'-[Module,File] ]
 3202        ;   [ 'Module ~w'-[Module] ]
 3203        )
 3204    ;   [ 'Module ~w (not loaded)'-[Module] ]
 3205    ).
 3206syntax_message(decl_option(incremental)) -->
 3207    [ 'Keep affected tables consistent' ].
 3208syntax_message(decl_option(abstract)) -->
 3209    [ 'Add abstracted goal to table dependency graph' ].
 3210syntax_message(decl_option(volatile)) -->
 3211    [ 'Do not include predicate in a saved program' ].
 3212syntax_message(decl_option(multifile)) -->
 3213    [ 'Clauses are spread over multiple files' ].
 3214syntax_message(decl_option(discontiguous)) -->
 3215    [ 'Clauses are not contiguous' ].
 3216syntax_message(decl_option(private)) -->
 3217    [ 'Tables or clauses are private to a thread' ].
 3218syntax_message(decl_option(local)) -->
 3219    [ 'Tables or clauses are private to a thread' ].
 3220syntax_message(decl_option(shared)) -->
 3221    [ 'Tables or clauses are shared between threads' ].
 3222syntax_message(decl_option(_Opt)) -->
 3223    [ 'Predicate property' ].
 3224syntax_message(rational(Value)) -->
 3225    [ 'Rational number ~w'-[Value] ].
 3226syntax_message(rule_condition) -->
 3227    [ 'Guard' ].
 3228syntax_message(neck(=>)) -->
 3229    [ 'Rule' ].
 3230syntax_message(neck(-->)) -->
 3231    [ 'Grammar rule' ].
 3232syntax_message(neck(==>)) -->
 3233    [ 'SSU Grammar rule' ].
 3234syntax_message(macro(String)) -->
 3235    [ 'Macro indicator (expands to ~s)'-[String] ].
 3236syntax_message(flag_name(Name)) -->
 3237    [ 'Prolog flag ~w'-[Name] ].
 3238syntax_message(known_flag_name(Name)) -->
 3239    [ 'Prolog flag ~w (not set; known)'-[Name] ].
 3240syntax_message(no_flag_name(Name)) -->
 3241    [ 'Prolog flag ~w (not set)'-[Name] ].
 3242
 3243goal_message(meta, _) -->
 3244    [ 'Meta call' ].
 3245goal_message(not_callable, _) -->
 3246    [ 'Goal is not callable (type error)' ].
 3247goal_message(expanded, _) -->
 3248    [ 'Expanded goal' ].
 3249goal_message(Class, Goal) -->
 3250    { predicate_name(Goal, PI) },
 3251    [ 'Call to ~q'-PI ],
 3252    goal_class(Class).
 3253
 3254goal_class(recursion) -->
 3255    [ ' (recursive call)' ].
 3256goal_class(undefined) -->
 3257    [ ' (undefined)' ].
 3258goal_class(global) -->
 3259    [ ' (Auto-imported from module user)' ].
 3260goal_class(global(Class, File:Line)) -->
 3261    [ ' (~w in user module from '-[Class], url(File:Line), ')' ].
 3262goal_class(global(Class, source_location(File,Line))) -->
 3263    [ ' (~w in user module from '-[Class], url(File:Line), ')' ].
 3264goal_class(global(Class, -)) -->
 3265    [ ' (~w in user module)'-[Class] ].
 3266goal_class(imported(From)) -->
 3267    [ ' (imported from ~q)'-[From] ].
 3268goal_class(extern(_, private)) -->
 3269    [ ' (WARNING: private predicate)' ].
 3270goal_class(extern(_, public)) -->
 3271    [ ' (public predicate)' ].
 3272goal_class(extern(_)) -->
 3273    [ ' (cross-module call)' ].
 3274goal_class(Class) -->
 3275    [ ' (~p)'-[Class] ].
 3276
 3277xpce_class_message(Type, Class) -->
 3278    [ 'XPCE ~w class ~q'-[Type, Class] ]