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-2018, 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(Singletons0),
  134                          module(SM),
  135                          comments(Comments)
  136                        ]),
  137              E,
  138              read_error(E, TB, Start, Fd)),
  139        fix_operators(Term, SM, TB),
  140        warnable_singletons(Singletons0, Singletons),
  141        colour_state_singletons(TB, Singletons),
  142        (   colourise_term(Term, TB, TermPos, Comments)
  143        ->  true
  144        ;   arg(1, TermPos, From),
  145            print_message(warning,
  146                          format('Failed to colourise ~p at index ~d~n',
  147                                 [Term, From]))
  148        ),
  149        Term == end_of_file,
  150    !.
  151
  152save_settings(TB, state(Style, Flags, OSM, Xref)) :-
  153    (   source_module(TB, SM)
  154    ->  true
  155    ;   SM = prolog_colour_ops
  156    ),
  157    set_xref(Xref, true),
  158    '$set_source_module'(OSM, SM),
  159    colour_state_module(TB, SM),
  160    push_operators([]),
  161    syntax_flags(Flags),
  162    '$style_check'(Style, Style).
  163
  164restore_settings(state(Style, Flags, OSM, Xref)) :-
  165    restore_syntax_flags(Flags),
  166    '$style_check'(_, Style),
  167    pop_operators,
  168    '$set_source_module'(OSM),
  169    set_xref(_, Xref).
  170
  171set_xref(Old, New) :-
  172    current_prolog_flag(xref, Old),
  173    !,
  174    set_prolog_flag(xref, New).
  175set_xref(false, New) :-
  176    set_prolog_flag(xref, New).
  177
  178
  179syntax_flags(Pairs) :-
  180    findall(set_prolog_flag(Flag, Value),
  181            syntax_flag(Flag, Value),
  182            Pairs).
  183
  184syntax_flag(Flag, Value) :-
  185    syntax_flag(Flag),
  186    current_prolog_flag(Flag, Value).
  187
  188restore_syntax_flags([]).
  189restore_syntax_flags([set_prolog_flag(Flag, Value)|T]) :-
  190    set_prolog_flag(Flag, Value),
  191    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.
  200source_module(TB, Module) :-
  201    colour_state_source_id_list(TB, []),
  202    !,
  203    colour_state_module(TB, Module).
  204source_module(TB, Module) :-
  205    colour_state_source_id(TB, SourceId),
  206    xref_option(SourceId, module(Module)),
  207    !.
  208source_module(TB, Module) :-
  209    (   colour_state_source_id(TB, File),
  210        atom(File)
  211    ;   colour_state_stream(TB, Fd),
  212        is_stream(Fd),
  213        stream_property(Fd, file_name(File))
  214    ),
  215    module_context(File, [], Module).
  216
  217module_context(File, _, Module) :-
  218    source_file_property(File, module(Module)),
  219    !.
  220module_context(File, Seen, Module) :-
  221    source_file_property(File, included_in(File2, _Line)),
  222    \+ memberchk(File, Seen),
  223    !,
  224    module_context(File2, [File|Seen], Module).
  225module_context(File, _, Module) :-
  226    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.
  233read_error(Error, TB, Start, EndSpec) :-
  234    (   syntax_error(Error, Id, CharNo)
  235    ->  message_to_string(error(syntax_error(Id), _), Msg),
  236        (   integer(EndSpec)
  237        ->  End = EndSpec
  238        ;   character_count(EndSpec, End)
  239        ),
  240        show_syntax_error(TB, CharNo:Msg, Start-End),
  241        fail
  242    ;   throw(Error)
  243    ).
  244
  245syntax_error(error(syntax_error(Id), stream(_S, _Line, _LinePos, CharNo)),
  246             Id, CharNo).
  247syntax_error(error(syntax_error(Id), file(_S, _Line, _LinePos, CharNo)),
  248             Id, CharNo).
  249syntax_error(error(syntax_error(Id), string(_Text, CharNo)),
  250             Id, CharNo).
 warnable_singletons(+Singletons, -Warn) is det
Warn is the subset of the singletons that we warn about.
  256warnable_singletons([], []).
  257warnable_singletons([H|T0], List) :-
  258    H = (Name=_Var),
  259    (   '$is_named_var'(Name)
  260    ->  List = [H|T]
  261    ;   List = T
  262    ),
  263    warnable_singletons(T0, T).
 colour_item(+Class, +TB, +Pos) is det
  267colour_item(Class, TB, Pos) :-
  268    arg(1, Pos, Start),
  269    arg(2, Pos, End),
  270    Len is End - Start,
  271    colour_state_closure(TB, Closure),
  272    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.
  280safe_push_op(P, T, N0, State) :-
  281    colour_state_module(State, CM),
  282    strip_module(CM:N0, M, N),
  283    (   is_list(N),
  284        N \== []                                % define list as operator
  285    ->  acyclic_term(N),
  286        forall(member(Name, N),
  287               safe_push_op(P, T, M:Name, State))
  288    ;   push_op(P, T, M:N)
  289    ),
  290    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.
  298fix_operators((:- Directive), M, Src) :-
  299    ground(Directive),
  300    catch(process_directive(Directive, M, Src), _, true),
  301    !.
  302fix_operators(_, _, _).
  303
  304process_directive(style_check(X), _, _) :-
  305    !,
  306    style_check(X).
  307process_directive(set_prolog_flag(Flag, Value), M, _) :-
  308    syntax_flag(Flag),
  309    !,
  310    set_prolog_flag(M:Flag, Value).
  311process_directive(M:op(P,T,N), _, Src) :-
  312    !,
  313    process_directive(op(P,T,N), M, Src).
  314process_directive(op(P,T,N), M, Src) :-
  315    !,
  316    safe_push_op(P, T, M:N, Src).
  317process_directive(module(_Name, Export), M, Src) :-
  318    !,
  319    forall(member(op(P,A,N), Export),
  320           safe_push_op(P,A,M:N, Src)).
  321process_directive(use_module(Spec), _, Src) :-
  322    !,
  323    catch(process_use_module1(Spec, Src), _, true).
  324process_directive(use_module(Spec, Imports), _, Src) :-
  325    !,
  326    catch(process_use_module2(Spec, Imports, Src), _, true).
  327process_directive(Directive, _, Src) :-
  328    prolog_source:expand((:-Directive), Src, _).
  329
  330syntax_flag(character_escapes).
  331syntax_flag(var_prefix).
  332syntax_flag(allow_variable_name_as_functor).
  333syntax_flag(allow_dot_in_atom).
 process_use_module1(+Imports, +Src)
