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

Prolog syntax colouring support.

This module defines reusable code to colourise Prolog source.

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

  105prolog_colourise_stream(Fd, SourceId, ColourItem) :-
  106    to_list(SourceId, SourceIdList),
  107    make_colour_state([ source_id_list(SourceIdList),
  108                        stream(Fd),
  109                        closure(ColourItem)
  110                      ],
  111                      TB),
  112    setup_call_cleanup(
  113        save_settings(TB, State),
  114        colourise_stream(Fd, TB),
  115        restore_settings(State)).
  116
  117to_list(List, List) :-
  118    is_list(List),
  119    !.
  120to_list(One, [One]).
  121
  122
  123colourise_stream(Fd, TB) :-
  124    (   peek_char(Fd, #)            % skip #! script line
  125    ->  skip(Fd, 10)
  126    ;   true
  127    ),
  128    repeat,
  129        colour_state_module(TB, SM),
  130        character_count(Fd, Start),
  131        catch(read_term(Fd, Term,
  132                        [ subterm_positions(TermPos),
  133                          singletons(Singletons),
  134                          module(SM),
  135                          comments(Comments)
  136                        ]),
  137              E,
  138              read_error(E, TB, Start, Fd)),
  139        fix_operators(Term, SM, TB),
  140        colour_state_singletons(TB, Singletons),
  141        (   colourise_term(Term, TB, TermPos, Comments)
  142        ->  true
  143        ;   arg(1, TermPos, From),
  144            print_message(warning,
  145                          format('Failed to colourise ~p at index ~d~n',
  146                                 [Term, From]))
  147        ),
  148        Term == end_of_file,
  149    !.
  150
  151save_settings(TB, state(Style, Flags, OSM)) :-
  152    (   source_module(TB, SM)
  153    ->  true
  154    ;   SM = prolog_colour_ops
  155    ),
  156    '$set_source_module'(OSM, SM),
  157    colour_state_module(TB, SM),
  158    push_operators([]),
  159    syntax_flags(Flags),
  160    '$style_check'(Style, Style).
  161
  162restore_settings(state(Style, Flags, OSM)) :-
  163    restore_syntax_flags(Flags),
  164    '$style_check'(_, Style),
  165    pop_operators,
  166    '$set_source_module'(OSM).
  167
  168syntax_flags(Pairs) :-
  169    findall(set_prolog_flag(Flag, Value),
  170            syntax_flag(Flag, Value),
  171            Pairs).
  172
  173syntax_flag(Flag, Value) :-
  174    syntax_flag(Flag),
  175    current_prolog_flag(Flag, Value).
  176
  177restore_syntax_flags([]).
  178restore_syntax_flags([set_prolog_flag(Flag, Value)|T]) :-
  179    set_prolog_flag(Flag, Value),
  180    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.
  189source_module(TB, Module) :-
  190    colour_state_source_id_list(TB, []),
  191    !,
  192    colour_state_module(TB, Module).
  193source_module(TB, Module) :-
  194    colour_state_source_id(TB, SourceId),
  195    xref_option(SourceId, module(Module)),
  196    !.
  197source_module(TB, Module) :-
  198    (   colour_state_source_id(TB, File),
  199        atom(File)
  200    ;   colour_state_stream(TB, Fd),
  201        is_stream(Fd),
  202        stream_property(Fd, file_name(File))
  203    ),
  204    module_context(File, [], Module).
  205
  206module_context(File, _, Module) :-
  207    source_file_property(File, module(Module)),
  208    !.
  209module_context(File, Seen, Module) :-
  210    source_file_property(File, included_in(File2, _Line)),
  211    \+ memberchk(File, Seen),
  212    !,
  213    module_context(File2, [File|Seen], Module).
  214module_context(File, _, Module) :-
  215    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.
  222read_error(Error, TB, Start, EndSpec) :-
  223    (   syntax_error(Error, Id, CharNo)
  224    ->  message_to_string(error(syntax_error(Id), _), Msg),
  225        (   integer(EndSpec)
  226        ->  End = EndSpec
  227        ;   character_count(EndSpec, End)
  228        ),
  229        show_syntax_error(TB, CharNo:Msg, Start-End),
  230        fail
  231    ;   throw(Error)
  232    ).
  233
  234syntax_error(error(syntax_error(Id), stream(_S, _Line, _LinePos, CharNo)),
  235             Id, CharNo).
  236syntax_error(error(syntax_error(Id), file(_S, _Line, _LinePos, CharNo)),
  237             Id, CharNo).
  238syntax_error(error(syntax_error(Id), string(_Text, CharNo)),
  239             Id, CharNo).
 colour_item(+Class, +TB, +Pos) is det
  243colour_item(Class, TB, Pos) :-
  244    arg(1, Pos, Start),
  245    arg(2, Pos, End),
  246    Len is End - Start,
  247    colour_state_closure(TB, Closure),
  248    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.
  256safe_push_op(P, T, N0, State) :-
  257    colour_state_module(State, CM),
  258    strip_module(CM:N0, M, N),
  259    (   is_list(N)
  260    ->  acyclic_term(N),
  261        forall(member(Name, N),
  262               safe_push_op(P, T, M:Name, State))
  263    ;   push_op(P, T, M:N)
  264    ),
  265    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.
  273fix_operators((:- Directive), M, Src) :-
  274    ground(Directive),
  275    catch(process_directive(Directive, M, Src), _, true),
  276    !.
  277fix_operators(_, _, _).
  278
  279process_directive(style_check(X), _, _) :-
  280    !,
  281    style_check(X).
  282process_directive(set_prolog_flag(Flag, Value), M, _) :-
  283    syntax_flag(Flag),
  284    !,
  285    set_prolog_flag(M:Flag, Value).
  286process_directive(M:op(P,T,N), _, Src) :-
  287    !,
  288    process_directive(op(P,T,N), M, Src).
  289process_directive(op(P,T,N), M, Src) :-
  290    !,
  291    safe_push_op(P, T, M:N, Src).
  292process_directive(module(_Name, Export), M, Src) :-
  293    !,
  294    forall(member(op(P,A,N), Export),
  295           safe_push_op(P,A,M:N, Src)).
  296process_directive(use_module(Spec), _, Src) :-
  297    !,
  298    catch(process_use_module(Spec, Src), _, true).
  299process_directive(Directive, _, Src) :-
  300    prolog_source:expand((:-Directive), Src, _).
  301
  302syntax_flag(character_escapes).
  303syntax_flag(var_prefix).
  304syntax_flag(allow_variable_name_as_functor).
  305syntax_flag(allow_dot_in_atom).
 process_use_module(+Imports, +Src)
Get the exported operators from the referenced files.
  311process_use_module([], _) :- !.
  312process_use_module([H|T], Src) :-
  313    !,
  314    process_use_module(H, Src),
  315    process_use_module(T, Src).
  316process_use_module(File, Src) :-
  317    (   xref_public_list(File, Src,
  318                         [ exports(Exports),
  319                           silent(true),
  320                           path(Path)
  321                         ])
  322    ->  forall(member(op(P,T,N), Exports),
  323               safe_push_op(P,T,N,Src)),
  324        colour_state_module(Src, SM),
  325        (   member(Syntax/4, Exports),
  326            load_quasi_quotation_syntax(SM:Path, Syntax),
  327            fail
  328        ;   true
  329        )
  330    ;   true
  331    ).
 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.
  341prolog_colourise_query(QueryString, SourceID, ColourItem) :-
  342    query_colour_state(SourceID, ColourItem, TB),
  343    setup_call_cleanup(
  344        save_settings(TB, State),
  345        colourise_query(QueryString, TB),
  346        restore_settings(State)).
  347
  348query_colour_state(module(Module), ColourItem, TB) :-
  349    !,
  350    make_colour_state([ source_id_list([]),
  351                        module(Module),
  352                        closure(ColourItem)
  353                      ],
  354                      TB).
  355query_colour_state(SourceID, ColourItem, TB) :-
  356    to_list(SourceID, SourceIDList),
  357    make_colour_state([ source_id_list(SourceIDList),
  358                        closure(ColourItem)
  359                      ],
  360                      TB).
  361
  362
  363colourise_query(QueryString, TB) :-
  364    colour_state_module(TB, SM),
  365    string_length(QueryString, End),
  366    (   catch(term_string(Query, QueryString,
  367                          [ subterm_positions(TermPos),
  368                            singletons(Singletons),
  369                            module(SM),
  370                            comments(Comments)
  371                          ]),
  372              E,
  373              read_error(E, TB, 0, End))
  374    ->  colour_state_singletons(TB, Singletons),
  375        colourise_comments(Comments, TB),
  376        (   Query == end_of_file
  377        ->  true
  378        ;   colourise_body(Query, TB, TermPos)
  379        )
  380    ;   true                        % only a syntax error
  381    ).
 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)
  396prolog_colourise_term(Stream, SourceId, ColourItem, Options) :-
  397    to_list(SourceId, SourceIdList),
  398    make_colour_state([ source_id_list(SourceIdList),
  399                        stream(Stream),
  400                        closure(ColourItem)
  401                      ],
  402                      TB),
  403    option(subterm_positions(TermPos), Options, _),
  404    findall(Op, xref_op(SourceId, Op), Ops),
  405    findall(Opt, xref_flag_option(SourceId, Opt), Opts),
  406    character_count(Stream, Start),
  407    (   source_module(TB, Module)
  408    ->  true
  409    ;   Module = prolog_colour_ops
  410    ),
  411    read_source_term_at_location(
  412        Stream, Term,
  413        [ module(Module),
  414          operators(Ops),
  415          error(Error),
  416          subterm_positions(TermPos),
  417          singletons(Singletons),
  418          comments(Comments)
  419        | Opts
  420        ]),
  421    (   var(Error)
  422    ->  colour_state_singletons(TB, Singletons),
  423        colour_item(range, TB, TermPos),            % Call to allow clearing
  424        colourise_term(Term, TB, TermPos, Comments)
  425    ;   character_count(Stream, End),
  426        TermPos = error_position(Start, End, Pos),
  427        colour_item(range, TB, TermPos),
  428        show_syntax_error(TB, Error, Start-End),
  429        Error = Pos:_Message
  430    ).
  431
  432xref_flag_option(TB, var_prefix(Bool)) :-
  433    xref_prolog_flag(TB, var_prefix, Bool, _Line).
  434
  435show_syntax_error(TB, Pos:Message, Range) :-
  436    integer(Pos),
  437    !,
  438    End is Pos + 1,
  439    colour_item(syntax_error(Message, Range), TB, Pos-End).
  440show_syntax_error(TB, _:Message, Range) :-
  441    colour_item(syntax_error(Message, Range), TB, Range).
  442
  443
  444singleton(Var, TB) :-
  445    colour_state_singletons(TB, Singletons),
  446    member_var(Var, Singletons).
  447
  448member_var(V, [_=V2|_]) :-
  449    V == V2,
  450    !.
  451member_var(V, [_|T]) :-
  452    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.
  463colourise_term(Term, TB, TermPos, Comments) :-
  464    colourise_comments(Comments, TB),
  465    (   Term == end_of_file
  466    ->  true
  467    ;   colourise_term(Term, TB, TermPos),
  468        colourise_fullstop(TB, TermPos)
  469    ).
  470
  471colourise_fullstop(TB, TermPos) :-
  472    arg(2, TermPos, EndTerm),
  473    Start is EndTerm,
  474    End is Start+1,
  475    colour_item(fullstop, TB, Start-End).
  476
  477colourise_comments(-, _).
  478colourise_comments([], _).
  479colourise_comments([H|T], TB) :-
  480    colourise_comment(H, TB),
  481    colourise_comments(T, TB).
  482
  483colourise_comment((-)-_, _) :- !.
  484colourise_comment(Pos-Comment, TB) :-
  485    comment_style(Comment, Style),
  486    stream_position_data(char_count, Pos, Start),
  487    string_length(Comment, Len),
  488    End is Start + Len + 1,
  489    colour_item(comment(Style), TB, Start-End).
  490
  491comment_style(Comment, structured) :-           % Starts %%, %! or /**
  492    structured_comment_start(Start),
  493    sub_string(Comment, 0, Len, _, Start),
  494    Next is Len+1,
  495    string_code(Next, Comment, NextCode),
  496    code_type(NextCode, space),
  497    !.
  498comment_style(Comment, line) :-                 % Starts %
  499    sub_string(Comment, 0, _, _, '%'),
  500    !.
  501comment_style(_, block).                        % Starts /*
 structured_comment_start(-Start)
Copied from library(pldoc/doc_process). Unfortunate, but we do not want to force loading pldoc.
  508structured_comment_start('%%').
  509structured_comment_start('%!').
  510structured_comment_start('/**').
 colourise_term(+Term, +TB, +Pos)
Colorise a file toplevel term.
  516colourise_term(Var, TB, Start-End) :-
  517    var(Var),
  518    !,
  519    colour_item(instantiation_error, TB, Start-End).
  520colourise_term(_, _, Pos) :-
  521    var(Pos),
  522    !.
  523colourise_term(Term, TB, parentheses_term_position(PO,PC,Pos)) :-
  524    !,
  525    colour_item(parentheses, TB, PO-PC),
  526    colourise_term(Term, TB, Pos).
  527colourise_term(Term, TB, Pos) :-
  528    term_colours(Term, FuncSpec-ArgSpecs),
  529    !,
  530    Pos = term_position(F,T,FF,FT,ArgPos),
  531    colour_item(term, TB, F-T),     % TBD: Allow specifying by term_colours/2?
  532    specified_item(FuncSpec, Term, TB, FF-FT),
  533    specified_items(ArgSpecs, Term, TB, ArgPos).
  534colourise_term((Head :- Body), TB,
  535               term_position(F,T,FF,FT,[HP,BP])) :-
  536    !,
  537    colour_item(clause,         TB, F-T),
  538    colour_item(neck(clause),   TB, FF-FT),
  539    colourise_clause_head(Head, TB, HP),
  540    colourise_body(Body, Head,  TB, BP).
  541colourise_term(((Head,RHC) --> Body), TB,
  542               term_position(F,T,FF,FT,
  543                             [ term_position(_,_,_,_,[HP,RHCP]),
  544                               BP
  545                             ])) :-
  546    !,
  547    colour_item(grammar_rule,       TB, F-T),
  548    colour_item(dcg_right_hand_ctx, TB, RHCP),
  549    colourise_term_arg(RHC, TB, RHCP),
  550    colour_item(neck(grammar_rule), TB, FF-FT),
  551    colourise_extended_head(Head, 2, TB, HP),
  552    colourise_dcg(Body, Head,       TB, BP).
  553colourise_term((Head --> Body), TB,                     % TBD: expansion!
  554               term_position(F,T,FF,FT,[HP,BP])) :-
  555    !,
  556    colour_item(grammar_rule,       TB, F-T),
  557    colour_item(neck(grammar_rule), TB, FF-FT),
  558    colourise_extended_head(Head, 2, TB, HP),
  559    colourise_dcg(Body, Head,       TB, BP).
  560colourise_term(:->(Head, Body), TB,
  561               term_position(F,T,FF,FT,[HP,BP])) :-
  562    !,
  563    colour_item(method,             TB, F-T),
  564    colour_item(neck(method(send)), TB, FF-FT),
  565    colour_method_head(send(Head),  TB, HP),
  566    colourise_method_body(Body,     TB, BP).
  567colourise_term(:<-(Head, Body), TB,
  568               term_position(F,T,FF,FT,[HP,BP])) :-
  569    !,
  570    colour_item(method,            TB, F-T),
  571    colour_item(neck(method(get)), TB, FF-FT),
  572    colour_method_head(get(Head),  TB, HP),
  573    colourise_method_body(Body,    TB, BP).
  574colourise_term((:- Directive), TB, Pos) :-
  575    !,
  576    colour_item(directive, TB, Pos),
  577    Pos = term_position(_F,_T,FF,FT,[ArgPos]),
  578    colour_item(neck(directive), TB, FF-FT),
  579    colourise_directive(Directive, TB, ArgPos).
  580colourise_term((?- Directive), TB, Pos) :-
  581    !,
  582    colourise_term((:- Directive), TB, Pos).
  583colourise_term(end_of_file, _, _) :- !.
  584colourise_term(Fact, TB, Pos) :-
  585    !,
  586    colour_item(clause, TB, Pos),
  587    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.
  595colourise_extended_head(Head, N, TB, Pos) :-
  596    extend(Head, N, TheHead),
  597    colourise_clause_head(TheHead, TB, Pos).
  598
  599extend(M:Head, N, M:ExtHead) :-
  600    nonvar(Head),
  601    !,
  602    extend(Head, N, ExtHead).
  603extend(Head, N, ExtHead) :-
  604    compound(Head),
  605    !,
  606    compound_name_arguments(Head, Name, Args),
  607    length(Extra, N),
  608    append(Args, Extra, NArgs),
  609    compound_name_arguments(ExtHead, Name, NArgs).
  610extend(Head, N, ExtHead) :-
  611    atom(Head),
  612    !,
  613    length(Extra, N),
  614    compound_name_arguments(ExtHead, Head, Extra).
  615extend(Head, _, Head).
  616
  617
  618colourise_clause_head(_, _, Pos) :-
  619    var(Pos),
  620    !.
  621colourise_clause_head(Head, TB, parentheses_term_position(PO,PC,Pos)) :-
  622    colour_item(parentheses, TB, PO-PC),
  623    colourise_clause_head(Head, TB, Pos).
  624colourise_clause_head(M:Head, TB, QHeadPos) :-
  625    QHeadPos = term_position(_,_,QF,QT,[MPos,HeadPos]),
  626    head_colours(M:Head, meta-[_, ClassSpec-ArgSpecs]),
  627    !,
  628    colour_item(module(M), TB, MPos),
  629    colour_item(functor, TB, QF-QT),
  630    functor_position(HeadPos, FPos, ArgPos),
  631    (   ClassSpec == classify
  632    ->  classify_head(TB, Head, Class)
  633    ;   Class = ClassSpec
  634    ),
  635    colour_item(head_term(Class, Head), TB, QHeadPos),
  636    colour_item(head(Class, Head), TB, FPos),
  637    specified_items(ArgSpecs, Head, TB, ArgPos).
  638colourise_clause_head(Head, TB, Pos) :-
  639    head_colours(Head, ClassSpec-ArgSpecs),
  640    !,
  641    functor_position(Pos, FPos, ArgPos),
  642    (   ClassSpec == classify
  643    ->  classify_head(TB, Head, Class)
  644    ;   Class = ClassSpec
  645    ),
  646    colour_item(head_term(Class, Head), TB, Pos),
  647    colour_item(head(Class, Head), TB, FPos),
  648    specified_items(ArgSpecs, Head, TB, ArgPos).
  649colourise_clause_head(:=(Eval, Ret), TB,
  650                      term_position(_,_,AF,AT,
  651                                    [ term_position(_,_,SF,ST,
  652                                                    [ SelfPos,
  653                                                      FuncPos
  654                                                    ]),
  655                                      RetPos
  656                                    ])) :-
  657    Eval =.. [.,M,Func],
  658    FuncPos = term_position(_,_,FF,FT,_),
  659    !,
  660    colourise_term_arg(M, TB, SelfPos),
  661    colour_item(func_dot, TB, SF-ST),               % .
  662    colour_item(dict_function(Func), TB, FF-FT),
  663    colourise_term_args(Func, TB, FuncPos),
  664    colour_item(dict_return_op, TB, AF-AT),         % :=
  665    colourise_term_arg(Ret, TB, RetPos).
  666colourise_clause_head(Head, TB, Pos) :-
  667    functor_position(Pos, FPos, _),
  668    classify_head(TB, Head, Class),
  669    colour_item(head_term(Class, Head), TB, Pos),
  670    colour_item(head(Class, Head), TB, FPos),
  671    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.
  678colourise_extern_head(Head, M, TB, Pos) :-
  679    functor_position(Pos, FPos, _),
  680    colour_item(head(extern(M), Head), TB, FPos),
  681    colourise_term_args(Head, TB, Pos).
  682
  683colour_method_head(SGHead, TB, Pos) :-
  684    arg(1, SGHead, Head),
  685    functor_name(SGHead, SG),
  686    functor_position(Pos, FPos, _),
  687    colour_item(method(SG), TB, FPos),
  688    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'.
  695functor_position(term_position(_,_,FF,FT,ArgPos), FF-FT, ArgPos) :- !.
  696functor_position(list_position(F,_T,Elms,none), F-FT, Elms) :-
  697    !,
  698    FT is F + 1.
  699functor_position(dict_position(_,_,FF,FT,KVPos), FF-FT, KVPos) :- !.
  700functor_position(brace_term_position(F,T,Arg), F-T, [Arg]) :- !.
  701functor_position(Pos, Pos, []).
 colourise_directive(+Body, +TB, +Pos)
Colourise the body of a directive.
  708colourise_directive(_,_,Pos) :-
  709    var(Pos),
  710    !.
  711colourise_directive(Dir, TB, parentheses_term_position(PO,PC,Pos)) :-
  712    !,
  713    colour_item(parentheses, TB, PO-PC),
  714    colourise_directive(Dir, TB, Pos).
  715colourise_directive((A,B), TB, term_position(_,_,_,_,[PA,PB])) :-
  716    !,
  717    colourise_directive(A, TB, PA),
  718    colourise_directive(B, TB, PB).
  719colourise_directive(Body, TB, Pos) :-
  720    nonvar(Body),
  721    directive_colours(Body, ClassSpec-ArgSpecs),   % specified
  722    !,
  723    functor_position(Pos, FPos, ArgPos),
  724    (   ClassSpec == classify
  725    ->  goal_classification(TB, Body, [], Class)
  726    ;   Class = ClassSpec
  727    ),
  728    colour_item(goal(Class, Body), TB, FPos),
  729    specified_items(ArgSpecs, Body, TB, ArgPos).
  730colourise_directive(Body, TB, Pos) :-
  731    colourise_body(Body, TB, Pos).
  732
  733
  734%       colourise_body(+Body, +TB, +Pos)
  735%
  736%       Breaks down to colourise_goal/3.
  737
  738colourise_body(Body, TB, Pos) :-
  739    colourise_body(Body, [], TB, Pos).
  740
  741colourise_body(Body, Origin, TB, Pos) :-
  742    colour_item(body, TB, Pos),
  743    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.
  752colourise_method_body(_, _, Pos) :-
  753    var(Pos),
  754    !.
  755colourise_method_body(Body, TB, parentheses_term_position(PO,PC,Pos)) :-
  756    !,
  757    colour_item(parentheses, TB, PO-PC),
  758    colourise_method_body(Body, TB, Pos).
  759colourise_method_body(::(_Comment,Body), TB,
  760                      term_position(_F,_T,_FF,_FT,[CP,BP])) :-
  761    !,
  762    colour_item(comment(string), TB, CP),
  763    colourise_body(Body, TB, BP).
  764colourise_method_body(Body, TB, Pos) :-         % deal with pri(::) < 1000
  765    Body =.. [F,A,B],
  766    control_op(F),
  767    !,
  768    Pos = term_position(_F,_T,FF,FT,
  769                        [ AP,
  770                          BP
  771                        ]),
  772    colour_item(control, TB, FF-FT),
  773    colourise_method_body(A, TB, AP),
  774    colourise_body(B, TB, BP).
  775colourise_method_body(Body, TB, Pos) :-
  776    colourise_body(Body, TB, Pos).
  777
  778control_op(',').
  779control_op((;)).
  780control_op((->)).
  781control_op((*->)).
 colourise_goals(+Body, +Origin, +TB, +Pos)
Colourise the goals in a body.
  787colourise_goals(_, _, _, Pos) :-
  788    var(Pos),
  789    !.
  790colourise_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  791    !,
  792    colour_item(parentheses, TB, PO-PC),
  793    colourise_goals(Body, Origin, TB, Pos).
  794colourise_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  795    body_compiled(Body),
  796    !,
  797    colour_item(control, TB, FF-FT),
  798    colourise_subgoals(ArgPos, 1, Body, Origin, TB).
  799colourise_goals(Goal, Origin, TB, Pos) :-
  800    colourise_goal(Goal, Origin, TB, Pos).
  801
  802colourise_subgoals([], _, _, _, _).
  803colourise_subgoals([Pos|T], N, Body, Origin, TB) :-
  804    arg(N, Body, Arg),
  805    colourise_goals(Arg, Origin, TB, Pos),
  806    NN is N + 1,
  807    colourise_subgoals(T, NN, Body, Origin, TB).
 colourise_dcg(+Body, +Head, +TB, +Pos)
Breaks down to colourise_dcg_goal/3.
  813colourise_dcg(Body, Head, TB, Pos) :-
  814    colour_item(dcg, TB, Pos),
  815    (   dcg_extend(Head, Origin)
  816    ->  true
  817    ;   Origin = Head
  818    ),
  819    colourise_dcg_goals(Body, Origin, TB, Pos).
  820
  821colourise_dcg_goals(Var, _, TB, Pos) :-
  822    var(Var),
  823    !,
  824    colour_item(goal(meta,Var), TB, Pos).
  825colourise_dcg_goals(_, _, _, Pos) :-
  826    var(Pos),
  827    !.
  828colourise_dcg_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  829    !,
  830    colour_item(parentheses, TB, PO-PC),
  831    colourise_dcg_goals(Body, Origin, TB, Pos).
  832colourise_dcg_goals({Body}, Origin, TB, brace_term_position(F,T,Arg)) :-
  833    !,
  834    colour_item(dcg(plain), TB, F-T),
  835    colourise_goals(Body, Origin, TB, Arg).
  836colourise_dcg_goals([], _, TB, Pos) :-
  837    !,
  838    colour_item(dcg(terminal), TB, Pos).
  839colourise_dcg_goals(List, _, TB, list_position(F,T,Elms,Tail)) :-
  840    List = [_|_],
  841    !,
  842    colour_item(dcg(terminal), TB, F-T),
  843    colourise_list_args(Elms, Tail, List, TB, classify).
  844colourise_dcg_goals(_, _, TB, string_position(F,T)) :-
  845    integer(F),
  846    !,
  847    colour_item(dcg(string), TB, F-T).
  848colourise_dcg_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  849    dcg_body_compiled(Body),       % control structures
  850    !,
  851    colour_item(control, TB, FF-FT),
  852    colourise_dcg_subgoals(ArgPos, 1, Body, Origin, TB).
  853colourise_dcg_goals(Goal, Origin, TB, Pos) :-
  854    colourise_dcg_goal(Goal, Origin, TB, Pos).
  855
  856colourise_dcg_subgoals([], _, _, _, _).
  857colourise_dcg_subgoals([Pos|T], N, Body, Origin, TB) :-
  858    arg(N, Body, Arg),
  859    colourise_dcg_goals(Arg, Origin, TB, Pos),
  860    NN is N + 1,
  861    colourise_dcg_subgoals(T, NN, Body, Origin, TB).
  862
  863dcg_extend(Term, _) :-
  864    var(Term), !, fail.
  865dcg_extend(M:Term, M:Goal) :-
  866    dcg_extend(Term, Goal).
  867dcg_extend(Term, Goal) :-
  868    compound(Term),
  869    !,
  870    compound_name_arguments(Term, Name, Args),
  871    append(Args, [_,_], NArgs),
  872    compound_name_arguments(Goal, Name, NArgs).
  873dcg_extend(Term, Goal) :-
  874    atom(Term),
  875    !,
  876    compound_name_arguments(Goal, Term, [_,_]).
  877
  878dcg_body_compiled(G) :-
  879    body_compiled(G),
  880    !.
  881dcg_body_compiled((_|_)).
  882
  883%       colourise_dcg_goal(+Goal, +Origin, +TB, +Pos).
  884
  885colourise_dcg_goal(!, Origin, TB, TermPos) :-
  886    !,
  887    colourise_goal(!, Origin, TB, TermPos).
  888colourise_dcg_goal(Goal, Origin, TB, TermPos) :-
  889    dcg_extend(Goal, TheGoal),
  890    !,
  891    colourise_goal(TheGoal, Origin, TB, TermPos).
  892colourise_dcg_goal(Goal, _, TB, Pos) :-
  893    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.
  904                                        % Deal with list as goal (consult)
  905colourise_goal(_,_,_,Pos) :-
  906    var(Pos),
  907    !.
  908colourise_goal(Goal, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  909    !,
  910    colour_item(parentheses, TB, PO-PC),
  911    colourise_goal(Goal, Origin, TB, Pos).
  912colourise_goal(Goal, _, TB, Pos) :-
  913    Pos = list_position(F,T,Elms,_),
  914    Goal = [_|_],
  915    !,
  916    FT is F + 1,
  917    AT is T - 1,
  918    colour_item(goal_term(built_in, Goal), TB, Pos),
  919    colour_item(goal(built_in, Goal), TB, F-FT),
  920    colour_item(goal(built_in, Goal), TB, AT-T),
  921    colourise_file_list(Goal, TB, Elms, any).
  922colourise_goal(Goal, Origin, TB, Pos) :-
  923    Pos = list_position(F,T,Elms,Tail),
  924    callable(Goal),
  925    Goal =.. [_,GH,GT|_],
  926    !,
  927    goal_classification(TB, Goal, Origin, Class),
  928    FT is F + 1,
  929    AT is T - 1,
  930    colour_item(goal_term(Class, Goal), TB, Pos),
  931    colour_item(goal(Class, Goal), TB, F-FT),
  932    colour_item(goal(Class, Goal), TB, AT-T),
  933    colourise_list_args(Elms, Tail, [GH|GT], TB, classify).
  934colourise_goal(Goal, _Origin, TB, Pos) :-
  935    Pos = quasi_quotation_position(_F,_T,_QQType,_QQTypePos,_CPos),
  936    !,
  937    colourise_term_arg(Goal, TB, Pos).
  938colourise_goal(Goal, Origin, TB, Pos) :-
  939    strip_module(Goal, _, PGoal),
  940    nonvar(PGoal),
  941    (   goal_classification(TB, Goal, Origin, ClassInferred),
  942        goal_colours(Goal, ClassInferred, ClassSpec-ArgSpecs)
  943    ->  true
  944    ;   goal_colours(Goal, ClassSpec-ArgSpecs)
  945    ),
  946    !,                                          % specified
  947    functor_position(Pos, FPos, ArgPos),
  948    (   ClassSpec == classify
  949    ->  goal_classification(TB, Goal, Origin, Class)
  950    ;   Class = ClassSpec
  951    ),
  952    colour_item(goal_term(Class, Goal), TB, Pos),
  953    colour_item(goal(Class, Goal), TB, FPos),
  954    colour_dict_braces(TB, Pos),
  955    specified_items(ArgSpecs, Goal, TB, ArgPos).
  956colourise_goal(Module:Goal, _Origin, TB, QGoalPos) :-
  957    QGoalPos = term_position(_,_,QF,QT,[PM,PG]),
  958    !,
  959    colour_item(module(Module), TB, PM),
  960    colour_item(functor, TB, QF-QT),
  961    (   PG = term_position(_,_,FF,FT,_)
  962    ->  FP = FF-FT
  963    ;   FP = PG
  964    ),
  965    (   callable(Goal)
  966    ->  qualified_goal_classification(Module:Goal, TB, Class),
  967        colour_item(goal_term(Class, Goal), TB, QGoalPos),
  968        colour_item(goal(Class, Goal), TB, FP),
  969        colourise_goal_args(Goal, Module, TB, PG)
  970    ;   var(Goal)
  971    ->  colourise_term_arg(Goal, TB, PG)
  972    ;   colour_item(type_error(callable), TB, PG)
  973    ).
  974colourise_goal(Op, _Origin, TB, Pos) :-
  975    nonvar(Op),
  976    Op = op(_,_,_),
  977    !,
  978    colourise_op_declaration(Op, TB, Pos).
  979colourise_goal(Goal, Origin, TB, Pos) :-
  980    goal_classification(TB, Goal, Origin, Class),
  981    (   Pos = term_position(_,_,FF,FT,_ArgPos)
  982    ->  FPos = FF-FT
  983    ;   FPos = Pos
  984    ),
  985    colour_item(goal_term(Class, Goal), TB, Pos),
  986    colour_item(goal(Class, Goal), TB, FPos),
  987    colourise_goal_args(Goal, TB, Pos).
  988
  989% make sure to emit a fragment for the braces of tag{k:v, ...} or
  990% {...} that is mapped to something else.
  991
  992colour_dict_braces(TB, dict_position(_F,T,_TF,TT,_KVPos)) :-
  993    !,
  994    BStart is TT+1,
  995    colour_item(dict_content, TB, BStart-T).
  996colour_dict_braces(TB, brace_term_position(F,T,_Arg)) :-
  997    !,
  998    colour_item(brace_term, TB, F-T).
  999colour_dict_braces(_, _).
 colourise_goal_args(+Goal, +TB, +Pos)
Colourise the arguments to a goal. This predicate deals with meta- and database-access predicates.
 1006colourise_goal_args(Goal, TB, Pos) :-
 1007    colourization_module(TB, Module),
 1008    colourise_goal_args(Goal, Module, TB, Pos).
 1009
 1010colourization_module(TB, Module) :-
 1011    (   colour_state_source_id(TB, SourceId),
 1012        xref_module(SourceId, Module)
 1013    ->  true
 1014    ;   Module = user
 1015    ).
 1016
 1017colourise_goal_args(Goal, M, TB, term_position(_,_,_,_,ArgPos)) :-
 1018    !,
 1019    (   meta_args(Goal, TB, MetaArgs)
 1020    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, ArgPos)
 1021    ;   colourise_goal_args(1, Goal, M, TB, ArgPos)
 1022    ).
 1023colourise_goal_args(Goal, M, TB, brace_term_position(_,_,ArgPos)) :-
 1024    !,
 1025    (   meta_args(Goal, TB, MetaArgs)
 1026    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, [ArgPos])
 1027    ;   colourise_goal_args(1, Goal, M, TB, [ArgPos])
 1028    ).
 1029colourise_goal_args(_, _, _, _).                % no arguments
 1030
 1031colourise_goal_args(_, _, _, _, []) :- !.
 1032colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1033    colourise_option_arg(Goal, Module, N, TB, P0),
 1034    !,
 1035    NN is N + 1,
 1036    colourise_goal_args(NN, Goal, Module, TB, PT).
 1037colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1038    arg(N, Goal, Arg),
 1039    colourise_term_arg(Arg, TB, P0),
 1040    NN is N + 1,
 1041    colourise_goal_args(NN, Goal, Module, TB, PT).
 1042
 1043
 1044colourise_meta_args(_, _, _, _, _, []) :- !.
 1045colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1046    colourise_option_arg(Goal, Module, N, TB, P0),
 1047    !,
 1048    NN is N + 1,
 1049    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1050colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1051    arg(N, Goal, Arg),
 1052    arg(N, MetaArgs, MetaSpec),
 1053    colourise_meta_arg(MetaSpec, Arg, TB, P0),
 1054    NN is N + 1,
 1055    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1056
 1057colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1058    expand_meta(MetaSpec, Arg, Expanded),
 1059    !,
 1060    colourise_goal(Expanded, [], TB, Pos). % TBD: recursion
 1061colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1062    MetaSpec == //,
 1063    !,
 1064    colourise_dcg_goals(Arg, //, TB, Pos).
 1065colourise_meta_arg(_, Arg, TB, Pos) :-
 1066    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.

 1079meta_args(Goal, TB, VarGoal) :-
 1080    colour_state_source_id(TB, SourceId),
 1081    xref_meta(SourceId, Goal, _),
 1082    !,
 1083    compound_name_arity(Goal, Name, Arity),
 1084    compound_name_arity(VarGoal, Name, Arity),
 1085    xref_meta(SourceId, VarGoal, MetaArgs),
 1086    instantiate_meta(MetaArgs).
 1087
 1088instantiate_meta([]).
 1089instantiate_meta([H|T]) :-
 1090    (   var(H)
 1091    ->  H = 0
 1092    ;   H = V+N
 1093    ->  V = N
 1094    ;   H = //(V)
 1095    ->  V = (//)
 1096    ),
 1097    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).
 1104expand_meta(MetaSpec, Goal, Goal) :-
 1105    MetaSpec == 0.
 1106expand_meta(MetaSpec, M:Goal, M:Expanded) :-
 1107    atom(M),
 1108    !,
 1109    expand_meta(MetaSpec, Goal, Expanded).
 1110expand_meta(MetaSpec, Goal, Expanded) :-
 1111    integer(MetaSpec),
 1112    callable(Goal),
 1113    !,
 1114    length(Extra, MetaSpec),
 1115    Goal =.. List0,
 1116    append(List0, Extra, List),
 1117    Expanded =.. List.
 colourise_setof(+Term, +TB, +Pos)
Colourise the 2nd argument of setof/bagof
 1123colourise_setof(Var^G, TB, term_position(_,_,FF,FT,[VP,GP])) :-
 1124    !,
 1125    colourise_term_arg(Var, TB, VP),
 1126    colour_item(ext_quant, TB, FF-FT),
 1127    colourise_setof(G, TB, GP).
 1128colourise_setof(Term, TB, Pos) :-
 1129    colourise_goal(Term, [], TB, Pos).
 1130
 1131%       colourise_db(+Arg, +TB, +Pos)
 1132%
 1133%       Colourise database modification calls (assert/1, retract/1 and
 1134%       friends.
 1135
 1136colourise_db((Head:-_Body), TB, term_position(_,_,_,_,[HP,_])) :-
 1137    !,
 1138    colourise_db(Head, TB, HP).
 1139colourise_db(Module:Head, TB, term_position(_,_,QF,QT,[MP,HP])) :-
 1140    !,
 1141    colour_item(module(Module), TB, MP),
 1142    colour_item(functor, TB, QF-QT),
 1143    (   atom(Module),
 1144        colour_state_source_id(TB, SourceId),
 1145        xref_module(SourceId, Module)
 1146    ->  colourise_db(Head, TB, HP)
 1147    ;   colourise_db(Head, TB, HP)
 1148    ).
 1149colourise_db(Head, TB, Pos) :-
 1150    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
 1159colourise_option_arg(Goal, Module, Arg, TB, ArgPos) :-
 1160    goal_name_arity(Goal, Name, Arity),
 1161    current_option_arg(Module:Name/Arity, Arg),
 1162    current_predicate_options(Module:Name/Arity, Arg, OptionDecl),
 1163    debug(emacs, 'Colouring option-arg ~w of ~p',
 1164          [Arg, Module:Name/Arity]),
 1165    arg(Arg, Goal, Options),
 1166    colourise_option(Options, Module, Goal, Arg, OptionDecl, TB, ArgPos).
 1167
 1168colourise_option(Options0, Module, Goal, Arg, OptionDecl, TB, Pos0) :-
 1169    strip_option_module_qualifier(Goal, Module, Arg, TB,
 1170                                  Options0, Pos0, Options, Pos),
 1171    (   Pos = list_position(F, T, ElmPos, TailPos)
 1172    ->  colour_item(list, TB, F-T),
 1173        colourise_option_list(Options, OptionDecl, TB, ElmPos, TailPos)
 1174    ;   (   var(Options)
 1175        ;   Options == []
 1176        )
 1177    ->  colourise_term_arg(Options, TB, Pos)
 1178    ;   colour_item(type_error(list), TB, Pos)
 1179    ).
 1180
 1181strip_option_module_qualifier(Goal, Module, Arg, TB,
 1182                              M:Options, term_position(_,_,_,_,[MP,Pos]),
 1183                              Options, Pos) :-
 1184    predicate_property(Module:Goal, meta_predicate(Head)),
 1185    arg(Arg, Head, :),
 1186    !,
 1187    colour_item(module(M), TB, MP).
 1188strip_option_module_qualifier(_, _, _, _,
 1189                              Options, Pos, Options, Pos).
 1190
 1191
 1192colourise_option_list(_, _, _, [], none) :- !.
 1193colourise_option_list(Tail, _, TB, [], TailPos) :-
 1194    !,
 1195    colourise_term_arg(Tail, TB, TailPos).
 1196colourise_option_list([H|T], OptionDecl, TB, [HPos|TPos], TailPos) :-
 1197    colourise_option(H, OptionDecl, TB, HPos),
 1198    colourise_option_list(T, OptionDecl, TB, TPos, TailPos).
 1199
 1200colourise_option(Opt, _, TB, Pos) :-
 1201    var(Opt),
 1202    !,
 1203    colourise_term_arg(Opt, TB, Pos).
 1204colourise_option(Opt, OptionDecl, TB, term_position(_,_,FF,FT,ValPosList)) :-
 1205    !,
 1206    generalise_term(Opt, GenOpt),
 1207    (   memberchk(GenOpt, OptionDecl)
 1208    ->  colour_item(option_name, TB, FF-FT),
 1209        Opt =.. [Name|Values],
 1210        GenOpt =.. [Name|Types],
 1211        colour_option_values(Values, Types, TB, ValPosList)
 1212    ;   colour_item(no_option_name, TB, FF-FT),
 1213        colourise_term_args(ValPosList, 1, Opt, TB)
 1214    ).
 1215colourise_option(_, _, TB, Pos) :-
 1216    colour_item(type_error(option), TB, Pos).
 1217
 1218colour_option_values([], [], _, _).
 1219colour_option_values([V0|TV], [T0|TT], TB, [P0|TP]) :-
 1220    (   (   var(V0)
 1221        ;   is_of_type(T0, V0)
 1222        ;   T0 = list(_),
 1223            member(E, V0),
 1224            var(E)
 1225        ;   functor(V0, '.', 2),
 1226            V0 \= [_|_]
 1227        )
 1228    ->  colourise_term_arg(V0, TB, P0)
 1229    ;   callable(V0),
 1230        (   T0 = callable
 1231        ->  N = 0
 1232        ;   T0 = (callable+N)
 1233        )
 1234    ->  colourise_meta_arg(N, V0, TB, P0)
 1235    ;   colour_item(type_error(T0), TB, P0)
 1236    ),
 1237    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
 1246colourise_files(List, TB, list_position(F,T,Elms,_), Why) :-
 1247    !,
 1248    colour_item(list, TB, F-T),
 1249    colourise_file_list(List, TB, Elms, Why).
 1250colourise_files(M:Spec, TB, term_position(_,_,_,_,[MP,SP]), Why) :-
 1251    !,
 1252    colour_item(module(M), TB, MP),
 1253    colourise_files(Spec, TB, SP, Why).
 1254colourise_files(Var, TB, P, _) :-
 1255    var(Var),
 1256    !,
 1257    colour_item(var, TB, P).
 1258colourise_files(Spec0, TB, Pos, Why) :-
 1259    strip_module(Spec0, _, Spec),
 1260    (   colour_state_source_id(TB, Source),
 1261        prolog_canonical_source(Source, SourceId),
 1262        catch(xref_source_file(Spec, Path, SourceId, [silent(true)]),
 1263              _, fail)
 1264    ->  (   Why = imported,
 1265            \+ resolves_anything(TB, Path),
 1266            exports_something(TB, Path)
 1267        ->  colour_item(file_no_depend(Path), TB, Pos)
 1268        ;   colour_item(file(Path), TB, Pos)
 1269        )
 1270    ;   colour_item(nofile, TB, Pos)
 1271    ).
 1272
 1273colourise_file_list([], _, _, _).
 1274colourise_file_list([H|T], TB, [PH|PT], Why) :-
 1275    colourise_files(H, TB, PH, Why),
 1276    colourise_file_list(T, TB, PT, Why).
 1277
 1278resolves_anything(TB, Path) :-
 1279    colour_state_source_id(TB, SourceId),
 1280    xref_defined(SourceId, Head, imported(Path)),
 1281    xref_called(SourceId, Head, _),
 1282    !.
 1283
 1284exports_something(TB, Path) :-
 1285    colour_state_source_id(TB, SourceId),
 1286    xref_defined(SourceId, _, imported(Path)),
 1287    !.
 colourise_directory(+Arg, +TB, +Pos)
Colourise argument that should be an existing directory.
 1293colourise_directory(Spec, TB, Pos) :-
 1294    (   colour_state_source_id(TB, SourceId),
 1295        catch(xref_source_file(Spec, Path, SourceId,
 1296                               [ file_type(directory),
 1297                                 silent(true)
 1298                               ]),
 1299              _, fail)
 1300    ->  colour_item(directory(Path), TB, Pos)
 1301    ;   colour_item(nofile, TB, Pos)
 1302    ).
 colourise_langoptions(+Term, +TB, +Pos) is det
Colourise the 3th argument of module/3
 1308colourise_langoptions([], _, _) :- !.
 1309colourise_langoptions([H|T], TB, list_position(PF,PT,[HP|TP],_)) :-
 1310    !,
 1311    colour_item(list, TB, PF-PT),
 1312    colourise_langoptions(H, TB, HP),
 1313    colourise_langoptions(T, TB, TP).
 1314colourise_langoptions(Spec, TB, Pos) :-
 1315    colourise_files(library(dialect/Spec), TB, Pos, imported).
 colourise_class(ClassName, TB, Pos)
Colourise an XPCE class.
 1321colourise_class(ClassName, TB, Pos) :-
 1322    colour_state_source_id(TB, SourceId),
 1323    classify_class(SourceId, ClassName, Classification),
 1324    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.
 1332classify_class(SourceId, Name, Class) :-
 1333    xref_defined_class(SourceId, Name, Class),
 1334    !.
 1335classify_class(_SourceId, Name, Class) :-
 1336    current_predicate(pce:send_class/3),
 1337    (   current_predicate(classify_class/2)
 1338    ->  true
 1339    ;   use_module(library(pce_meta), [classify_class/2])
 1340    ),
 1341    member(G, [classify_class(Name, Class)]),
 1342    call(G).
 colourise_term_args(+Term, +TB, +Pos)
colourise head/body principal terms.
 1348colourise_term_args(Term, TB,
 1349                    term_position(_,_,_,_,ArgPos)) :-
 1350    !,
 1351    colourise_term_args(ArgPos, 1, Term, TB).
 1352colourise_term_args(_, _, _).
 1353
 1354colourise_term_args([], _, _, _).
 1355colourise_term_args([Pos|T], N, Term, TB) :-
 1356    arg(N, Term, Arg),
 1357    colourise_term_arg(Arg, TB, Pos),
 1358    NN is N + 1,
 1359    colourise_term_args(T, NN, Term, TB).
 1360
 1361colourise_term_arg(_, _, Pos) :-
 1362    var(Pos),
 1363    !.
 1364colourise_term_arg(Arg, TB, parentheses_term_position(PO,PC,Pos)) :-
 1365    !,
 1366    colour_item(parentheses, TB, PO-PC),
 1367    colourise_term_arg(Arg, TB, Pos).
 1368colourise_term_arg(Var, TB, Pos) :-                     % variable
 1369    var(Var), Pos = _-_,
 1370    !,
 1371    (   singleton(Var, TB)
 1372    ->  colour_item(singleton, TB, Pos)
 1373    ;   colour_item(var, TB, Pos)
 1374    ).
 1375colourise_term_arg(List, TB, list_position(F, T, Elms, Tail)) :-
 1376    !,
 1377    colour_item(list, TB, F-T),
 1378    colourise_list_args(Elms, Tail, List, TB, classify).    % list
 1379colourise_term_arg(String, TB, string_position(F, T)) :-       % string
 1380    !,
 1381    (   string(String)
 1382    ->  colour_item(string, TB, F-T)
 1383    ;   String = [H|_]
 1384    ->  (   integer(H)
 1385        ->  colour_item(codes, TB, F-T)
 1386        ;   colour_item(chars, TB, F-T)
 1387        )
 1388    ;   String == []
 1389    ->  colour_item(codes, TB, F-T)
 1390    ).
 1391colourise_term_arg(_, TB,
 1392                   quasi_quotation_position(F,T,QQType,QQTypePos,CPos)) :-
 1393    !,
 1394    colourise_qq_type(QQType, TB, QQTypePos),
 1395    functor_name(QQType, Type),
 1396    colour_item(qq_content(Type), TB, CPos),
 1397    arg(1, CPos, SE),
 1398    SS is SE-2,
 1399    FE is F+2,
 1400    TS is T-2,
 1401    colour_item(qq(open),  TB, F-FE),
 1402    colour_item(qq(sep),   TB, SS-SE),
 1403    colour_item(qq(close), TB, TS-T).
 1404colourise_term_arg({Term}, TB, brace_term_position(F,T,Arg)) :-
 1405    !,
 1406    colour_item(brace_term, TB, F-T),
 1407    colourise_term_arg(Term, TB, Arg).
 1408colourise_term_arg(Map, TB, dict_position(F,T,TF,TT,KVPos)) :-
 1409    !,
 1410    is_dict(Map, Tag),
 1411    colour_item(dict, TB, F-T),
 1412    TagPos = TF-TT,
 1413    (   var(Tag)
 1414    ->  (   singleton(Tag, TB)
 1415        ->  colour_item(singleton, TB, TagPos)
 1416        ;   colour_item(var, TB, TagPos)
 1417        )
 1418    ;   colour_item(dict_tag, TB, TagPos)
 1419    ),
 1420    BStart is TT+1,
 1421    colour_item(dict_content, TB, BStart-T),
 1422    colourise_dict_kv(Map, TB, KVPos).
 1423colourise_term_arg([](List,Term), TB,                   % [] as operator
 1424                   term_position(_,_,0,0,[ListPos,ArgPos])) :-
 1425    !,
 1426    colourise_term_arg(List, TB, ListPos),
 1427    colourise_term_arg(Term, TB, ArgPos).
 1428colourise_term_arg(Compound, TB, Pos) :-                % compound
 1429    compound(Compound),
 1430    !,
 1431    (   Pos = term_position(_F,_T,FF,FT,_ArgPos)
 1432    ->  colour_item(functor, TB, FF-FT)             % TBD: Infix/Postfix?
 1433    ;   true                                        % TBD: When is this
 1434    ),
 1435    colourise_term_args(Compound, TB, Pos).
 1436colourise_term_arg(EmptyList, TB, Pos) :-
 1437    EmptyList == [],
 1438    !,
 1439    colour_item(empty_list, TB, Pos).
 1440colourise_term_arg(Atom, TB, Pos) :-
 1441    atom(Atom),
 1442    !,
 1443    colour_item(atom, TB, Pos).
 1444colourise_term_arg(Integer, TB, Pos) :-
 1445    integer(Integer),
 1446    !,
 1447    colour_item(int, TB, Pos).
 1448colourise_term_arg(Float, TB, Pos) :-
 1449    float(Float),
 1450    !,
 1451    colour_item(float, TB, Pos).
 1452colourise_term_arg(_Arg, _TB, _Pos) :-
 1453    true.
 1454
 1455colourise_list_args([HP|TP], Tail, [H|T], TB, How) :-
 1456    specified_item(How, H, TB, HP),
 1457    colourise_list_args(TP, Tail, T, TB, How).
 1458colourise_list_args([], none, _, _, _) :- !.
 1459colourise_list_args([], TP, T, TB, How) :-
 1460    specified_item(How, T, TB, TP).
 colourise_qq_type(+QQType, +TB, +QQTypePos)
Colouring the type part of a quasi quoted term
 1466colourise_qq_type(QQType, TB, QQTypePos) :-
 1467    functor_position(QQTypePos, FPos, _),
 1468    colour_item(qq_type, TB, FPos),
 1469    colourise_term_args(QQType, TB, QQTypePos).
 1470
 1471qq_position(quasi_quotation_position(_,_,_,_,_)).
 colourise_dict_kv(+Dict, +TB, +KVPosList)
Colourise the name-value pairs in the dict
 1477colourise_dict_kv(_, _, []) :- !.
 1478colourise_dict_kv(Dict, TB, [key_value_position(_F,_T,SF,ST,K,KP,VP)|KV]) :-
 1479    colour_item(dict_key, TB, KP),
 1480    colour_item(dict_sep, TB, SF-ST),
 1481    get_dict(K, Dict, V),
 1482    colourise_term_arg(V, TB, VP),
 1483    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).
 1491colourise_exports([], _, _) :- !.
 1492colourise_exports(List, TB, list_position(F,T,ElmPos,Tail)) :-
 1493    !,
 1494    colour_item(list, TB, F-T),
 1495    (   Tail == none
 1496    ->  true
 1497    ;   colour_item(type_error(list), TB, Tail)
 1498    ),
 1499    colourise_exports2(List, TB, ElmPos).
 1500colourise_exports(_, TB, Pos) :-
 1501    colour_item(type_error(list), TB, Pos).
 1502
 1503colourise_exports2([G0|GT], TB, [P0|PT]) :-
 1504    !,
 1505    colourise_declaration(G0, TB, P0),
 1506    colourise_exports2(GT, TB, PT).
 1507colourise_exports2(_, _, _).
 colourise_imports(+List, +File, +TB, +Pos)
Colourise import list from use_module/2, importing from File.
 1514colourise_imports(List, File, TB, Pos) :-
 1515    (   colour_state_source_id(TB, SourceId),
 1516        ground(File),
 1517        catch(xref_public_list(File, SourceId,
 1518                               [ path(Path),
 1519                                 public(Public),
 1520                                 silent(true)
 1521                               ] ), _, fail)
 1522    ->  true
 1523    ;   Public = [],
 1524        Path = (-)
 1525    ),
 1526    colourise_imports(List, Path, Public, TB, Pos).
 1527
 1528colourise_imports([], _, _, TB, Pos) :-
 1529    !,
 1530    colour_item(empty_list, TB, Pos).
 1531colourise_imports(List, File, Public, TB, list_position(F,T,ElmPos,Tail)) :-
 1532    !,
 1533    colour_item(list, TB, F-T),
 1534    (   Tail == none
 1535    ->  true
 1536    ;   colour_item(type_error(list), TB, Tail)
 1537    ),
 1538    colourise_imports2(List, File, Public, TB, ElmPos).
 1539colourise_imports(except(Except), File, Public, TB,
 1540                  term_position(_,_,FF,FT,[LP])) :-
 1541    !,
 1542    colour_item(keyword(except), TB, FF-FT),
 1543    colourise_imports(Except, File, Public, TB, LP).
 1544colourise_imports(_, _, _, TB, Pos) :-
 1545    colour_item(type_error(list), TB, Pos).
 1546
 1547colourise_imports2([G0|GT], File, Public, TB, [P0|PT]) :-
 1548    !,
 1549    colourise_import(G0, File, TB, P0),
 1550    colourise_imports2(GT, File, Public, TB, PT).
 1551colourise_imports2(_, _, _, _, _).
 1552
 1553
 1554colourise_import(PI as Name, File, TB, term_position(_,_,FF,FT,[PP,NP])) :-
 1555    pi_to_term(PI, Goal),
 1556    !,
 1557    colour_item(goal(imported(File), Goal), TB, PP),
 1558    rename_goal(Goal, Name, NewGoal),
 1559    goal_classification(TB, NewGoal, [], Class),
 1560    colour_item(goal(Class, NewGoal), TB, NP),
 1561    colour_item(keyword(as), TB, FF-FT).
 1562colourise_import(PI, File, TB, Pos) :-
 1563    pi_to_term(PI, Goal),
 1564    colour_state_source_id(TB, SourceID),
 1565    (   \+ xref_defined(SourceID, Goal, imported(File))
 1566    ->  colour_item(undefined_import, TB, Pos)
 1567    ;   \+ xref_called(SourceID, Goal, _)
 1568    ->  colour_item(unused_import, TB, Pos)
 1569    ),
 1570    !.
 1571colourise_import(PI, _, TB, Pos) :-
 1572    colourise_declaration(PI, TB, Pos).
 colourise_declarations(+Term, +TB, +Pos)
Colourise the Predicate indicator lists of dynamic, multifile, etc declarations.
 1580colourise_declarations(List, TB, list_position(F,T,Elms,none)) :-
 1581    !,
 1582    colour_item(list, TB, F-T),
 1583    colourise_list_declarations(List, TB, Elms).
 1584colourise_declarations((Head,Tail), TB,
 1585                       term_position(_,_,_,_,[PH,PT])) :-
 1586    !,
 1587    colourise_declaration(Head, TB, PH),
 1588    colourise_declarations(Tail, TB, PT).
 1589colourise_declarations(Last, TB, Pos) :-
 1590    colourise_declaration(Last, TB, Pos).
 1591
 1592colourise_list_declarations([], _, []).
 1593colourise_list_declarations([H|T], TB, [HP|TP]) :-
 1594    colourise_declaration(H, TB, HP),
 1595    colourise_list_declarations(T, TB, TP).
 colourise_declaration(+Decl, +TB, +Pos) is det
Colourise declaration sequences as used by module/2, dynamic/1, etc.
 1602colourise_declaration(PI, TB, term_position(F,T,FF,FT,[NamePos,ArityPos])) :-
 1603    pi_to_term(PI, Goal),
 1604    !,
 1605    goal_classification(TB, Goal, [], Class),
 1606    colour_item(predicate_indicator(Class, Goal), TB, F-T),
 1607    colour_item(goal(Class, Goal), TB, NamePos),
 1608    colour_item(predicate_indicator, TB, FF-FT),
 1609    colour_item(arity, TB, ArityPos).
 1610colourise_declaration(Module:PI, TB,
 1611                      term_position(_,_,QF,QT,[PM,PG])) :-
 1612    atom(Module), pi_to_term(PI, Goal),
 1613    !,
 1614    colour_item(module(M), TB, PM),
 1615    colour_item(functor, TB, QF-QT),
 1616    colour_item(predicate_indicator(extern(M), Goal), TB, PG),
 1617    PG = term_position(_,_,FF,FT,[NamePos,ArityPos]),
 1618    colour_item(goal(extern(M), Goal), TB, NamePos),
 1619    colour_item(predicate_indicator, TB, FF-FT),
 1620    colour_item(arity, TB, ArityPos).
 1621colourise_declaration(op(N,T,P), TB, Pos) :-
 1622    colour_item(exported_operator, TB, Pos),
 1623    colourise_op_declaration(op(N,T,P), TB, Pos).
 1624colourise_declaration(_, TB, Pos) :-
 1625    colour_item(type_error(export_declaration), TB, Pos).
 1626
 1627pi_to_term(Name/Arity, Term) :-
 1628    atom(Name), integer(Arity), Arity >= 0,
 1629    !,
 1630    functor(Term, Name, Arity).
 1631pi_to_term(Name//Arity0, Term) :-
 1632    atom(Name), integer(Arity0), Arity0 >= 0,
 1633    !,
 1634    Arity is Arity0 + 2,
 1635    functor(Term, Name, Arity).
 1636
 1637colourise_meta_declarations((Head,Tail), Extra, TB,
 1638                            term_position(_,_,_,_,[PH,PT])) :-
 1639    !,
 1640    colourise_meta_declaration(Head, Extra, TB, PH),
 1641    colourise_meta_declarations(Tail, Extra, TB, PT).
 1642colourise_meta_declarations(Last, Extra, TB, Pos) :-
 1643    colourise_meta_declaration(Last, Extra, TB, Pos).
 1644
 1645colourise_meta_declaration(M:Head, Extra, TB,
 1646                           term_position(_,_,QF,QT,
 1647                                         [ MP,
 1648                                           term_position(_,_,FF,FT,ArgPos)
 1649                                         ])) :-
 1650    !,
 1651    colour_item(module(M), TB, MP),
 1652    colour_item(functor, TB, QF-QT),
 1653    colour_item(goal(extern(M),Head), TB, FF-FT),
 1654    Head =.. [_|Args],
 1655    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1656colourise_meta_declaration(Head, Extra, TB, term_position(_,_,FF,FT,ArgPos)) :-
 1657    !,
 1658    goal_classification(TB, Head, [], Class),
 1659    colour_item(goal(Class, Head), TB, FF-FT),
 1660    Head =.. [_|Args],
 1661    colourise_meta_decls(Args, Extra, TB, ArgPos).
 1662colourise_meta_declaration([H|T], Extra, TB, list_position(LF,LT,[HP],TP)) :-
 1663    !,
 1664    colour_item(list, TB, LF-LT),
 1665    colourise_meta_decls([H,T], Extra, TB, [HP,TP]).
 1666colourise_meta_declaration(_, _, TB, Pos) :-
 1667    !,
 1668    colour_item(type_error(compound), TB, Pos).
 1669
 1670colourise_meta_decls([], _, _, []).
 1671colourise_meta_decls([Arg|ArgT], Extra, TB, [PosH|PosT]) :-
 1672    colourise_meta_decl(Arg, Extra, TB, PosH),
 1673    colourise_meta_decls(ArgT, Extra, TB, PosT).
 1674
 1675colourise_meta_decl(Arg, Extra, TB, Pos) :-
 1676    nonvar(Arg),
 1677    (   valid_meta_decl(Arg)
 1678    ->  true
 1679    ;   memberchk(Arg, Extra)
 1680    ),
 1681    colour_item(meta(Arg), TB, Pos).
 1682colourise_meta_decl(_, _, TB, Pos) :-
 1683    colour_item(error, TB, Pos).
 1684
 1685valid_meta_decl(:).
 1686valid_meta_decl(*).
 1687valid_meta_decl(//).
 1688valid_meta_decl(^).
 1689valid_meta_decl(?).
 1690valid_meta_decl(+).
 1691valid_meta_decl(-).
 1692valid_meta_decl(I) :- integer(I), between(0,9,I).
 colourise_op_declaration(Op, TB, Pos) is det
 1696colourise_op_declaration(op(P,T,N), TB, term_position(_,_,FF,FT,[PP,TP,NP])) :-
 1697    colour_item(goal(built_in, op(N,T,P)), TB, FF-FT),
 1698    colour_op_priority(P, TB, PP),
 1699    colour_op_type(T, TB, TP),
 1700    colour_op_name(N, TB, NP).
 1701
 1702colour_op_name(_, _, Pos) :-
 1703    var(Pos),
 1704    !.
 1705colour_op_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 1706    !,
 1707    colour_item(parentheses, TB, PO-PC),
 1708    colour_op_name(Name, TB, Pos).
 1709colour_op_name(Name, TB, Pos) :-
 1710    var(Name),
 1711    !,
 1712    colour_item(var, TB, Pos).
 1713colour_op_name(Name, TB, Pos) :-
 1714    (atom(Name) ; Name == []),
 1715    !,
 1716    colour_item(identifier, TB, Pos).
 1717colour_op_name(Module:Name, TB, term_position(_F,_T,QF,QT,[MP,NP])) :-
 1718    !,
 1719    colour_item(module(Module), TB, MP),
 1720    colour_item(functor, TB, QF-QT),
 1721    colour_op_name(Name, TB, NP).
 1722colour_op_name(List, TB, list_position(F,T,Elems,none)) :-
 1723    !,
 1724    colour_item(list, TB, F-T),
 1725    colour_op_names(List, TB, Elems).
 1726colour_op_name(_, TB, Pos) :-
 1727    colour_item(error, TB, Pos).
 1728
 1729colour_op_names([], _, []).
 1730colour_op_names([H|T], TB, [HP|TP]) :-
 1731    colour_op_name(H, TB, HP),
 1732    colour_op_names(T, TB, TP).
 1733
 1734colour_op_type(Type, TB, Pos) :-
 1735    var(Type),
 1736    !,
 1737    colour_item(var, TB, Pos).
 1738colour_op_type(Type, TB, Pos) :-
 1739    op_type(Type),
 1740    !,
 1741    colour_item(op_type(Type), TB, Pos).
 1742colour_op_type(_, TB, Pos) :-
 1743    colour_item(error, TB, Pos).
 1744
 1745colour_op_priority(Priority, TB, Pos) :-
 1746    var(Priority), colour_item(var, TB, Pos).
 1747colour_op_priority(Priority, TB, Pos) :-
 1748    integer(Priority),
 1749    between(0, 1200, Priority),
 1750    !,
 1751    colour_item(int, TB, Pos).
 1752colour_op_priority(_, TB, Pos) :-
 1753    colour_item(error, TB, Pos).
 1754
 1755op_type(fx).
 1756op_type(fy).
 1757op_type(xf).
 1758op_type(yf).
 1759op_type(xfy).
 1760op_type(xfx).
 1761op_type(yfx).
 colourise_prolog_flag_name(+Name, +TB, +Pos)
Colourise the name of a Prolog flag
 1768colourise_prolog_flag_name(_, _, Pos) :-
 1769    var(Pos),
 1770    !.
 1771colourise_prolog_flag_name(Name, TB, parentheses_term_position(PO,PC,Pos)) :-
 1772    !,
 1773    colour_item(parentheses, TB, PO-PC),
 1774    colourise_prolog_flag_name(Name, TB, Pos).
 1775colourise_prolog_flag_name(Name, TB, Pos) :-
 1776    atom(Name),
 1777    !,
 1778    (   current_prolog_flag(Name, _)
 1779    ->  colour_item(flag_name(Name), TB, Pos)
 1780    ;   colour_item(no_flag_name(Name), TB, Pos)
 1781    ).
 1782colourise_prolog_flag_name(Name, TB, Pos) :-
 1783    colourise_term(Name, TB, Pos).
 1784
 1785
 1786                 /*******************************
 1787                 *        CONFIGURATION         *
 1788                 *******************************/
 1789
 1790%       body_compiled(+Term)
 1791%
 1792%       Succeeds if term is a construct handled by the compiler.
 1793
 1794body_compiled((_,_)).
 1795body_compiled((_->_)).
 1796body_compiled((_*->_)).
 1797body_compiled((_;_)).
 1798body_compiled(\+_).
 goal_classification(+TB, +Goal, +Origin, -Class)
