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-2019, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9    All rights reserved.
   10
   11    Redistribution and use in source and binary forms, with or without
   12    modification, are permitted provided that the following conditions
   13    are met:
   14
   15    1. Redistributions of source code must retain the above copyright
   16       notice, this list of conditions and the following disclaimer.
   17
   18    2. Redistributions in binary form must reproduce the above copyright
   19       notice, this list of conditions and the following disclaimer in
   20       the documentation and/or other materials provided with the
   21       distribution.
   22
   23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   26    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   27    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   28    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   29    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   31    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   33    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34    POSSIBILITY OF SUCH DAMAGE.
   35*/
   36
   37:- module(prolog_colour,
   38          [ prolog_colourise_stream/3,  % +Stream, +SourceID, :ColourItem
   39            prolog_colourise_term/4,    % +Stream, +SourceID, :ColourItem, +Opts
   40            prolog_colourise_query/3,   % +String, +SourceID, :ColourItem
   41            syntax_colour/2,            % +Class, -Attributes
   42            syntax_message//1           % +Class
   43          ]).   44:- use_module(library(prolog_xref)).   45:- use_module(library(predicate_options)).   46:- use_module(library(prolog_source)).   47:- use_module(library(lists)).   48:- use_module(library(operators)).   49:- use_module(library(debug)).   50:- use_module(library(error)).   51:- use_module(library(option)).   52:- use_module(library(record)).   53
   54:- meta_predicate
   55    prolog_colourise_stream(+, +, 3),
   56    prolog_colourise_query(+, +, 3),
   57    prolog_colourise_term(+, +, 3, +).   58
   59:- predicate_options(prolog_colourise_term/4, 4,
   60                     [ subterm_positions(-any)
   61                     ]).

Prolog syntax colouring support.

This module defines reusable code to colourise Prolog source.