Get the exported operators from the referenced files.
  339process_use_module1([], _) :- !.
  340process_use_module1([H|T], Src) :-
  341    !,
  342    process_use_module1(H, Src),
  343    process_use_module1(T, Src).
  344process_use_module1(File, Src) :-
  345    (   xref_public_list(File, Src,
  346                         [ exports(Exports),
  347                           silent(true),
  348                           path(Path)
  349                         ])
  350    ->  forall(member(op(P,T,N), Exports),
  351               safe_push_op(P,T,N,Src)),
  352        colour_state_module(Src, SM),
  353        (   member(Syntax/4, Exports),
  354            load_quasi_quotation_syntax(SM:Path, Syntax),
  355            fail
  356        ;   true
  357        )
  358    ;   true
  359    ).
  360
  361process_use_module2(File, Imports, Src) :-
  362    (   xref_public_list(File, Src,
  363                         [ exports(Exports),
  364                           silent(true),
  365                           path(Path)
  366                         ])
  367    ->  forall(( member(op(P,T,N), Exports),
  368                 member(op(P,T,N), Imports)),
  369               safe_push_op(P,T,N,Src)),
  370        colour_state_module(Src, SM),
  371        (   member(Syntax/4, Exports),
  372            member(Syntax/4, Imports),
  373            load_quasi_quotation_syntax(SM:Path, Syntax),
  374            fail
  375        ;   true
  376        )
  377    ;   true
  378    ).
 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.
  387prolog_colourise_query(QueryString, SourceID, ColourItem) :-
  388    query_colour_state(SourceID, ColourItem, TB),
  389    setup_call_cleanup(
  390        save_settings(TB, State),
  391        colourise_query(QueryString, TB),
  392        restore_settings(State)).
  393
  394query_colour_state(module(Module), ColourItem, TB) :-
  395    !,
  396    make_colour_state([ source_id_list([]),
  397                        module(Module),
  398                        closure(ColourItem)
  399                      ],
  400                      TB).
  401query_colour_state(SourceID, ColourItem, TB) :-
  402    to_list(SourceID, SourceIDList),
  403    make_colour_state([ source_id_list(SourceIDList),
  404                        closure(ColourItem)
  405                      ],
  406                      TB).
  407
  408
  409colourise_query(QueryString, TB) :-
  410    colour_state_module(TB, SM),
  411    string_length(QueryString, End),
  412    (   catch(term_string(Query, QueryString,
  413                          [ subterm_positions(TermPos),
  414                            singletons(Singletons0),
  415                            module(SM),
  416                            comments(Comments)
  417                          ]),
  418              E,
  419              read_error(E, TB, 0, End))
  420    ->  warnable_singletons(Singletons0, Singletons),
  421        colour_state_singletons(TB, Singletons),
  422        colourise_comments(Comments, TB),
  423        (   Query == end_of_file
  424        ->  true
  425        ;   colourise_body(Query, TB, TermPos)
  426        )
  427    ;   true                        % only a syntax error
  428    ).
 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)
  443prolog_colourise_term(Stream, SourceId, ColourItem, Options) :-
  444    to_list(SourceId, SourceIdList),
  445    make_colour_state([ source_id_list(SourceIdList),
  446                        stream(Stream),
  447                        closure(ColourItem)
  448                      ],
  449                      TB),
  450    option(subterm_positions(TermPos), Options, _),
  451    findall(Op, xref_op(SourceId, Op), Ops),
  452    debug(colour, 'Ops from ~p: ~p', [SourceId, Ops]),
  453    findall(Opt, xref_flag_option(SourceId, Opt), Opts),
  454    character_count(Stream, Start),
  455    (   source_module(TB, Module)
  456    ->  true
  457    ;   Module = prolog_colour_ops
  458    ),
  459    read_source_term_at_location(
  460        Stream, Term,
  461        [ module(Module),
  462          operators(Ops),
  463          error(Error),
  464          subterm_positions(TermPos),
  465          singletons(Singletons0),
  466          comments(Comments)
  467        | Opts
  468        ]),
  469    (   var(Error)
  470    ->  warnable_singletons(Singletons0, Singletons),
  471        colour_state_singletons(TB, Singletons),
  472        colour_item(range, TB, TermPos),            % Call to allow clearing
  473        colourise_term(Term, TB, TermPos, Comments)
  474    ;   character_count(Stream, End),
  475        TermPos = error_position(Start, End, Pos),
  476        colour_item(range, TB, TermPos),
  477        show_syntax_error(TB, Error, Start-End),
  478        Error = Pos:_Message
  479    ).
  480
  481xref_flag_option(TB, var_prefix(Bool)) :-
  482    xref_prolog_flag(TB, var_prefix, Bool, _Line).
  483
  484show_syntax_error(TB, Pos:Message, Range) :-
  485    integer(Pos),
  486    !,
  487    End is Pos + 1,
  488    colour_item(syntax_error(Message, Range), TB, Pos-End).
  489show_syntax_error(TB, _:Message, Range) :-
  490    colour_item(syntax_error(Message, Range), TB, Range).
  491
  492
  493singleton(Var, TB) :-
  494    colour_state_singletons(TB, Singletons),
  495    member_var(Var, Singletons).
  496
  497member_var(V, [_=V2|_]) :-
  498    V == V2,
  499    !.
  500member_var(V, [_|T]) :-
  501    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.
  512colourise_term(Term, TB, TermPos, Comments) :-
  513    colourise_comments(Comments, TB),
  514    (   Term == end_of_file
  515    ->  true
  516    ;   colourise_term(Term, TB, TermPos),
  517        colourise_fullstop(TB, TermPos)
  518    ).
  519
  520colourise_fullstop(TB, TermPos) :-
  521    arg(2, TermPos, EndTerm),
  522    Start is EndTerm,
  523    End is Start+1,
  524    colour_item(fullstop, TB, Start-End).
  525
  526colourise_comments(-, _).
  527colourise_comments([], _).
  528colourise_comments([H|T], TB) :-
  529    colourise_comment(H, TB),
  530    colourise_comments(T, TB).
  531
  532colourise_comment((-)-_, _) :- !.
  533colourise_comment(Pos-Comment, TB) :-
  534    comment_style(Comment, Style),
  535    stream_position_data(char_count, Pos, Start),
  536    string_length(Comment, Len),
  537    End is Start + Len + 1,
  538    colour_item(comment(Style), TB, Start-End).
  539
  540comment_style(Comment, structured) :-           % Starts %%, %! or /**
  541    structured_comment_start(Start),
  542    sub_string(Comment, 0, Len, _, Start),
  543    Next is Len+1,
  544    string_code(Next, Comment, NextCode),
  545    code_type(NextCode, space),
  546    !.
  547comment_style(Comment, line) :-                 % Starts %
  548    sub_string(Comment, 0, _, _, '%'),
  549    !.
  550comment_style(_, block).                        % Starts /*
 structured_comment_start(-Start)
Copied from library(pldoc/doc_process). Unfortunate, but we do not want to force loading pldoc.
  557structured_comment_start('%%').
  558structured_comment_start('%!').
  559structured_comment_start('/**').
 colourise_term(+Term, +TB, +Pos)
Colorise a file toplevel term.
  565colourise_term(Var, TB, Start-End) :-
  566    var(Var),
  567    !,
  568    colour_item(instantiation_error, TB, Start-End).
  569colourise_term(_, _, Pos) :-
  570    var(Pos),
  571    !.
  572colourise_term(Term, TB, parentheses_term_position(PO,PC,Pos)) :-
  573    !,
  574    colour_item(parentheses, TB, PO-PC),
  575    colourise_term(Term, TB, Pos).
  576colourise_term(Term, TB, Pos) :-
  577    term_colours(Term, FuncSpec-ArgSpecs),
  578    !,
  579    Pos = term_position(F,T,FF,FT,ArgPos),
  580    colour_item(term, TB, F-T),     % TBD: Allow specifying by term_colours/2?
  581    specified_item(FuncSpec, Term, TB, FF-FT),
  582    specified_items(ArgSpecs, Term, TB, ArgPos).
  583colourise_term((Head :- Body), TB,
  584               term_position(F,T,FF,FT,[HP,BP])) :-
  585    !,
  586    colour_item(clause,         TB, F-T),
  587    colour_item(neck(clause),   TB, FF-FT),
  588    colourise_clause_head(Head, TB, HP),
  589    colourise_body(Body, Head,  TB, BP).
  590colourise_term(((Head,RHC) --> Body), TB,
  591               term_position(F,T,FF,FT,
  592                             [ term_position(_,_,_,_,[HP,RHCP]),
  593                               BP
  594                             ])) :-
  595    !,
  596    colour_item(grammar_rule,       TB, F-T),
  597    colour_item(dcg_right_hand_ctx, TB, RHCP),
  598    colourise_term_arg(RHC, TB, RHCP),
  599    colour_item(neck(grammar_rule), TB, FF-FT),
  600    colourise_extended_head(Head, 2, TB, HP),
  601    colourise_dcg(Body, Head,       TB, BP).
  602colourise_term((Head --> Body), TB,                     % TBD: expansion!
  603               term_position(F,T,FF,FT,[HP,BP])) :-
  604    !,
  605    colour_item(grammar_rule,       TB, F-T),
  606    colour_item(neck(grammar_rule), TB, FF-FT),
  607    colourise_extended_head(Head, 2, TB, HP),
  608    colourise_dcg(Body, Head,       TB, BP).
  609colourise_term(:->(Head, Body), TB,
  610               term_position(F,T,FF,FT,[HP,BP])) :-
  611    !,
  612    colour_item(method,             TB, F-T),
  613    colour_item(neck(method(send)), TB, FF-FT),
  614    colour_method_head(send(Head),  TB, HP),
  615    colourise_method_body(Body,     TB, BP).
  616colourise_term(:<-(Head, Body), TB,
  617               term_position(F,T,FF,FT,[HP,BP])) :-
  618    !,
  619    colour_item(method,            TB, F-T),
  620    colour_item(neck(method(get)), TB, FF-FT),
  621    colour_method_head(get(Head),  TB, HP),
  622    colourise_method_body(Body,    TB, BP).
  623colourise_term((:- Directive), TB, Pos) :-
  624    !,
  625    colour_item(directive, TB, Pos),
  626    Pos = term_position(_F,_T,FF,FT,[ArgPos]),
  627    colour_item(neck(directive), TB, FF-FT),
  628    colourise_directive(Directive, TB, ArgPos).
  629colourise_term((?- Directive), TB, Pos) :-
  630    !,
  631    colourise_term((:- Directive), TB, Pos).
  632colourise_term(end_of_file, _, _) :- !.
  633colourise_term(Fact, TB, Pos) :-
  634    !,
  635    colour_item(clause, TB, Pos),
  636    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.
  644colourise_extended_head(Head, N, TB, Pos) :-
  645    extend(Head, N, TheHead),
  646    colourise_clause_head(TheHead, TB, Pos).
  647
  648extend(M:Head, N, M:ExtHead) :-
  649    nonvar(Head),
  650    !,
  651    extend(Head, N, ExtHead).
  652extend(Head, N, ExtHead) :-
  653    compound(Head),
  654    !,
  655    compound_name_arguments(Head, Name, Args),
  656    length(Extra, N),
  657    append(Args, Extra, NArgs),
  658    compound_name_arguments(ExtHead, Name, NArgs).
  659extend(Head, N, ExtHead) :-
  660    atom(Head),
  661    !,
  662    length(Extra, N),
  663    compound_name_arguments(ExtHead, Head, Extra).
  664extend(Head, _, Head).
  665
  666
  667colourise_clause_head(_, _, Pos) :-
  668    var(Pos),
  669    !.
  670colourise_clause_head(Head, TB, parentheses_term_position(PO,PC,Pos)) :-
  671    colour_item(parentheses, TB, PO-PC),
  672    colourise_clause_head(Head, TB, Pos).
  673colourise_clause_head(M:Head, TB, QHeadPos) :-
  674    QHeadPos = term_position(_,_,QF,QT,[MPos,HeadPos]),
  675    head_colours(M:Head, meta-[_, ClassSpec-ArgSpecs]),
  676    !,
  677    colourise_module(M, TB, MPos),
  678    colour_item(functor, TB, QF-QT),
  679    functor_position(HeadPos, FPos, ArgPos),
  680    (   ClassSpec == classify
  681    ->  classify_head(TB, Head, Class)
  682    ;   Class = ClassSpec
  683    ),
  684    colour_item(head_term(Class, Head), TB, QHeadPos),
  685    colour_item(head(Class, Head), TB, FPos),
  686    specified_items(ArgSpecs, Head, TB, ArgPos).
  687colourise_clause_head(Head, TB, Pos) :-
  688    head_colours(Head, ClassSpec-ArgSpecs),
  689    !,
  690    functor_position(Pos, FPos, ArgPos),
  691    (   ClassSpec == classify
  692    ->  classify_head(TB, Head, Class)
  693    ;   Class = ClassSpec
  694    ),
  695    colour_item(head_term(Class, Head), TB, Pos),
  696    colour_item(head(Class, Head), TB, FPos),
  697    specified_items(ArgSpecs, Head, TB, ArgPos).
  698colourise_clause_head(:=(Eval, Ret), TB,
  699                      term_position(_,_,AF,AT,
  700                                    [ term_position(_,_,SF,ST,
  701                                                    [ SelfPos,
  702                                                      FuncPos
  703                                                    ]),
  704                                      RetPos
  705                                    ])) :-
  706    Eval =.. [.,M,Func],
  707    FuncPos = term_position(_,_,FF,FT,_),
  708    !,
  709    colourise_term_arg(M, TB, SelfPos),
  710    colour_item(func_dot, TB, SF-ST),               % .
  711    colour_item(dict_function(Func), TB, FF-FT),
  712    colourise_term_args(Func, TB, FuncPos),
  713    colour_item(dict_return_op, TB, AF-AT),         % :=
  714    colourise_term_arg(Ret, TB, RetPos).
  715colourise_clause_head(Head, TB, Pos) :-
  716    functor_position(Pos, FPos, _),
  717    classify_head(TB, Head, Class),
  718    colour_item(head_term(Class, Head), TB, Pos),
  719    colour_item(head(Class, Head), TB, FPos),
  720    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.
  727colourise_extern_head(Head, M, TB, Pos) :-
  728    functor_position(Pos, FPos, _),
  729    colour_item(head(extern(M), Head), TB, FPos),
  730    colourise_term_args(Head, TB, Pos).
  731
  732colour_method_head(SGHead, TB, Pos) :-
  733    arg(1, SGHead, Head),
  734    functor_name(SGHead, SG),
  735    functor_position(Pos, FPos, _),
  736    colour_item(method(SG), TB, FPos),
  737    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'.
  744functor_position(term_position(_,_,FF,FT,ArgPos), FF-FT, ArgPos) :- !.
  745functor_position(list_position(F,_T,Elms,none), F-FT, Elms) :-
  746    !,
  747    FT is F + 1.
  748functor_position(dict_position(_,_,FF,FT,KVPos), FF-FT, KVPos) :- !.
  749functor_position(brace_term_position(F,T,Arg), F-T, [Arg]) :- !.
  750functor_position(Pos, Pos, []).
  751
  752colourise_module(Term, TB, Pos) :-
  753    (   var(Term)
  754    ;   atom(Term)
  755    ),
  756    !,
  757    colour_item(module(Term), TB, Pos).
  758colourise_module(_, TB, Pos) :-
  759    colour_item(type_error(module), TB, Pos).
 colourise_directive(+Body, +TB, +Pos)
Colourise the body of a directive.
  765colourise_directive(_,_,Pos) :-
  766    var(Pos),
  767    !.
  768colourise_directive(Dir, TB, parentheses_term_position(PO,PC,Pos)) :-
  769    !,
  770    colour_item(parentheses, TB, PO-PC),
  771    colourise_directive(Dir, TB, Pos).
  772colourise_directive((A,B), TB, term_position(_,_,_,_,[PA,PB])) :-
  773    !,
  774    colourise_directive(A, TB, PA),
  775    colourise_directive(B, TB, PB).
  776colourise_directive(Body, TB, Pos) :-
  777    nonvar(Body),
  778    directive_colours(Body, ClassSpec-ArgSpecs),   % specified
  779    !,
  780    functor_position(Pos, FPos, ArgPos),
  781    (   ClassSpec == classify
  782    ->  goal_classification(TB, Body, [], Class)
  783    ;   Class = ClassSpec
  784    ),
  785    colour_item(goal(Class, Body), TB, FPos),
  786    specified_items(ArgSpecs, Body, TB, ArgPos).
  787colourise_directive(Body, TB, Pos) :-
  788    colourise_body(Body, TB, Pos).
  789
  790
  791%       colourise_body(+Body, +TB, +Pos)
  792%
  793%       Breaks down to colourise_goal/3.
  794
  795colourise_body(Body, TB, Pos) :-
  796    colourise_body(Body, [], TB, Pos).
  797
  798colourise_body(Body, Origin, TB, Pos) :-
  799    colour_item(body, TB, Pos),
  800    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.
  809colourise_method_body(_, _, Pos) :-
  810    var(Pos),
  811    !.
  812colourise_method_body(Body, TB, parentheses_term_position(PO,PC,Pos)) :-
  813    !,
  814    colour_item(parentheses, TB, PO-PC),
  815    colourise_method_body(Body, TB, Pos).
  816colourise_method_body(::(_Comment,Body), TB,
  817                      term_position(_F,_T,_FF,_FT,[CP,BP])) :-
  818    !,
  819    colour_item(comment(string), TB, CP),
  820    colourise_body(Body, TB, BP).
  821colourise_method_body(Body, TB, Pos) :-         % deal with pri(::) < 1000
  822    Body =.. [F,A,B],
  823    control_op(F),
  824    !,
  825    Pos = term_position(_F,_T,FF,FT,
  826                        [ AP,
  827                          BP
  828                        ]),
  829    colour_item(control, TB, FF-FT),
  830    colourise_method_body(A, TB, AP),
  831    colourise_body(B, TB, BP).
  832colourise_method_body(Body, TB, Pos) :-
  833    colourise_body(Body, TB, Pos).
  834
  835control_op(',').
  836control_op((;)).
  837control_op((->)).
  838control_op((*->)).
 colourise_goals(+Body, +Origin, +TB, +Pos)
Colourise the goals in a body.
  844colourise_goals(_, _, _, Pos) :-
  845    var(Pos),
  846    !.
  847colourise_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  848    !,
  849    colour_item(parentheses, TB, PO-PC),
  850    colourise_goals(Body, Origin, TB, Pos).
  851colourise_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  852    body_compiled(Body),
  853    !,
  854    colour_item(control, TB, FF-FT),
  855    colourise_subgoals(ArgPos, 1, Body, Origin, TB).
  856colourise_goals(Goal, Origin, TB, Pos) :-
  857    colourise_goal(Goal, Origin, TB, Pos).
  858
  859colourise_subgoals([], _, _, _, _).
  860colourise_subgoals([Pos|T], N, Body, Origin, TB) :-
  861    arg(N, Body, Arg),
  862    colourise_goals(Arg, Origin, TB, Pos),
  863    NN is N + 1,
  864    colourise_subgoals(T, NN, Body, Origin, TB).
 colourise_dcg(+Body, +Head, +TB, +Pos)
Breaks down to colourise_dcg_goal/3.
  870colourise_dcg(Body, Head, TB, Pos) :-
  871    colour_item(dcg, TB, Pos),
  872    (   dcg_extend(Head, Origin)
  873    ->  true
  874    ;   Origin = Head
  875    ),
  876    colourise_dcg_goals(Body, Origin, TB, Pos).
  877
  878colourise_dcg_goals(Var, _, TB, Pos) :-
  879    var(Var),
  880    !,
  881    colour_item(goal(meta,Var), TB, Pos).
  882colourise_dcg_goals(_, _, _, Pos) :-
  883    var(Pos),
  884    !.
  885colourise_dcg_goals(Body, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  886    !,
  887    colour_item(parentheses, TB, PO-PC),
  888    colourise_dcg_goals(Body, Origin, TB, Pos).
  889colourise_dcg_goals({Body}, Origin, TB, brace_term_position(F,T,Arg)) :-
  890    !,
  891    colour_item(dcg(plain), TB, F-T),
  892    colourise_goals(Body, Origin, TB, Arg).
  893colourise_dcg_goals([], _, TB, Pos) :-
  894    !,
  895    colour_item(dcg(terminal), TB, Pos).
  896colourise_dcg_goals(List, _, TB, list_position(F,T,Elms,Tail)) :-
  897    List = [_|_],
  898    !,
  899    colour_item(dcg(terminal), TB, F-T),
  900    colourise_list_args(Elms, Tail, List, TB, classify).
  901colourise_dcg_goals(_, _, TB, string_position(F,T)) :-
  902    integer(F),
  903    !,
  904    colour_item(dcg(string), TB, F-T).
  905colourise_dcg_goals(Body, Origin, TB, term_position(_,_,FF,FT,ArgPos)) :-
  906    dcg_body_compiled(Body),       % control structures
  907    !,
  908    colour_item(control, TB, FF-FT),
  909    colourise_dcg_subgoals(ArgPos, 1, Body, Origin, TB).
  910colourise_dcg_goals(Goal, Origin, TB, Pos) :-
  911    colourise_dcg_goal(Goal, Origin, TB, Pos).
  912
  913colourise_dcg_subgoals([], _, _, _, _).
  914colourise_dcg_subgoals([Pos|T], N, Body, Origin, TB) :-
  915    arg(N, Body, Arg),
  916    colourise_dcg_goals(Arg, Origin, TB, Pos),
  917    NN is N + 1,
  918    colourise_dcg_subgoals(T, NN, Body, Origin, TB).
  919
  920dcg_extend(Term, _) :-
  921    var(Term), !, fail.
  922dcg_extend(M:Term, M:Goal) :-
  923    dcg_extend(Term, Goal).
  924dcg_extend(Term, Goal) :-
  925    compound(Term),
  926    !,
  927    compound_name_arguments(Term, Name, Args),
  928    append(Args, [_,_], NArgs),
  929    compound_name_arguments(Goal, Name, NArgs).
  930dcg_extend(Term, Goal) :-
  931    atom(Term),
  932    !,
  933    compound_name_arguments(Goal, Term, [_,_]).
  934
  935dcg_body_compiled(G) :-
  936    body_compiled(G),
  937    !.
  938dcg_body_compiled((_|_)).
  939
  940%       colourise_dcg_goal(+Goal, +Origin, +TB, +Pos).
  941
  942colourise_dcg_goal(!, Origin, TB, TermPos) :-
  943    !,
  944    colourise_goal(!, Origin, TB, TermPos).
  945colourise_dcg_goal(Goal, Origin, TB, TermPos) :-
  946    dcg_extend(Goal, TheGoal),
  947    !,
  948    colourise_goal(TheGoal, Origin, TB, TermPos).
  949colourise_dcg_goal(Goal, _, TB, Pos) :-
  950    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.
  961                                        % Deal with list as goal (consult)
  962colourise_goal(_,_,_,Pos) :-
  963    var(Pos),
  964    !.
  965colourise_goal(Goal, Origin, TB, parentheses_term_position(PO,PC,Pos)) :-
  966    !,
  967    colour_item(parentheses, TB, PO-PC),
  968    colourise_goal(Goal, Origin, TB, Pos).
  969colourise_goal(Goal, _, TB, Pos) :-
  970    Pos = list_position(F,T,Elms,TailPos),
  971    Goal = [_|_],
  972    !,
  973    FT is F + 1,
  974    AT is T - 1,
  975    colour_item(goal_term(built_in, Goal), TB, Pos),
  976    colour_item(goal(built_in, Goal), TB, F-FT),
  977    colour_item(goal(built_in, Goal), TB, AT-T),
  978    colourise_file_list(Goal, TB, Elms, TailPos, any).
  979colourise_goal(Goal, Origin, TB, Pos) :-
  980    Pos = list_position(F,T,Elms,Tail),
  981    callable(Goal),
  982    Goal =.. [_,GH,GT|_],
  983    !,
  984    goal_classification(TB, Goal, Origin, Class),
  985    FT is F + 1,
  986    AT is T - 1,
  987    colour_item(goal_term(Class, Goal), TB, Pos),
  988    colour_item(goal(Class, Goal), TB, F-FT),
  989    colour_item(goal(Class, Goal), TB, AT-T),
  990    colourise_list_args(Elms, Tail, [GH|GT], TB, classify).
  991colourise_goal(Goal, _Origin, TB, Pos) :-
  992    Pos = quasi_quotation_position(_F,_T,_QQType,_QQTypePos,_CPos),
  993    !,
  994    colourise_term_arg(Goal, TB, Pos).
  995colourise_goal(Goal, Origin, TB, Pos) :-
  996    strip_module(Goal, _, PGoal),
  997    nonvar(PGoal),
  998    (   goal_classification(TB, Goal, Origin, ClassInferred),
  999        goal_colours(Goal, ClassInferred, ClassSpec-ArgSpecs)
 1000    ->  true
 1001    ;   goal_colours(Goal, ClassSpec-ArgSpecs)
 1002    ),
 1003    !,                                          % specified
 1004    functor_position(Pos, FPos, ArgPos),
 1005    (   ClassSpec == classify
 1006    ->  goal_classification(TB, Goal, Origin, Class)
 1007    ;   Class = ClassSpec
 1008    ),
 1009    colour_item(goal_term(Class, Goal), TB, Pos),
 1010    colour_item(goal(Class, Goal), TB, FPos),
 1011    colour_dict_braces(TB, Pos),
 1012    specified_items(ArgSpecs, Goal, TB, ArgPos).
 1013colourise_goal(Module:Goal, _Origin, TB, QGoalPos) :-
 1014    QGoalPos = term_position(_,_,QF,QT,[PM,PG]),
 1015    !,
 1016    colourise_module(Module, TB, PM),
 1017    colour_item(functor, TB, QF-QT),
 1018    (   PG = term_position(_,_,FF,FT,_)
 1019    ->  FP = FF-FT
 1020    ;   FP = PG
 1021    ),
 1022    (   callable(Goal)
 1023    ->  qualified_goal_classification(Module:Goal, TB, Class),
 1024        colour_item(goal_term(Class, Goal), TB, QGoalPos),
 1025        colour_item(goal(Class, Goal), TB, FP),
 1026        colourise_goal_args(Goal, Module, TB, PG)
 1027    ;   var(Goal)
 1028    ->  colourise_term_arg(Goal, TB, PG)
 1029    ;   colour_item(type_error(callable), TB, PG)
 1030    ).
 1031colourise_goal(Op, _Origin, TB, Pos) :-
 1032    nonvar(Op),
 1033    Op = op(_,_,_),
 1034    !,
 1035    colourise_op_declaration(Op, TB, Pos).
 1036colourise_goal(Goal, Origin, TB, Pos) :-
 1037    goal_classification(TB, Goal, Origin, Class),
 1038    (   Pos = term_position(_,_,FF,FT,_ArgPos)
 1039    ->  FPos = FF-FT
 1040    ;   FPos = Pos
 1041    ),
 1042    colour_item(goal_term(Class, Goal), TB, Pos),
 1043    colour_item(goal(Class, Goal), TB, FPos),
 1044    colourise_goal_args(Goal, TB, Pos).
 1045
 1046% make sure to emit a fragment for the braces of tag{k:v, ...} or
 1047% {...} that is mapped to something else.
 1048
 1049colour_dict_braces(TB, dict_position(_F,T,_TF,TT,_KVPos)) :-
 1050    !,
 1051    BStart is TT+1,
 1052    colour_item(dict_content, TB, BStart-T).
 1053colour_dict_braces(TB, brace_term_position(F,T,_Arg)) :-
 1054    !,
 1055    colour_item(brace_term, TB, F-T).
 1056colour_dict_braces(_, _).
 colourise_goal_args(+Goal, +TB, +Pos)
Colourise the arguments to a goal. This predicate deals with meta- and database-access predicates.
 1063colourise_goal_args(Goal, TB, Pos) :-
 1064    colourization_module(TB, Module),
 1065    colourise_goal_args(Goal, Module, TB, Pos).
 1066
 1067colourization_module(TB, Module) :-
 1068    (   colour_state_source_id(TB, SourceId),
 1069        xref_module(SourceId, Module)
 1070    ->  true
 1071    ;   Module = user
 1072    ).
 1073
 1074colourise_goal_args(Goal, M, TB, term_position(_,_,_,_,ArgPos)) :-
 1075    !,
 1076    (   meta_args(Goal, TB, MetaArgs)
 1077    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, ArgPos)
 1078    ;   colourise_goal_args(1, Goal, M, TB, ArgPos)
 1079    ).
 1080colourise_goal_args(Goal, M, TB, brace_term_position(_,_,ArgPos)) :-
 1081    !,
 1082    (   meta_args(Goal, TB, MetaArgs)
 1083    ->  colourise_meta_args(1, Goal, M, MetaArgs, TB, [ArgPos])
 1084    ;   colourise_goal_args(1, Goal, M, TB, [ArgPos])
 1085    ).
 1086colourise_goal_args(_, _, _, _).                % no arguments
 1087
 1088colourise_goal_args(_, _, _, _, []) :- !.
 1089colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1090    colourise_option_arg(Goal, Module, N, TB, P0),
 1091    !,
 1092    NN is N + 1,
 1093    colourise_goal_args(NN, Goal, Module, TB, PT).
 1094colourise_goal_args(N, Goal, Module, TB, [P0|PT]) :-
 1095    arg(N, Goal, Arg),
 1096    colourise_term_arg(Arg, TB, P0),
 1097    NN is N + 1,
 1098    colourise_goal_args(NN, Goal, Module, TB, PT).
 1099
 1100
 1101colourise_meta_args(_, _, _, _, _, []) :- !.
 1102colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1103    colourise_option_arg(Goal, Module, N, TB, P0),
 1104    !,
 1105    NN is N + 1,
 1106    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1107colourise_meta_args(N, Goal, Module, MetaArgs, TB, [P0|PT]) :-
 1108    arg(N, Goal, Arg),
 1109    arg(N, MetaArgs, MetaSpec),
 1110    colourise_meta_arg(MetaSpec, Arg, TB, P0),
 1111    NN is N + 1,
 1112    colourise_meta_args(NN, Goal, Module, MetaArgs, TB, PT).
 1113
 1114colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1115    nonvar(Arg),
 1116    expand_meta(MetaSpec, Arg, Expanded),
 1117    !,
 1118    colourise_goal(Expanded, [], TB, Pos). % TBD: recursion
 1119colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 1120    nonvar(Arg),
 1121    MetaSpec == //,
 1122    !,
 1123    colourise_dcg_goals(Arg, //, TB, Pos).
 1124colourise_meta_arg(_, Arg, TB, Pos) :-
 1125    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.

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

 2249syntax_colour(Class, Attributes) :-
 2250    (   style(Class, Attributes)            % user hook
 2251    ;   def_style(Class, Attributes)        % system default
 2252    ).
 term_colours(+Term, -FunctorColour, -ArgColours)
Define colourisation for specific terms.
 2259term_colours((?- Directive), Colours) :-
 2260    term_colours((:- Directive), Colours).
 2261term_colours((prolog:Head --> _),
 2262             neck(grammar_rule) - [ expanded - [ module(prolog),
 2263                                                 hook(message) - [ identifier
 2264                                                                 ]
 2265                                               ],
 2266                                    dcg_body(prolog:Head)
 2267                                  ]) :-
 2268    prolog_message_hook(Head).
 2269
 2270prolog_message_hook(message(_)).
 2271prolog_message_hook(error_message(_)).
 2272prolog_message_hook(message_context(_)).
 2273prolog_message_hook(message_location(_)).
 2274
 2275%       XPCE rules
 2276
 2277term_colours(variable(_, _, _, _),
 2278             expanded - [ identifier,
 2279                          classify,
 2280                          classify,
 2281                          comment(string)
 2282                        ]).
 2283term_colours(variable(_, _, _),
 2284             expanded - [ identifier,
 2285                          classify,
 2286                          atom
 2287                        ]).
 2288term_colours(handle(_, _, _),
 2289             expanded - [ classify,
 2290                          classify,
 2291                          classify
 2292                        ]).
 2293term_colours(handle(_, _, _, _),
 2294             expanded - [ classify,
 2295                          classify,
 2296                          classify,
 2297                          classify
 2298                        ]).
 2299term_colours(class_variable(_,_,_,_),
 2300             expanded - [ identifier,
 2301                          pce(type),
 2302                          pce(default),
 2303                          comment(string)
 2304                        ]).
 2305term_colours(class_variable(_,_,_),
 2306             expanded - [ identifier,
 2307                          pce(type),
 2308                          pce(default)
 2309                        ]).
 2310term_colours(delegate_to(_),
 2311             expanded - [ classify
 2312                        ]).
 2313term_colours((:- encoding(_)),
 2314             expanded - [ expanded - [ classify
 2315                                     ]
 2316                        ]).
 2317term_colours((:- pce_begin_class(_, _, _)),
 2318             expanded - [ expanded - [ identifier,
 2319                                       pce_new,
 2320                                       comment(string)
 2321                                     ]
 2322                        ]).
 2323term_colours((:- pce_begin_class(_, _)),
 2324             expanded - [ expanded - [ identifier,
 2325                                       pce_new
 2326                                     ]
 2327                        ]).
 2328term_colours((:- pce_extend_class(_)),
 2329             expanded - [ expanded - [ identifier
 2330                                     ]
 2331                        ]).
 2332term_colours((:- pce_end_class),
 2333             expanded - [ expanded
 2334                        ]).
 2335term_colours((:- pce_end_class(_)),
 2336             expanded - [ expanded - [ identifier
 2337                                     ]
 2338                        ]).
 2339term_colours((:- use_class_template(_)),
 2340             expanded - [ expanded - [ pce_new
 2341                                     ]
 2342                        ]).
 2343term_colours((:- emacs_begin_mode(_,_,_,_,_)),
 2344             expanded - [ expanded - [ identifier,
 2345                                       classify,
 2346                                       classify,
 2347                                       classify,
 2348                                       classify
 2349                                     ]
 2350                        ]).
 2351term_colours((:- emacs_extend_mode(_,_)),
 2352             expanded - [ expanded - [ identifier,
 2353                                       classify
 2354                                     ]
 2355                        ]).
 2356term_colours((:- pce_group(_)),
 2357             expanded - [ expanded - [ identifier
 2358                                     ]
 2359                        ]).
 2360term_colours((:- pce_global(_, new(_))),
 2361             expanded - [ expanded - [ identifier,
 2362                                       pce_arg
 2363                                     ]
 2364                        ]).
 2365term_colours((:- emacs_end_mode),
 2366             expanded - [ expanded
 2367                        ]).
 2368term_colours(pce_ifhostproperty(_,_),
 2369             expanded - [ classify,
 2370                          classify
 2371                        ]).
 2372term_colours((_,_),
 2373             error - [ classify,
 2374                       classify
 2375                     ]).
 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.
 2382specified_item(_Class, _Term, _TB, Pos) :-
 2383    var(Pos),
 2384    !.
 2385specified_item(Class, Term, TB, parentheses_term_position(PO,PC,Pos)) :-
 2386    !,
 2387    colour_item(parentheses, TB, PO-PC),
 2388    specified_item(Class, Term, TB, Pos).
 2389specified_item(_, Var, TB, Pos) :-
 2390    (   var(Var)
 2391    ;   qq_position(Pos)
 2392    ),
 2393    !,
 2394    colourise_term_arg(Var, TB, Pos).
 2395                                        % generic classification
 2396specified_item(classify, Term, TB, Pos) :-
 2397    !,
 2398    colourise_term_arg(Term, TB, Pos).
 2399                                        % classify as head
 2400specified_item(head, Term, TB, Pos) :-
 2401    !,
 2402    colourise_clause_head(Term, TB, Pos).
 2403                                        % expanded head (DCG=2, ...)
 2404specified_item(head(+N), Term, TB, Pos) :-
 2405    !,
 2406    colourise_extended_head(Term, N, TB, Pos).
 2407                                        % M:Head
 2408specified_item(extern(M), Term, TB, Pos) :-
 2409    !,
 2410    colourise_extern_head(Term, M, TB, Pos).
 2411                                        % classify as body
 2412specified_item(body, Term, TB, Pos) :-
 2413    !,
 2414    colourise_body(Term, TB, Pos).
 2415specified_item(body(Goal), _Term0, TB, Pos) :-
 2416    !,
 2417    colourise_body(Goal, TB, Pos).
 2418specified_item(dcg_body(Head), Term, TB, Pos) :-
 2419    !,
 2420    colourise_dcg(Term, Head, TB, Pos).
 2421specified_item(setof, Term, TB, Pos) :-
 2422    !,
 2423    colourise_setof(Term, TB, Pos).
 2424specified_item(meta(MetaSpec), Term, TB, Pos) :-
 2425    !,
 2426    colourise_meta_arg(MetaSpec, Term, TB, Pos).
 2427                                        % DCG goal in body
 2428specified_item(dcg, Term, TB, Pos) :-
 2429    !,
 2430    colourise_dcg(Term, [], TB, Pos).
 2431                                        % assert/retract arguments
 2432specified_item(db, Term, TB, Pos) :-
 2433    !,
 2434    colourise_db(Term, TB, Pos).
 2435                                        % files
 2436specified_item(file, Term, TB, Pos) :-
 2437    !,
 2438    colourise_files(Term, TB, Pos, any).
 2439specified_item(imported_file, Term, TB, Pos) :-
 2440    !,
 2441    colourise_files(Term, TB, Pos, imported).
 2442specified_item(langoptions, Term, TB, Pos) :-
 2443    !,
 2444    colourise_langoptions(Term, TB, Pos).
 2445
 2446                                        % directory
 2447specified_item(directory, Term, TB, Pos) :-
 2448    !,
 2449    colourise_directory(Term, TB, Pos).
 2450                                        % [Name/Arity, ...]
 2451specified_item(exports, Term, TB, Pos) :-
 2452    !,
 2453    colourise_exports(Term, TB, Pos).
 2454                                        % [Name/Arity, ...]
 2455specified_item(imports(File), Term, TB, Pos) :-
 2456    !,
 2457    colourise_imports(Term, File, TB, Pos).
 2458                                        % Name/Arity, ...
 2459specified_item(predicates, Term, TB, Pos) :-
 2460    !,
 2461    colourise_declarations(Term, TB, Pos).
 2462                                        % Name/Arity
 2463specified_item(predicate, Term, TB, Pos) :-
 2464    !,
 2465    colourise_declaration(Term, TB, Pos).
 2466                                        % head(Arg, ...)
 2467specified_item(meta_declarations, Term, TB, Pos) :-
 2468    !,
 2469    colourise_meta_declarations(Term, [], TB, Pos).
 2470specified_item(meta_declarations(Extra), Term, TB, Pos) :-
 2471    !,
 2472    colourise_meta_declarations(Term, Extra, TB, Pos).
 2473                                        % set_prolog_flag(Name, _)
 2474specified_item(prolog_flag_name, Term, TB, Pos) :-
 2475    !,
 2476    colourise_prolog_flag_name(Term, TB, Pos).
 2477                                        % XPCE new argument
 2478specified_item(pce_new, Term, TB, Pos) :-
 2479    !,
 2480    (   atom(Term)
 2481    ->  colourise_class(Term, TB, Pos)
 2482    ;   compound(Term)
 2483    ->  functor_name(Term, Class),
 2484        Pos = term_position(_,_,FF, FT, ArgPos),
 2485        colourise_class(Class, TB, FF-FT),
 2486        specified_items(pce_arg, Term, TB, ArgPos)
 2487    ;   colourise_term_arg(Term, TB, Pos)
 2488    ).
 2489                                        % Generic XPCE arguments
 2490specified_item(pce_arg, new(X), TB,
 2491               term_position(_,_,_,_,[ArgPos])) :-
 2492    !,
 2493    specified_item(pce_new, X, TB, ArgPos).
 2494specified_item(pce_arg, new(X, T), TB,
 2495               term_position(_,_,_,_,[P1, P2])) :-
 2496    !,
 2497    colourise_term_arg(X, TB, P1),
 2498    specified_item(pce_new, T, TB, P2).
 2499specified_item(pce_arg, @(Ref), TB, Pos) :-
 2500    !,
 2501    colourise_term_arg(@(Ref), TB, Pos).
 2502specified_item(pce_arg, prolog(Term), TB,
 2503               term_position(_,_,FF,FT,[ArgPos])) :-
 2504    !,
 2505    colour_item(prolog_data, TB, FF-FT),
 2506    colourise_term_arg(Term, TB, ArgPos).
 2507specified_item(pce_arg, Term, TB, Pos) :-
 2508    compound(Term),
 2509    Term \= [_|_],
 2510    !,
 2511    specified_item(pce_new, Term, TB, Pos).
 2512specified_item(pce_arg, Term, TB, Pos) :-
 2513    !,
 2514    colourise_term_arg(Term, TB, Pos).
 2515                                        % List of XPCE arguments
 2516specified_item(pce_arg_list, List, TB, list_position(F,T,Elms,Tail)) :-
 2517    !,
 2518    colour_item(list, TB, F-T),
 2519    colourise_list_args(Elms, Tail, List, TB, pce_arg).
 2520specified_item(pce_arg_list, Term, TB, Pos) :-
 2521    !,
 2522    specified_item(pce_arg, Term, TB, Pos).
 2523                                        % XPCE selector
 2524specified_item(pce_selector, Term, TB,
 2525               term_position(_,_,_,_,ArgPos)) :-
 2526    !,
 2527    specified_items(pce_arg, Term, TB, ArgPos).
 2528specified_item(pce_selector, Term, TB, Pos) :-
 2529    colourise_term_arg(Term, TB, Pos).
 2530                                        % Nested specification
 2531specified_item(FuncSpec-ArgSpecs, Term, TB,
 2532               term_position(_,_,FF,FT,ArgPos)) :-
 2533    !,
 2534    specified_item(FuncSpec, Term, TB, FF-FT),
 2535    specified_items(ArgSpecs, Term, TB, ArgPos).
 2536                                        % Nested for {...}
 2537specified_item(FuncSpec-[ArgSpec], {Term}, TB,
 2538               brace_term_position(F,T,ArgPos)) :-
 2539    !,
 2540    specified_item(FuncSpec, {Term}, TB, F-T),
 2541    specified_item(ArgSpec, Term, TB, ArgPos).
 2542                                        % Specified
 2543specified_item(FuncSpec-ElmSpec, List, TB,
 2544               list_position(F,T,ElmPos,TailPos)) :-
 2545    !,
 2546    colour_item(FuncSpec, TB, F-T),
 2547    specified_list(ElmSpec, List, TB, ElmPos, TailPos).
 2548specified_item(Class, _, TB, Pos) :-
 2549    colour_item(Class, TB, Pos).
 specified_items(+Spec, +Term, +TB, +PosList)
 2553specified_items(Specs, Term, TB, PosList) :-
 2554    is_dict(Term),
 2555    !,
 2556    specified_dict_kv(PosList, Term, TB, Specs).
 2557specified_items(Specs, Term, TB, PosList) :-
 2558    is_list(Specs),
 2559    !,
 2560    specified_arglist(Specs, 1, Term, TB, PosList).
 2561specified_items(Spec, Term, TB, PosList) :-
 2562    specified_argspec(PosList, Spec, 1, Term, TB).
 2563
 2564
 2565specified_arglist([], _, _, _, _).
 2566specified_arglist(_, _, _, _, []) :- !.         % Excess specification args
 2567specified_arglist([S0|ST], N, T, TB, [P0|PT]) :-
 2568    (   S0 == options,
 2569        colourization_module(TB, Module),
 2570        colourise_option_arg(T, Module, N, TB, P0)
 2571    ->  true
 2572    ;   arg(N, T, Term),
 2573        specified_item(S0, Term, TB, P0)
 2574    ),
 2575    NN is N + 1,
 2576    specified_arglist(ST, NN, T, TB, PT).
 2577
 2578specified_argspec([], _, _, _, _).
 2579specified_argspec([P0|PT], Spec, N, T, TB) :-
 2580    arg(N, T, Term),
 2581    specified_item(Spec, Term, TB, P0),
 2582    NN is N + 1,
 2583    specified_argspec(PT, Spec, NN, T, TB).
 2584
 2585
 2586%       specified_list(+Spec, +List, +TB, +PosList, TailPos)
 2587
 2588specified_list([], [], _, [], _).
 2589specified_list([HS|TS], [H|T], TB, [HP|TP], TailPos) :-
 2590    !,
 2591    specified_item(HS, H, TB, HP),
 2592    specified_list(TS, T, TB, TP, TailPos).
 2593specified_list(Spec, [H|T], TB, [HP|TP], TailPos) :-
 2594    specified_item(Spec, H, TB, HP),
 2595    specified_list(Spec, T, TB, TP, TailPos).
 2596specified_list(_, _, _, [], none) :- !.
 2597specified_list(Spec, Tail, TB, [], TailPos) :-
 2598    specified_item(Spec, Tail, TB, TailPos).
 specified_dict_kv(+PosList, +Term, +TB, +Specs)
Arguments:
Specs- is a list of dict_kv(+Key, +KeySpec, +ArgSpec)
 2604specified_dict_kv([], _, _, _).
 2605specified_dict_kv([key_value_position(_F,_T,SF,ST,K,KP,VP)|Pos],
 2606                  Dict, TB, Specs) :-
 2607    specified_dict_kv1(K, Specs, KeySpec, ValueSpec),
 2608    colour_item(KeySpec, TB, KP),
 2609    colour_item(dict_sep, TB, SF-ST),
 2610    get_dict(K, Dict, V),
 2611    specified_item(ValueSpec, V, TB, VP),
 2612    specified_dict_kv(Pos, Dict, TB, Specs).
 2613
 2614specified_dict_kv1(Key, Specs, KeySpec, ValueSpec) :-
 2615    Specs = [_|_],
 2616    memberchk(dict_kv(Key, KeySpec, ValueSpec), Specs),
 2617    !.
 2618specified_dict_kv1(Key, dict_kv(Key2, KeySpec, ValueSpec), KeySpec, ValueSpec) :-
 2619    \+ Key \= Key2,
 2620    !.              % do not bind Key2
 2621specified_dict_kv1(_, _, dict_key, classify).
 2622
 2623
 2624                 /*******************************
 2625                 *         DESCRIPTIONS         *
 2626                 *******************************/
 2627
 2628syntax_message(Class) -->
 2629    message(Class),
 2630    !.
 2631syntax_message(qq(_)) -->
 2632    [ 'Quasi quote delimiter' ].
 2633syntax_message(qq_type) -->
 2634    [ 'Quasi quote type term' ].
 2635syntax_message(qq_content(Type)) -->
 2636    [ 'Quasi quote content (~w syntax)'-[Type] ].
 2637syntax_message(goal(Class, Goal)) -->
 2638    !,
 2639    goal_message(Class, Goal).
 2640syntax_message(class(Type, Class)) -->
 2641    !,
 2642    xpce_class_message(Type, Class).
 2643syntax_message(dict_return_op) -->
 2644    !,
 2645    [ ':= separates function from return value' ].
 2646syntax_message(dict_function) -->
 2647    !,
 2648    [ 'Function on a dict' ].
 2649syntax_message(ext_quant) -->
 2650    !,
 2651    [ 'Existential quantification operator' ].
 2652syntax_message(hook(message)) -->
 2653    [ 'Rule for print_message/2' ].
 2654syntax_message(module(Module)) -->
 2655    (   { current_module(Module) }
 2656    ->  (   { module_property(Module, file(File)) }
 2657        ->  [ 'Module ~w defined in ~w'-[Module,File] ]
 2658        ;   [ 'Module ~w'-[Module] ]
 2659        )
 2660    ;   [ 'Module ~w (not loaded)'-[Module] ]
 2661    ).
 2662
 2663goal_message(meta, _) -->
 2664    [ 'Meta call' ].
 2665goal_message(not_callable, _) -->
 2666    [ 'Goal is not callable (type error)' ].
 2667goal_message(expanded, _) -->
 2668    [ 'Expanded goal' ].
 2669goal_message(Class, Goal) -->
 2670    { predicate_name(Goal, PI) },
 2671    [ 'Call to ~q'-PI ],
 2672    goal_class(Class).
 2673
 2674goal_class(recursion) -->
 2675    [ ' (recursive call)' ].
 2676goal_class(undefined) -->
 2677    [ ' (undefined)' ].
 2678goal_class(global) -->
 2679    [ ' (Auto-imported from module user)' ].
 2680goal_class(imported(From)) -->
 2681    [ ' (imported from ~q)'-[From] ].
 2682goal_class(extern(_, private)) -->
 2683    [ ' (WARNING: private predicate)' ].
 2684goal_class(extern(_, public)) -->
 2685    [ ' (public predicate)' ].
 2686goal_class(extern(_)) -->
 2687    [ ' (cross-module call)' ].
 2688goal_class(Class) -->
 2689    [ ' (~p)'-[Class] ].
 2690
 2691xpce_class_message(Type, Class) -->
 2692    [ 'XPCE ~w class ~q'-[Type, Class] ]