Classify Goal appearing in TB and called from a clause with head Origin. For directives, Origin is [].
 1805goal_classification(_, QGoal, _, Class) :-
 1806    strip_module(QGoal, _, Goal),
 1807    (   var(Goal)
 1808    ->  !, Class = meta
 1809    ;   \+ callable(Goal)
 1810    ->  !, Class = not_callable
 1811    ).
 1812goal_classification(_, Goal, Origin, recursion) :-
 1813    callable(Origin),
 1814    generalise_term(Goal, Origin),
 1815    !.
 1816goal_classification(TB, Goal, _, How) :-
 1817    colour_state_source_id(TB, SourceId),
 1818    xref_defined(SourceId, Goal, How),
 1819    How \= public(_),
 1820    !.
 1821goal_classification(_TB, Goal, _, Class) :-
 1822    goal_classification(Goal, Class),
 1823    !.
 1824goal_classification(TB, Goal, _, How) :-
 1825    colour_state_module(TB, Module),
 1826    atom(Module),
 1827    Module \== prolog_colour_ops,
 1828    predicate_property(Module:Goal, imported_from(From)),
 1829    !,
 1830    How = imported(From).
 1831goal_classification(_TB, _Goal, _, undefined).
 goal_classification(+Goal, -Class)
Multifile hookable classification for non-local goals.
 1837goal_classification(Goal, built_in) :-
 1838    built_in_predicate(Goal),
 1839    !.
 1840goal_classification(Goal, autoload(From)) :-    % SWI-Prolog
 1841    predicate_property(Goal, autoload(From)).
 1842goal_classification(Goal, global) :-            % SWI-Prolog
 1843    strip_module(Goal, _, PGoal),
 1844    current_predicate(_, user:PGoal),
 1845    !.
 1846goal_classification(Goal, Class) :-
 1847    compound(Goal),
 1848    compound_name_arity(Goal, Name, Arity),
 1849    vararg_goal_classification(Name, Arity, Class).
 vararg_goal_classification(+Name, +Arity, -Class) is semidet