To be done
- : The one-term version */
   71:- multifile
   72    style/2,                        % +ColourClass, -Attributes
   73    message//1,                     % +ColourClass
   74    term_colours/2,                 % +SourceTerm, -ColourSpec
   75    goal_colours/2,                 % +Goal, -ColourSpec
   76    goal_colours/3,                 % +Goal, +Class, -ColourSpec
   77    directive_colours/2,            % +Goal, -ColourSpec
   78    goal_classification/2,          % +Goal, -Class
   79    vararg_goal_classification/3.   % +Name, +Arity, -Class
   80
   81
   82:- record
   83    colour_state(source_id_list,
   84                 module,
   85                 stream,
   86                 closure,
   87                 singletons).   88
   89colour_state_source_id(State, SourceID) :-
   90    colour_state_source_id_list(State, SourceIDList),
   91    member(SourceID, SourceIDList).
 prolog_colourise_stream(+Stream, +SourceID, :ColourItem) 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:

  106prolog_colourise_stream(Fd, SourceId, ColourItem) :-
  107    to_list(SourceId, SourceIdList),
  108    make_colour_state([ source_id_list(SourceIdList),
  109                        stream(Fd),
  110                        closure(ColourItem)
  111                      ],
  112                      TB),
  113    setup_call_cleanup(
  114        save_settings(TB, State),
  115        colourise_stream(Fd, TB),
  116        restore_settings(State)).
  117
  118to_list(List, List) :-
  119    is_list(List),
  120    !.
  121to_list(One, [One]).
  122
  123
  124colourise_stream(Fd, TB) :-
  125    (   peek_char(Fd, #)            % skip #! script line
  126    ->  skip(Fd, 10)
  127    ;   true
  128    ),
  129    repeat,
  130        colour_state_module(TB, SM),
  131        character_count(Fd, Start),
  132        catch(read_term(Fd, Term,
  133                        [ subterm_positions(TermPos),
  134                          singletons(Singletons0),
  135                          module(SM),
  136                          comments(Comments)
  137                        ]),
  138              E,
  139              read_error(E, TB, Start, Fd)),
  140        fix_operators(Term, SM, TB),
  141        warnable_singletons(Singletons0, Singletons),
  142        colour_state_singletons(TB, Singletons),
  143        (   colourise_term(Term, TB, TermPos, Comments)
  144        ->  true
  145        ;   arg(1, TermPos, From),
  146            print_message(warning,
  147                          format('Failed to colourise ~p at index ~d~n',
  148                                 [Term, From]))
  149        ),
  150        Term == end_of_file,
  151    !.
  152
  153save_settings(TB, state(Style, Flags, OSM, Xref)) :-
  154    (   source_module(TB, SM)
  155    ->  true
  156    ;   SM = prolog_colour_ops
  157    ),
  158    set_xref(Xref, true),
  159    '$set_source_module'(OSM, SM),
  160    colour_state_module(TB, SM),
  161    push_operators([]),
  162    syntax_flags(Flags),
  163    '$style_check'(Style, Style).
  164
  165restore_settings(state(Style, Flags, OSM, Xref)) :-
  166    restore_syntax_flags(Flags),
  167    '$style_check'(_, Style),
  168    pop_operators,
  169    '$set_source_module'(OSM),
  170    set_xref(_, Xref).
  171
  172set_xref(Old, New) :-
  173    current_prolog_flag(xref, Old),
  174    !,
  175    set_prolog_flag(xref, New).
  176set_xref(false, New) :-
  177    set_prolog_flag(xref, New).
  178
  179
  180syntax_flags(Pairs) :-
  181    findall(set_prolog_flag(Flag, Value),
  182            syntax_flag(Flag, Value),
  183            Pairs).
  184
  185syntax_flag(Flag, Value) :-
  186    syntax_flag(Flag),
  187    current_prolog_flag(Flag, Value).
  188
  189restore_syntax_flags([]).
  190restore_syntax_flags([set_prolog_flag(Flag, Value)|T]) :-
  191    set_prolog_flag(Flag, Value),
  192    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.
  201source_module(TB, Module) :-
  202    colour_state_source_id_list(TB, []),
  203    !,
  204    colour_state_module(TB, Module).
  205source_module(TB, Module) :-
  206    colour_state_source_id(TB, SourceId),
  207    xref_option(SourceId, module(Module)),
  208    !.
  209source_module(TB, Module) :-
  210    (   colour_state_source_id(TB, File),
  211        atom(File)
  212    ;   colour_state_stream(TB, Fd),
  213        is_stream(Fd),
  214        stream_property(Fd, file_name(File))
  215    ),
  216    module_context(File, [], Module).
  217
  218module_context(File, _, Module) :-
  219    source_file_property(File, module(Module)),
  220    !.
  221module_context(File, Seen, Module) :-
  222    source_file_property(File, included_in(File2, _Line)),
  223    \+ memberchk(File, Seen),
  224    !,
  225    module_context(File2, [File|Seen], Module).
  226module_context(File, _, Module) :-
  227    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.
  234read_error(Error, TB, Start, EndSpec) :-
  235    (   syntax_error(Error, Id, CharNo)
  236    ->  message_to_string(error(syntax_error(Id), _), Msg),
  237        (   integer(EndSpec)
  238        ->  End = EndSpec
  239        ;   character_count(EndSpec, End)
  240        ),
  241        show_syntax_error(TB, CharNo:Msg, Start-End),
  242        fail
  243    ;   throw(Error)
  244    ).
  245
  246syntax_error(error(syntax_error(Id), stream(_S, _Line, _LinePos, CharNo)),
  247             Id, CharNo).
  248syntax_error(error(syntax_error(Id), file(_S, _Line, _LinePos, CharNo)),
  249             Id, CharNo).
  250syntax_error(error(syntax_error(Id), string(_Text, CharNo)),
  251             Id, CharNo).
 warnable_singletons(+Singletons, -Warn) is det
Warn is the subset of the singletons that we warn about.
  257warnable_singletons([], []).
  258warnable_singletons([H|T0], List) :-
  259    H = (Name=_Var),
  260    (   '$is_named_var'(Name)
  261    ->  List = [H|T]
  262    ;   List = T
  263    ),
  264    warnable_singletons(T0, T).
 colour_item(+Class, +TB, +Pos) is det
  268colour_item(Class, TB, Pos) :-
  269    arg(1, Pos, Start),
  270    arg(2, Pos, End),
  271    Len is End - Start,
  272    colour_state_closure(TB, Closure),
  273    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.
  281safe_push_op(P, T, N0, State) :-
  282    colour_state_module(State, CM),
  283    strip_module(CM:N0, M, N),
  284    (   is_list(N),
  285        N \== []                                % define list as operator
  286    ->  acyclic_term(N),
  287        forall(member(Name, N),
  288               safe_push_op(P, T, M:Name, State))
  289    ;   push_op(P, T, M:N)
  290    ),
  291    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.
  299fix_operators((:- Directive), M, Src) :-
  300    ground(Directive),
  301    catch(process_directive(Directive, M, Src), _, true),
  302    !.
  303fix_operators(_, _, _).
  304
  305process_directive(style_check(X), _, _) :-
  306    !,
  307    style_check(X).
  308process_directive(set_prolog_flag(Flag, Value), M, _) :-
  309    syntax_flag(Flag),
  310    !,
  311    set_prolog_flag(M:Flag, Value).
  312process_directive(M:op(P,T,N), _, Src) :-
  313    !,
  314    process_directive(op(P,T,N), M, Src).
  315process_directive(op(P,T,N), M, Src) :-
  316    !,
  317    safe_push_op(P, T, M:N, Src).
  318process_directive(module(_Name, Export), M, Src) :-
  319    !,
  320    forall(member(op(P,A,N), Export),
  321           safe_push_op(P,A,M:N, Src)).
  322process_directive(use_module(Spec), _, Src) :-
  323    !,
  324    catch(process_use_module1(Spec, Src), _, true).
  325process_directive(use_module(Spec, Imports), _, Src) :-
  326    !,
  327    catch(process_use_module2(Spec, Imports, Src), _, true).
  328process_directive(Directive, _, Src) :-
  329    prolog_source:expand((:-Directive), Src, _).
  330
  331syntax_flag(character_escapes).
  332syntax_flag(var_prefix).
  333syntax_flag(allow_variable_name_as_functor).
  334syntax_flag(allow_dot_in_atom).
 process_use_module1(+Imports, +Src)
Get the exported operators from the referenced files.
  340process_use_module1([], _) :- !.
  341process_use_module1([H|T], Src) :-
  342    !,
  343    process_use_module1(H, Src),
  344    process_use_module1(T, Src).
  345process_use_module1(File, Src) :-
  346    (   xref_public_list(File, Src,
  347                         [ exports(Exports),
  348                           silent(true),
  349                           path(Path)
  350                         ])
  351    ->  forall(member(op(P,T,N), Exports),
  352               safe_push_op(P,T,N,Src)),
  353        colour_state_module(Src, SM),
  354        (   member(Syntax/4, Exports),
  355            load_quasi_quotation_syntax(SM:Path, Syntax),
  356            fail
  357        ;   true
  358        )
  359    ;   true
  360    ).
  361
  362process_use_module2(File, Imports, Src) :-
  363    (   xref_public_list(File, Src,
  364                         [ exports(Exports),
  365                           silent(true),
  366                           path(Path)
  367                         ])
  368    ->  forall(( member(op(P,T,N), Exports),
  369                 member(op(P,T,N), Imports)),
  370               safe_push_op(P,T,N,Src)),
  371        colour_state_module(Src, SM),
  372        (   member(Syntax/4, Exports),
  373            member(Syntax/4, Imports),
  374            load_quasi_quotation_syntax(SM:Path, Syntax),
  375            fail
  376        ;   true
  377        )
  378    ;   true
  379    ).
 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.
  388prolog_colourise_query(QueryString, SourceID, ColourItem) :-
  389    query_colour_state(SourceID, ColourItem, TB),
  390    setup_call_cleanup(
  391        save_settings(TB, State),
  392        colourise_query(QueryString, TB),
  393        restore_settings(State)).
  394
  395query_colour_state(module(Module), ColourItem, TB) :-
  396    !,
  397    make_colour_state([ source_id_list([]),
  398                        module(Module),
  399                        closure(ColourItem)
  400                      ],
  401                      TB).
  402query_colour_state(SourceID, ColourItem, TB) :-
  403    to_list(SourceID, SourceIDList),
  404    make_colour_state([ source_id_list(SourceIDList),
  405                        closure(ColourItem)
  406                      ],
  407                      TB).
  408
  409
  410colourise_query(QueryString, TB) :-
  411    colour_state_module(TB, SM),
  412    string_length(QueryString, End),
  413    (   catch(term_string(Query, QueryString,
  414                          [ subterm_positions(TermPos),
  415                            singletons(Singletons0),
  416                            module(SM),
  417                            comments(Comments)
  418                          ]),
  419              E,
  420              read_error(E, TB, 0, End))
  421    ->  warnable_singletons(Singletons0, Singletons),
  422        colour_state_singletons(TB, Singletons),
  423        colourise_comments(Comments, TB),
  424        (   Query == end_of_file
  425        ->  true
  426        ;   colourise_body(Query, TB, TermPos)
  427        )
  428    ;   true                        % only a syntax error
  429    ).
 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 preceed it.

Options:

subterm_positions(-TermPos)
Return complete term-layout. If an error is read, this is a term error_position(StartClause, EndClause, ErrorPos)
  444prolog_colourise_term(Stream, SourceId, ColourItem, Options) :-
  445    to_list(SourceId, SourceIdList),
  446    make_colour_state([ source_id_list(SourceIdList),
  447                        stream(Stream),
  448                        closure(ColourItem)
  449                      ],
  450                      TB),
  451    option(subterm_positions(TermPos), Options, _),
  452    findall(Op, xref_op(SourceId, Op), Ops),
  453    debug(colour, 'Ops from ~p: ~p', [SourceId, Ops]),
  454    findall(Opt, xref_flag_option(SourceId, Opt), Opts),
  455    character_count(Stream, Start),
  456    (   source_module(TB, Module)
  457    ->  true
  458    ;   Module = prolog_colour_ops
  459    ),
  460    read_source_term_at_location(
  461        Stream, Term,
  462        [ module(Module),
  463          operators(Ops),
  464          error(Error),
  465          subterm_positions(TermPos),
  466          singletons(Singletons0),
  467          comments(Comments)
  468        | Opts
  469        ]),
  470    (   var(Error)
  471    ->  warnable_singletons(Singletons0, Singletons),
  472        colour_state_singletons(TB, Singletons),
  473        colour_item(range, TB, TermPos),            % Call to allow clearing
  474        colourise_term(Term, TB, TermPos, Comments)
  475    ;   character_count(Stream, End),
  476        TermPos = error_position(Start, End, Pos),
  477        colour_item(range, TB, TermPos),
  478        show_syntax_error(TB, Error, Start-End),
  479        Error = Pos:_Message
  480    ).
  481
  482xref_flag_option(TB, var_prefix(Bool)) :-
  483    xref_prolog_flag(TB, var_prefix, Bool, _Line).
  484
  485show_syntax_error(TB, Pos:Message, Range) :-
  486    integer(Pos),
  487    !,
  488    End is Pos + 1,
  489    colour_item(syntax_error(Message, Range), TB, Pos-End).
  490show_syntax_error(TB, _:Message, Range) :-
  491    colour_item(syntax_error(Message, Range), TB, Range).
  492
  493
  494singleton(Var, TB) :-
  495    colour_state_singletons(TB, Singletons),
  496    member_var(Var, Singletons).
  497
  498member_var(V, [_=V2|_]) :-
  499    V == V2,
  500    !.
  501member_var(V, [_|T]) :-
  502    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.
  513colourise_term(Term, TB, TermPos, Comments) :-
  514    colourise_comments(Comments, TB),
  515    (   Term == end_of_file
  516    ->  true
  517    ;   colourise_term(Term, TB, TermPos),
  518        colourise_fullstop(TB, TermPos)
  519    ).
  520
  521colourise_fullstop(TB, TermPos) :-
  522    arg(2, TermPos, EndTerm),
  523    Start is EndTerm,
  524    End is Start+1,
  525    colour_item(fullstop, TB, Start-End).
  526
  527colourise_comments(-, _).
  528colourise_comments([], _).
  529colourise_comments([H|T], TB) :-
  530    colourise_comment(H, TB),
  531    colourise_comments(T, TB).
  532
  533colourise_comment((-)-_, _) :- !.
  534colourise_comment(Pos-Comment, TB) :-
  535    comment_style(Comment, Style),
  536    stream_position_data(char_count, Pos, Start),
  537    string_length(Comment, Len),
  538    End is Start + Len + 1,
  539    colour_item(comment(Style), TB, Start-End).
  540
  541comment_style(Comment, structured) :-           % Starts %%, %! or /**
  542    structured_comment_start(Start),
  543    sub_string(Comment, 0, Len, _, Start),
  544    Next is Len+1,
  545    string_code(Next, Comment, NextCode),
  546    code_type(NextCode, space),
  547    !.
  548comment_style(Comment, line) :-                 % Starts %
  549    sub_string(Comment, 0, _, _, '%'),
  550    !.
  551comment_style(_, block).                        % Starts /*
 structured_comment_start(-Start)
Copied from library(pldoc/doc_process). Unfortunate, but we do not want to force loading pldoc.
  558structured_comment_start('%%').
  559structured_comment_start('%!').
  560structured_comment_start('/**').
 colourise_term(+Term, +TB, +Pos)
Colorise a file toplevel term.
  566colourise_term(Var, TB, Start-End) :-
  567    var(Var),
  568    !,
  569    colour_item(instantiation_error, TB, Start-End).
  570colourise_term(_, _, Pos) :-
  571    var(Pos),
  572    !.
  573colourise_term(Term, TB, parentheses_term_position(PO,PC,Pos)) :-
  574    !,
  575    colour_item(parentheses, TB, PO-PC),
  576    colourise_term(Term, TB, Pos).
  577colourise_term(Term, TB, Pos) :-
  578    term_colours(Term, FuncSpec-ArgSpecs),
  579    !,
  580    Pos = term_position(F,T,FF,FT,ArgPos),
  581    colour_item(term, TB, F-T),     % TBD: Allow specifying by term_colours/2?
  582    specified_item(FuncSpec, Term, TB, FF-FT),
  583    specified_items(ArgSpecs, Term, TB, ArgPos).
  584colourise_term((Head :- Body), TB,
  585               term_position(F,T,FF,FT,[HP,BP])) :-
  586    !,
  587    colour_item(clause,         TB, F-T),
  588    colour_item(neck(clause),   TB, FF-FT),
  589    colourise_clause_head(Head, TB, HP),
  590    colourise_body(Body, Head,  TB, BP).
  591colourise_term(((Head,RHC) --> Body), TB,
  592               term_position(F,T,FF,FT,
  593                             [ term_position(_,_,_,_,[HP,RHCP]),
  594                               BP
  595                             ])) :-
  596    !,
  597    colour_item(grammar_rule,       TB, F-T),
  598    colour_item(dcg_right_hand_ctx, TB, RHCP),
  599    colourise_term_arg(RHC, TB, RHCP),
  600    colour_item(neck(grammar_rule), TB, FF-FT),
  601    colourise_extended_head(Head, 2, TB, HP),
  602    colourise_dcg(Body, Head,       TB, BP).
  603colourise_term((Head --> Body), TB,                     % TBD: expansion!
  604               term_position(F,T,FF,FT,[HP,BP])) :-
  605    !,
  606    colour_item(grammar_rule,       TB, F-T),
  607    colour_item(neck(grammar_rule), TB, FF-FT),
  608    colourise_extended_head(Head, 2, TB, HP),
  609    colourise_dcg(Body, Head,       TB, BP).
  610colourise_term(:->(Head, Body), TB,
  611               term_position(F,T,FF,FT,[HP,BP])) :-
  612    !,
  613    colour_item(method,             TB, F-T),
  614    colour_item(neck(method(send)), TB, FF-FT),
  615    colour_method_head(send(Head),  TB, HP),
  616    colourise_method_body(Body,     TB, BP).
  617colourise_term(:<-(Head, Body), TB,
  618               term_position(F,T,FF,FT,[HP,BP])) :-
  619    !,
  620    colour_item(method,            TB, F-T),
  621    colour_item(neck(method(get)), TB, FF-FT),
  622    colour_method_head(get(Head),  TB, HP),
  623    colourise_method_body(Body,    TB, BP).
  624colourise_term((:- Directive), TB, Pos) :-
  625    !,
  626    colour_item(directive, TB, Pos),
  627    Pos = term_position(_F,_T,FF,FT,[ArgPos]),
  628    colour_item(neck(directive), TB, FF-FT),
  629    colourise_directive(Directive, TB, ArgPos).
  630colourise_term((?- Directive), TB, Pos) :-
  631    !,
  632    colourise_term((:- Directive), TB, Pos).
  633colourise_term(end_of_file, _, _) :- !.
  634colourise_term(Fact, TB, Pos) :-
  635    !,
  636    colour_item(clause, TB, Pos),
  637    colourise_clause_head(Fact, TB, Pos).
 colourise_extended_head(+Head, +ExtraArgs, +TB, +Pos) is det
Colourise a clause-head that is extended by term_expansion, getting ExtraArgs more arguments (e.g., DCGs add two more arguments.
  645colourise_extended_head(Head, N, TB, Pos) :-
  646    extend(Head, N, TheHead),
  647    colourise_clause_head(TheHead, TB, Pos).
  648
  649extend(M:Head, N, M:ExtHead) :-
  650    nonvar(Head),
  651    !,
  652    extend(Head, N, ExtHead).
  653extend(Head, N, ExtHead) :-
  654    compound(Head),
  655    !,
  656    compound_name_arguments(Head, Name, Args),
  657    length(Extra, N),
  658    append(Args, Extra, NArgs),
  659    compound_name_arguments(ExtHead, Name, NArgs).
  660extend(Head, N, ExtHead) :-
  661    atom(Head),
  662    !,
  663    length(Extra, N),
  664    compound_name_arguments(ExtHead, Head, Extra).
  665extend(Head, _, Head).
  666
  667
  668colourise_clause_head(_, _, Pos) :-
  669    var(Pos),
  670    !.
  671colourise_clause_head(Head, TB, parentheses_term_position(PO,PC,Pos)) :-
  672    colour_item(parentheses, TB, PO-PC),
  673    colourise_clause_head(Head, TB, Pos).
  674colourise_clause_head(M:Head, TB, QHeadPos) :-
  675    QHeadPos = term_position(_,_,QF,QT,[MPos,HeadPos]),
  676    head_colours(M:Head, meta-[_, ClassSpec-ArgSpecs]),
  677    !,
  678    colourise_module(M, TB, MPos),
  679    colour_item(functor, TB, QF-QT),
  680    functor_position(HeadPos, FPos, ArgPos),
  681    (   ClassSpec == classify
  682    ->  classify_head(TB, Head, Class)
  683    ;   Class = ClassSpec
  684    ),
  685    colour_item(head_term(Class, Head), TB, QHeadPos),
  686    colour_item(head(Class, Head), TB, FPos),
  687    specified_items(ArgSpecs, Head, TB, ArgPos).
  688colourise_clause_head(Head, TB, Pos) :-
  689    head_colours(Head, ClassSpec-ArgSpecs),
  690    !,
  691    functor_position(Pos, FPos, ArgPos),
  692    (   ClassSpec == classify
  693    ->  classify_head(TB, Head, Class)
  694    ;   Class = ClassSpec
  695    ),
  696    colour_item(head_term(Class, Head), TB, Pos),
  697    colour_item(head(Class, Head), TB, FPos),
  698    specified_items(ArgSpecs, Head, TB, ArgPos).
  699colourise_clause_head(:=(Eval, Ret), TB,
  700                      term_position(_,_,AF,AT,
  701                                    [ term_position(_,_,SF,ST,
  702                                                    [ SelfPos,
  703                                                      FuncPos
  704                                                    ]),
  705                                      RetPos
  706                                    ])) :-
  707    Eval =.. [.,M,Func],
  708    FuncPos = term_position(_,_,FF,FT,_),
  709    !,
  710    colourise_term_arg(M, TB, SelfPos),
  711    colour_item(func_dot, TB, SF-ST),               % .
  712    colour_item(dict_function(Func), TB, FF-FT),
  713    colourise_term_args(Func, TB, FuncPos),
  714    colour_item(dict_return_op, TB, AF-AT),         % :=
  715    colourise_term_arg(Ret, TB, RetPos).
  716colourise_clause_head(Head, TB, Pos) :-
  717    functor_position(Pos, FPos, _),
  718    classify_head(TB, Head, Class),
  719    colour_item(head_term(Class, Head), TB, Pos),
  720    colour_item(head(Class, Head), TB, FPos),
  721    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.
  728colourise_extern_head(Head, M, TB, Pos) :-
  729    functor_position(Pos, FPos, _),
  730    colour_item(head(extern(M), Head), TB, FPos),
  731    colourise_term_args(Head, TB, Pos).
  732
  733colour_method_head(SGHead, TB, Pos) :-
  734    arg(1, SGHead, Head),
  735    functor_name(SGHead, SG),
  736    functor_position(Pos, FPos, _),
  737    colour_item(method(SG), TB, FPos),
  738    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'.
  745functor_position(term_position(_,_,FF,FT,ArgPos), FF-FT, ArgPos) :- !.
  746functor_position(list_position(F,_T,Elms,none), F-FT, Elms) :-
  747    !,
  748    FT is F + 1.
  749functor_position(dict_position(_,_,FF,FT,KVPos), FF-FT, KVPos) :- !.
  750functor_position(brace_term_position(F,T,Arg), F-T, [Arg]) :- !.
  751functor_position(Pos, Pos, []).
  752
  753colourise_module(Term, TB, Pos) :-
  754    (   var(Term)
  755    ;   atom(Term)
  756    ),
  757    !,
  758    colour_item(module(Term), TB, Pos).
  759colourise_module(_, TB, Pos) :-
  760    colour_item(type_error(module), TB, Pos).
 colourise_directive(+Body, +TB, +Pos)
Colourise the body of a directive.
  766colourise_directive(_,_,Pos) :-
  767    var(Pos),
  768    !.
  769colourise_directive(Dir, TB, parentheses_term_position(PO,PC,Pos)) :-
  770    !,
  771    colour_item(parentheses, TB, PO-PC),
  772    colourise_directive(Dir, TB, Pos).
  773colourise_directive((A,B), TB, term_position(_,_,_,_,[PA,PB])) :-
  774    !,
  775    colourise_directive(A, TB, PA),
  776    colourise_directive(B, TB, PB).
  777colourise_directive(Body, TB, Pos) :-
  778    nonvar(Body),
  779    directive_colours(Body, ClassSpec-ArgSpecs),   % specified
  780    !,
  781    functor_position(Pos, FPos, ArgPos),
  782    (   ClassSpec == classify
  783    ->  goal_classification(TB, Body, [], Class)
  784    ;   Class = ClassSpec
  785    ),
  786    colour_item(goal(Class, Body), TB, FPos),
  787    specified_items(ArgSpecs, Body, TB, ArgPos).
  788colourise_directive(Body, TB, Pos) :-
  789    colourise_body(Body, TB, Pos).
  790
  791
  792%       colourise_body(+Body, +TB, +Pos)
  793%
  794%       Breaks down to colourise_goal/3.
  795
  796colourise_body(Body, TB, Pos) :-
  797    colourise_body(Body, [], TB, Pos).
  798
  799colourise_body(Body, Origin, TB, Pos) :-
  800    colour_item(body, TB, Pos),
  801    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.
  810colourise_method_body(_, _, Pos) :-
  811    var(Pos),
  812    !.
  813colourise_method_body(Body, TB, parentheses_term_position(PO,PC,Pos)) :-
  814    !,
  815    colour_item(parentheses, TB, PO-PC),
  816    colourise_method_body(Body, TB, Pos).
  817colourise_method_body(::(_Comment,Body), TB,
  818                      term_position(_F,_T,_FF,_FT,[CP,BP])) :-
  819    !,
  820    colour_item(comment(string), TB, CP),
  821    colourise_body(Body, TB, BP).
  822colourise_method_body(Body, TB, Pos) :-         % deal with pri(::) < 1000
  823    Body =.. [F,A,B],
  824    control_op(F),
  825    !,
  826    Pos = term_position(_F,_T,FF,FT,
  827                        [ AP,
  828                          BP
  829                        ]),
  830    colour_item(control, TB, FF-FT),
  831    colourise_method_body(A, TB, AP),
  832    colourise_body(B, TB, BP).
  833colourise_method_body(Body, TB, Pos) :-
  834    colourise_body(Body, TB, Pos).
  835
  836control_op(',').
  837control_op((;)).
  838control_op((->)).
  839control_op((*->)).
 colourise_goals(+Body, +Origin, +TB, +Pos)
Colourise the goals in a body.
  845colourise_goals(_, _, _, Pos) :-
  846    var(Pos),
  847    !.
  848colourise_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  849    !,
  850    colour_item(parentheses, TB, PO-PC),
  851    colourise_goals(Body, Origin, TB, Pos).
  852colourise_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  853    body_compiled(Body),
  854    !,
  855    colour_item(control, TB, FF-FT),
  856    colourise_subgoals(ArgPos, 1, Body, Origin, TB).
  857colourise_goals(Goal, Origin, TB, Pos) :-
  858    colourise_goal(Goal, Origin, TB, Pos).
  859
  860colourise_subgoals([], _, _, _, _).
  861colourise_subgoals([Pos|T], N, Body, Origin, TB) :-
  862    arg(N, Body, Arg),
  863    colourise_goals(Arg, Origin, TB, Pos),
  864    NN is N + 1,
  865    colourise_subgoals(T, NN, Body, Origin, TB).
 colourise_dcg(+Body, +Head, +TB, +Pos)
Breaks down to colourise_dcg_goal/3.
  871colourise_dcg(Body, Head, TB, Pos) :-
  872    colour_item(dcg, TB, Pos),
  873    (   dcg_extend(Head, Origin)
  874    ->  true
  875    ;   Origin = Head
  876    ),
  877    colourise_dcg_goals(Body, Origin, TB, Pos).
  878
  879colourise_dcg_goals(Var, _, TB, Pos) :-
  880    var(Var),
  881    !,
  882    colour_item(goal(meta,Var), TB, Pos).
  883colourise_dcg_goals(_, _, _, Pos) :-
  884    var(Pos),
  885    !.
  886colourise_dcg_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  887    !,
  888    colour_item(parentheses, TB, PO-PC),
  889    colourise_dcg_goals(Body, Origin, TB, Pos).
  890colourise_dcg_goals({Body}, Origin, TB, brace_term_position(F,T,Arg)) :-
  891    !,
  892    colour_item(dcg(plain), TB, F-T),
  893    colourise_goals(Body, Origin, TB, Arg).
  894colourise_dcg_goals([], _, TB, Pos) :-
  895    !,
  896    colour_item(dcg(terminal), TB, Pos).
  897colourise_dcg_goals(List, _, TB, list_position(F,T,Elms,Tail)) :-
  898    List = [_|_],
  899    !,
  900    colour_item(dcg(terminal), TB, F-T),
  901    colourise_list_args(Elms, Tail, List, TB, classify).
  902colourise_dcg_goals(_, _, TB, string_position(F,T)) :-
  903    integer(F),
  904    !,
  905    colour_item(dcg(string), TB, F-T).
  906colourise_dcg_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  907    dcg_body_compiled(Body),       % control structures
  908    !,
  909    colour_item(control, TB, FF-FT),
  910    colourise_dcg_subgoals(ArgPos, 1, Body, Origin, TB).
  911colourise_dcg_goals(Goal, Origin, TB, Pos) :-
  912    colourise_dcg_goal(Goal, Origin, TB, Pos).
  913
  914colourise_dcg_subgoals([], _, _, _, _).
  915colourise_dcg_subgoals([Pos|T], N, Body, Origin, TB) :-
  916    arg(N, Body, Arg),
  917    colourise_dcg_goals(Arg, Origin, TB, Pos),
  918    NN is N + 1,
  919    colourise_dcg_subgoals(T, NN, Body, Origin, TB).
  920
  921dcg_extend(Term, _) :-
  922    var(Term), !, fail.
  923dcg_extend(M:Term, M:Goal) :-
  924    dcg_extend(Term, Goal).
  925dcg_extend(Term, Goal) :-
  926    compound(Term),
  927    !,
  928    compound_name_arguments(Term, Name, Args),
  929    append(Args, [_,_], NArgs),
  930    compound_name_arguments(Goal, Name, NArgs).
  931dcg_extend(Term, Goal) :-
  932    atom(Term),
  933    !,
  934    compound_name_arguments(Goal, Term, [_,_]).
  935
  936dcg_body_compiled(G) :-
  937    body_compiled(G),
  938    !.
  939dcg_body_compiled((_|_)).
  940
  941%       colourise_dcg_goal(+Goal, +Origin, +TB, +Pos).
  942
  943colourise_dcg_goal(!, Origin, TB, TermPos) :-
  944    !,
  945    colourise_goal(!, Origin, TB, TermPos).
  946colourise_dcg_goal(Goal, Origin, TB, TermPos) :-
  947    dcg_extend(Goal, TheGoal),
  948    !,
  949    colourise_goal(TheGoal, Origin, TB, TermPos).
  950colourise_dcg_goal(Goal, _, TB, Pos) :-
  951    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.
  962                                        % Deal with list as goal (consult)
  963colourise_goal(_,_,_,Pos) :-
  964    var(Pos),
  965    !.
  966colourise_goal(Goal, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  967    !,
  968    colour_item(parentheses, TB, PO-PC),
  969    colourise_goal(Goal, Origin, TB, Pos).
  970colourise_goal(Goal, _, TB, Pos) :-
  971    Pos = list_position(F,T,Elms,TailPos),
  972    Goal = [_|_],
  973    !,
  974    FT is F + 1,
  975    AT is T - 1,
  976    colour_item(goal_term(built_in, Goal), TB, Pos),
  977    colour_item(goal(built_in, Goal), TB, F-FT),
  978    colour_item(goal(built_in, Goal), TB, AT-T),
  979    colourise_file_list(Goal, TB, Elms, TailPos, any).
  980colourise_goal(Goal, Origin, TB, Pos) :-
  981    Pos = list_position(F,T,Elms,Tail),
  982    callable(Goal),
  983    Goal =.. [_,GH,GT|_],
  984    !,
  985    goal_classification(TB, Goal, Origin, Class),
  986    FT is F + 1,
  987    AT is T - 1,
  988    colour_item(goal_term(Class, Goal), TB, Pos),
  989    colour_item(goal(Class, Goal), TB, F-FT),
  990    colour_item(goal(Class, Goal), TB, AT-T),
  991    colourise_list_args(Elms, Tail, [GH|GT], TB, classify).
  992colourise_goal(Goal, _Origin, TB, Pos) :-
  993    Pos = quasi_quotation_position(_F,_T,_QQType,_QQTypePos,_CPos),
  994    !,
  995    colourise_term_arg(Goal, TB, Pos).
  996colourise_goal(Goal, Origin, TB, Pos) :-
  997    strip_module(Goal, _, PGoal),
  998    nonvar(PGoal),
  999    (   goal_classification(TB, Goal, Origin, ClassInferred),
 1000        goal_colours(Goal, ClassInferred, ClassSpec-ArgSpecs)
 1001    ->  true
 1002    ;   goal_colours(Goal, ClassSpec-ArgSpecs)
 1003    ),
 1004    !,                                          % specified
 1005    functor_position(Pos, FPos, ArgPos),
 1006    (   ClassSpec == classify
 1007    ->  goal_classification(TB, Goal, Origin, Class)
 1008    ;   Class = ClassSpec
 1009    ),
 1010    colour_item(goal_term(Class, Goal), TB, Pos),
 1011    colour_item(goal(Class, Goal), TB, FPos),
 1012    colour_dict_braces(TB, Pos),
 1013    specified_items(ArgSpecs, Goal, TB, ArgPos).
 1014colourise_goal(Module:Goal, _Origin, TB, QGoalPos) :-
 1015    QGoalPos = term_position(_,_,QF,QT,[PM,PG]),
 1016    !,
 1017    colourise_module(Module, TB, PM),
 1018    colour_item(functor, TB, QF-QT),
 1019    (   PG = term_position(_,_,FF,FT,_)
 1020    ->  FP = FF-FT
 1021    ;   FP = PG
 1022    ),
 1023    (   callable(Goal)
 1024    ->  qualified_goal_classification(Module:Goal, TB, Class),
 1025        colour_item(goal_term(Class, Goal), TB, QGoalPos),
 1026        colour_item(goal(Class, Goal), TB, FP),
 1027        colourise_goal_args(Goal, Module, TB, PG)
 1028    ;   var(Goal)
 1029    ->  colourise_term_arg(Goal, TB, PG)
 1030    ;   colour_item(type_error(callable), TB, PG)
 1031    ).
 1032colourise_goal(Op, _Origin, TB, Pos) :-
 1033    nonvar(Op),
 1034    Op = op(_,_,_),
 1035    !,
 1036    colourise_op_declaration(Op, TB, Pos).
 1037colourise_goal(Goal, Origin, TB, Pos) :-
 1038    goal_classification(TB, Goal, Origin, Class),
 1039    (   Pos = term_position(_,_,FF,FT,_ArgPos)
 1040    ->  FPos = FF-FT
 1041    ;   FPos = Pos
 1042    ),
 1043    colour_item(goal_term(Class, Goal), TB, Pos),
 1044    colour_item(goal(Class, Goal), TB, FPos),
 1045    colourise_goal_args(Goal, TB, Pos).
 1046
 1047% make sure to emit a fragment for the braces of tag{k:v, ...} or
 1048% {...} that is mapped to something else.
 1049
 1050colour_dict_braces(TB, dict_position(_F,T,_TF,TT,_KVPos)) :-
 1051    !,
 1052    BStart is TT+1,
 1053    colour_item(dict_content, TB, BStart-T).
 1054colour_dict_braces(TB, brace_term_position(F,T,_Arg)) :-
 1055    !,
 1056    colour_item(brace_term, TB, F-T).
 1057colour_dict_braces(_, _).
 colourise_goal_args(+Goal, +TB, +Pos)
Colourise the arguments to a goal. This predicate deals with meta- and database-access predicates.
 1064colourise_goal_args(Goal, TB, Pos) :-
 1065    colourization_module(TB, Module),
 1066    colourise_goal_args(Goal, Module, TB, Pos).
 1067
 1068colourization_module(TB, Module) :-
 1069    (   colour_state_source_id(TB, SourceId),
 1070        xref_module(SourceId, Module)
 1071    ->  true
 1072    ;   Module = user
 1073    ).
 1074
 1075colourise_goal_args(Goal, M, TB, term_position(_,_,_,_,ArgPos)) :-
 1076    !,
 1077    (   meta_args(Goal, TB, MetaArgs)
 1078    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, ArgPos)
 1079    ;   colourise_goal_args(1, Goal, M, TB, ArgPos)
 1080    ).
 1081colourise_goal_args(Goal, M, TB, brace_term_position(_,_,ArgPos)) :-
 1082    !,
 1083    (   meta_args(Goal, TB, MetaArgs)
 1084    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, [ArgPos])
 1085    ;   colourise_goal_args(1, Goal, M, TB, [ArgPos])
 1086    ).
 1087colourise_goal_args(_, _, _, _).                % no arguments
 1088
 1089colourise_goal_args(_, _, _, _, []) :- !.
 1090colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1091    colourise_option_arg(Goal, Module, N, TB, P0),
 1092    !,
 1093    NN is N + 1,
 1094    colourise_goal_args(NN, Goal, Module, TB, PT).
 1095colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1096    arg(N, Goal, Arg),
 1097    colourise_term_arg(Arg, TB, P0),
 1098    NN is N + 1,
 1099    colourise_goal_args(NN, Goal, Module, TB, PT).
 1100
 1101
 1102colourise_meta_args(_, _, _, _, _, []) :- !.
 1103colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1104    colourise_option_arg(Goal, Module, N, TB, P0),
 1105    !,
 1106    NN is N + 1,
 1107    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1108colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1109    arg(N, Goal, Arg),
 1110    arg(N, MetaArgs, MetaSpec),
 1111    colourise_meta_arg(MetaSpec, Arg, TB, P0),
 1112    NN is N + 1,
 1113    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1114
 1115colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1116    nonvar(Arg),
 1117    expand_meta(MetaSpec, Arg, Expanded),
 1118    !,
 1119    colourise_goal(Expanded, [], TB, Pos). % TBD: recursion
 1120colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1121    nonvar(Arg),
 1122    MetaSpec == //,
 1123    !,
 1124    colourise_dcg_goals(Arg, //, TB, Pos).
 1125colourise_meta_arg(_, Arg, TB, Pos) :-
 1126    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.

 1139meta_args(Goal, TB, VarGoal) :-
 1140    colour_state_source_id(TB, SourceId),
 1141    xref_meta(SourceId, Goal, _),
 1142    !,
 1143    compound_name_arity(Goal, Name, Arity),
 1144    compound_name_arity(VarGoal, Name, Arity),
 1145    xref_meta(SourceId, VarGoal, MetaArgs),
 1146    instantiate_meta(MetaArgs).
 1147
 1148instantiate_meta([]).
 1149instantiate_meta([H|T]) :-
 1150    (   var(H)
 1151    ->  H = 0
 1152    ;   H = V+N
 1153    ->  V = N
 1154    ;   H = //(V)
 1155    ->  V = (//)
 1156    ),
 1157    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).
 1164expand_meta(MetaSpec, Goal, Goal) :-
 1165    MetaSpec == 0.
 1166expand_meta(MetaSpec, M:Goal, M:Expanded) :-
 1167    atom(M),
 1168    !,
 1169    expand_meta(MetaSpec, Goal, Expanded).
 1170expand_meta(MetaSpec, Goal, Expanded) :-
 1171    integer(MetaSpec),
 1172    MetaSpec > 0,
 1173    (   atom(Goal)
 1174    ->  functor(Expanded, Goal, MetaSpec)
 1175    ;   compound(Goal)
 1176    ->  compound_name_arguments(Goal, Name, Args0),
 1177        length(Extra, MetaSpec),
 1178        append(Args0, Extra, Args),
 1179        compound_name_arguments(Expanded, Name, Args)
 1180    ).
 colourise_setof(+Term, +TB, +Pos)
Colourise the 2nd argument of setof/bagof
 1186colourise_setof(Var^G, TB, term_position(_,_,FF,FT,[VP,GP])) :-
 1187    !,
 1188    colourise_term_arg(Var, TB, VP),
 1189    colour_item(ext_quant, TB, FF-FT),
 1190    colourise_setof(G, TB, GP).
 1191colourise_setof(Term, TB, Pos) :-
 1192    colourise_goal(Term, [], TB, Pos).
 1193
 1194%       colourise_db(+Arg, +TB, +Pos)
 1195%
 1196%       Colourise database modification calls (assert/1, retract/1 and
 1197%       friends.
 1198
 1199colourise_db((Head:-_Body), TB, term_position(_,_,_,_,[HP,_])) :-
 1200    !,
 1201    colourise_db(Head, TB, HP).
 1202colourise_db(Module:Head, TB, term_position(_,_,QF,QT,[MP,HP])) :-
 1203    !,
 1204    colourise_module(Module, TB, MP),
 1205    colour_item(functor, TB, QF-QT),
 1206    (   atom(Module),
 1207        colour_state_source_id(TB, SourceId),
 1208        xref_module(SourceId, Module)
 1209    ->  colourise_db(Head, TB, HP)
 1210    ;   colourise_db(Head, TB, HP)
 1211    ).
 1212colourise_db(Head, TB, Pos) :-
 1213    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
 1222colourise_option_arg(Goal, Module, Arg, TB, ArgPos) :-
 1223    goal_name_arity(Goal, Name, Arity),
 1224    current_option_arg(Module:Name/Arity, Arg),
 1225    current_predicate_options(Module:Name/Arity, Arg, OptionDecl),
 1226    debug(emacs, 'Colouring option-arg ~w of ~p',
 1227          [Arg, Module:Name/Arity]),
 1228    arg(Arg, Goal, Options),
 1229    colourise_option(Options, Module, Goal, Arg, OptionDecl, TB, ArgPos).
 1230
 1231colourise_option(Options0, Module, Goal, Arg, OptionDecl, TB, Pos0) :-
 1232    strip_option_module_qualifier(Goal, Module, Arg, TB,
 1233                                  Options0, Pos0, Options, Pos),
 1234    (   Pos = list_position(F, T, ElmPos, TailPos)
 1235    ->  colour_item(list, TB, F-T),
 1236        colourise_option_list(Options, OptionDecl, TB, ElmPos, TailPos)
 1237    ;   (   var(Options)
 1238        ;   Options == []
 1239        )
 1240    ->  colourise_term_arg(Options, TB, Pos)
 1241    ;   colour_item(type_error(list), TB, Pos)
 1242    ).
 1243
 1244strip_option_module_qualifier(Goal, Module, Arg, TB,
 1245                              M:Options, term_position(_,_,_,_,[MP,Pos]),
 1246                              Options, Pos) :-
 1247    predicate_property(Module:Goal, meta_predicate(Head)),
 1248    arg(Arg, Head, :),
 1249    !,
 1250    colourise_module(M, TB, MP).
 1251strip_option_module_qualifier(_, _, _, _,
 1252                              Options, Pos, Options, Pos).
 1253
 1254
 1255colourise_option_list(_, _, _, [], none) :- !.
 1256colourise_option_list(Tail, _, TB, [], TailPos) :-
 1257    !,
 1258    colourise_term_arg(Tail, TB, TailPos).
 1259colourise_option_list([H|T], OptionDecl, TB, [HPos|TPos], TailPos) :-
 1260    colourise_option(H, OptionDecl, TB, HPos),
 1261    colourise_option_list(T, OptionDecl, TB, TPos, TailPos).
 1262
 1263colourise_option(Opt, _, TB, Pos) :-
 1264    var(Opt),
 1265    !,
 1266    colourise_term_arg(Opt, TB, Pos).
 1267colourise_option(Opt, OptionDecl, TB, term_position(_,_,FF,FT,ValPosList)) :-
 1268    !,
 1269    generalise_term(Opt, GenOpt),
 1270    (   memberchk(GenOpt, OptionDecl)
 1271    ->  colour_item(option_name, TB, FF-FT),
 1272        Opt =.. [Name|Values],
 1273        GenOpt =.. [Name|Types],
 1274        colour_option_values(Values, Types, TB, ValPosList)
 1275    ;   colour_item(no_option_name, TB, FF-FT),
 1276        colourise_term_args(ValPosList, 1, Opt, TB)
 1277    ).
 1278colourise_option(_, _, TB, Pos) :-
 1279    colour_item(type_error(option), TB, Pos).
 1280
 1281colour_option_values([], [], _, _).
 1282colour_option_values([V0|TV], [T0|TT], TB, [P0|TP]) :-
 1283    (   (   var(V0)
 1284        ;   is_of_type(T0, V0)
 1285        ;   T0 = list(_),
 1286            member(E, V0),
 1287            var(E)
 1288        ;   functor(V0, '.', 2),
 1289            V0 \= [_|_]
 1290        )
 1291    ->  colourise_term_arg(V0, TB, P0)
 1292    ;   callable(V0),
 1293        (   T0 = callable
 1294        ->  N = 0
 1295        ;   T0 = (callable+N)
 1296        )
 1297    ->  colourise_meta_arg(N, V0, TB, P0)
 1298    ;   colour_item(type_error(T0), TB, P0)
 1299    ),
 1300    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
 1309colourise_files(List, TB, list_position(F,T,Elms,TailPos), Why) :-
 1310    !,
 1311    colour_item(list, TB, F-T),
 1312    colourise_file_list(List, TB, Elms, TailPos, Why).
 1313colourise_files(M:Spec, TB, term_position(_,_,_,_,[MP,SP]), Why) :-
 1314    !,
 1315    colourise_module(M, TB, MP),
 1316    colourise_files(Spec, TB, SP, Why).
 1317colourise_files(Var, TB, P, _) :-
 1318    var(Var),
 1319    !,
 1320    colour_item(var, TB, P).
 1321colourise_files(Spec0, TB, Pos, Why) :-
 1322    strip_module(Spec0, _, Spec),
 1323    (   colour_state_source_id(TB, Source),
 1324        prolog_canonical_source(Source, SourceId),
 1325        catch(xref_source_file(Spec, Path, SourceId, [silent(true)]),
 1326              _, fail)
 1327    ->  (   Why = imported,
 1328            \+ resolves_anything(TB, Path),
 1329            exports_something(TB, Path)
 1330        ->  colour_item(file_no_depend(Path), TB, Pos)
 1331        ;   colour_item(file(Path), TB, Pos)
 1332        )
 1333    ;   colour_item(nofile, TB, Pos)
 1334    ).
 colourise_file_list(+Files, +TB, +ElmPos, +TailPos, +Why)
 1338colourise_file_list([], _, [], none, _).
 1339colourise_file_list(Last, TB, [], TailPos, _Why) :-
 1340    (   var(Last)
 1341    ->  colourise_term(Last, TB, TailPos)
 1342    ;   colour_item(type_error(list), TB, TailPos)
 1343    ).
 1344colourise_file_list([H|T], TB, [PH|PT], TailPos, Why) :-
 1345    colourise_files(H, TB, PH, Why),
 1346    colourise_file_list(T, TB, PT, TailPos, Why).
 1347
 1348resolves_anything(TB, Path) :-
 1349    colour_state_source_id(TB, SourceId),
 1350    xref_defined(SourceId, Head, imported(Path)),
 1351    xref_called(SourceId, Head, _),
 1352    !.
 1353
 1354exports_something(TB, Path) :-
 1355    colour_state_source_id(TB, SourceId),
 1356    xref_defined(SourceId, _, imported(Path)),
 1357    !.
 colourise_directory(+Arg, +TB, +Pos)
Colourise argument that should be an existing directory.
 1363colourise_directory(Spec, TB, Pos) :-
 1364    (   colour_state_source_id(TB, SourceId),
 1365        catch(xref_source_file(Spec, Path, SourceId,
 1366                               [ file_type(directory),
 1367                                 silent(true)
 1368                               ]),
 1369              _, fail)
 1370    ->  colour_item(directory(Path), TB, Pos)
 1371    ;   colour_item(nofile, TB, Pos)
 1372    ).
 colourise_langoptions(+Term, +TB, +Pos) is det
Colourise the 3th argument of module/3
 1378colourise_langoptions([], _, _) :- !.
 1379colourise_langoptions([H|T], TB, list_position(PF,PT,[HP|TP],_)) :-
 1380    !,
 1381    colour_item(list, TB, PF-PT),
 1382    colourise_langoptions(H, TB, HP),
 1383    colourise_langoptions(T, TB, TP).
 1384colourise_langoptions(Spec, TB, Pos) :-
 1385    colourise_files(library(dialect/Spec), TB, Pos, imported).
 colourise_class(ClassName, TB, Pos)
Colourise an XPCE class.
 1391colourise_class(ClassName, TB, Pos) :-
 1392    colour_state_source_id(TB, SourceId),
 1393    classify_class(SourceId, ClassName, Classification),
 1394    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.
 1402classify_class(SourceId, Name, Class) :-
 1403    xref_defined_class(SourceId, Name, Class),
 1404    !.
 1405classify_class(_SourceId, Name, Class) :-
 1406    current_predicate(pce:send_class/3),
 1407    (   current_predicate(classify_class/2)
 1408    ->  true
 1409    ;   use_module(library(pce_meta), [classify_class/2])
 1410    ),
 1411    member(G, [classify_class(Name, Class)]),
 1412    call(G).
 colourise_term_args(+Term, +TB, +Pos)
colourise head/body principal terms.
 1418colourise_term_args(Term, TB,
 1419                    term_position(_,_,_,_,ArgPos)) :-
 1420    !,
 1421    colourise_term_args(ArgPos, 1, Term, TB).
 1422colourise_term_args(_, _, _).
 1423
 1424colourise_term_args([], _, _, _).
 1425colourise_term_args([Pos|T], N, Term, TB) :-
 1426    arg(N, Term, Arg),
 1427    colourise_term_arg(Arg, TB, Pos),
 1428    NN is N + 1,
 1429    colourise_term_args(T, NN, Term, TB).
 1430
 1431colourise_term_arg(_, _, Pos) :-
 1432    var(Pos),
 1433    !.
 1434colourise_term_arg(Arg, TB, parentheses_term_position(PO,PC,Pos)) :-
 1435    !,
 1436    colour_item(parentheses, TB, PO-PC),
 1437    colourise_term_arg(Arg, TB, Pos).
 1438colourise_term_arg(Var, TB, Pos) :-                     % variable
 1439    var(Var), Pos = _-_,
 1440    !,
 1441    (   singleton(Var, TB)
 1442    ->  colour_item(singleton, TB, Pos)
 1443    ;   colour_item(var, TB, Pos)
 1444    ).
 1445colourise_term_arg(List, TB, list_position(F, T, Elms, Tail)) :-
 1446    !,
 1447    colour_item(list, TB, F-T),
 1448    colourise_list_args(Elms, Tail, List, TB, classify).    % list
 1449colourise_term_arg(String, TB, string_position(F, T)) :-       % string
 1450    !,
 1451    (   string(String)
 1452    ->  colour_item(string, TB, F-T)
 1453    ;   String = [H|_]
 1454    ->  (   integer(H)
 1455        ->  colour_item(codes, TB, F-T)
 1456        ;   colour_item(chars, TB, F-T)
 1457        )
 1458    ;   String == []
 1459    ->  colour_item(codes, TB, F-T)
 1460    ).
 1461colourise_term_arg(_, TB,
 1462                   quasi_quotation_position(F,T,QQType,QQTypePos,CPos)) :-
 1463    !,
 1464    colourise_qq_type(QQType, TB, QQTypePos),
 1465    functor_name(QQType, Type),
 1466    colour_item(qq_content(Type), TB, CPos),
 1467    arg(1, CPos, SE),
 1468    SS is SE-2,
 1469    FE is F+2,
 1470    TS is T-2,
 1471    colour_item(qq(open),  TB, F-FE),
 1472    colour_item(qq(sep),   TB, SS-SE),
 1473    colour_item(qq(close), TB, TS-T).
 1474colourise_term_arg({Term}, TB, brace_term_position(F,T,Arg)) :-
 1475    !,
 1476    colour_item(brace_term, TB, F-T),
 1477    colourise_term_arg(Term, TB, Arg).
 1478colourise_term_arg(Map, TB, dict_position(F,T,TF,TT,KVPos)) :-
 1479    !,
 1480    is_dict(Map, Tag),
 1481    colour_item(dict, TB, F-T),
 1482    TagPos = TF-TT,
 1483    (   var(Tag)
 1484    ->  (   singleton(Tag, TB)
 1485        ->  colour_item(singleton, TB, TagPos)
 1486        ;   colour_item(var, TB, TagPos)
 1487        )
 1488    ;   colour_item(dict_tag, TB, TagPos)
 1489    ),
 1490    BStart is TT+1,
 1491    colour_item(dict_content, TB, BStart-T),
 1492    colourise_dict_kv(Map, TB, KVPos).
 1493colourise_term_arg([](List,Term), TB,                   % [] as operator
 1494                   term_position(_,_,0,0,[ListPos,ArgPos])) :-
 1495    !,
 1496    colourise_term_arg(List, TB, ListPos),
 1497    colourise_term_arg(Term, TB, ArgPos).
 1498colourise_term_arg(Compound, TB, Pos) :-                % compound
 1499    compound(Compound),
 1500    !,
 1501    (   Pos = term_position(_F,_T,FF,FT,_ArgPos)
 1502    ->  colour_item(functor, TB, FF-FT)             % TBD: Infix/Postfix?
 1503    ;   true                                        % TBD: When is this
 1504    ),
 1505    colourise_term_args(Compound, TB, Pos).
 1506colourise_term_arg(EmptyList, TB, Pos) :-
 1507    EmptyList == [],
 1508    !,
 1509    colour_item(empty_list, TB, Pos).
 1510colourise_term_arg(Atom, TB, Pos) :-
 1511    atom(Atom),
 1512    !,
 1513    colour_item(atom, TB, Pos).
 1514colourise_term_arg(Integer, TB, Pos) :-
 1515    integer(Integer),
 1516    !,
 1517    colour_item(int, TB, Pos).
 1518colourise_term_arg(Float, TB, Pos) :-
 1519    float(Float),
 1520    !,
 1521    colour_item(float, TB, Pos).
 1522colourise_term_arg(_Arg, _TB, _Pos) :-
 1523    true.
 1524
 1525colourise_list_args([HP|TP], Tail, [H|T], TB, How) :-
 1526    specified_item(How, H, TB, HP),
 1527    colourise_list_args(TP, Tail, T, TB, How).
 1528colourise_list_args([], none, _, _, _) :- !.
 1529colourise_list_args([], TP, T, TB, How) :-
 1530    specified_item(How, T, TB, TP).
 colourise_qq_type(+QQType, +TB, +QQTypePos)
Colouring the type part of a quasi quoted term
 1536colourise_qq_type(QQType, TB, QQTypePos) :-
 1537    functor_position(QQTypePos, FPos, _),
 1538    colour_item(qq_type, TB, FPos),
 1539    colourise_term_args(QQType, TB, QQTypePos).
 1540
 1541qq_position(quasi_quotation_position(_,_,_,_,_)).
 colourise_dict_kv(+Dict, +TB, +KVPosList)
Colourise the name-value pairs in the dict
 1547colourise_dict_kv(_, _, []) :- !.
 1548colourise_dict_kv(Dict, TB, [key_value_position(_F,_T,SF,ST,K,KP,VP)|KV]) :-
 1549    colour_item(dict_key, TB, KP),
 1550    colour_item(dict_sep, TB, SF-ST),
 1551    get_dict(K, Dict, V),
 1552    colourise_term_arg(V, TB, VP),
 1553    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).
 1561colourise_exports([], TB, Pos) :- !,
 1562    colourise_term_arg([], TB, Pos).
 1563colourise_exports(List, TB, list_position(F,T,ElmPos,Tail)) :-
 1564    !,
 1565    colour_item(list, TB, F-T),
 1566    (   Tail == none
 1567    ->  true
 1568    ;   colour_item(type_error(list), TB, Tail)
 1569    ),
 1570    colourise_exports2(List, TB, ElmPos).
 1571colourise_exports(_, TB, Pos) :-
 1572    colour_item(type_error(list), TB, Pos).
 1573
 1574colourise_exports2([G0|GT], TB, [P0|PT]) :-
 1575    !,
 1576    colourise_declaration(G0, TB, P0),
 1577    colourise_exports2(GT, TB, PT).
 1578colourise_exports2(_, _, _).
 colourise_imports(+List, +File, +TB, +Pos)
Colourise import list from use_module/2, importing from File.
 1585colourise_imports(List, File, TB, Pos) :-
 1586    (   colour_state_source_id(TB, SourceId),
 1587        ground(File),
 1588        catch(xref_public_list(File, SourceId,
 1589                               [ path(Path),
 1590                                 public(Public),
 1591                                 silent(true)
 1592                               ] ), _, fail)
 1593    ->  true
 1594    ;   Public = [],
 1595        Path = (-)
 1596    ),
 1597    colourise_imports(List, Path, Public, TB, Pos).
 1598
 1599colourise_imports([], _, _, TB, Pos) :-
 1600    !,
 1601    colour_item(empty_list, TB, Pos).
 1602colourise_imports(List, File, Public, TB, list_position(F,T,ElmPos,Tail)) :-
 1603    !,
 1604    colour_item(list, TB, F-T),
 1605    (   Tail == none
 1606    ->  true
 1607    ;   colour_item(type_error(list), TB, Tail)
 1608    ),
 1609    colourise_imports2(List, File, Public, TB, ElmPos).
 1610colourise_imports(except(Except), File, Public, TB,
 1611                  term_position(_,_,FF,FT,[LP])) :-
 1612    !,
 1613    colour_item(keyword(except), TB, FF-FT),
 1614    colourise_imports(Except, File, Public, TB, LP).
 1615colourise_imports(_, _, _, TB, Pos) :-
 1616    colour_item(type_error(list), TB, Pos).
 1617
 1618colourise_imports2([G0|GT], File, Public, TB, [P0|PT]) :-
 1619    !,
 1620    colourise_import(G0, File, TB, P0),
 1621    colourise_imports2(GT, File, Public, TB, PT).
 1622colourise_imports2(_, _, _, _, _).
 1623
 1624
 1625colourise_import(PI as Name, File, TB, term_position(_,_,FF,FT,[PP,NP])) :-
 1626    pi_to_term(PI, Goal),
 1627    !,
 1628    colour_item(goal(imported(File), Goal), TB, PP),
 1629    rename_goal(Goal, Name, NewGoal),
 1630    goal_classification(TB, NewGoal, [], Class),
 1631    colour_item(goal(Class, NewGoal), TB, NP),
 1632    colour_item(keyword(as), TB, FF-FT).
 1633colourise_import(PI, File, TB, Pos) :-
 1634    pi_to_term(PI, Goal),
 1635    colour_state_source_id(TB, SourceID),
 1636    (   \+ xref_defined(SourceID, Goal, imported(File))
 1637    ->  colour_item(undefined_import, TB, Pos)
 1638    ;   \+ xref_called(SourceID, Goal, _)
 1639    ->  colour_item(unused_import, TB, Pos)
 1640    ),
 1641    !.
 1642colourise_import(PI, _, TB, Pos) :-
 1643    colourise_declaration(PI, TB, Pos).
 colourise_declarations(+Term, +TB, +Pos)
Colourise the Predicate indicator lists of dynamic, multifile, etc declarations.
 1651colourise_declarations(List, TB, list_position(F,T,Elms,none)) :-
 1652    !,
 1653    colour_item(list, TB, F-T),
 1654    colourise_list_declarations(List, TB, Elms).
 1655colourise_declarations((Head,Tail), TB,
 1656                       term_position(_,_,_,_,[PH,PT])) :-
 1657    !,
 1658    colourise_declaration(Head, TB, PH),
 1659    colourise_declarations(Tail, TB, PT).
 1660colourise_declarations(Last, TB, Pos) :-
 1661    colourise_declaration(Last, TB, Pos).
 1662
 1663colourise_list_declarations([], _, []).
 1664colourise_list_declarations([H|T], TB, [HP|TP]) :-
 1665    colourise_declaration(H, TB, HP),
 1666    colourise_list_declarations(T, TB, TP).
 colourise_declaration(+Decl, +TB, +Pos) is det
Colourise declaration sequences as used by module/2, dynamic/1, etc.
 1673colourise_declaration(PI, TB, term_position(F,T,FF,FT,[NamePos,ArityPos])) :-
 1674    pi_to_term(PI, Goal),
 1675    !,
 1676    goal_classification(TB, Goal, [], Class),
 1677    colour_item(predicate_indicator(Class, Goal), TB, F-T),
 1678    colour_item(goal(Class, Goal), TB, NamePos),
 1679    colour_item(predicate_indicator, TB, FF-FT),
 1680    colour_item(arity, TB, ArityPos).
 1681colourise_declaration(Module:PI, TB,
 1682                      term_position(_,_,QF,QT,[PM,PG])) :-
 1683    atom(Module), pi_to_term(PI, Goal),
 1684    !,
 1685    colourise_module(M, TB, PM),
 1686    colour_item(functor, TB, QF-QT),
 1687    colour_item(predicate_indicator(extern(M), Goal), TB, PG),
 1688    PG = term_position(_,_,FF,FT,[NamePos,ArityPos]),
 1689    colour_item(goal(extern(M), Goal), TB, NamePos),
 1690    colour_item(predicate_indicator, TB, FF-FT),
 1691    colour_item(arity, TB, ArityPos).
 1692colourise_declaration(op(N,T,P), TB, Pos) :-
 1693    colour_item(exported_operator, TB, Pos),
 1694    colourise_op_declaration(op(N,T,P), TB, Pos).
 1695colourise_declaration(_, TB, Pos) :-
 1696    colour_item(type_error(export_declaration), TB, Pos).
 1697
 1698pi_to_term(Name/Arity, Term) :-
 1699    atom(Name), integer(Arity), Arity >= 0,
 1700    !,
 1701    functor(Term, Name, Arity).
 1702pi_to_term(Name//Arity0, Term) :-
 1703    atom(Name), integer(Arity0), Arity0 >= 0,
 1704    !,
 1705    Arity is Arity0 + 2,
 1706    functor(Term, Name, Arity).
 1707
 1708colourise_meta_declarations((Head,Tail), Extra, TB,
 1709                            term_position(_,_,_,_,[PH,PT])) :-
 1710    !,
 1711    colourise_meta_declaration(Head, Extra, TB, PH),
 1712    colourise_meta_declarations(Tail, Extra, TB, PT).
 1713colourise_meta_declarations(Last, Extra, TB, Pos) :-
 1714    colourise_meta_declaration(Last, Extra, TB, Pos).
 1715
 1716colourise_meta_declaration(M:Head, Extra, TB,
 1717                           term_position(_,_,QF,QT,
 1718                                         [ MP,
 1719                                           term_position(_,_,FF,FT,ArgPos)
 1720                                         ])) :-
 1721    compound(Head),
 1722    !,
 1723    colourise_module(M, TB, MP),
 1724    colour_item(functor, TB, QF-QT),
 1725    colour_item(goal(extern(M),Head), TB, FF-FT),
 1726    compound_name_arguments(Head, _, Args),
 1727    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1728colourise_meta_declaration(Head, Extra, TB, term_position(_,_,FF,FT,ArgPos)) :-
 1729    compound(Head),
 1730    !,
 1731    goal_classification(TB, Head, [], Class),
 1732    colour_item(goal(Class, Head), TB, FF-FT),
 1733    compound_name_arguments(Head, _, Args),
 1734    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1735colourise_meta_declaration([H|T], Extra, TB, list_position(LF,LT,[HP],TP)) :-
 1736    !,
 1737    colour_item(list, TB, LF-LT),
 1738    colourise_meta_decls([H,T], Extra, TB, [HP,TP]).
 1739colourise_meta_declaration(_, _, TB, Pos) :-
 1740    !,
 1741    colour_item(type_error(compound), TB, Pos).
 1742
 1743colourise_meta_decls([], _, _, []).
 1744colourise_meta_decls([Arg|ArgT], Extra, TB, [PosH|PosT]) :-
 1745    colourise_meta_decl(Arg, Extra, TB, PosH),
 1746    colourise_meta_decls(ArgT, Extra, TB, PosT).
 1747
 1748colourise_meta_decl(Arg, Extra, TB, Pos) :-
 1749    nonvar(Arg),
 1750    (   valid_meta_decl(Arg)
 1751    ->  true
 1752    ;   memberchk(Arg, Extra)
 1753    ),
 1754    colour_item(meta(Arg), TB, Pos).
 1755colourise_meta_decl(_, _, TB, Pos) :-
 1756    colour_item(error, TB, Pos).
 1757
 1758valid_meta_decl(:).
 1759valid_meta_decl(*).
 1760valid_meta_decl(//).
 1761valid_meta_decl(^).
 1762valid_meta_decl(?).
 1763valid_meta_decl(+).
 1764valid_meta_decl(-).
 1765valid_meta_decl(I) :- integer(I), between(0,9,I).
 colourise_table_declarations(+Term, +TB, +Pos)
 1769colourise_table_declarations(Term, TB, parentheses_term_position(PO,PC,Pos)) :-
 1770    !,
 1771    colour_item(parentheses, TB, PO-PC),
 1772    colourise_table_declarations(Term, TB, Pos).
 1773colourise_table_declarations((Head,Tail), TB,
 1774                             term_position(_,_,_,_,[PH,PT])) :-
 1775    !,
 1776    colourise_table_declarations(Head, TB, PH),
 1777    colourise_table_declarations(Tail, TB, PT).
 1778colourise_table_declarations(as(Spec, Options), TB,
 1779                             term_position(_,_,FF,FT,[PH,PT])) :-
 1780    !,
 1781    colour_item(keyword(as), TB, FF-FT),
 1782    colourise_table_declarations(Spec, TB, PH),
 1783    colourise_table_options(Options, TB, PT).
 1784colourise_table_declarations(PI, TB, Pos) :-
 1785    pi_to_term(PI, _),
 1786    !,
 1787    colourise_declaration(PI, TB, Pos).
 1788colourise_table_declarations(Goal, TB, term_position(_F,_T,FF,FT,ArgPos)) :-
 1789    callable(Goal),
 1790    !,
 1791    compound_name_arguments(Goal, _, Args),
 1792    goal_classification(TB, Goal, [], Class),
 1793    colour_item(goal(Class, Goal), TB, FF-FT),
 1794    colourise_table_modes(Args, TB, ArgPos).
 1795colourise_table_declarations(Goal, TB, Pos) :-
 1796    atom(Goal),
 1797    !,
 1798    goal_classification(TB, Goal, [], Class),
 1799    colour_item(goal(Class, Goal), TB, Pos).
 1800
 1801colourise_table_modes([], _, _).
 1802colourise_table_modes([H|T], TB, [PH|PT]) :-
 1803    colourise_table_mode(H, TB, PH),
 1804    colourise_table_modes(T, TB, PT).
 1805
 1806colourise_table_mode(H, TB, Pos) :-
 1807    table_mode(H, Mode),
 1808    !,
 1809    colour_item(table_mode(Mode), TB, Pos).
 1810colourise_table_mode(lattice(Spec), TB, term_position(_F,_T,FF,FT,[ArgPos])) :-
 1811    !,
 1812    colour_item(table_mode(lattice), TB, FF-FT),
 1813    table_moded_call(Spec, 3, TB, ArgPos).
 1814colourise_table_mode(po(Spec), TB, term_position(_F,_T,FF,FT,[ArgPos])) :-
 1815    !,
 1816    colour_item(table_mode(po), TB, FF-FT),
 1817    table_moded_call(Spec, 2, TB, ArgPos).
 1818colourise_table_mode(_, TB, Pos) :-
 1819    colour_item(type_error(table_mode), TB, Pos).
 1820
 1821table_mode(Var, index) :-
 1822    var(Var),
 1823    !.
 1824table_mode(+, index).
 1825table_mode(index, index).
 1826table_mode(-, first).
 1827table_mode(first, first).
 1828table_mode(last, last).
 1829table_mode(min, min).
 1830table_mode(max, max).
 1831table_mode(sum, sum).
 1832
 1833table_moded_call(Atom, Arity, TB, Pos) :-
 1834    atom(Atom),
 1835    functor(Head, Atom, Arity),
 1836    goal_classification(TB, Head, [], Class),
 1837    colour_item(goal(Class, Head), TB, Pos).
 1838table_moded_call(Atom/Arity, Arity, TB,
 1839                 term_position(_,_,FF,FT,[NP,AP])) :-
 1840    atom(Atom),
 1841    !,
 1842    functor(Head, Atom, Arity),
 1843    goal_classification(TB, Head, [], Class),
 1844    colour_item(goal(Class, Head), TB, NP),
 1845    colour_item(predicate_indicator, TB, FF-FT),
 1846    colour_item(arity, TB, AP).
 1847table_moded_call(Head, Arity, TB, Pos) :-
 1848    Pos = term_position(_,_,FF,FT,_),
 1849    compound(Head),
 1850    !,
 1851    compound_name_arity(Head, _Name, Arity),
 1852    goal_classification(TB, Head, [], Class),
 1853    colour_item(goal(Class, Head), TB, FF-FT),
 1854    colourise_term_args(Head, TB, Pos).
 1855table_moded_call(_, _, TB, Pos) :-
 1856    colour_item(type_error(predicate_name_or_indicator), TB, Pos).
 1857
 1858colourise_table_options(Options, TB,
 1859                        parentheses_term_position(_,_,Pos)) :-
 1860    !,
 1861    colourise_table_options(Options, TB, Pos).
 1862colourise_table_options((Head,Tail), TB,
 1863                        term_position(_,_,_,_,[PH,PT])) :-
 1864    !,
 1865    colourise_table_options(Head, TB, PH),
 1866    colourise_table_options(Tail, TB, PT).
 1867colourise_table_options(Atom, TB, F-T) :-
 1868    nonvar(Atom),
 1869    valid_table_option(Atom),
 1870    !,
 1871    colour_item(table_option(Atom), TB, F-T).
 1872colourise_table_options(_, TB, Pos) :-
 1873    colour_item(type_error(table_option), TB, Pos).
 1874
 1875valid_table_option(subsumptive).
 1876valid_table_option(variant).
 1877valid_table_option(incremental).
 1878valid_table_option(shared).
 1879valid_table_option(private).
 colourise_op_declaration(Op, TB, Pos) is det
 1883colourise_op_declaration(op(P,T,N), TB, term_position(_,_,FF,FT,[PP,TP,NP])) :-
 1884    colour_item(goal(built_in, op(N,T,P)), TB, FF-FT),
 1885    colour_op_priority(P, TB, PP),
 1886    colour_op_type(T, TB, TP),
 1887    colour_op_name(N, TB, NP).
 1888
 1889colour_op_name(_, _, Pos) :-
 1890    var(Pos),
 1891    !.
 1892colour_op_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 1893    !,
 1894    colour_item(parentheses, TB, PO-PC),
 1895    colour_op_name(Name, TB, Pos).
 1896colour_op_name(Name, TB, Pos) :-
 1897    var(Name),
 1898    !,
 1899    colour_item(var, TB, Pos).
 1900colour_op_name(Name, TB, Pos) :-
 1901    (atom(Name) ; Name == []),
 1902    !,
 1903    colour_item(identifier, TB, Pos).
 1904colour_op_name(Module:Name, TB, term_position(_F,_T,QF,QT,[MP,NP])) :-
 1905    !,
 1906    colourise_module(Module, TB, MP),
 1907    colour_item(functor, TB, QF-QT),
 1908    colour_op_name(Name, TB, NP).
 1909colour_op_name(List, TB, list_position(F,T,Elems,none)) :-
 1910    !,
 1911    colour_item(list, TB, F-T),
 1912    colour_op_names(List, TB, Elems).
 1913colour_op_name(_, TB, Pos) :-
 1914    colour_item(error, TB, Pos).
 1915
 1916colour_op_names([], _, []).
 1917colour_op_names([H|T], TB, [HP|TP]) :-
 1918    colour_op_name(H, TB, HP),
 1919    colour_op_names(T, TB, TP).
 1920
 1921colour_op_type(Type, TB, Pos) :-
 1922    var(Type),
 1923    !,
 1924    colour_item(var, TB, Pos).
 1925colour_op_type(Type, TB, Pos) :-
 1926    op_type(Type),
 1927    !,
 1928    colour_item(op_type(Type), TB, Pos).
 1929colour_op_type(_, TB, Pos) :-
 1930    colour_item(error, TB, Pos).
 1931
 1932colour_op_priority(Priority, TB, Pos) :-
 1933    var(Priority), colour_item(var, TB, Pos).
 1934colour_op_priority(Priority, TB, Pos) :-
 1935    integer(Priority),
 1936    between(0, 1200, Priority),
 1937    !,
 1938    colour_item(int, TB, Pos).
 1939colour_op_priority(_, TB, Pos) :-
 1940    colour_item(error, TB, Pos).
 1941
 1942op_type(fx).
 1943op_type(fy).
 1944op_type(xf).
 1945op_type(yf).
 1946op_type(xfy).
 1947op_type(xfx).
 1948op_type(yfx).
 colourise_prolog_flag_name(+Name, +TB, +Pos)
Colourise the name of a Prolog flag
 1955colourise_prolog_flag_name(_, _, Pos) :-
 1956    var(Pos),
 1957    !.
 1958colourise_prolog_flag_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 1959    !,
 1960    colour_item(parentheses, TB, PO-PC),
 1961    colourise_prolog_flag_name(Name, TB, Pos).
 1962colourise_prolog_flag_name(Name, TB, Pos) :-
 1963    atom(Name),
 1964    !,
 1965    (   current_prolog_flag(Name, _)
 1966    ->  colour_item(flag_name(Name), TB, Pos)
 1967    ;   colour_item(no_flag_name(Name), TB, Pos)
 1968    ).
 1969colourise_prolog_flag_name(Name, TB, Pos) :-
 1970    colourise_term(Name, TB, Pos).
 1971
 1972
 1973                 /*******************************
 1974                 *        CONFIGURATION         *
 1975                 *******************************/
 1976
 1977%       body_compiled(+Term)
 1978%
 1979%       Succeeds if term is a construct handled by the compiler.
 1980
 1981body_compiled((_,_)).
 1982body_compiled((_->_)).
 1983body_compiled((_*->_)).
 1984body_compiled((_;_)).
 1985body_compiled(\+_).
 goal_classification(+TB, +Goal, +Origin, -Class)
Classify Goal appearing in TB and called from a clause with head Origin. For directives, Origin is [].
 1992goal_classification(_, QGoal, _, Class) :-
 1993    strip_module(QGoal, _, Goal),
 1994    (   var(Goal)
 1995    ->  !, Class = meta
 1996    ;   \+ callable(Goal)
 1997    ->  !, Class = not_callable
 1998    ).
 1999goal_classification(_, Goal, Origin, recursion) :-
 2000    callable(Origin),
 2001    generalise_term(Goal, Origin),
 2002    !.
 2003goal_classification(TB, Goal, _, How) :-
 2004    colour_state_source_id(TB, SourceId),
 2005    xref_defined(SourceId, Goal, How),
 2006    How \= public(_),
 2007    !.
 2008goal_classification(_TB, Goal, _, Class) :-
 2009    call_goal_classification(Goal, Class),
 2010    !.
 2011goal_classification(TB, Goal, _, How) :-
 2012    colour_state_module(TB, Module),
 2013    atom(Module),
 2014    Module \== prolog_colour_ops,
 2015    predicate_property(Module:Goal, imported_from(From)),
 2016    !,
 2017    How = imported(From).
 2018goal_classification(_TB, _Goal, _, undefined).
 goal_classification(+Goal, -Class)
Multifile hookable classification for non-local goals.
 2024call_goal_classification(Goal, Class) :-
 2025    catch(goal_classification(Goal, Class), _,
 2026          Class = type_error(callable)).
 2027
 2028goal_classification(Goal, built_in) :-
 2029    built_in_predicate(Goal),
 2030    !.
 2031goal_classification(Goal, autoload(From)) :-    % SWI-Prolog
 2032    predicate_property(Goal, autoload(From)).
 2033goal_classification(Goal, global) :-            % SWI-Prolog
 2034    strip_module(Goal, _, PGoal),
 2035    current_predicate(_, user:PGoal),
 2036    !.
 2037goal_classification(Goal, Class) :-
 2038    compound(Goal),
 2039    compound_name_arity(Goal, Name, Arity),
 2040    vararg_goal_classification(Name, Arity, Class).
 vararg_goal_classification(+Name, +Arity, -Class) is semidet
Multifile hookable classification for vararg predicates.
 2046vararg_goal_classification(call, Arity, built_in) :-
 2047    Arity >= 1.
 2048vararg_goal_classification(send_super, Arity, expanded) :- % XPCE (TBD)
 2049    Arity >= 2.
 2050vararg_goal_classification(get_super, Arity, expanded) :-  % XPCE (TBD)
 2051    Arity >= 3.
 qualified_goal_classification(:Goal, +TB, -Class)
Classify an explicitly qualified goal.
 2057qualified_goal_classification(Goal, TB, Class) :-
 2058    goal_classification(TB, Goal, [], Class),
 2059    Class \== undefined,
 2060    !.
 2061qualified_goal_classification(Module:Goal, _, extern(Module, How)) :-
 2062    predicate_property(Module:Goal, visible),
 2063    !,
 2064    (   (   predicate_property(Module:Goal, public)
 2065        ;   predicate_property(Module:Goal, exported)
 2066        )
 2067    ->  How = (public)
 2068    ;   How = (private)
 2069    ).
 2070qualified_goal_classification(Module:_, _, extern(Module, unknown)).
 classify_head(+TB, +Head, -Class)
Classify a clause head
 2076classify_head(TB, Goal, exported) :-
 2077    colour_state_source_id(TB, SourceId),
 2078    xref_exported(SourceId, Goal),
 2079    !.
 2080classify_head(_TB, Goal, hook) :-
 2081    xref_hook(Goal),
 2082    !.
 2083classify_head(TB, Goal, hook) :-
 2084    colour_state_source_id(TB, SourceId),
 2085    xref_module(SourceId, M),
 2086    xref_hook(M:Goal),
 2087    !.
 2088classify_head(TB, Goal, Class) :-
 2089    built_in_predicate(Goal),
 2090    (   system_module(TB)
 2091    ->  (   predicate_property(system:Goal, iso)
 2092        ->  Class = def_iso
 2093        ;   goal_name(Goal, Name),
 2094            \+ sub_atom(Name, 0, _, _, $)
 2095        ->  Class = def_swi
 2096        )
 2097    ;   (   predicate_property(system:Goal, iso)
 2098        ->  Class = iso
 2099        ;   Class = built_in
 2100        )
 2101    ).
 2102classify_head(TB, Goal, unreferenced) :-
 2103    colour_state_source_id(TB, SourceId),
 2104    \+ (xref_called(SourceId, Goal, By), By \= Goal),
 2105    !.
 2106classify_head(TB, Goal, How) :-
 2107    colour_state_source_id(TB, SourceId),
 2108    (   xref_defined(SourceId, Goal, imported(From))
 2109    ->  How = imported(From)
 2110    ;   xref_defined(SourceId, Goal, How)
 2111    ),
 2112    !.
 2113classify_head(_TB, _Goal, undefined).
 2114
 2115built_in_predicate(Goal) :-
 2116    predicate_property(system:Goal, built_in),
 2117    !.
 2118built_in_predicate(module(_, _)).       % reserved expanded constructs
 2119built_in_predicate(module(_, _, _)).
 2120built_in_predicate(if(_)).
 2121built_in_predicate(elif(_)).
 2122built_in_predicate(else).
 2123built_in_predicate(endif).
 2124
 2125goal_name(_:G, Name) :- nonvar(G), !, goal_name(G, Name).
 2126goal_name(G, Name) :- callable(G), functor_name(G, Name).
 2127
 2128system_module(TB) :-
 2129    colour_state_source_id(TB, SourceId),
 2130    xref_module(SourceId, M),
 2131    module_property(M, class(system)).
 2132
 2133generalise_term(Specific, General) :-
 2134    (   compound(Specific)
 2135    ->  compound_name_arity(Specific, Name, Arity),
 2136        compound_name_arity(General0, Name, Arity),
 2137        General = General0
 2138    ;   General = Specific
 2139    ).
 2140
 2141rename_goal(Goal0, Name, Goal) :-
 2142    (   compound(Goal0)
 2143    ->  compound_name_arity(Goal0, _, Arity),
 2144        compound_name_arity(Goal, Name, Arity)
 2145    ;   Goal = Name
 2146    ).
 2147
 2148functor_name(Term, Name) :-
 2149    (   compound(Term)
 2150    ->  compound_name_arity(Term, Name, _)
 2151    ;   atom(Term)
 2152    ->  Name = Term
 2153    ).
 2154
 2155goal_name_arity(Goal, Name, Arity) :-
 2156    (   compound(Goal)
 2157    ->  compound_name_arity(Goal, Name, Arity)
 2158    ;   atom(Goal)
 2159    ->  Name = Goal, Arity = 0
 2160    ).
 2161
 2162
 2163%       Specify colours for individual goals.
 2164
 2165goal_colours(module(_,_),            built_in-[identifier,exports]).
 2166goal_colours(module(_,_,_),          built_in-[identifier,exports,langoptions]).
 2167goal_colours(use_module(_),          built_in-[imported_file]).
 2168goal_colours(use_module(File,_),     built_in-[file,imports(File)]).
 2169goal_colours(reexport(_),            built_in-[file]).
 2170goal_colours(reexport(File,_),       built_in-[file,imports(File)]).
 2171goal_colours(dynamic(_),             built_in-[predicates]).
 2172goal_colours(thread_local(_),        built_in-[predicates]).
 2173goal_colours(module_transparent(_),  built_in-[predicates]).
 2174goal_colours(discontiguous(_),       built_in-[predicates]).
 2175goal_colours(multifile(_),           built_in-[predicates]).
 2176goal_colours(volatile(_),            built_in-[predicates]).
 2177goal_colours(public(_),              built_in-[predicates]).
 2178goal_colours(table(_),               built_in-[table_declarations]).
 2179goal_colours(meta_predicate(_),      built_in-[meta_declarations]).
 2180goal_colours(consult(_),             built_in-[file]).
 2181goal_colours(include(_),             built_in-[file]).
 2182goal_colours(ensure_loaded(_),       built_in-[file]).
 2183goal_colours(load_files(_),          built_in-[file]).
 2184goal_colours(load_files(_,_),        built_in-[file,options]).
 2185goal_colours(setof(_,_,_),           built_in-[classify,setof,classify]).
 2186goal_colours(bagof(_,_,_),           built_in-[classify,setof,classify]).
 2187goal_colours(predicate_options(_,_,_), built_in-[predicate,classify,classify]).
 2188% Database access
 2189goal_colours(assert(_),              built_in-[db]).
 2190goal_colours(asserta(_),             built_in-[db]).
 2191goal_colours(assertz(_),             built_in-[db]).
 2192goal_colours(assert(_,_),            built_in-[db,classify]).
 2193goal_colours(asserta(_,_),           built_in-[db,classify]).
 2194goal_colours(assertz(_,_),           built_in-[db,classify]).
 2195goal_colours(retract(_),             built_in-[db]).
 2196goal_colours(retractall(_),          built_in-[db]).
 2197goal_colours(clause(_,_),            built_in-[db,classify]).
 2198goal_colours(clause(_,_,_),          built_in-[db,classify,classify]).
 2199% misc
 2200goal_colours(set_prolog_flag(_,_),   built_in-[prolog_flag_name,classify]).
 2201goal_colours(current_prolog_flag(_,_), built_in-[prolog_flag_name,classify]).
 2202% XPCE stuff
 2203goal_colours(pce_autoload(_,_),      classify-[classify,file]).
 2204goal_colours(pce_image_directory(_), classify-[directory]).
 2205goal_colours(new(_, _),              built_in-[classify,pce_new]).
 2206goal_colours(send_list(_,_,_),       built_in-pce_arg_list).
 2207goal_colours(send(_,_),              built_in-[pce_arg,pce_selector]).
 2208goal_colours(get(_,_,_),             built_in-[pce_arg,pce_selector,pce_arg]).
 2209goal_colours(send_super(_,_),        built_in-[pce_arg,pce_selector]).
 2210goal_colours(get_super(_,_),         built_in-[pce_arg,pce_selector,pce_arg]).
 2211goal_colours(get_chain(_,_,_),       built_in-[pce_arg,pce_selector,pce_arg]).
 2212goal_colours(Pce,                    built_in-pce_arg) :-
 2213    compound(Pce),
 2214    functor_name(Pce, Functor),
 2215    pce_functor(Functor).
 2216
 2217pce_functor(send).
 2218pce_functor(get).
 2219pce_functor(send_super).
 2220pce_functor(get_super).
 2221
 2222
 2223                 /*******************************
 2224                 *        SPECIFIC HEADS        *
 2225                 *******************************/
 2226
 2227head_colours(file_search_path(_,_), hook-[identifier,classify]).
 2228head_colours(library_directory(_),  hook-[file]).
 2229head_colours(resource(_,_),         hook-[identifier,file]).
 2230head_colours(resource(_,_,_),       hook-[identifier,file,classify]).
 2231
 2232head_colours(Var, _) :-
 2233    var(Var),
 2234    !,
 2235    fail.
 2236head_colours(M:H, Colours) :-
 2237    M == user,
 2238    head_colours(H, HC),
 2239    HC = hook - _,
 2240    !,
 2241    Colours = meta-[module(user), HC ].
 2242head_colours(M:H, Colours) :-
 2243    atom(M), callable(H),
 2244    xref_hook(M:H),
 2245    !,
 2246    Colours = meta-[module(M), hook-classify ].
 2247head_colours(M:_, meta-[module(M),extern(M)]).
 2248
 2249
 2250                 /*******************************
 2251                 *             STYLES           *
 2252                 *******************************/
 def_style(+Pattern, -Style)
Define the style used for the given pattern. Definitions here can be overruled by defining rules for style/2
 2260def_style(goal(built_in,_),        [colour(blue)]).
 2261def_style(goal(imported(_),_),     [colour(blue)]).
 2262def_style(goal(autoload(_),_),     [colour(navy_blue)]).
 2263def_style(goal(global,_),          [colour(navy_blue)]).
 2264def_style(goal(undefined,_),       [colour(red)]).
 2265def_style(goal(thread_local(_),_), [colour(magenta), underline(true)]).
 2266def_style(goal(dynamic(_),_),      [colour(magenta)]).
 2267def_style(goal(multifile(_),_),    [colour(navy_blue)]).
 2268def_style(goal(expanded,_),        [colour(blue), underline(true)]).
 2269def_style(goal(extern(_),_),       [colour(blue), underline(true)]).
 2270def_style(goal(extern(_,private),_), [colour(red)]).
 2271def_style(goal(extern(_,public),_), [colour(blue)]).
 2272def_style(goal(recursion,_),       [underline(true)]).
 2273def_style(goal(meta,_),            [colour(red4)]).
 2274def_style(goal(foreign(_),_),      [colour(darkturquoise)]).
 2275def_style(goal(local(_),_),        []).
 2276def_style(goal(constraint(_),_),   [colour(darkcyan)]).
 2277def_style(goal(not_callable,_),    [background(orange)]).
 2278
 2279def_style(option_name,             [colour('#3434ba')]).
 2280def_style(no_option_name,          [colour(red)]).
 2281
 2282def_style(head(exported,_),        [colour(blue), bold(true)]).
 2283def_style(head(public(_),_),       [colour('#016300'), bold(true)]).
 2284def_style(head(extern(_),_),       [colour(blue), bold(true)]).
 2285def_style(head(dynamic,_),         [colour(magenta), bold(true)]).
 2286def_style(head(multifile,_),       [colour(navy_blue), bold(true)]).
 2287def_style(head(unreferenced,_),    [colour(red), bold(true)]).
 2288def_style(head(hook,_),            [colour(blue), underline(true)]).
 2289def_style(head(meta,_),            []).
 2290def_style(head(constraint(_),_),   [colour(darkcyan), bold(true)]).
 2291def_style(head(imported(_),_),     [colour(darkgoldenrod4), bold(true)]).
 2292def_style(head(built_in,_),        [background(orange), bold(true)]).
 2293def_style(head(iso,_),             [background(orange), bold(true)]).
 2294def_style(head(def_iso,_),         [colour(blue), bold(true)]).
 2295def_style(head(def_swi,_),         [colour(blue), bold(true)]).
 2296def_style(head(_,_),               [bold(true)]).
 2297
 2298def_style(module(_),               [colour(dark_slate_blue)]).
 2299def_style(comment(_),              [colour(dark_green)]).
 2300
 2301def_style(directive,               [background(grey90)]).
 2302def_style(method(_),               [bold(true)]).
 2303
 2304def_style(var,                     [colour(red4)]).
 2305def_style(singleton,               [bold(true), colour(red4)]).
 2306def_style(unbound,                 [colour(red), bold(true)]).
 2307def_style(quoted_atom,             [colour(navy_blue)]).
 2308def_style(string,                  [colour(navy_blue)]).
 2309def_style(codes,                   [colour(navy_blue)]).
 2310def_style(chars,                   [colour(navy_blue)]).
 2311def_style(nofile,                  [colour(red)]).
 2312def_style(file(_),                 [colour(blue), underline(true)]).
 2313def_style(file_no_depend(_),       [colour(blue), underline(true), background(pink)]).
 2314def_style(directory(_),            [colour(blue)]).
 2315def_style(class(built_in,_),       [colour(blue), underline(true)]).
 2316def_style(class(library(_),_),     [colour(navy_blue), underline(true)]).
 2317def_style(class(local(_,_,_),_),   [underline(true)]).
 2318def_style(class(user(_),_),        [underline(true)]).
 2319def_style(class(user,_),           [underline(true)]).
 2320def_style(class(undefined,_),      [colour(red), underline(true)]).
 2321def_style(prolog_data,             [colour(blue), underline(true)]).
 2322def_style(flag_name(_),            [colour(blue)]).
 2323def_style(no_flag_name(_),         [colour(red)]).
 2324def_style(unused_import,           [colour(blue), background(pink)]).
 2325def_style(undefined_import,        [colour(red)]).
 2326
 2327def_style(constraint(_),           [colour(darkcyan)]).
 2328
 2329def_style(keyword(_),              [colour(blue)]).
 2330def_style(identifier,              [bold(true)]).
 2331def_style(delimiter,               [bold(true)]).
 2332def_style(expanded,                [colour(blue), underline(true)]).
 2333def_style(hook(_),                 [colour(blue), underline(true)]).
 2334def_style(op_type(_),              [colour(blue)]).
 2335
 2336def_style(qq_type,                 [bold(true)]).
 2337def_style(qq(_),                   [colour(blue), bold(true)]).
 2338def_style(qq_content(_),           [colour(red4)]).
 2339
 2340def_style(dict_tag,                [bold(true)]).
 2341def_style(dict_key,                [bold(true)]).
 2342def_style(dict_function(_),        [colour(navy_blue)]).
 2343def_style(dict_return_op,          [colour(blue)]).
 2344
 2345def_style(hook,                    [colour(blue), underline(true)]).
 2346def_style(dcg_right_hand_ctx,      [background('#d4ffe3')]).
 2347
 2348def_style(error,                   [background(orange)]).
 2349def_style(type_error(_),           [background(orange)]).
 2350def_style(syntax_error(_,_),       [background(orange)]).
 2351def_style(instantiation_error,     [background(orange)]).
 2352
 2353def_style(table_option(_),	   [bold(true)]).
 2354def_style(table_mode(_),	   [bold(true)]).
 syntax_colour(?Class, ?Attributes) is nondet
True when a range classified Class must be coloured using Attributes. Attributes is a list of:

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

 2370syntax_colour(Class, Attributes) :-
 2371    (   style(Class, Attributes)            % user hook
 2372    ;   def_style(Class, Attributes)        % system default
 2373    ).
 term_colours(+Term, -FunctorColour, -ArgColours)
Define colourisation for specific terms.
 2380term_colours((?- Directive), Colours) :-
 2381    term_colours((:- Directive), Colours).
 2382term_colours((prolog:Head --> _),
 2383             neck(grammar_rule) - [ expanded - [ module(prolog),
 2384                                                 hook(message) - [ identifier
 2385                                                                 ]
 2386                                               ],
 2387                                    dcg_body(prolog:Head)
 2388                                  ]) :-
 2389    prolog_message_hook(Head).
 2390
 2391prolog_message_hook(message(_)).
 2392prolog_message_hook(error_message(_)).
 2393prolog_message_hook(message_context(_)).
 2394prolog_message_hook(message_location(_)).
 2395
 2396%       XPCE rules
 2397
 2398term_colours(variable(_, _, _, _),
 2399             expanded - [ identifier,
 2400                          classify,
 2401                          classify,
 2402                          comment(string)
 2403                        ]).
 2404term_colours(variable(_, _, _),
 2405             expanded - [ identifier,
 2406                          classify,
 2407                          atom
 2408                        ]).
 2409term_colours(handle(_, _, _),
 2410             expanded - [ classify,
 2411                          classify,
 2412                          classify
 2413                        ]).
 2414term_colours(handle(_, _, _, _),
 2415             expanded - [ classify,
 2416                          classify,
 2417                          classify,
 2418                          classify
 2419                        ]).
 2420term_colours(class_variable(_,_,_,_),
 2421             expanded - [ identifier,
 2422                          pce(type),
 2423                          pce(default),
 2424                          comment(string)
 2425                        ]).
 2426term_colours(class_variable(_,_,_),
 2427             expanded - [ identifier,
 2428                          pce(type),
 2429                          pce(default)
 2430                        ]).
 2431term_colours(delegate_to(_),
 2432             expanded - [ classify
 2433                        ]).
 2434term_colours((:- encoding(_)),
 2435             expanded - [ expanded - [ classify
 2436                                     ]
 2437                        ]).
 2438term_colours((:- pce_begin_class(_, _, _)),
 2439             expanded - [ expanded - [ identifier,
 2440                                       pce_new,
 2441                                       comment(string)
 2442                                     ]
 2443                        ]).
 2444term_colours((:- pce_begin_class(_, _)),
 2445             expanded - [ expanded - [ identifier,
 2446                                       pce_new
 2447                                     ]
 2448                        ]).
 2449term_colours((:- pce_extend_class(_)),
 2450             expanded - [ expanded - [ identifier
 2451                                     ]
 2452                        ]).
 2453term_colours((:- pce_end_class),
 2454             expanded - [ expanded
 2455                        ]).
 2456term_colours((:- pce_end_class(_)),
 2457             expanded - [ expanded - [ identifier
 2458                                     ]
 2459                        ]).
 2460term_colours((:- use_class_template(_)),
 2461             expanded - [ expanded - [ pce_new
 2462                                     ]
 2463                        ]).
 2464term_colours((:- emacs_begin_mode(_,_,_,_,_)),
 2465             expanded - [ expanded - [ identifier,
 2466                                       classify,
 2467                                       classify,
 2468                                       classify,
 2469                                       classify
 2470                                     ]
 2471                        ]).
 2472term_colours((:- emacs_extend_mode(_,_)),
 2473             expanded - [ expanded - [ identifier,
 2474                                       classify
 2475                                     ]
 2476                        ]).
 2477term_colours((:- pce_group(_)),
 2478             expanded - [ expanded - [ identifier
 2479                                     ]
 2480                        ]).
 2481term_colours((:- pce_global(_, new(_))),
 2482             expanded - [ expanded - [ identifier,
 2483                                       pce_arg
 2484                                     ]
 2485                        ]).
 2486term_colours((:- emacs_end_mode),
 2487             expanded - [ expanded
 2488                        ]).
 2489term_colours(pce_ifhostproperty(_,_),
 2490             expanded - [ classify,
 2491                          classify
 2492                        ]).
 2493term_colours((_,_),
 2494             error - [ classify,
 2495                       classify
 2496                     ]).
 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.
 2503specified_item(_Class, _Term, _TB, Pos) :-
 2504    var(Pos),
 2505    !.
 2506specified_item(Class, Term, TB, parentheses_term_position(PO,PC,Pos)) :-
 2507    !,
 2508    colour_item(parentheses, TB, PO-PC),
 2509    specified_item(Class, Term, TB, Pos).
 2510specified_item(_, Var, TB, Pos) :-
 2511    (   var(Var)
 2512    ;   qq_position(Pos)
 2513    ),
 2514    !,
 2515    colourise_term_arg(Var, TB, Pos).
 2516                                        % generic classification
 2517specified_item(classify, Term, TB, Pos) :-
 2518    !,
 2519    colourise_term_arg(Term, TB, Pos).
 2520                                        % classify as head
 2521specified_item(head, Term, TB, Pos) :-
 2522    !,
 2523    colourise_clause_head(Term, TB, Pos).
 2524                                        % expanded head (DCG=2, ...)
 2525specified_item(head(+N), Term, TB, Pos) :-
 2526    !,
 2527    colourise_extended_head(Term, N, TB, Pos).
 2528                                        % M:Head
 2529specified_item(extern(M), Term, TB, Pos) :-
 2530    !,
 2531    colourise_extern_head(Term, M, TB, Pos).
 2532                                        % classify as body
 2533specified_item(body, Term, TB, Pos) :-
 2534    !,
 2535    colourise_body(Term, TB, Pos).
 2536specified_item(body(Goal), _Term0, TB, Pos) :-
 2537    !,
 2538    colourise_body(Goal, TB, Pos).
 2539specified_item(dcg_body(Head), Term, TB, Pos) :-
 2540    !,
 2541    colourise_dcg(Term, Head, TB, Pos).
 2542specified_item(setof, Term, TB, Pos) :-
 2543    !,
 2544    colourise_setof(Term, TB, Pos).
 2545specified_item(meta(MetaSpec), Term, TB, Pos) :-
 2546    !,
 2547    colourise_meta_arg(MetaSpec, Term, TB, Pos).
 2548                                        % DCG goal in body
 2549specified_item(dcg, Term, TB, Pos) :-
 2550    !,
 2551    colourise_dcg(Term, [], TB, Pos).
 2552                                        % assert/retract arguments
 2553specified_item(db, Term, TB, Pos) :-
 2554    !,
 2555    colourise_db(Term, TB, Pos).
 2556                                        % files
 2557specified_item(file, Term, TB, Pos) :-
 2558    !,
 2559    colourise_files(Term, TB, Pos, any).
 2560specified_item(imported_file, Term, TB, Pos) :-
 2561    !,
 2562    colourise_files(Term, TB, Pos, imported).
 2563specified_item(langoptions, Term, TB, Pos) :-
 2564    !,
 2565    colourise_langoptions(Term, TB, Pos).
 2566
 2567                                        % directory
 2568specified_item(directory, Term, TB, Pos) :-
 2569    !,
 2570    colourise_directory(Term, TB, Pos).
 2571                                        % [Name/Arity, ...]
 2572specified_item(exports, Term, TB, Pos) :-
 2573    !,
 2574    colourise_exports(Term, TB, Pos).
 2575                                        % [Name/Arity, ...]
 2576specified_item(imports(File), Term, TB, Pos) :-
 2577    !,
 2578    colourise_imports(Term, File, TB, Pos).
 2579                                        % Name/Arity, ...
 2580specified_item(predicates, Term, TB, Pos) :-
 2581    !,
 2582    colourise_declarations(Term, TB, Pos).
 2583                                        % Name/Arity
 2584specified_item(predicate, Term, TB, Pos) :-
 2585    !,
 2586    colourise_declaration(Term, TB, Pos).
 2587                                        % head(Arg, ...)
 2588specified_item(meta_declarations, Term, TB, Pos) :-
 2589    !,
 2590    colourise_meta_declarations(Term, [], TB, Pos).
 2591specified_item(meta_declarations(Extra), Term, TB, Pos) :-
 2592    !,
 2593    colourise_meta_declarations(Term, Extra, TB, Pos).
 2594specified_item(table_declarations, Term, TB, Pos) :-
 2595    !,
 2596    colourise_table_declarations(Term, TB, Pos).
 2597                                        % set_prolog_flag(Name, _)
 2598specified_item(prolog_flag_name, Term, TB, Pos) :-
 2599    !,
 2600    colourise_prolog_flag_name(Term, TB, Pos).
 2601                                        % XPCE new argument
 2602specified_item(pce_new, Term, TB, Pos) :-
 2603    !,
 2604    (   atom(Term)
 2605    ->  colourise_class(Term, TB, Pos)
 2606    ;   compound(Term)
 2607    ->  functor_name(Term, Class),
 2608        Pos = term_position(_,_,FF, FT, ArgPos),
 2609        colourise_class(Class, TB, FF-FT),
 2610        specified_items(pce_arg, Term, TB, ArgPos)
 2611    ;   colourise_term_arg(Term, TB, Pos)
 2612    ).
 2613                                        % Generic XPCE arguments
 2614specified_item(pce_arg, new(X), TB,
 2615               term_position(_,_,_,_,[ArgPos])) :-
 2616    !,
 2617    specified_item(pce_new, X, TB, ArgPos).
 2618specified_item(pce_arg, new(X, T), TB,
 2619               term_position(_,_,_,_,[P1, P2])) :-
 2620    !,
 2621    colourise_term_arg(X, TB, P1),
 2622    specified_item(pce_new, T, TB, P2).
 2623specified_item(pce_arg, @(Ref), TB, Pos) :-
 2624    !,
 2625    colourise_term_arg(@(Ref), TB, Pos).
 2626specified_item(pce_arg, prolog(Term), TB,
 2627               term_position(_,_,FF,FT,[ArgPos])) :-
 2628    !,
 2629    colour_item(prolog_data, TB, FF-FT),
 2630    colourise_term_arg(Term, TB, ArgPos).
 2631specified_item(pce_arg, Term, TB, Pos) :-
 2632    compound(Term),
 2633    Term \= [_|_],
 2634    !,
 2635    specified_item(pce_new, Term, TB, Pos).
 2636specified_item(pce_arg, Term, TB, Pos) :-
 2637    !,
 2638    colourise_term_arg(Term, TB, Pos).
 2639                                        % List of XPCE arguments
 2640specified_item(pce_arg_list, List, TB, list_position(F,T,Elms,Tail)) :-
 2641    !,
 2642    colour_item(list, TB, F-T),
 2643    colourise_list_args(Elms, Tail, List, TB, pce_arg).
 2644specified_item(pce_arg_list, Term, TB, Pos) :-
 2645    !,
 2646    specified_item(pce_arg, Term, TB, Pos).
 2647                                        % XPCE selector
 2648specified_item(pce_selector, Term, TB,
 2649               term_position(_,_,_,_,ArgPos)) :-
 2650    !,
 2651    specified_items(pce_arg, Term, TB, ArgPos).
 2652specified_item(pce_selector, Term, TB, Pos) :-
 2653    colourise_term_arg(Term, TB, Pos).
 2654                                        % Nested specification
 2655specified_item(FuncSpec-ArgSpecs, Term, TB,
 2656               term_position(_,_,FF,FT,ArgPos)) :-
 2657    !,
 2658    specified_item(FuncSpec, Term, TB, FF-FT),
 2659    specified_items(ArgSpecs, Term, TB, ArgPos).
 2660                                        % Nested for {...}
 2661specified_item(FuncSpec-[ArgSpec], {Term}, TB,
 2662               brace_term_position(F,T,ArgPos)) :-
 2663    !,
 2664    specified_item(FuncSpec, {Term}, TB, F-T),
 2665    specified_item(ArgSpec, Term, TB, ArgPos).
 2666                                        % Specified
 2667specified_item(FuncSpec-ElmSpec, List, TB,
 2668               list_position(F,T,ElmPos,TailPos)) :-
 2669    !,
 2670    colour_item(FuncSpec, TB, F-T),
 2671    specified_list(ElmSpec, List, TB, ElmPos, TailPos).
 2672specified_item(Class, _, TB, Pos) :-
 2673    colour_item(Class, TB, Pos).
 specified_items(+Spec, +Term, +TB, +PosList)
 2677specified_items(Specs, Term, TB, PosList) :-
 2678    is_dict(Term),
 2679    !,
 2680    specified_dict_kv(PosList, Term, TB, Specs).
 2681specified_items(Specs, Term, TB, PosList) :-
 2682    is_list(Specs),
 2683    !,
 2684    specified_arglist(Specs, 1, Term, TB, PosList).
 2685specified_items(Spec, Term, TB, PosList) :-
 2686    specified_argspec(PosList, Spec, 1, Term, TB).
 2687
 2688
 2689specified_arglist([], _, _, _, _).
 2690specified_arglist(_, _, _, _, []) :- !.         % Excess specification args
 2691specified_arglist([S0|ST], N, T, TB, [P0|PT]) :-
 2692    (   S0 == options,
 2693        colourization_module(TB, Module),
 2694        colourise_option_arg(T, Module, N, TB, P0)
 2695    ->  true
 2696    ;   arg(N, T, Term),
 2697        specified_item(S0, Term, TB, P0)
 2698    ),
 2699    NN is N + 1,
 2700    specified_arglist(ST, NN, T, TB, PT).
 2701
 2702specified_argspec([], _, _, _, _).
 2703specified_argspec([P0|PT], Spec, N, T, TB) :-
 2704    arg(N, T, Term),
 2705    specified_item(Spec, Term, TB, P0),
 2706    NN is N + 1,
 2707    specified_argspec(PT, Spec, NN, T, TB).
 2708
 2709
 2710%       specified_list(+Spec, +List, +TB, +PosList, TailPos)
 2711
 2712specified_list([], [], _, [], _).
 2713specified_list([HS|TS], [H|T], TB, [HP|TP], TailPos) :-
 2714    !,
 2715    specified_item(HS, H, TB, HP),
 2716    specified_list(TS, T, TB, TP, TailPos).
 2717specified_list(Spec, [H|T], TB, [HP|TP], TailPos) :-
 2718    specified_item(Spec, H, TB, HP),
 2719    specified_list(Spec, T, TB, TP, TailPos).
 2720specified_list(_, _, _, [], none) :- !.
 2721specified_list(Spec, Tail, TB, [], TailPos) :-
 2722    specified_item(Spec, Tail, TB, TailPos).
 specified_dict_kv(+PosList, +Term, +TB, +Specs)
Arguments:
Specs- is a list of dict_kv(+Key, +KeySpec, +ArgSpec)
 2728specified_dict_kv([], _, _, _).
 2729specified_dict_kv([key_value_position(_F,_T,SF,ST,K,KP,VP)|Pos],
 2730                  Dict, TB, Specs) :-
 2731    specified_dict_kv1(K, Specs, KeySpec, ValueSpec),
 2732    colour_item(KeySpec, TB, KP),
 2733    colour_item(dict_sep, TB, SF-ST),
 2734    get_dict(K, Dict, V),
 2735    specified_item(ValueSpec, V, TB, VP),
 2736    specified_dict_kv(Pos, Dict, TB, Specs).
 2737
 2738specified_dict_kv1(Key, Specs, KeySpec, ValueSpec) :-
 2739    Specs = [_|_],
 2740    memberchk(dict_kv(Key, KeySpec, ValueSpec), Specs),
 2741    !.
 2742specified_dict_kv1(Key, dict_kv(Key2, KeySpec, ValueSpec), KeySpec, ValueSpec) :-
 2743    \+ Key \= Key2,
 2744    !.              % do not bind Key2
 2745specified_dict_kv1(_, _, dict_key, classify).
 2746
 2747
 2748                 /*******************************
 2749                 *         DESCRIPTIONS         *
 2750                 *******************************/
 2751
 2752syntax_message(Class) -->
 2753    message(Class),
 2754    !.
 2755syntax_message(qq(_)) -->
 2756    [ 'Quasi quote delimiter' ].
 2757syntax_message(qq_type) -->
 2758    [ 'Quasi quote type term' ].
 2759syntax_message(qq_content(Type)) -->
 2760    [ 'Quasi quote content (~w syntax)'-[Type] ].
 2761syntax_message(goal(Class, Goal)) -->
 2762    !,
 2763    goal_message(Class, Goal).
 2764syntax_message(class(Type, Class)) -->
 2765    !,
 2766    xpce_class_message(Type, Class).
 2767syntax_message(dict_return_op) -->
 2768    !,
 2769    [ ':= separates function from return value' ].
 2770syntax_message(dict_function) -->
 2771    !,
 2772    [ 'Function on a dict' ].
 2773syntax_message(ext_quant) -->
 2774    !,
 2775    [ 'Existential quantification operator' ].
 2776syntax_message(hook(message)) -->
 2777    [ 'Rule for print_message/2' ].
 2778syntax_message(module(Module)) -->
 2779    (   { current_module(Module) }
 2780    ->  (   { module_property(Module, file(File)) }
 2781        ->  [ 'Module ~w defined in ~w'-[Module,File] ]
 2782        ;   [ 'Module ~w'-[Module] ]
 2783        )
 2784    ;   [ 'Module ~w (not loaded)'-[Module] ]
 2785    ).
 2786syntax_message(table_option(_)) -->
 2787    [ 'Table option' ].
 2788
 2789goal_message(meta, _) -->
 2790    [ 'Meta call' ].
 2791goal_message(not_callable, _) -->
 2792    [ 'Goal is not callable (type error)' ].
 2793goal_message(expanded, _) -->
 2794    [ 'Expanded goal' ].
 2795goal_message(Class, Goal) -->
 2796    { predicate_name(Goal, PI) },
 2797    [ 'Call to ~q'-PI ],
 2798    goal_class(Class).
 2799
 2800goal_class(recursion) -->
 2801    [ ' (recursive call)' ].
 2802goal_class(undefined) -->
 2803    [ ' (undefined)' ].
 2804goal_class(global) -->
 2805    [ ' (Auto-imported from module user)' ].
 2806goal_class(imported(From)) -->
 2807    [ ' (imported from ~q)'-[From] ].
 2808goal_class(extern(_, private)) -->
 2809    [ ' (WARNING: private predicate)' ].
 2810goal_class(extern(_, public)) -->
 2811    [ ' (public predicate)' ].
 2812goal_class(extern(_)) -->
 2813    [ ' (cross-module call)' ].
 2814goal_class(Class) -->
 2815    [ ' (~p)'-[Class] ].
 2816
 2817xpce_class_message(Type, Class) -->
 2818    [ 'XPCE ~w class ~q'-[Type, Class] ]