Multifile hookable classification for vararg predicates.
 1855vararg_goal_classification(call, Arity, built_in) :-
 1856    Arity >= 1.
 1857vararg_goal_classification(send_super, Arity, expanded) :- % XPCE (TBD)
 1858    Arity >= 2.
 1859vararg_goal_classification(get_super, Arity, expanded) :-  % XPCE (TBD)
 1860    Arity >= 3.
 qualified_goal_classification(:Goal, +TB, -Class)
Classify an explicitly qualified goal.
 1866qualified_goal_classification(Goal, TB, Class) :-
 1867    goal_classification(TB, Goal, [], Class),
 1868    Class \== undefined,
 1869    !.
 1870qualified_goal_classification(Module:Goal, _, extern(Module, How)) :-
 1871    predicate_property(Module:Goal, visible),
 1872    !,
 1873    (   (   predicate_property(Module:Goal, public)
 1874        ;   predicate_property(Module:Goal, exported)
 1875        )
 1876    ->  How = (public)
 1877    ;   How = (private)
 1878    ).
 1879qualified_goal_classification(Module:_, _, extern(Module, unknown)).
 classify_head(+TB, +Head, -Class)
Classify a clause head
 1885classify_head(TB, Goal, exported) :-
 1886    colour_state_source_id(TB, SourceId),
 1887    xref_exported(SourceId, Goal),
 1888    !.
 1889classify_head(_TB, Goal, hook) :-
 1890    xref_hook(Goal),
 1891    !.
 1892classify_head(TB, Goal, hook) :-
 1893    colour_state_source_id(TB, SourceId),
 1894    xref_module(SourceId, M),
 1895    xref_hook(M:Goal),
 1896    !.
 1897classify_head(TB, Goal, Class) :-
 1898    built_in_predicate(Goal),
 1899    (   system_module(TB)
 1900    ->  (   predicate_property(system:Goal, iso)
 1901        ->  Class = def_iso
 1902        ;   goal_name(Goal, Name),
 1903            \+ sub_atom(Name, 0, _, _, $)
 1904        ->  Class = def_swi
 1905        )
 1906    ;   (   predicate_property(system:Goal, iso)
 1907        ->  Class = iso
 1908        ;   Class = built_in
 1909        )
 1910    ).
 1911classify_head(TB, Goal, unreferenced) :-
 1912    colour_state_source_id(TB, SourceId),
 1913    \+ (xref_called(SourceId, Goal, By), By \= Goal),
 1914    !.
 1915classify_head(TB, Goal, How) :-
 1916    colour_state_source_id(TB, SourceId),
 1917    (   xref_defined(SourceId, Goal, imported(From))
 1918    ->  How = imported(From)
 1919    ;   xref_defined(SourceId, Goal, How)
 1920    ),
 1921    !.
 1922classify_head(_TB, _Goal, undefined).
 1923
 1924built_in_predicate(Goal) :-
 1925    predicate_property(system:Goal, built_in),
 1926    !.
 1927built_in_predicate(module(_, _)).       % reserved expanded constructs
 1928built_in_predicate(module(_, _, _)).
 1929built_in_predicate(if(_)).
 1930built_in_predicate(elif(_)).
 1931built_in_predicate(else).
 1932built_in_predicate(endif).
 1933
 1934goal_name(_:G, Name) :- nonvar(G), !, goal_name(G, Name).
 1935goal_name(G, Name) :- callable(G), functor_name(G, Name).
 1936
 1937system_module(TB) :-
 1938    colour_state_source_id(TB, SourceId),
 1939    xref_module(SourceId, M),
 1940    module_property(M, class(system)).
 1941
 1942generalise_term(Specific, General) :-
 1943    (   compound(Specific)
 1944    ->  compound_name_arity(Specific, Name, Arity),
 1945        compound_name_arity(General0, Name, Arity),
 1946        General = General0
 1947    ;   General = Specific
 1948    ).
 1949
 1950rename_goal(Goal0, Name, Goal) :-
 1951    (   compound(Goal0)
 1952    ->  compound_name_arity(Goal0, _, Arity),
 1953        compound_name_arity(Goal, Name, Arity)
 1954    ;   Goal = Name
 1955    ).
 1956
 1957functor_name(Term, Name) :-
 1958    (   compound(Term)
 1959    ->  compound_name_arity(Term, Name, _)
 1960    ;   atom(Term)
 1961    ->  Name = Term
 1962    ).
 1963
 1964goal_name_arity(Goal, Name, Arity) :-
 1965    (   compound(Goal)
 1966    ->  compound_name_arity(Goal, Name, Arity)
 1967    ;   atom(Goal)
 1968    ->  Name = Goal, Arity = 0
 1969    ).
 1970
 1971
 1972%       Specify colours for individual goals.
 1973
 1974goal_colours(module(_,_),            built_in-[identifier,exports]).
 1975goal_colours(module(_,_,_),          built_in-[identifier,exports,langoptions]).
 1976goal_colours(use_module(_),          built_in-[imported_file]).
 1977goal_colours(use_module(File,_),     built_in-[file,imports(File)]).
 1978goal_colours(reexport(_),            built_in-[file]).
 1979goal_colours(reexport(File,_),       built_in-[file,imports(File)]).
 1980goal_colours(dynamic(_),             built_in-[predicates]).
 1981goal_colours(thread_local(_),        built_in-[predicates]).
 1982goal_colours(module_transparent(_),  built_in-[predicates]).
 1983goal_colours(discontiguous(_),       built_in-[predicates]).
 1984goal_colours(multifile(_),           built_in-[predicates]).
 1985goal_colours(volatile(_),            built_in-[predicates]).
 1986goal_colours(public(_),              built_in-[predicates]).
 1987goal_colours(meta_predicate(_),      built_in-[meta_declarations]).
 1988goal_colours(consult(_),             built_in-[file]).
 1989goal_colours(include(_),             built_in-[file]).
 1990goal_colours(ensure_loaded(_),       built_in-[file]).
 1991goal_colours(load_files(_),          built_in-[file]).
 1992goal_colours(load_files(_,_),        built_in-[file,options]).
 1993goal_colours(setof(_,_,_),           built_in-[classify,setof,classify]).
 1994goal_colours(bagof(_,_,_),           built_in-[classify,setof,classify]).
 1995goal_colours(predicate_options(_,_,_), built_in-[predicate,classify,classify]).
 1996% Database access
 1997goal_colours(assert(_),              built_in-[db]).
 1998goal_colours(asserta(_),             built_in-[db]).
 1999goal_colours(assertz(_),             built_in-[db]).
 2000goal_colours(assert(_,_),            built_in-[db,classify]).
 2001goal_colours(asserta(_,_),           built_in-[db,classify]).
 2002goal_colours(assertz(_,_),           built_in-[db,classify]).
 2003goal_colours(retract(_),             built_in-[db]).
 2004goal_colours(retractall(_),          built_in-[db]).
 2005goal_colours(clause(_,_),            built_in-[db,classify]).
 2006goal_colours(clause(_,_,_),          built_in-[db,classify,classify]).
 2007% misc
 2008goal_colours(set_prolog_flag(_,_),   built_in-[prolog_flag_name,classify]).
 2009goal_colours(current_prolog_flag(_,_), built_in-[prolog_flag_name,classify]).
 2010% XPCE stuff
 2011goal_colours(pce_autoload(_,_),      classify-[classify,file]).
 2012goal_colours(pce_image_directory(_), classify-[directory]).
 2013goal_colours(new(_, _),              built_in-[classify,pce_new]).
 2014goal_colours(send_list(_,_,_),       built_in-pce_arg_list).
 2015goal_colours(send(_,_),              built_in-[pce_arg,pce_selector]).
 2016goal_colours(get(_,_,_),             built_in-[pce_arg,pce_selector,pce_arg]).
 2017goal_colours(send_super(_,_),        built_in-[pce_arg,pce_selector]).
 2018goal_colours(get_super(_,_),         built_in-[pce_arg,pce_selector,pce_arg]).
 2019goal_colours(get_chain(_,_,_),       built_in-[pce_arg,pce_selector,pce_arg]).
 2020goal_colours(Pce,                    built_in-pce_arg) :-
 2021    compound(Pce),
 2022    functor_name(Pce, Functor),
 2023    pce_functor(Functor).
 2024
 2025pce_functor(send).
 2026pce_functor(get).
 2027pce_functor(send_super).
 2028pce_functor(get_super).
 2029
 2030
 2031                 /*******************************
 2032                 *        SPECIFIC HEADS        *
 2033                 *******************************/
 2034
 2035head_colours(file_search_path(_,_), hook-[identifier,classify]).
 2036head_colours(library_directory(_),  hook-[file]).
 2037head_colours(resource(_,_,_),       hook-[identifier,classify,file]).
 2038
 2039head_colours(Var, _) :-
 2040    var(Var),
 2041    !,
 2042    fail.
 2043head_colours(M:H, Colours) :-
 2044    M == user,
 2045    head_colours(H, HC),
 2046    HC = hook - _,
 2047    !,
 2048    Colours = meta-[module(user), HC ].
 2049head_colours(M:H, Colours) :-
 2050    atom(M), callable(H),
 2051    xref_hook(M:H),
 2052    !,
 2053    Colours = meta-[module(M), hook-classify ].
 2054head_colours(M:_, meta-[module(M),extern(M)]).
 2055
 2056
 2057                 /*******************************
 2058                 *             STYLES           *
 2059                 *******************************/
 def_style(+Pattern, -Style)
Define the style used for the given pattern. Definitions here can be overruled by defining rules for style/2
 2067def_style(goal(built_in,_),        [colour(blue)]).
 2068def_style(goal(imported(_),_),     [colour(blue)]).
 2069def_style(goal(autoload(_),_),     [colour(navy_blue)]).
 2070def_style(goal(global,_),          [colour(navy_blue)]).
 2071def_style(goal(undefined,_),       [colour(red)]).
 2072def_style(goal(thread_local(_),_), [colour(magenta), underline(true)]).
 2073def_style(goal(dynamic(_),_),      [colour(magenta)]).
 2074def_style(goal(multifile(_),_),    [colour(navy_blue)]).
 2075def_style(goal(expanded,_),        [colour(blue), underline(true)]).
 2076def_style(goal(extern(_),_),       [colour(blue), underline(true)]).
 2077def_style(goal(extern(_,private),_), [colour(red)]).
 2078def_style(goal(extern(_,public),_), [colour(blue)]).
 2079def_style(goal(recursion,_),       [underline(true)]).
 2080def_style(goal(meta,_),            [colour(red4)]).
 2081def_style(goal(foreign(_),_),      [colour(darkturquoise)]).
 2082def_style(goal(local(_),_),        []).
 2083def_style(goal(constraint(_),_),   [colour(darkcyan)]).
 2084def_style(goal(not_callable,_),    [background(orange)]).
 2085
 2086def_style(option_name,             [colour('#3434ba')]).
 2087def_style(no_option_name,          [colour(red)]).
 2088
 2089def_style(head(exported,_),        [colour(blue), bold(true)]).
 2090def_style(head(public(_),_),       [colour('#016300'), bold(true)]).
 2091def_style(head(extern(_),_),       [colour(blue), bold(true)]).
 2092def_style(head(dynamic,_),         [colour(magenta), bold(true)]).
 2093def_style(head(multifile,_),       [colour(navy_blue), bold(true)]).
 2094def_style(head(unreferenced,_),    [colour(red), bold(true)]).
 2095def_style(head(hook,_),            [colour(blue), underline(true)]).
 2096def_style(head(meta,_),            []).
 2097def_style(head(constraint(_),_),   [colour(darkcyan), bold(true)]).
 2098def_style(head(imported(_),_),     [colour(darkgoldenrod4), bold(true)]).
 2099def_style(head(built_in,_),        [background(orange), bold(true)]).
 2100def_style(head(iso,_),             [background(orange), bold(true)]).
 2101def_style(head(def_iso,_),         [colour(blue), bold(true)]).
 2102def_style(head(def_swi,_),         [colour(blue), bold(true)]).
 2103def_style(head(_,_),               [bold(true)]).
 2104
 2105def_style(module(_),               [colour(dark_slate_blue)]).
 2106def_style(comment(_),              [colour(dark_green)]).
 2107
 2108def_style(directive,               [background(grey90)]).
 2109def_style(method(_),               [bold(true)]).
 2110
 2111def_style(var,                     [colour(red4)]).
 2112def_style(singleton,               [bold(true), colour(red4)]).
 2113def_style(unbound,                 [colour(red), bold(true)]).
 2114def_style(quoted_atom,             [colour(navy_blue)]).
 2115def_style(string,                  [colour(navy_blue)]).
 2116def_style(codes,                   [colour(navy_blue)]).
 2117def_style(chars,                   [colour(navy_blue)]).
 2118def_style(nofile,                  [colour(red)]).
 2119def_style(file(_),                 [colour(blue), underline(true)]).
 2120def_style(file_no_depend(_),       [colour(blue), underline(true), background(pink)]).
 2121def_style(directory(_),            [colour(blue)]).
 2122def_style(class(built_in,_),       [colour(blue), underline(true)]).
 2123def_style(class(library(_),_),     [colour(navy_blue), underline(true)]).
 2124def_style(class(local(_,_,_),_),   [underline(true)]).
 2125def_style(class(user(_),_),        [underline(true)]).
 2126def_style(class(user,_),           [underline(true)]).
 2127def_style(class(undefined,_),      [colour(red), underline(true)]).
 2128def_style(prolog_data,             [colour(blue), underline(true)]).
 2129def_style(flag_name(_),            [colour(blue)]).
 2130def_style(no_flag_name(_),         [colour(red)]).
 2131def_style(unused_import,           [colour(blue), background(pink)]).
 2132def_style(undefined_import,        [colour(red)]).
 2133
 2134def_style(constraint(_),           [colour(darkcyan)]).
 2135
 2136def_style(keyword(_),              [colour(blue)]).
 2137def_style(identifier,              [bold(true)]).
 2138def_style(delimiter,               [bold(true)]).
 2139def_style(expanded,                [colour(blue), underline(true)]).
 2140def_style(hook(_),                 [colour(blue), underline(true)]).
 2141def_style(op_type(_),              [colour(blue)]).
 2142
 2143def_style(qq_type,                 [bold(true)]).
 2144def_style(qq(_),                   [colour(blue), bold(true)]).
 2145def_style(qq_content(_),           [colour(red4)]).
 2146
 2147def_style(dict_tag,                [bold(true)]).
 2148def_style(dict_key,                [bold(true)]).
 2149def_style(dict_function(_),        [colour(navy_blue)]).
 2150def_style(dict_return_op,          [colour(blue)]).
 2151
 2152def_style(hook,                    [colour(blue), underline(true)]).
 2153def_style(dcg_right_hand_ctx,      [background('#d4ffe3')]).
 2154
 2155def_style(error,                   [background(orange)]).
 2156def_style(type_error(_),           [background(orange)]).
 2157def_style(syntax_error(_,_),       [background(orange)]).
 2158def_style(instantiation_error,     [background(orange)]).
 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.

 2174syntax_colour(Class, Attributes) :-
 2175    (   style(Class, Attributes)            % user hook
 2176    ;   def_style(Class, Attributes)        % system default
 2177    ).
 term_colours(+Term, -FunctorColour, -ArgColours)
Define colourisation for specific terms.
 2184term_colours((?- Directive), Colours) :-
 2185    term_colours((:- Directive), Colours).
 2186term_colours((prolog:Head --> _),
 2187             neck(grammar_rule) - [ expanded - [ module(prolog),
 2188                                                 hook(message) - [ identifier
 2189                                                                 ]
 2190                                               ],
 2191                                    dcg_body(prolog:Head)
 2192                                  ]) :-
 2193    prolog_message_hook(Head).
 2194
 2195prolog_message_hook(message(_)).
 2196prolog_message_hook(error_message(_)).
 2197prolog_message_hook(message_context(_)).
 2198prolog_message_hook(message_location(_)).
 2199
 2200%       XPCE rules
 2201
 2202term_colours(variable(_, _, _, _),
 2203             expanded - [ identifier,
 2204                          classify,
 2205                          classify,
 2206                          comment(string)
 2207                        ]).
 2208term_colours(variable(_, _, _),
 2209             expanded - [ identifier,
 2210                          classify,
 2211                          atom
 2212                        ]).
 2213term_colours(handle(_, _, _),
 2214             expanded - [ classify,
 2215                          classify,
 2216                          classify
 2217                        ]).
 2218term_colours(handle(_, _, _, _),
 2219             expanded - [ classify,
 2220                          classify,
 2221                          classify,
 2222                          classify
 2223                        ]).
 2224term_colours(class_variable(_,_,_,_),
 2225             expanded - [ identifier,
 2226                          pce(type),
 2227                          pce(default),
 2228                          comment(string)
 2229                        ]).
 2230term_colours(class_variable(_,_,_),
 2231             expanded - [ identifier,
 2232                          pce(type),
 2233                          pce(default)
 2234                        ]).
 2235term_colours(delegate_to(_),
 2236             expanded - [ classify
 2237                        ]).
 2238term_colours((:- encoding(_)),
 2239             expanded - [ expanded - [ classify
 2240                                     ]
 2241                        ]).
 2242term_colours((:- pce_begin_class(_, _, _)),
 2243             expanded - [ expanded - [ identifier,
 2244                                       pce_new,
 2245                                       comment(string)
 2246                                     ]
 2247                        ]).
 2248term_colours((:- pce_begin_class(_, _)),
 2249             expanded - [ expanded - [ identifier,
 2250                                       pce_new
 2251                                     ]
 2252                        ]).
 2253term_colours((:- pce_extend_class(_)),
 2254             expanded - [ expanded - [ identifier
 2255                                     ]
 2256                        ]).
 2257term_colours((:- pce_end_class),
 2258             expanded - [ expanded
 2259                        ]).
 2260term_colours((:- pce_end_class(_)),
 2261             expanded - [ expanded - [ identifier
 2262                                     ]
 2263                        ]).
 2264term_colours((:- use_class_template(_)),
 2265             expanded - [ expanded - [ pce_new
 2266                                     ]
 2267                        ]).
 2268term_colours((:- emacs_begin_mode(_,_,_,_,_)),
 2269             expanded - [ expanded - [ identifier,
 2270                                       classify,
 2271                                       classify,
 2272                                       classify,
 2273                                       classify
 2274                                     ]
 2275                        ]).
 2276term_colours((:- emacs_extend_mode(_,_)),
 2277             expanded - [ expanded - [ identifier,
 2278                                       classify
 2279                                     ]
 2280                        ]).
 2281term_colours((:- pce_group(_)),
 2282             expanded - [ expanded - [ identifier
 2283                                     ]
 2284                        ]).
 2285term_colours((:- pce_global(_, new(_))),
 2286             expanded - [ expanded - [ identifier,
 2287                                       pce_arg
 2288                                     ]
 2289                        ]).
 2290term_colours((:- emacs_end_mode),
 2291             expanded - [ expanded
 2292                        ]).
 2293term_colours(pce_ifhostproperty(_,_),
 2294             expanded - [ classify,
 2295                          classify
 2296                        ]).
 2297term_colours((_,_),
 2298             error - [ classify,
 2299                       classify
 2300                     ]).
 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.
 2307specified_item(_Class, _Term, _TB, Pos) :-
 2308    var(Pos),
 2309    !.
 2310specified_item(Class, Term, TB, parentheses_term_position(PO,PC,Pos)) :-
 2311    !,
 2312    colour_item(parentheses, TB, PO-PC),
 2313    specified_item(Class, Term, TB, Pos).
 2314specified_item(_, Var, TB, Pos) :-
 2315    (   var(Var)
 2316    ;   qq_position(Pos)
 2317    ),
 2318    !,
 2319    colourise_term_arg(Var, TB, Pos).
 2320                                        % generic classification
 2321specified_item(classify, Term, TB, Pos) :-
 2322    !,
 2323    colourise_term_arg(Term, TB, Pos).
 2324                                        % classify as head
 2325specified_item(head, Term, TB, Pos) :-
 2326    !,
 2327    colourise_clause_head(Term, TB, Pos).
 2328                                        % expanded head (DCG=2, ...)
 2329specified_item(head(+N), Term, TB, Pos) :-
 2330    !,
 2331    colourise_extended_head(Term, N, TB, Pos).
 2332                                        % M:Head
 2333specified_item(extern(M), Term, TB, Pos) :-
 2334    !,
 2335    colourise_extern_head(Term, M, TB, Pos).
 2336                                        % classify as body
 2337specified_item(body, Term, TB, Pos) :-
 2338    !,
 2339    colourise_body(Term, TB, Pos).
 2340specified_item(body(Goal), _Term0, TB, Pos) :-
 2341    !,
 2342    colourise_body(Goal, TB, Pos).
 2343specified_item(dcg_body(Head), Term, TB, Pos) :-
 2344    !,
 2345    colourise_dcg(Term, Head, TB, Pos).
 2346specified_item(setof, Term, TB, Pos) :-
 2347    !,
 2348    colourise_setof(Term, TB, Pos).
 2349specified_item(meta(MetaSpec), Term, TB, Pos) :-
 2350    !,
 2351    colourise_meta_arg(MetaSpec, Term, TB, Pos).
 2352                                        % DCG goal in body
 2353specified_item(dcg, Term, TB, Pos) :-
 2354    !,
 2355    colourise_dcg(Term, [], TB, Pos).
 2356                                        % assert/retract arguments
 2357specified_item(db, Term, TB, Pos) :-
 2358    !,
 2359    colourise_db(Term, TB, Pos).
 2360                                        % files
 2361specified_item(file, Term, TB, Pos) :-
 2362    !,
 2363    colourise_files(Term, TB, Pos, any).
 2364specified_item(imported_file, Term, TB, Pos) :-
 2365    !,
 2366    colourise_files(Term, TB, Pos, imported).
 2367specified_item(langoptions, Term, TB, Pos) :-
 2368    !,
 2369    colourise_langoptions(Term, TB, Pos).
 2370
 2371                                        % directory
 2372specified_item(directory, Term, TB, Pos) :-
 2373    !,
 2374    colourise_directory(Term, TB, Pos).
 2375                                        % [Name/Arity, ...]
 2376specified_item(exports, Term, TB, Pos) :-
 2377    !,
 2378    colourise_exports(Term, TB, Pos).
 2379                                        % [Name/Arity, ...]
 2380specified_item(imports(File), Term, TB, Pos) :-
 2381    !,
 2382    colourise_imports(Term, File, TB, Pos).
 2383                                        % Name/Arity, ...
 2384specified_item(predicates, Term, TB, Pos) :-
 2385    !,
 2386    colourise_declarations(Term, TB, Pos).
 2387                                        % Name/Arity
 2388specified_item(predicate, Term, TB, Pos) :-
 2389    !,
 2390    colourise_declaration(Term, TB, Pos).
 2391                                        % head(Arg, ...)
 2392specified_item(meta_declarations, Term, TB, Pos) :-
 2393    !,
 2394    colourise_meta_declarations(Term, [], TB, Pos).
 2395specified_item(meta_declarations(Extra), Term, TB, Pos) :-
 2396    !,
 2397    colourise_meta_declarations(Term, Extra, TB, Pos).
 2398                                        % set_prolog_flag(Name, _)
 2399specified_item(prolog_flag_name, Term, TB, Pos) :-
 2400    !,
 2401    colourise_prolog_flag_name(Term, TB, Pos).
 2402                                        % XPCE new argument
 2403specified_item(pce_new, Term, TB, Pos) :-
 2404    !,
 2405    (   atom(Term)
 2406    ->  colourise_class(Term, TB, Pos)
 2407    ;   compound(Term)
 2408    ->  functor_name(Term, Class),
 2409        Pos = term_position(_,_,FF, FT, ArgPos),
 2410        colourise_class(Class, TB, FF-FT),
 2411        specified_items(pce_arg, Term, TB, ArgPos)
 2412    ;   colourise_term_arg(Term, TB, Pos)
 2413    ).
 2414                                        % Generic XPCE arguments
 2415specified_item(pce_arg, new(X), TB,
 2416               term_position(_,_,_,_,[ArgPos])) :-
 2417    !,
 2418    specified_item(pce_new, X, TB, ArgPos).
 2419specified_item(pce_arg, new(X, T), TB,
 2420               term_position(_,_,_,_,[P1, P2])) :-
 2421    !,
 2422    colourise_term_arg(X, TB, P1),
 2423    specified_item(pce_new, T, TB, P2).
 2424specified_item(pce_arg, @(Ref), TB, Pos) :-
 2425    !,
 2426    colourise_term_arg(@(Ref), TB, Pos).
 2427specified_item(pce_arg, prolog(Term), TB,
 2428               term_position(_,_,FF,FT,[ArgPos])) :-
 2429    !,
 2430    colour_item(prolog_data, TB, FF-FT),
 2431    colourise_term_arg(Term, TB, ArgPos).
 2432specified_item(pce_arg, Term, TB, Pos) :-
 2433    compound(Term),
 2434    Term \= [_|_],
 2435    !,
 2436    specified_item(pce_new, Term, TB, Pos).
 2437specified_item(pce_arg, Term, TB, Pos) :-
 2438    !,
 2439    colourise_term_arg(Term, TB, Pos).
 2440                                        % List of XPCE arguments
 2441specified_item(pce_arg_list, List, TB, list_position(F,T,Elms,Tail)) :-
 2442    !,
 2443    colour_item(list, TB, F-T),
 2444    colourise_list_args(Elms, Tail, List, TB, pce_arg).
 2445specified_item(pce_arg_list, Term, TB, Pos) :-
 2446    !,
 2447    specified_item(pce_arg, Term, TB, Pos).
 2448                                        % XPCE selector
 2449specified_item(pce_selector, Term, TB,
 2450               term_position(_,_,_,_,ArgPos)) :-
 2451    !,
 2452    specified_items(pce_arg, Term, TB, ArgPos).
 2453specified_item(pce_selector, Term, TB, Pos) :-
 2454    colourise_term_arg(Term, TB, Pos).
 2455                                        % Nested specification
 2456specified_item(FuncSpec-ArgSpecs, Term, TB,
 2457               term_position(_,_,FF,FT,ArgPos)) :-
 2458    !,
 2459    specified_item(FuncSpec, Term, TB, FF-FT),
 2460    specified_items(ArgSpecs, Term, TB, ArgPos).
 2461                                        % Nested for {...}
 2462specified_item(FuncSpec-[ArgSpec], {Term}, TB,
 2463               brace_term_position(F,T,ArgPos)) :-
 2464    !,
 2465    specified_item(FuncSpec, {Term}, TB, F-T),
 2466    specified_item(ArgSpec, Term, TB, ArgPos).
 2467                                        % Specified
 2468specified_item(FuncSpec-ElmSpec, List, TB,
 2469               list_position(F,T,ElmPos,TailPos)) :-
 2470    !,
 2471    colour_item(FuncSpec, TB, F-T),
 2472    specified_list(ElmSpec, List, TB, ElmPos, TailPos).
 2473specified_item(Class, _, TB, Pos) :-
 2474    colour_item(Class, TB, Pos).
 specified_items(+Spec, +Term, +TB, +PosList)
 2478specified_items(Specs, Term, TB, PosList) :-
 2479    is_dict(Term),
 2480    !,
 2481    specified_dict_kv(PosList, Term, TB, Specs).
 2482specified_items(Specs, Term, TB, PosList) :-
 2483    is_list(Specs),
 2484    !,
 2485    specified_arglist(Specs, 1, Term, TB, PosList).
 2486specified_items(Spec, Term, TB, PosList) :-
 2487    specified_argspec(PosList, Spec, 1, Term, TB).
 2488
 2489
 2490specified_arglist([], _, _, _, _).
 2491specified_arglist(_, _, _, _, []) :- !.         % Excess specification args
 2492specified_arglist([S0|ST], N, T, TB, [P0|PT]) :-
 2493    (   S0 == options,
 2494        colourization_module(TB, Module),
 2495        colourise_option_arg(T, Module, N, TB, P0)
 2496    ->  true
 2497    ;   arg(N, T, Term),
 2498        specified_item(S0, Term, TB, P0)
 2499    ),
 2500    NN is N + 1,
 2501    specified_arglist(ST, NN, T, TB, PT).
 2502
 2503specified_argspec([], _, _, _, _).
 2504specified_argspec([P0|PT], Spec, N, T, TB) :-
 2505    arg(N, T, Term),
 2506    specified_item(Spec, Term, TB, P0),
 2507    NN is N + 1,
 2508    specified_argspec(PT, Spec, NN, T, TB).
 2509
 2510
 2511%       specified_list(+Spec, +List, +TB, +PosList, TailPos)
 2512
 2513specified_list([], [], _, [], _).
 2514specified_list([HS|TS], [H|T], TB, [HP|TP], TailPos) :-
 2515    !,
 2516    specified_item(HS, H, TB, HP),
 2517    specified_list(TS, T, TB, TP, TailPos).
 2518specified_list(Spec, [H|T], TB, [HP|TP], TailPos) :-
 2519    specified_item(Spec, H, TB, HP),
 2520    specified_list(Spec, T, TB, TP, TailPos).
 2521specified_list(_, _, _, [], none) :- !.
 2522specified_list(Spec, Tail, TB, [], TailPos) :-
 2523    specified_item(Spec, Tail, TB, TailPos).
 specified_dict_kv(+PosList, +Term, +TB, +Specs)
Arguments:
Specs- is a list of dict_kv(+Key, +KeySpec, +ArgSpec)
 2529specified_dict_kv([], _, _, _).
 2530specified_dict_kv([key_value_position(_F,_T,SF,ST,K,KP,VP)|Pos],
 2531                  Dict, TB, Specs) :-
 2532    specified_dict_kv1(K, Specs, KeySpec, ValueSpec),
 2533    colour_item(KeySpec, TB, KP),
 2534    colour_item(dict_sep, TB, SF-ST),
 2535    get_dict(K, Dict, V),
 2536    specified_item(ValueSpec, V, TB, VP),
 2537    specified_dict_kv(Pos, Dict, TB, Specs).
 2538
 2539specified_dict_kv1(Key, Specs, KeySpec, ValueSpec) :-
 2540    Specs = [_|_],
 2541    memberchk(dict_kv(Key, KeySpec, ValueSpec), Specs),
 2542    !.
 2543specified_dict_kv1(Key, dict_kv(Key2, KeySpec, ValueSpec), KeySpec, ValueSpec) :-
 2544    \+ Key \= Key2,
 2545    !.              % do not bind Key2
 2546specified_dict_kv1(_, _, dict_key, classify).
 2547
 2548
 2549                 /*******************************
 2550                 *         DESCRIPTIONS         *
 2551                 *******************************/
 2552
 2553syntax_message(Class) -->
 2554    message(Class),
 2555    !.
 2556syntax_message(qq(_)) -->
 2557    [ 'Quasi quote delimiter' ].
 2558syntax_message(qq_type) -->
 2559    [ 'Quasi quote type term' ].
 2560syntax_message(qq_content(Type)) -->
 2561    [ 'Quasi quote content (~w syntax)'-[Type] ].
 2562syntax_message(goal(Class, Goal)) -->
 2563    !,
 2564    goal_message(Class, Goal).
 2565syntax_message(class(Type, Class)) -->
 2566    !,
 2567    xpce_class_message(Type, Class).
 2568syntax_message(dict_return_op) -->
 2569    !,
 2570    [ ':= separates function from return value' ].
 2571syntax_message(dict_function) -->
 2572    !,
 2573    [ 'Function on a dict' ].
 2574syntax_message(ext_quant) -->
 2575    !,
 2576    [ 'Existential quantification operator' ].
 2577syntax_message(hook(message)) -->
 2578    [ 'Rule for print_message/2' ].
 2579syntax_message(module(Module)) -->
 2580    (   { current_module(Module) }
 2581    ->  (   { module_property(Module, file(File)) }
 2582        ->  [ 'Module ~w defined in ~w'-[Module,File] ]
 2583        ;   [ 'Module ~w'-[Module] ]
 2584        )
 2585    ;   [ 'Module ~w (not loaded)'-[Module] ]
 2586    ).
 2587
 2588goal_message(meta, _) -->
 2589    [ 'Meta call' ].
 2590goal_message(not_callable, _) -->
 2591    [ 'Goal is not callable (type error)' ].
 2592goal_message(expanded, _) -->
 2593    [ 'Expanded goal' ].
 2594goal_message(Class, Goal) -->
 2595    { predicate_name(Goal, PI) },
 2596    [ 'Call to ~q'-PI ],
 2597    goal_class(Class).
 2598
 2599goal_class(recursion) -->
 2600    [ ' (recursive call)' ].
 2601goal_class(undefined) -->
 2602    [ ' (undefined)' ].
 2603goal_class(global) -->
 2604    [ ' (Auto-imported from module user)' ].
 2605goal_class(imported(From)) -->
 2606    [ ' (imported from ~q)'-[From] ].
 2607goal_class(extern(_, private)) -->
 2608    [ ' (WARNING: private predicate)' ].
 2609goal_class(extern(_, public)) -->
 2610    [ ' (public predicate)' ].
 2611goal_class(extern(_)) -->
 2612    [ ' (cross-module call)' ].
 2613goal_class(Class) -->
 2614    [ ' (~p)'-[Class] ].
 2615
 2616xpce_class_message(Type, Class) -->
 2617    [ 'XPCE ~w class ~q'-[Type, Class] ]