1510 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
			
		
		
	
	
			1510 lines
		
	
	
		
			46 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
/*  Part of SWI-Prolog
 | 
						|
 | 
						|
    Author:        Jan Wielemaker
 | 
						|
    E-mail:        J.Wielemaker@cs.vu.nl
 | 
						|
    WWW:           http://www.swi-prolog.org/projects/xpce/
 | 
						|
    Copyright (C): 1985-2011, University of Amsterdam
 | 
						|
			      VU University Amsterdam
 | 
						|
 | 
						|
    This program is free software; you can redistribute it and/or
 | 
						|
    modify it under the terms of the GNU General Public License
 | 
						|
    as published by the Free Software Foundation; either version 2
 | 
						|
    of the License, or (at your option) any later version.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU Lesser General Public
 | 
						|
    License along with this library; if not, write to the Free Software
 | 
						|
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
						|
 | 
						|
    As a special exception, if you link this library with other files,
 | 
						|
    compiled with a Free Software compiler, to produce an executable, this
 | 
						|
    library does not by itself cause the resulting executable to be covered
 | 
						|
    by the GNU General Public License. This exception does not however
 | 
						|
    invalidate any other reasons why the executable file might be covered by
 | 
						|
    the GNU General Public License.
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
:- module(prolog_colour,
 | 
						|
	  [ prolog_colourise_stream/3,	% +Stream, +SourceID, :ColourItem
 | 
						|
	    prolog_colourise_term/4,	% +Stream, +SourceID, :ColourItem, +Options
 | 
						|
	    syntax_colour/2,		% +Class, -Attributes
 | 
						|
	    syntax_message//1		% +Class
 | 
						|
	  ]).
 | 
						|
:- use_module(library(prolog_xref)).
 | 
						|
:- use_module(library(predicate_options)).
 | 
						|
:- use_module(library(prolog_source)).
 | 
						|
:- use_module(library(lists)).
 | 
						|
:- use_module(library(operators)).
 | 
						|
:- use_module(library(debug)).
 | 
						|
:- use_module(library(edit)).
 | 
						|
:- use_module(library(error)).
 | 
						|
:- use_module(library(option)).
 | 
						|
:- use_module(library(record)).
 | 
						|
:- if(exists_source(library(pce_meta))).
 | 
						|
:- use_module(library(pce_meta)).
 | 
						|
:- endif.
 | 
						|
 | 
						|
:- meta_predicate
 | 
						|
	prolog_colourise_stream(+, +, 3),
 | 
						|
	prolog_colourise_term(+, +, 3, +).
 | 
						|
 | 
						|
:- predicate_options(prolog_colourise_term/4, 4,
 | 
						|
		     [ subterm_positions(-any)
 | 
						|
		     ]).
 | 
						|
 | 
						|
/** <module> Prolog syntax colouring support.
 | 
						|
@ingroup swi
 | 
						|
 | 
						|
This module defines reusable code to colourise Prolog source.
 | 
						|
 | 
						|
@tbd: The one-term version
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
:- multifile
 | 
						|
	style/2,			% +ColourClass, -Attributes
 | 
						|
	message//1,			% +ColourClass
 | 
						|
	term_colours/2,			% +SourceTerm, -ColourSpec
 | 
						|
	goal_colours/2,			% +Goal, -ColourSpec
 | 
						|
	directive_colours/2,		% +Goal, -ColourSpec
 | 
						|
	goal_classification/2.		% +Goal, -Class
 | 
						|
 | 
						|
 | 
						|
:- record
 | 
						|
	colour_state(source_id,
 | 
						|
		     closure,
 | 
						|
		     singletons).
 | 
						|
 | 
						|
%%	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:
 | 
						|
%
 | 
						|
%	  * The syntactical category
 | 
						|
%	  * Start position (character offset) of the fragment
 | 
						|
%	  * Length of the fragment (in characters).
 | 
						|
 | 
						|
prolog_colourise_stream(Fd, SourceId, ColourItem) :-
 | 
						|
	make_colour_state([ source_id(SourceId),
 | 
						|
			    closure(ColourItem)
 | 
						|
			  ],
 | 
						|
			  TB),
 | 
						|
	setup_call_cleanup(
 | 
						|
	    save_settings(State),
 | 
						|
	    colourise_stream(Fd, TB),
 | 
						|
	    restore_settings(State)).
 | 
						|
 | 
						|
colourise_stream(Fd, TB) :-
 | 
						|
	(   peek_char(Fd, #)		% skip #! script line
 | 
						|
	->  skip(Fd, 10)
 | 
						|
	;   true
 | 
						|
	),
 | 
						|
	repeat,
 | 
						|
	    '$set_source_module'(SM, SM),
 | 
						|
	    character_count(Fd, Start),
 | 
						|
	    catch(read_term(Fd, Term,
 | 
						|
			    [ subterm_positions(TermPos),
 | 
						|
			      singletons(Singletons),
 | 
						|
			      module(SM),
 | 
						|
			      comments(Comments)
 | 
						|
			    ]),
 | 
						|
		  E,
 | 
						|
		  read_error(E, TB, Fd, Start)),
 | 
						|
	    fix_operators(Term, TB),
 | 
						|
	    colour_state_singletons(TB, Singletons),
 | 
						|
	    (	colourise_term(Term, TB, TermPos, Comments)
 | 
						|
	    ->	true
 | 
						|
	    ;	arg(1, TermPos, From),
 | 
						|
	        print_message(warning,
 | 
						|
			      format('Failed to colourise ~p at index ~d~n',
 | 
						|
				     [Term, From]))
 | 
						|
	    ),
 | 
						|
	    Term == end_of_file, !.
 | 
						|
 | 
						|
save_settings(state(Style, Esc)) :-
 | 
						|
	push_operators([]),
 | 
						|
	current_prolog_flag(character_escapes, Esc),
 | 
						|
	'$style_check'(Style, Style).
 | 
						|
 | 
						|
restore_settings(state(Style, Esc)) :-
 | 
						|
	set_prolog_flag(character_escapes, Esc),
 | 
						|
	'$style_check'(_, Style),
 | 
						|
	pop_operators.
 | 
						|
 | 
						|
%%	read_error(+Error, +TB, +Stream, +Start) is failure.
 | 
						|
%
 | 
						|
%	If this is a syntax error, create a syntax-error fragment.
 | 
						|
 | 
						|
read_error(Error, TB, Stream, Start) :-
 | 
						|
	(   Error = error(syntax_error(Id), stream(_S, _Line, _LinePos, CharNo))
 | 
						|
	->  message_to_string(error(syntax_error(Id), _), Msg),
 | 
						|
	    character_count(Stream, End),
 | 
						|
	    show_syntax_error(TB, CharNo:Msg, Start-End),
 | 
						|
	    fail
 | 
						|
	;   throw(Error)
 | 
						|
	).
 | 
						|
 | 
						|
%%	colour_item(+Class, +TB, +Pos) is det.
 | 
						|
 | 
						|
colour_item(Class, TB, Pos) :-
 | 
						|
	arg(1, Pos, Start),
 | 
						|
	arg(2, Pos, End),
 | 
						|
	Len is End - Start,
 | 
						|
	colour_state_closure(TB, Closure),
 | 
						|
	call(Closure, Class, Start, Len).
 | 
						|
 | 
						|
 | 
						|
%%	safe_push_op(+Prec, +Type, :Name)
 | 
						|
%
 | 
						|
%	Define operators into the default source module and register
 | 
						|
%	them to be undone by pop_operators/0.
 | 
						|
 | 
						|
safe_push_op(P, T, N0) :-
 | 
						|
	(   N0 = _:_
 | 
						|
	->  N = N0
 | 
						|
	;   '$set_source_module'(M, M),
 | 
						|
	    N = M:N0
 | 
						|
	),
 | 
						|
	push_op(P, T, N),
 | 
						|
	debug(colour, ':- ~w.', [op(P,T,N)]).
 | 
						|
 | 
						|
%%	fix_operators(+Term, +Src) 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.
 | 
						|
 | 
						|
fix_operators((:- Directive), Src) :-
 | 
						|
	catch(process_directive(Directive, Src), _, true), !.
 | 
						|
fix_operators(_, _).
 | 
						|
 | 
						|
process_directive(style_check(X), _) :- !,
 | 
						|
	style_check(X).
 | 
						|
process_directive(op(P,T,N), _) :- !,
 | 
						|
	safe_push_op(P, T, N).
 | 
						|
process_directive(module(_Name, Export), _) :- !,
 | 
						|
	forall(member(op(P,A,N), Export),
 | 
						|
	       safe_push_op(P,A,N)).
 | 
						|
process_directive(use_module(Spec), Src) :- !,
 | 
						|
	catch(process_use_module(Spec, Src), _, true).
 | 
						|
process_directive(Directive, Src) :-
 | 
						|
	prolog_source:expand((:-Directive), Src, _).
 | 
						|
 | 
						|
%%	process_use_module(+Imports, +Src)
 | 
						|
%
 | 
						|
%	Get the exported operators from the referenced files.
 | 
						|
 | 
						|
process_use_module([], _) :- !.
 | 
						|
process_use_module([H|T], Src) :- !,
 | 
						|
	process_use_module(H, Src),
 | 
						|
	process_use_module(T, Src).
 | 
						|
process_use_module(File, Src) :-
 | 
						|
	(   xref_public_list(File, _Path, Public, Src)
 | 
						|
	->  forall(member(op(P,T,N), Public),
 | 
						|
		   safe_push_op(P,T,N))
 | 
						|
	;   true
 | 
						|
	).
 | 
						|
 | 
						|
%%	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)
 | 
						|
 | 
						|
prolog_colourise_term(Stream, SourceId, ColourItem, Options) :-
 | 
						|
	make_colour_state([ source_id(SourceId),
 | 
						|
			    closure(ColourItem)
 | 
						|
			  ],
 | 
						|
			  TB),
 | 
						|
	option(subterm_positions(TermPos), Options, _),
 | 
						|
	findall(Op, xref_op(SourceId, Op), Ops),
 | 
						|
	character_count(Stream, Start),
 | 
						|
	read_source_term_at_location(
 | 
						|
	    Stream, Term,
 | 
						|
	    [ module(prolog_colour),
 | 
						|
	      operators(Ops),
 | 
						|
	      error(Error),
 | 
						|
	      subterm_positions(TermPos),
 | 
						|
	      singletons(Singletons),
 | 
						|
	      comments(Comments)
 | 
						|
	    ]),
 | 
						|
	(   var(Error)
 | 
						|
	->  colour_state_singletons(TB, Singletons),
 | 
						|
	    colour_item(range, TB, TermPos),		% Call to allow clearing
 | 
						|
	    colourise_term(Term, TB, TermPos, Comments)
 | 
						|
	;   character_count(Stream, End),
 | 
						|
	    TermPos = error_position(Start, End, Pos),
 | 
						|
	    colour_item(range, TB, TermPos),
 | 
						|
	    show_syntax_error(TB, Error, Start-End),
 | 
						|
	    Error = Pos:_Message
 | 
						|
	).
 | 
						|
 | 
						|
show_syntax_error(TB, Pos:Message, Range) :-
 | 
						|
	End is Pos + 1,
 | 
						|
	colour_item(syntax_error(Message, Range), TB, Pos-End).
 | 
						|
 | 
						|
 | 
						|
singleton(Var, TB) :-
 | 
						|
	colour_state_singletons(TB, Singletons),
 | 
						|
	member_var(Var, Singletons).
 | 
						|
 | 
						|
member_var(V, [_=V2|_]) :-
 | 
						|
	V == V2, !.
 | 
						|
member_var(V, [_|T]) :-
 | 
						|
	member_var(V, T).
 | 
						|
 | 
						|
%%	colourise_term(+Term, +TB, +Termpos, +Comments)
 | 
						|
 | 
						|
colourise_term(Term, TB, TermPos, Comments) :-
 | 
						|
	colourise_comments(Comments, TB),
 | 
						|
	colourise_term(Term, TB, TermPos).
 | 
						|
 | 
						|
colourise_comments(-, _).
 | 
						|
colourise_comments([], _).
 | 
						|
colourise_comments([H|T], TB) :-
 | 
						|
	colourise_comment(H, TB),
 | 
						|
	colourise_comments(T, TB).
 | 
						|
 | 
						|
colourise_comment(Pos-Comment, TB) :-
 | 
						|
	stream_position_data(char_count, Pos, Start),
 | 
						|
	string_length(Comment, Len),
 | 
						|
	End is Start + Len + 1,
 | 
						|
	colour_item(comment, TB, Start-End).
 | 
						|
 | 
						|
colourise_term(Term, TB, Pos) :-
 | 
						|
	term_colours(Term, FuncSpec-ArgSpecs), !,
 | 
						|
	Pos = term_position(_,_,FF,FT,ArgPos),
 | 
						|
	specified_item(FuncSpec, Term, TB, FF-FT),
 | 
						|
	specified_items(ArgSpecs, Term, TB, ArgPos).
 | 
						|
colourise_term((Head :- Body), TB,
 | 
						|
	       term_position(F,T,FF,FT,[HP,BP])) :- !,
 | 
						|
	colour_item(clause,	    TB,	F-T),
 | 
						|
	colour_item(neck(clause),   TB,	FF-FT),
 | 
						|
	colourise_clause_head(Head, TB,	HP),
 | 
						|
	colourise_body(Body, Head,  TB,	BP).
 | 
						|
colourise_term((Head --> Body), TB,			% TBD: expansion!
 | 
						|
	       term_position(F,T,FF,FT,[HP,BP])) :- !,
 | 
						|
	colour_item(grammar_rule,	TB, F-T),
 | 
						|
	colour_item(neck(grammar_rule),	TB, FF-FT),
 | 
						|
	colourise_extended_head(Head, 2, TB, HP),
 | 
						|
	colourise_dcg(Body, Head,	TB, BP).
 | 
						|
colourise_term(:->(Head, Body), TB,
 | 
						|
	       term_position(F,T,FF,FT,[HP,BP])) :- !,
 | 
						|
	colour_item(method,		TB, F-T),
 | 
						|
	colour_item(neck(method(send)),	TB, FF-FT),
 | 
						|
	colour_method_head(send(Head),	TB, HP),
 | 
						|
	colourise_method_body(Body,	TB, BP).
 | 
						|
colourise_term(:<-(Head, Body), TB,
 | 
						|
	       term_position(F,T,FF,FT,[HP,BP])) :- !,
 | 
						|
	colour_item(method,	       TB, F-T),
 | 
						|
	colour_item(neck(method(get)), TB, FF-FT),
 | 
						|
	colour_method_head(get(Head),  TB, HP),
 | 
						|
	colourise_method_body(Body,    TB, BP).
 | 
						|
colourise_term((:- Directive), TB, Pos) :- !,
 | 
						|
	colour_item(directive, TB, Pos),
 | 
						|
	arg(5, Pos, [ArgPos]),
 | 
						|
	colourise_directive(Directive, TB, ArgPos).
 | 
						|
colourise_term((?- Directive), TB, Pos) :- !,
 | 
						|
	colourise_term((:- Directive), TB, Pos).
 | 
						|
colourise_term(end_of_file, _, _) :- !.
 | 
						|
colourise_term(Fact, TB, Pos) :- !,
 | 
						|
	colour_item(clause, TB,	Pos),
 | 
						|
	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.
 | 
						|
 | 
						|
colourise_extended_head(Head, N, TB, Pos) :-
 | 
						|
	extend(Head, N, TheHead),
 | 
						|
	colourise_clause_head(TheHead, TB, Pos).
 | 
						|
 | 
						|
extend(M:Head, N, M:ExtHead) :-
 | 
						|
	nonvar(Head), !,
 | 
						|
	extend(Head, N, ExtHead).
 | 
						|
extend(Head, N, ExtHead) :-
 | 
						|
	callable(Head), !,
 | 
						|
	Head =.. List,
 | 
						|
	length(Extra, N),
 | 
						|
	append(List, Extra, List1),
 | 
						|
	ExtHead =.. List1.
 | 
						|
extend(Head, _, Head).
 | 
						|
 | 
						|
 | 
						|
colourise_clause_head(Head, TB, Pos) :-
 | 
						|
	head_colours(Head, ClassSpec-ArgSpecs), !,
 | 
						|
	functor_position(Pos, FPos, ArgPos),
 | 
						|
	(   ClassSpec == classify
 | 
						|
	->  classify_head(TB, Head, Class)
 | 
						|
	;   Class = ClassSpec
 | 
						|
	),
 | 
						|
	colour_item(head(Class), TB, FPos),
 | 
						|
	specified_items(ArgSpecs, Head, TB, ArgPos).
 | 
						|
colourise_clause_head(Head, TB, Pos) :-
 | 
						|
	functor_position(Pos, FPos, _),
 | 
						|
	classify_head(TB, Head, Class),
 | 
						|
	colour_item(head(Class), TB, FPos),
 | 
						|
	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.
 | 
						|
 | 
						|
colourise_extern_head(Head, M, TB, Pos) :-
 | 
						|
	functor_position(Pos, FPos, _),
 | 
						|
	colour_item(head(extern(M)), TB, FPos),
 | 
						|
	colourise_term_args(Head, TB, Pos).
 | 
						|
 | 
						|
colour_method_head(SGHead, TB, Pos) :-
 | 
						|
	arg(1, SGHead, Head),
 | 
						|
	functor(SGHead, SG, _),
 | 
						|
	functor_position(Pos, FPos, _),
 | 
						|
	colour_item(method(SG), TB, FPos),
 | 
						|
	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'.
 | 
						|
 | 
						|
functor_position(term_position(_,_,FF,FT,ArgPos), FF-FT, ArgPos) :- !.
 | 
						|
functor_position(list_position(F,_T,Elms,none), F-FT, Elms) :- !,
 | 
						|
	FT is F + 1.
 | 
						|
functor_position(Pos, Pos, []).
 | 
						|
 | 
						|
 | 
						|
%%	colourise_directive(+Body, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the body of a directive.
 | 
						|
 | 
						|
colourise_directive((A,B), TB, term_position(_,_,_,_,[PA,PB])) :- !,
 | 
						|
	colourise_directive(A, TB, PA),
 | 
						|
	colourise_directive(B, TB, PB).
 | 
						|
colourise_directive(Body, TB, Pos) :-
 | 
						|
	nonvar(Body),
 | 
						|
	directive_colours(Body, ClassSpec-ArgSpecs), !, % specified
 | 
						|
	functor_position(Pos, FPos, ArgPos),
 | 
						|
	(   ClassSpec == classify
 | 
						|
	->  goal_classification(TB, Body, [], Class)
 | 
						|
	;   Class = ClassSpec
 | 
						|
	),
 | 
						|
	colour_item(goal(Class, Body), TB, FPos),
 | 
						|
	specified_items(ArgSpecs, Body, TB, ArgPos).
 | 
						|
colourise_directive(Body, TB, Pos) :-
 | 
						|
	colourise_body(Body, TB, Pos).
 | 
						|
 | 
						|
 | 
						|
%	colourise_body(+Body, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Breaks down to colourise_goal/3.
 | 
						|
 | 
						|
colourise_body(Body, TB, Pos) :-
 | 
						|
	colourise_body(Body, [], TB, Pos).
 | 
						|
 | 
						|
colourise_body(Body, Origin, TB, Pos) :-
 | 
						|
	colour_item(body, TB, Pos),
 | 
						|
	colourise_goals(Body, Origin, TB, Pos).
 | 
						|
 | 
						|
%%	colourise_method_body(+MethodBody, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the optional "comment":: as pce(comment) and proceed
 | 
						|
%	with the body.
 | 
						|
%
 | 
						|
%	@tbd	Get this handled by a hook.
 | 
						|
 | 
						|
colourise_method_body(::(_Comment,Body), TB,
 | 
						|
		      term_position(_F,_T,_FF,_FT,[CP,BP])) :- !,
 | 
						|
	colour_item(comment, TB, CP),
 | 
						|
	colourise_body(Body, TB, BP).
 | 
						|
colourise_method_body(Body, TB, Pos) :-		% deal with pri(::) < 1000
 | 
						|
	Body =.. [F,A,B],
 | 
						|
	control_op(F), !,
 | 
						|
	Pos = term_position(_F,_T,_FF,_FT,
 | 
						|
			    [ AP,
 | 
						|
			      BP
 | 
						|
			    ]),
 | 
						|
	colourise_method_body(A, TB, AP),
 | 
						|
	colourise_body(B, TB, BP).
 | 
						|
colourise_method_body(Body, TB, Pos) :-
 | 
						|
	colourise_body(Body, TB, Pos).
 | 
						|
 | 
						|
control_op(',').
 | 
						|
control_op((;)).
 | 
						|
control_op((->)).
 | 
						|
control_op((*->)).
 | 
						|
 | 
						|
colourise_goals(Body, Origin, TB, term_position(_,_,_,_,ArgPos)) :-
 | 
						|
	body_compiled(Body), !,
 | 
						|
	colourise_subgoals(ArgPos, 1, Body, Origin, TB).
 | 
						|
colourise_goals(Goal, Origin, TB, Pos) :-
 | 
						|
	colourise_goal(Goal, Origin, TB, Pos).
 | 
						|
 | 
						|
colourise_subgoals([], _, _, _, _).
 | 
						|
colourise_subgoals([Pos|T], N, Body, Origin, TB) :-
 | 
						|
	arg(N, Body, Arg),
 | 
						|
	colourise_goals(Arg, Origin, TB, Pos),
 | 
						|
	NN is N + 1,
 | 
						|
	colourise_subgoals(T, NN, Body, Origin, TB).
 | 
						|
 | 
						|
%	colourise_dcg(+Body, +Head, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Breaks down to colourise_dcg_goal/3.
 | 
						|
 | 
						|
colourise_dcg(Body, Head, TB, Pos) :-
 | 
						|
	colour_item(dcg, TB, Pos),
 | 
						|
	dcg_extend(Head, Origin),
 | 
						|
	colourise_dcg_goals(Body, Origin, TB, Pos).
 | 
						|
 | 
						|
colourise_dcg_goals(Var, _, TB, Pos) :-
 | 
						|
	var(Var), !,
 | 
						|
	colour_item(goal(meta,Var), TB, Pos).
 | 
						|
colourise_dcg_goals({Body}, Origin, TB,	brace_term_position(F,T,Arg)) :- !,
 | 
						|
	colour_item(dcg(plain), TB, F-T),
 | 
						|
	colourise_goals(Body, Origin, TB, Arg).
 | 
						|
colourise_dcg_goals([], _, TB, Pos) :- !,
 | 
						|
	colour_item(dcg(list), TB, Pos).
 | 
						|
colourise_dcg_goals(List, _, TB, Pos) :-
 | 
						|
	List = [_|_], !,
 | 
						|
	colour_item(dcg(list), TB, Pos),
 | 
						|
	colourise_term_args(List, TB, Pos).
 | 
						|
colourise_dcg_goals(Body, Origin, TB, term_position(_,_,_,_,ArgPos)) :-
 | 
						|
	body_compiled(Body), !,
 | 
						|
	colourise_dcg_subgoals(ArgPos, 1, Body, Origin, TB).
 | 
						|
colourise_dcg_goals(Goal, Origin, TB, Pos) :-
 | 
						|
	colourise_dcg_goal(Goal, Origin, TB, Pos),
 | 
						|
	colourise_term_args(Goal, TB, Pos).
 | 
						|
 | 
						|
colourise_dcg_subgoals([], _, _, _, _).
 | 
						|
colourise_dcg_subgoals([Pos|T], N, Body, Origin, TB) :-
 | 
						|
	arg(N, Body, Arg),
 | 
						|
	colourise_dcg_goals(Arg, Origin, TB, Pos),
 | 
						|
	NN is N + 1,
 | 
						|
	colourise_dcg_subgoals(T, NN, Body, Origin, TB).
 | 
						|
 | 
						|
dcg_extend(Term, _) :-
 | 
						|
	var(Term), !, fail.
 | 
						|
dcg_extend(M:Term, M:Goal) :-
 | 
						|
	dcg_extend(Term, Goal).
 | 
						|
dcg_extend(Term, Goal) :-
 | 
						|
	callable(Term),
 | 
						|
	Term =.. List,
 | 
						|
	append(List, [_,_], List2),
 | 
						|
	Goal =.. List2.
 | 
						|
 | 
						|
%	colourise_dcg_goal(+Goal, +Origin, +TB, +Pos).
 | 
						|
 | 
						|
colourise_dcg_goal(!, Origin, TB, TermPos) :- !,
 | 
						|
	colourise_goal(!, Origin, TB, TermPos).
 | 
						|
colourise_dcg_goal(Goal, Origin, TB, TermPos) :-
 | 
						|
	dcg_extend(Goal, TheGoal), !,
 | 
						|
	colourise_goal(TheGoal, Origin, TB, TermPos).
 | 
						|
colourise_dcg_goal(Goal, _, TB, Pos) :-
 | 
						|
	colourise_term_args(Goal, TB, Pos).
 | 
						|
 | 
						|
 | 
						|
%	colourise_goal(+Goal, +Origin, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise access to a single goal.
 | 
						|
 | 
						|
					% Deal with list as goal (consult)
 | 
						|
colourise_goal(Goal, _, TB, list_position(F,T,Elms,_)) :- !,
 | 
						|
	FT is F + 1,
 | 
						|
	AT is T - 1,
 | 
						|
	colour_item(goal(built_in, Goal), TB, F-FT),
 | 
						|
	colour_item(goal(built_in, Goal), TB, AT-T),
 | 
						|
	colourise_file_list(Goal, TB, Elms).
 | 
						|
colourise_goal(Goal, Origin, TB, Pos) :-
 | 
						|
	nonvar(Goal),
 | 
						|
	goal_colours(Goal, ClassSpec-ArgSpecs), !, % specified
 | 
						|
	functor_position(Pos, FPos, ArgPos),
 | 
						|
	(   ClassSpec == classify
 | 
						|
	->  goal_classification(TB, Goal, Origin, Class)
 | 
						|
	;   Class = ClassSpec
 | 
						|
	),
 | 
						|
	colour_item(goal(Class, Goal), TB, FPos),
 | 
						|
	specified_items(ArgSpecs, Goal, TB, ArgPos).
 | 
						|
colourise_goal(Module:Goal, _Origin, TB, term_position(_,_,_,_,[PM,PG])) :- !,
 | 
						|
	colour_item(module(Module), TB, PM),
 | 
						|
	(   PG = term_position(_,_,FF,FT,_)
 | 
						|
	->  FP = FF-FT
 | 
						|
	;   FP = PG
 | 
						|
	),
 | 
						|
	colour_item(goal(extern(Module), Goal), TB, FP),
 | 
						|
	colourise_goal_args(Goal, TB, PG).
 | 
						|
colourise_goal(Goal, Origin, TB, Pos) :-
 | 
						|
	goal_classification(TB, Goal, Origin, Class),
 | 
						|
	(   Pos = term_position(_,_,FF,FT,_ArgPos)
 | 
						|
	->  FPos = FF-FT
 | 
						|
	;   FPos = Pos
 | 
						|
	),
 | 
						|
	colour_item(goal(Class, Goal), TB, FPos),
 | 
						|
	colourise_goal_args(Goal, TB, Pos).
 | 
						|
 | 
						|
%%	colourise_goal_args(+Goal, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the arguments to a goal. This predicate deals with
 | 
						|
%	meta- and database-access predicates.
 | 
						|
 | 
						|
colourise_goal_args(Goal, TB, term_position(_,_,_,_,ArgPos)) :-
 | 
						|
	colourise_options(Goal, TB, ArgPos),
 | 
						|
	meta_args(Goal, MetaArgs), !,
 | 
						|
	colourise_meta_args(1, Goal, MetaArgs, TB, ArgPos).
 | 
						|
colourise_goal_args(Goal, TB, Pos) :-
 | 
						|
	Pos = term_position(_,_,_,_,ArgPos), !,
 | 
						|
	colourise_options(Goal, TB, ArgPos),
 | 
						|
	colourise_term_args(Goal, TB, Pos).
 | 
						|
colourise_goal_args(_, _, _).		% no arguments
 | 
						|
 | 
						|
colourise_meta_args(_, _, _, _, []) :- !.
 | 
						|
colourise_meta_args(N, Goal, MetaArgs, TB, [P0|PT]) :-
 | 
						|
	arg(N, Goal, Arg),
 | 
						|
	arg(N, MetaArgs, MetaSpec),
 | 
						|
	colourise_meta_arg(MetaSpec, Arg, TB, P0),
 | 
						|
	NN is N + 1,
 | 
						|
	colourise_meta_args(NN, Goal, MetaArgs, TB, PT).
 | 
						|
 | 
						|
colourise_meta_arg(MetaSpec, Arg, TB, Pos) :-
 | 
						|
	expand_meta(MetaSpec, Arg, Expanded), !,
 | 
						|
	colourise_goal(Expanded, [], TB, Pos). % TBD: recursion
 | 
						|
colourise_meta_arg(_, Arg, TB, Pos) :-
 | 
						|
	colourise_term_arg(Arg, TB, Pos).
 | 
						|
 | 
						|
%	meta_args(+Goal, -ArgSpec)
 | 
						|
%
 | 
						|
%	Return a copy of Goal, where each meta-argument is an integer
 | 
						|
%	representing the number of extra arguments. 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.
 | 
						|
 | 
						|
meta_args(Goal, VarGoal) :-
 | 
						|
	xref_meta(Goal, _),
 | 
						|
	functor(Goal, Name, Arity),
 | 
						|
	functor(VarGoal, Name, Arity),
 | 
						|
	xref_meta(VarGoal, MetaArgs),
 | 
						|
	instantiate_meta(MetaArgs).
 | 
						|
 | 
						|
instantiate_meta([]).
 | 
						|
instantiate_meta([H|T]) :-
 | 
						|
	(   var(H)
 | 
						|
	->  H = 0
 | 
						|
	;   H = V+N
 | 
						|
	->  V = N
 | 
						|
	),
 | 
						|
	instantiate_meta(T).
 | 
						|
 | 
						|
%	expand_meta(+MetaSpec, +Goal, -Expanded)
 | 
						|
%
 | 
						|
%	Add extra arguments to the goal if the meta-specifier is an
 | 
						|
%	integer (see above).
 | 
						|
 | 
						|
expand_meta(MetaSpec, Goal, Goal) :-
 | 
						|
	MetaSpec == 0.
 | 
						|
expand_meta(MetaSpec, M:Goal, M:Expanded) :-
 | 
						|
	atom(M), !,
 | 
						|
	expand_meta(MetaSpec, Goal, Expanded).
 | 
						|
expand_meta(MetaSpec, Goal, Expanded) :-
 | 
						|
	integer(MetaSpec),
 | 
						|
	callable(Goal), !,
 | 
						|
	length(Extra, MetaSpec),
 | 
						|
	Goal =.. List0,
 | 
						|
	append(List0, Extra, List),
 | 
						|
	Expanded =.. List.
 | 
						|
 | 
						|
%%	colourise_setof(+Term, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the 2nd argument of setof/bagof
 | 
						|
 | 
						|
colourise_setof(Var^G, TB, term_position(_,_,FF,FT,[VP,GP])) :- !,
 | 
						|
	colourise_term_arg(Var, TB, VP),
 | 
						|
	colour_item(built_in, TB, FF-FT),
 | 
						|
	colourise_setof(G, TB, GP).
 | 
						|
colourise_setof(Term, TB, Pos) :-
 | 
						|
	colourise_goal(Term, [], TB, Pos).
 | 
						|
 | 
						|
%	colourise_db(+Arg, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise database modification calls (assert/1, retract/1 and
 | 
						|
%	friends.
 | 
						|
 | 
						|
colourise_db((Head:-_Body), TB, term_position(_,_,_,_,[HP,_])) :- !,
 | 
						|
	colourise_db(Head, TB, HP).
 | 
						|
colourise_db(Module:Head, TB, term_position(_,_,_,_,[MP,HP])) :- !,
 | 
						|
	colour_item(module(Module), TB, MP),
 | 
						|
	(   atom(Module),
 | 
						|
	    colour_state_source_id(TB, SourceId),
 | 
						|
	    xref_module(SourceId, Module)
 | 
						|
	->  colourise_db(Head, TB, HP)
 | 
						|
	;   true			% TBD: Modifying in other module
 | 
						|
	).
 | 
						|
colourise_db(Head, TB, Pos) :-
 | 
						|
	colourise_goal(Head, '<db-change>', TB, Pos).
 | 
						|
 | 
						|
 | 
						|
%%	colourise_options(+Goal, +TB, +ArgPos)
 | 
						|
%
 | 
						|
%	Colourise predicate options
 | 
						|
 | 
						|
colourise_options(Goal, TB, ArgPos) :-
 | 
						|
	(   compound(Goal),
 | 
						|
	    functor(Goal, Name, Arity),
 | 
						|
	    (	colour_state_source_id(TB, SourceId),
 | 
						|
		xref_module(SourceId, Module)
 | 
						|
	    ->	true
 | 
						|
	    ;	Module = user
 | 
						|
	    ),
 | 
						|
	    current_predicate_options(Module:Name/Arity, Arg, OptionDecl),
 | 
						|
	    debug(emacs, 'Colouring option-arg ~w of ~p',
 | 
						|
		  [Arg, Module:Name/Arity]),
 | 
						|
	    arg(Arg, Goal, Options0),
 | 
						|
	    nth1(Arg, ArgPos, Pos0),
 | 
						|
	    strip_option_module_qualifier(Goal, Module, Arg, TB,
 | 
						|
					  Options0, Pos0, Options, Pos),
 | 
						|
	    (	Pos = list_position(_, _, ElmPos, TailPos)
 | 
						|
	    ->	colourise_option_list(Options, OptionDecl, TB, ElmPos, TailPos)
 | 
						|
	    ;	(   var(Options)
 | 
						|
		;   Options == []
 | 
						|
		)
 | 
						|
	    ->	colourise_term_arg(Options, TB, Pos)
 | 
						|
	    ;	colour_item(type_error(list), TB, Pos)
 | 
						|
	    ),
 | 
						|
	    fail
 | 
						|
	;   true
 | 
						|
	).
 | 
						|
 | 
						|
strip_option_module_qualifier(Goal, Module, Arg, TB,
 | 
						|
			      M:Options, term_position(_,_,_,_,[MP,Pos]),
 | 
						|
			      Options, Pos) :-
 | 
						|
	predicate_property(Module:Goal, meta_predicate(Head)),
 | 
						|
	arg(Arg, Head, :), !,
 | 
						|
	colour_item(module(M), TB, MP).
 | 
						|
strip_option_module_qualifier(_, _, _, _,
 | 
						|
			      Options, Pos, Options, Pos).
 | 
						|
 | 
						|
 | 
						|
colourise_option_list(_, _, _, [], none).
 | 
						|
colourise_option_list(Tail, _, TB, [], TailPos) :-
 | 
						|
	colourise_term_arg(Tail, TB, TailPos).
 | 
						|
colourise_option_list([H|T], OptionDecl, TB, [HPos|TPos], TailPos) :-
 | 
						|
	colourise_option(H, OptionDecl, TB, HPos),
 | 
						|
	colourise_option_list(T, OptionDecl, TB, TPos, TailPos).
 | 
						|
 | 
						|
colourise_option(Opt, _, TB, Pos) :-
 | 
						|
	var(Opt), !,
 | 
						|
	colourise_term_arg(Opt, TB, Pos).
 | 
						|
colourise_option(Opt, OptionDecl, TB, term_position(_,_,FF,FT,ValPosList)) :- !,
 | 
						|
	functor(Opt, Name, Arity),
 | 
						|
	functor(GenOpt, Name, Arity),
 | 
						|
	(   memberchk(GenOpt, OptionDecl)
 | 
						|
	->  colour_item(option_name, TB, FF-FT),
 | 
						|
	    Opt =.. [Name|Values],
 | 
						|
	    GenOpt =.. [Name|Types],
 | 
						|
	    colour_option_values(Values, Types, TB, ValPosList)
 | 
						|
	;   colour_item(no_option_name, TB, FF-FT)
 | 
						|
	).
 | 
						|
colourise_option(_, _, TB, Pos) :-
 | 
						|
	colour_item(type_error(option), TB, Pos).
 | 
						|
 | 
						|
colour_option_values([], [], _, _).
 | 
						|
colour_option_values([V0|TV], [T0|TT], TB, [P0|TP]) :-
 | 
						|
	(   (   var(V0)
 | 
						|
	    ;	is_of_type(T0, V0)
 | 
						|
	    )
 | 
						|
	->  colourise_term_arg(V0, TB, P0)
 | 
						|
	;   callable(V0),
 | 
						|
	    (	T0 = callable
 | 
						|
	    ->	N = 0
 | 
						|
	    ;	T0 = (callable+N)
 | 
						|
	    )
 | 
						|
	->  colourise_meta_arg(N, V0, TB, P0)
 | 
						|
	;   colour_item(type_error(T0), TB, P0)
 | 
						|
	),
 | 
						|
	colour_option_values(TV, TT, TB, TP).
 | 
						|
 | 
						|
 | 
						|
%%	colourise_files(+Arg, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the argument list of one of the file-loading predicates.
 | 
						|
 | 
						|
colourise_files(List, TB, list_position(_,_,Elms,_)) :- !,
 | 
						|
	colourise_file_list(List, TB, Elms).
 | 
						|
colourise_files(M:Spec, TB, term_position(_,_,_,_,[MP,SP])) :- !,
 | 
						|
	colour_item(module(M), TB, MP),
 | 
						|
	colourise_files(Spec, TB, SP).
 | 
						|
colourise_files(Var, TB, P) :-
 | 
						|
	var(Var), !,
 | 
						|
	colour_item(var, TB, P).
 | 
						|
colourise_files(Spec0, TB, Pos) :-
 | 
						|
	strip_module(Spec0, _, Spec),
 | 
						|
	(   colour_state_source_id(TB, Source),
 | 
						|
	    prolog_canonical_source(Source, SourceId),
 | 
						|
	    catch(xref_source_file(Spec, Path, SourceId), _, fail)
 | 
						|
	->  colour_item(file(Path), TB, Pos)
 | 
						|
	;   colour_item(nofile, TB, Pos)
 | 
						|
	).
 | 
						|
 | 
						|
colourise_file_list([], _, _).
 | 
						|
colourise_file_list([H|T], TB, [PH|PT]) :-
 | 
						|
	colourise_files(H, TB, PH),
 | 
						|
	colourise_file_list(T, TB, PT).
 | 
						|
 | 
						|
 | 
						|
%%	colourise_directory(+Arg, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise argument that should be an existing directory.
 | 
						|
 | 
						|
colourise_directory(Spec, TB, Pos) :-
 | 
						|
	(   colour_state_source_id(TB, SourceId),
 | 
						|
	    catch(xref_source_file(Spec, Path, SourceId,
 | 
						|
				   [file_type(directory)]),
 | 
						|
		  _, fail)
 | 
						|
	->  colour_item(directory(Path), TB, Pos)
 | 
						|
	;   colour_item(nofile, TB, Pos)
 | 
						|
	).
 | 
						|
 | 
						|
 | 
						|
%%	colourise_class(ClassName, TB, Pos)
 | 
						|
%
 | 
						|
%	Colourise an XPCE class.
 | 
						|
 | 
						|
colourise_class(ClassName, TB, Pos) :-
 | 
						|
	colour_state_source_id(TB, SourceId),
 | 
						|
	classify_class(SourceId, ClassName, Classification),
 | 
						|
	colour_item(class(Classification, ClassName), TB, Pos).
 | 
						|
 | 
						|
%%	classify_class(+SourceId, +ClassName, -Classification).
 | 
						|
 | 
						|
classify_class(SourceId, Name, Class) :-
 | 
						|
	xref_defined_class(SourceId, Name, Class), !.
 | 
						|
:- if(current_predicate(classify_class/2)).
 | 
						|
classify_class(_, Name, Class) :-
 | 
						|
	classify_class(Name, Class).
 | 
						|
:- endif.
 | 
						|
 | 
						|
%%	colourise_term_args(+Term, +TB, +Pos)
 | 
						|
%
 | 
						|
%	colourise head/body principal terms.
 | 
						|
 | 
						|
colourise_term_args(Term, TB,
 | 
						|
		    term_position(_,_,_,_,ArgPos)) :- !,
 | 
						|
	colourise_term_args(ArgPos, 1, Term, TB).
 | 
						|
colourise_term_args(_, _, _).
 | 
						|
 | 
						|
colourise_term_args([], _, _, _).
 | 
						|
colourise_term_args([Pos|T], N, Term, TB) :-
 | 
						|
	arg(N, Term, Arg),
 | 
						|
	colourise_term_arg(Arg, TB, Pos),
 | 
						|
	NN is N + 1,
 | 
						|
	colourise_term_args(T, NN, Term, TB).
 | 
						|
 | 
						|
colourise_term_arg(Var, TB, Pos) :-			% variable
 | 
						|
	var(Var), !,
 | 
						|
	(   singleton(Var, TB)
 | 
						|
	->  colour_item(singleton, TB, Pos)
 | 
						|
	;   colour_item(var, TB, Pos)
 | 
						|
	).
 | 
						|
colourise_term_arg(List, TB, list_position(_, _, Elms, Tail)) :- !,
 | 
						|
	colourise_list_args(Elms, Tail, List, TB, classify).	% list
 | 
						|
colourise_term_arg(Compound, TB, Pos) :-		% compound
 | 
						|
	compound(Compound), !,
 | 
						|
	colourise_term_args(Compound, TB, Pos).
 | 
						|
colourise_term_arg(_, TB, string_position(F, T)) :- !,	% string
 | 
						|
	colour_item(string, TB, F-T).
 | 
						|
colourise_term_arg(Atom, TB, Pos) :-			% single quoted atom
 | 
						|
	atom(Atom), !,
 | 
						|
	colour_item(atom, TB, Pos).
 | 
						|
colourise_term_arg(_Arg, _TB, _Pos) :-
 | 
						|
	true.
 | 
						|
 | 
						|
colourise_list_args([HP|TP], Tail, [H|T], TB, How) :-
 | 
						|
	specified_item(How, H, TB, HP),
 | 
						|
	colourise_list_args(TP, Tail, T, TB, How).
 | 
						|
colourise_list_args([], none, _, _, _) :- !.
 | 
						|
colourise_list_args([], TP, T, TB, How) :-
 | 
						|
	specified_item(How, T, TB, TP).
 | 
						|
 | 
						|
 | 
						|
%	colourise_exports(+List, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the module export-list (or any other list holding
 | 
						|
%	terms of the form Name/Arity referring to predicates).
 | 
						|
 | 
						|
colourise_exports([], _, _) :- !.
 | 
						|
colourise_exports(List, TB, list_position(_,_,ElmPos,Tail)) :- !,
 | 
						|
	(   Tail == none
 | 
						|
	->  true
 | 
						|
	;   colour_item(type_error(list), TB, Tail)
 | 
						|
	),
 | 
						|
	colourise_exports2(List, TB, ElmPos).
 | 
						|
colourise_exports(_, TB, Pos) :-
 | 
						|
	colour_item(type_error(list), TB, Pos).
 | 
						|
 | 
						|
colourise_exports2([G0|GT], TB, [P0|PT]) :- !,
 | 
						|
	colourise_declaration(G0, TB, P0),
 | 
						|
	colourise_exports2(GT, TB, PT).
 | 
						|
colourise_exports2(_, _, _).
 | 
						|
 | 
						|
 | 
						|
%	colourise_imports(+List, +File, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise import list from use_module/2, importing from File.
 | 
						|
 | 
						|
colourise_imports(List, File, TB, Pos) :-
 | 
						|
	(   colour_state_source_id(TB, SourceId),
 | 
						|
	    catch(xref_public_list(File, Path, Public, SourceId), _, fail)
 | 
						|
	->  true
 | 
						|
	;   Public = []
 | 
						|
	),
 | 
						|
	colourise_imports(List, Path, Public, TB, Pos).
 | 
						|
 | 
						|
colourise_imports([], _, _, _, _).
 | 
						|
colourise_imports(List, File, Public, TB, list_position(_,_,ElmPos,Tail)) :- !,
 | 
						|
	(   Tail == none
 | 
						|
	->  true
 | 
						|
	;   colour_item(type_error(list), TB, Tail)
 | 
						|
	),
 | 
						|
	colourise_imports2(List, File, Public, TB, ElmPos).
 | 
						|
colourise_imports(except(Except), File, Public, TB,
 | 
						|
		  term_position(_,_,FF,FT,[LP])) :- !,
 | 
						|
	colour_item(keyword(except), TB, FF-FT),
 | 
						|
	colourise_imports(Except, File, Public, TB, LP).
 | 
						|
colourise_imports(_, _, _, TB, Pos) :-
 | 
						|
	colour_item(type_error(list), TB, Pos).
 | 
						|
 | 
						|
colourise_imports2([G0|GT], File, Public, TB, [P0|PT]) :- !,
 | 
						|
	colourise_import(G0, File, TB, P0),
 | 
						|
	colourise_imports2(GT, File, Public, TB, PT).
 | 
						|
colourise_imports2(_, _, _, _, _).
 | 
						|
 | 
						|
 | 
						|
colourise_import(PI as Name, File, TB, term_position(_,_,FF,FT,[PP,NP])) :-
 | 
						|
	pi_to_term(PI, Goal), !,
 | 
						|
	colour_item(goal(imported(File), Goal), TB, PP),
 | 
						|
	functor(Goal, _, Arity),
 | 
						|
	functor(NewGoal, Name, Arity),
 | 
						|
	goal_classification(TB, NewGoal, [], Class),
 | 
						|
	colour_item(goal(Class, NewGoal), TB, NP),
 | 
						|
	colour_item(keyword(as), TB, FF-FT).
 | 
						|
colourise_import(PI, _, TB, Pos) :-
 | 
						|
	colourise_declaration(PI, TB, Pos).
 | 
						|
 | 
						|
 | 
						|
%%	colourise_declarations(+Term, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the Predicate indicator lists of dynamic, multifile, etc
 | 
						|
%	declarations.
 | 
						|
 | 
						|
colourise_declarations((Head,Tail), TB,
 | 
						|
		       term_position(_,_,_,_,[PH,PT])) :- !,
 | 
						|
	colourise_declaration(Head, TB, PH),
 | 
						|
	colourise_declarations(Tail, TB, PT).
 | 
						|
colourise_declarations(Last, TB, Pos) :-
 | 
						|
	colourise_declaration(Last, TB, Pos).
 | 
						|
 | 
						|
colourise_declaration(PI, TB, Pos) :-
 | 
						|
	pi_to_term(PI, Goal), !,
 | 
						|
	goal_classification(TB, Goal, [], Class),
 | 
						|
	colour_item(goal(Class, Goal), TB, Pos).
 | 
						|
colourise_declaration(Module:PI, TB,
 | 
						|
		      term_position(_,_,_,_,[PM,PG])) :-
 | 
						|
	atom(Module), pi_to_term(PI, Goal), !,
 | 
						|
	colour_item(module(M), TB, PM),
 | 
						|
	colour_item(goal(extern(M), Goal), TB, PG).
 | 
						|
colourise_declaration(op(_,_,_), TB, Pos) :-
 | 
						|
	colour_item(exported_operator, TB, Pos).
 | 
						|
colourise_declaration(_, TB, Pos) :-
 | 
						|
	colour_item(type_error(export_declaration), TB, Pos).
 | 
						|
 | 
						|
pi_to_term(Name/Arity, Term) :-
 | 
						|
	atom(Name), integer(Arity), !,
 | 
						|
	functor(Term, Name, Arity).
 | 
						|
pi_to_term(Name//Arity0, Term) :-
 | 
						|
	atom(Name), integer(Arity0), !,
 | 
						|
	Arity is Arity0 + 2,
 | 
						|
	functor(Term, Name, Arity).
 | 
						|
 | 
						|
%%	colourise_prolog_flag_name(+Name, +TB, +Pos)
 | 
						|
%
 | 
						|
%	Colourise the name of a Prolog flag
 | 
						|
 | 
						|
colourise_prolog_flag_name(Name, TB, Pos) :-
 | 
						|
	atom(Name), !,
 | 
						|
	(   current_prolog_flag(Name, _)
 | 
						|
	->  colour_item(flag_name(Name), TB, Pos)
 | 
						|
	;   colour_item(no_flag_name(Name), TB, Pos)
 | 
						|
	).
 | 
						|
colourise_prolog_flag_name(Name, TB, Pos) :-
 | 
						|
	colourise_term(Name, TB, Pos).
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	  CONFIGURATION		*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
%	body_compiled(+Term)
 | 
						|
%
 | 
						|
%	Succeeds if term is a construct handled by the compiler.
 | 
						|
 | 
						|
body_compiled((_,_)).
 | 
						|
body_compiled((_->_)).
 | 
						|
body_compiled((_*->_)).
 | 
						|
body_compiled((_;_)).
 | 
						|
body_compiled(\+_).
 | 
						|
 | 
						|
%	goal_classification(+TB, +Goal, +Origin, -Class)
 | 
						|
%
 | 
						|
%	Classify Goal appearing in TB and called from a clause with head
 | 
						|
%	Origin.  For directives Origin is [].
 | 
						|
 | 
						|
goal_classification(_, Goal, _, meta) :-
 | 
						|
	var(Goal), !.
 | 
						|
goal_classification(_, Goal, Origin, recursion) :-
 | 
						|
	callable(Goal),
 | 
						|
	functor(Goal, Name, Arity),
 | 
						|
	functor(Origin, Name, Arity), !.
 | 
						|
goal_classification(TB, Goal, _, How) :-
 | 
						|
	colour_state_source_id(TB, SourceId),
 | 
						|
	xref_defined(SourceId, Goal, How),
 | 
						|
	How \= public(_), !.
 | 
						|
goal_classification(_TB, Goal, _, Class) :-
 | 
						|
	goal_classification(Goal, Class), !.
 | 
						|
goal_classification(_TB, _Goal, _, undefined).
 | 
						|
 | 
						|
%	goal_classification(+Goal, -Class)
 | 
						|
%
 | 
						|
%	Multifile hookable classification for non-local goals.
 | 
						|
 | 
						|
goal_classification(Goal, built_in) :-
 | 
						|
	built_in_predicate(Goal), !.
 | 
						|
goal_classification(Goal, autoload) :-	% SWI-Prolog
 | 
						|
	functor(Goal, Name, Arity),
 | 
						|
	'$in_library'(Name, Arity, _Path), !.
 | 
						|
goal_classification(Goal, global) :-	% SWI-Prolog
 | 
						|
	current_predicate(_, user:Goal), !.
 | 
						|
goal_classification(SS, expanded) :-	% XPCE (TBD)
 | 
						|
	functor(SS, send_super, A),
 | 
						|
	A >= 2, !.
 | 
						|
goal_classification(SS, expanded) :-	% XPCE (TBD)
 | 
						|
	functor(SS, get_super, A),
 | 
						|
	A >= 3, !.
 | 
						|
 | 
						|
classify_head(TB, Goal, exported) :-
 | 
						|
	colour_state_source_id(TB, SourceId),
 | 
						|
	xref_exported(SourceId, Goal), !.
 | 
						|
classify_head(_TB, Goal, hook) :-
 | 
						|
	xref_hook(Goal), !.
 | 
						|
classify_head(TB, Goal, hook) :-
 | 
						|
	colour_state_source_id(TB, SourceId),
 | 
						|
	xref_module(SourceId, M),
 | 
						|
	xref_hook(M:Goal), !.
 | 
						|
classify_head(TB, Goal, unreferenced) :-
 | 
						|
	colour_state_source_id(TB, SourceId),
 | 
						|
	\+ (xref_called(SourceId, Goal, By), By \= Goal), !.
 | 
						|
classify_head(TB, Goal, How) :-
 | 
						|
	colour_state_source_id(TB, SourceId),
 | 
						|
	xref_defined(SourceId, Goal, How), !.
 | 
						|
classify_head(_TB, Goal, built_in) :-
 | 
						|
	built_in_predicate(Goal), !.
 | 
						|
classify_head(_TB, _Goal, undefined).
 | 
						|
 | 
						|
built_in_predicate(Goal) :-
 | 
						|
	predicate_property(system:Goal, built_in), !.
 | 
						|
built_in_predicate(module(_, _)).
 | 
						|
built_in_predicate(if(_)).
 | 
						|
built_in_predicate(elif(_)).
 | 
						|
built_in_predicate(else).
 | 
						|
built_in_predicate(endif).
 | 
						|
 | 
						|
%	Specify colours for individual goals.
 | 
						|
 | 
						|
goal_colours(module(_,_),	     built_in-[identifier,exports]).
 | 
						|
goal_colours(use_module(_),	     built_in-[file]).
 | 
						|
goal_colours(use_module(File,_),     built_in-[file,imports(File)]).
 | 
						|
goal_colours(reexport(_),	     built_in-[file]).
 | 
						|
goal_colours(reexport(File,_),       built_in-[file,imports(File)]).
 | 
						|
goal_colours(dynamic(_),	     built_in-[predicates]).
 | 
						|
goal_colours(thread_local(_),	     built_in-[predicates]).
 | 
						|
goal_colours(module_transparent(_),  built_in-[predicates]).
 | 
						|
goal_colours(multifile(_),	     built_in-[predicates]).
 | 
						|
goal_colours(volatile(_),	     built_in-[predicates]).
 | 
						|
goal_colours(public(_),		     built_in-[predicates]).
 | 
						|
goal_colours(consult(_),	     built_in-[file]).
 | 
						|
goal_colours(include(_),	     built_in-[file]).
 | 
						|
goal_colours(ensure_loaded(_),	     built_in-[file]).
 | 
						|
goal_colours(load_files(_,_),	     built_in-[file,classify]).
 | 
						|
goal_colours(setof(_,_,_),	     built_in-[classify,setof,classify]).
 | 
						|
goal_colours(bagof(_,_,_),	     built_in-[classify,setof,classify]).
 | 
						|
goal_colours(predicate_options(_,_,_), built_in-[predicate,classify,classify]).
 | 
						|
% Database access
 | 
						|
goal_colours(assert(_),		     built_in-[db]).
 | 
						|
goal_colours(asserta(_),	     built_in-[db]).
 | 
						|
goal_colours(assertz(_),	     built_in-[db]).
 | 
						|
goal_colours(assert(_,_),	     built_in-[db,classify]).
 | 
						|
goal_colours(asserta(_,_),	     built_in-[db,classify]).
 | 
						|
goal_colours(assertz(_,_),	     built_in-[db,classify]).
 | 
						|
goal_colours(retract(_),	     built_in-[db]).
 | 
						|
goal_colours(retractall(_),	     built_in-[db]).
 | 
						|
goal_colours(clause(_,_),	     built_in-[db,classify]).
 | 
						|
goal_colours(clause(_,_,_),	     built_in-[db,classify,classify]).
 | 
						|
% misc
 | 
						|
goal_colours(set_prolog_flag(_,_),   built_in-[prolog_flag_name,classify]).
 | 
						|
goal_colours(current_prolog_flag(_,_), built_in-[prolog_flag_name,classify]).
 | 
						|
% XPCE stuff
 | 
						|
goal_colours(pce_autoload(_,_),	     classify-[classify,file]).
 | 
						|
goal_colours(pce_image_directory(_), classify-[directory]).
 | 
						|
goal_colours(new(_, _),		     built_in-[classify,pce_new]).
 | 
						|
goal_colours(send_list(_,_,_),	     built_in-pce_arg_list).
 | 
						|
goal_colours(send(_,_),		     built_in-[pce_arg,pce_selector]).
 | 
						|
goal_colours(get(_,_,_),	     built_in-[pce_arg,pce_selector,pce_arg]).
 | 
						|
goal_colours(send_super(_,_),	     built_in-[pce_arg,pce_selector]).
 | 
						|
goal_colours(get_super(_,_),	     built_in-[pce_arg,pce_selector,pce_arg]).
 | 
						|
goal_colours(get_chain(_,_,_),	     built_in-[pce_arg,pce_selector,pce_arg]).
 | 
						|
goal_colours(Pce,		     built_in-pce_arg) :-
 | 
						|
	compound(Pce),
 | 
						|
	functor(Pce, Functor, _),
 | 
						|
	pce_functor(Functor).
 | 
						|
 | 
						|
pce_functor(send).
 | 
						|
pce_functor(get).
 | 
						|
pce_functor(send_super).
 | 
						|
pce_functor(get_super).
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	  SPECIFIC HEADS	*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
head_colours(file_search_path(_,_), hook-[identifier,classify]).
 | 
						|
head_colours(library_directory(_),  hook-[file]).
 | 
						|
head_colours(resource(_,_,_),	    hook-[identifier,classify,file]).
 | 
						|
 | 
						|
head_colours(Var, _) :-
 | 
						|
	var(Var), !,
 | 
						|
	fail.
 | 
						|
head_colours(M:H, Colours) :-
 | 
						|
	atom(M), callable(H),
 | 
						|
	xref_hook(M:H), !,
 | 
						|
	Colours = hook - [ hook, hook-classify ].
 | 
						|
head_colours(M:H, Colours) :-
 | 
						|
	M == user,
 | 
						|
	head_colours(H, HC),
 | 
						|
	HC = hook - _, !,
 | 
						|
	Colours = hook - [ hook, HC ].
 | 
						|
head_colours(M:_, meta-[module(M),extern(M)]).
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	       STYLES		*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
%%	def_style(+Pattern, -Style)
 | 
						|
%
 | 
						|
%	Define the style used for the   given  pattern. Definitions here
 | 
						|
%	can     be     overruled     by       defining     rules     for
 | 
						|
%	emacs_prolog_colours:style/2
 | 
						|
 | 
						|
def_style(goal(built_in,_),	   [colour(blue)]).
 | 
						|
def_style(goal(imported(_),_),	   [colour(blue)]).
 | 
						|
def_style(goal(autoload,_),	   [colour(navy_blue)]).
 | 
						|
def_style(goal(global,_),	   [colour(navy_blue)]).
 | 
						|
def_style(goal(undefined,_),	   [colour(red)]).
 | 
						|
def_style(goal(thread_local(_),_), [colour(magenta), underline(true)]).
 | 
						|
def_style(goal(dynamic(_),_),	   [colour(magenta)]).
 | 
						|
def_style(goal(multifile(_),_),	   [colour(navy_blue)]).
 | 
						|
def_style(goal(expanded,_),	   [colour(blue), underline(true)]).
 | 
						|
def_style(goal(extern(_),_),	   [colour(blue), underline(true)]).
 | 
						|
def_style(goal(recursion,_),	   [underline(true)]).
 | 
						|
def_style(goal(meta,_),		   [colour(red4)]).
 | 
						|
def_style(goal(foreign(_),_),	   [colour(darkturquoise)]).
 | 
						|
def_style(goal(local(_),_),	   []).
 | 
						|
def_style(goal(constraint(_),_),   [colour(darkcyan)]).
 | 
						|
 | 
						|
def_style(option_name,		   [colour('#3434ba')]).
 | 
						|
def_style(no_option_name,	   [colour(red)]).
 | 
						|
 | 
						|
def_style(head(exported),	   [colour(blue), bold(true)]).
 | 
						|
def_style(head(public(_)),	   [colour('#016300'), bold(true)]).
 | 
						|
def_style(head(extern(_)),	   [colour(blue), bold(true)]).
 | 
						|
def_style(head(dynamic),	   [colour(magenta), bold(true)]).
 | 
						|
def_style(head(multifile),	   [colour(navy_blue), bold(true)]).
 | 
						|
def_style(head(unreferenced),	   [colour(red), bold(true)]).
 | 
						|
def_style(head(hook),		   [colour(blue), underline(true)]).
 | 
						|
def_style(head(meta),		   []).
 | 
						|
def_style(head(constraint(_)),	   [colour(darkcyan), bold(true)]).
 | 
						|
def_style(head(_),		   [bold(true)]).
 | 
						|
def_style(module(_),		   [colour(dark_slate_blue)]).
 | 
						|
def_style(comment,		   [colour(dark_green)]).
 | 
						|
 | 
						|
def_style(directive,		   [background(grey90)]).
 | 
						|
def_style(method(_),		   [bold(true)]).
 | 
						|
 | 
						|
def_style(var,			   [colour(red4)]).
 | 
						|
def_style(singleton,		   [bold(true), colour(red4)]).
 | 
						|
def_style(unbound,		   [colour(red), bold(true)]).
 | 
						|
def_style(quoted_atom,		   [colour(navy_blue)]).
 | 
						|
def_style(string,		   [colour(navy_blue)]).
 | 
						|
def_style(nofile,		   [colour(red)]).
 | 
						|
def_style(file(_),		   [colour(blue), underline(true)]).
 | 
						|
def_style(directory(_),		   [colour(blue)]).
 | 
						|
def_style(class(built_in,_),	   [colour(blue), underline(true)]).
 | 
						|
def_style(class(library(_),_),	   [colour(navy_blue), underline(true)]).
 | 
						|
def_style(class(local(_,_,_),_),   [underline(true)]).
 | 
						|
def_style(class(user(_),_),	   [underline(true)]).
 | 
						|
def_style(class(user,_),	   [underline(true)]).
 | 
						|
def_style(class(undefined,_),	   [colour(red), underline(true)]).
 | 
						|
def_style(prolog_data,		   [colour(blue), underline(true)]).
 | 
						|
def_style(flag_name(_),		   [colour(blue)]).
 | 
						|
def_style(no_flag_name(_),	   [colour(red)]).
 | 
						|
 | 
						|
def_style(keyword(_),		   [colour(blue)]).
 | 
						|
def_style(identifier,		   [bold(true)]).
 | 
						|
def_style(delimiter,		   [bold(true)]).
 | 
						|
def_style(expanded,		   [colour(blue), underline(true)]).
 | 
						|
 | 
						|
def_style(hook,			   [colour(blue), underline(true)]).
 | 
						|
 | 
						|
def_style(error,		   [background(orange)]).
 | 
						|
def_style(type_error(_),	   [background(orange)]).
 | 
						|
def_style(syntax_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:
 | 
						|
%
 | 
						|
%	  * colour(ColourName)
 | 
						|
%	  * background(ColourName)
 | 
						|
%	  * bold(Boolean)
 | 
						|
%	  * underline(Boolean)
 | 
						|
%
 | 
						|
%	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.
 | 
						|
 | 
						|
syntax_colour(Class, Attributes) :-
 | 
						|
	(   style(Class, Attributes)		% user hook
 | 
						|
	;   def_style(Class, Attributes)	% system default
 | 
						|
	).
 | 
						|
 | 
						|
 | 
						|
%%	term_colours(+Term, -FunctorColour, -ArgColours)
 | 
						|
%
 | 
						|
%	Define colourisation for specific terms.
 | 
						|
 | 
						|
term_colours((?- Directive), Colours) :-
 | 
						|
	term_colours((:- Directive), Colours).
 | 
						|
term_colours((prolog:Head --> _),
 | 
						|
	     expanded - [ expanded - [ expanded,
 | 
						|
				       expanded - [ identifier
 | 
						|
						  ]
 | 
						|
				     ],
 | 
						|
			  classify
 | 
						|
			]) :-
 | 
						|
	prolog_message_hook(Head).
 | 
						|
 | 
						|
prolog_message_hook(message(_)).
 | 
						|
prolog_message_hook(error_message(_)).
 | 
						|
prolog_message_hook(message_context(_)).
 | 
						|
prolog_message_hook(message_location(_)).
 | 
						|
 | 
						|
%	XPCE rules
 | 
						|
 | 
						|
term_colours(variable(_, _, _, _),
 | 
						|
	     expanded - [ identifier,
 | 
						|
			  classify,
 | 
						|
			  classify,
 | 
						|
			  comment
 | 
						|
			]).
 | 
						|
term_colours(variable(_, _, _),
 | 
						|
	     expanded - [ identifier,
 | 
						|
			  classify,
 | 
						|
			  atom
 | 
						|
			]).
 | 
						|
term_colours(handle(_, _, _),
 | 
						|
	     expanded - [ classify,
 | 
						|
			  classify,
 | 
						|
			  classify
 | 
						|
			]).
 | 
						|
term_colours(handle(_, _, _, _),
 | 
						|
	     expanded - [ classify,
 | 
						|
			  classify,
 | 
						|
			  classify,
 | 
						|
			  classify
 | 
						|
			]).
 | 
						|
term_colours(class_variable(_,_,_,_),
 | 
						|
	     expanded - [ identifier,
 | 
						|
			  pce(type),
 | 
						|
			  pce(default),
 | 
						|
			  comment
 | 
						|
			]).
 | 
						|
term_colours(class_variable(_,_,_),
 | 
						|
	     expanded - [ identifier,
 | 
						|
			  pce(type),
 | 
						|
			  pce(default)
 | 
						|
			]).
 | 
						|
term_colours(delegate_to(_),
 | 
						|
	     expanded - [ classify
 | 
						|
			]).
 | 
						|
term_colours((:- encoding(_)),
 | 
						|
	     expanded - [ expanded - [ classify
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- pce_begin_class(_, _, _)),
 | 
						|
	     expanded - [ expanded - [ identifier,
 | 
						|
				       pce_new,
 | 
						|
				       comment
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- pce_begin_class(_, _)),
 | 
						|
	     expanded - [ expanded - [ identifier,
 | 
						|
				       pce_new
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- pce_extend_class(_)),
 | 
						|
	     expanded - [ expanded - [ identifier
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- pce_end_class),
 | 
						|
	     expanded - [ expanded
 | 
						|
			]).
 | 
						|
term_colours((:- pce_end_class(_)),
 | 
						|
	     expanded - [ expanded - [ identifier
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- use_class_template(_)),
 | 
						|
	     expanded - [ expanded - [ pce_new
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- emacs_begin_mode(_,_,_,_,_)),
 | 
						|
	     expanded - [ expanded - [ identifier,
 | 
						|
				       classify,
 | 
						|
				       classify,
 | 
						|
				       classify,
 | 
						|
				       classify
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- emacs_extend_mode(_,_)),
 | 
						|
	     expanded - [ expanded - [ identifier,
 | 
						|
				       classify
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- pce_group(_)),
 | 
						|
	     expanded - [ expanded - [ identifier
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- pce_global(_, new(_))),
 | 
						|
	     expanded - [ expanded - [ identifier,
 | 
						|
				       pce_arg
 | 
						|
				     ]
 | 
						|
			]).
 | 
						|
term_colours((:- emacs_end_mode),
 | 
						|
	     expanded - [ expanded
 | 
						|
			]).
 | 
						|
term_colours(pce_ifhostproperty(_,_),
 | 
						|
	     expanded - [ classify,
 | 
						|
			  classify
 | 
						|
			]).
 | 
						|
term_colours((_,_),
 | 
						|
	     error - [ classify,
 | 
						|
		       classify
 | 
						|
		     ]).
 | 
						|
 | 
						|
specified_item(_, Var, TB, Pos) :-
 | 
						|
	var(Var), !,
 | 
						|
	colourise_term_arg(Var, TB, Pos).
 | 
						|
					% generic classification
 | 
						|
specified_item(classify, Term, TB, Pos) :- !,
 | 
						|
	colourise_term_arg(Term, TB, Pos).
 | 
						|
					% classify as head
 | 
						|
specified_item(head, Term, TB, Pos) :- !,
 | 
						|
	colourise_clause_head(Term, TB, Pos).
 | 
						|
					% expanded head (DCG=2, ...)
 | 
						|
specified_item(head(+N), Term, TB, Pos) :- !,
 | 
						|
	colourise_extended_head(Term, N, TB, Pos).
 | 
						|
					% M:Head
 | 
						|
specified_item(extern(M), Term, TB, Pos) :- !,
 | 
						|
	colourise_extern_head(Term, M, TB, Pos).
 | 
						|
					% classify as body
 | 
						|
specified_item(body, Term, TB, Pos) :- !,
 | 
						|
	colourise_body(Term, TB, Pos).
 | 
						|
specified_item(setof, Term, TB, Pos) :- !,
 | 
						|
	colourise_setof(Term, TB, Pos).
 | 
						|
specified_item(meta(MetaSpec), Term, TB, Pos) :- !,
 | 
						|
	colourise_meta_arg(MetaSpec, Term, TB, Pos).
 | 
						|
					% DCG goal in body
 | 
						|
specified_item(dcg, Term, TB, Pos) :- !,
 | 
						|
	colourise_dcg(Term, [], TB, Pos).
 | 
						|
					% assert/retract arguments
 | 
						|
specified_item(db, Term, TB, Pos) :- !,
 | 
						|
	colourise_db(Term, TB, Pos).
 | 
						|
					% files
 | 
						|
specified_item(file, Term, TB, Pos) :- !,
 | 
						|
	colourise_files(Term, TB, Pos).
 | 
						|
					% directory
 | 
						|
specified_item(directory, Term, TB, Pos) :- !,
 | 
						|
	colourise_directory(Term, TB, Pos).
 | 
						|
					% [Name/Arity, ...]
 | 
						|
specified_item(exports, Term, TB, Pos) :- !,
 | 
						|
	colourise_exports(Term, TB, Pos).
 | 
						|
					% [Name/Arity, ...]
 | 
						|
specified_item(imports(File), Term, TB, Pos) :- !,
 | 
						|
	colourise_imports(Term, File, TB, Pos).
 | 
						|
					% Name/Arity, ...
 | 
						|
specified_item(predicates, Term, TB, Pos) :- !,
 | 
						|
	colourise_declarations(Term, TB, Pos).
 | 
						|
					% Name/Arity
 | 
						|
specified_item(predicate, Term, TB, Pos) :- !,
 | 
						|
	colourise_declaration(Term, TB, Pos).
 | 
						|
					% set_prolog_flag(Name, _)
 | 
						|
specified_item(prolog_flag_name, Term, TB, Pos) :- !,
 | 
						|
	colourise_prolog_flag_name(Term, TB, Pos).
 | 
						|
					% XPCE new argument
 | 
						|
specified_item(pce_new, Term, TB, Pos) :- !,
 | 
						|
	(   atom(Term)
 | 
						|
	->  colourise_class(Term, TB, Pos)
 | 
						|
	;   compound(Term)
 | 
						|
	->  functor(Term, Class, _),
 | 
						|
	    Pos = term_position(_,_,FF, FT, ArgPos),
 | 
						|
	    colourise_class(Class, TB, FF-FT),
 | 
						|
	    specified_items(pce_arg, Term, TB, ArgPos)
 | 
						|
	;   colourise_term_arg(Term, TB, Pos)
 | 
						|
	).
 | 
						|
					% Generic XPCE arguments
 | 
						|
specified_item(pce_arg, new(X), TB,
 | 
						|
	       term_position(_,_,_,_,[ArgPos])) :- !,
 | 
						|
	specified_item(pce_new, X, TB, ArgPos).
 | 
						|
specified_item(pce_arg, new(X, T), TB,
 | 
						|
	       term_position(_,_,_,_,[P1, P2])) :- !,
 | 
						|
	colourise_term_arg(X, TB, P1),
 | 
						|
	specified_item(pce_new, T, TB, P2).
 | 
						|
specified_item(pce_arg, @(Ref), TB, Pos) :- !,
 | 
						|
	colourise_term_arg(@(Ref), TB, Pos).
 | 
						|
specified_item(pce_arg, prolog(Term), TB,
 | 
						|
	       term_position(_,_,FF,FT,[ArgPos])) :- !,
 | 
						|
	colour_item(prolog_data, TB, FF-FT),
 | 
						|
	colourise_term_arg(Term, TB, ArgPos).
 | 
						|
specified_item(pce_arg, Term, TB, Pos) :-
 | 
						|
	compound(Term),
 | 
						|
	Term \= [_|_], !,
 | 
						|
	specified_item(pce_new, Term, TB, Pos).
 | 
						|
specified_item(pce_arg, Term, TB, Pos) :- !,
 | 
						|
	colourise_term_arg(Term, TB, Pos).
 | 
						|
					% List of XPCE arguments
 | 
						|
specified_item(pce_arg_list, List, TB, list_position(_,_,Elms,Tail)) :- !,
 | 
						|
	colourise_list_args(Elms, Tail, List, TB, pce_arg).
 | 
						|
specified_item(pce_arg_list, Term, TB, Pos) :- !,
 | 
						|
	specified_item(pce_arg, Term, TB, Pos).
 | 
						|
					% XPCE selector
 | 
						|
specified_item(pce_selector, Term, TB,
 | 
						|
	       term_position(_,_,_,_,ArgPos)) :- !,
 | 
						|
	specified_items(pce_arg, Term, TB, ArgPos).
 | 
						|
specified_item(pce_selector, Term, TB, Pos) :-
 | 
						|
	colourise_term_arg(Term, TB, Pos).
 | 
						|
					% Nested specification
 | 
						|
specified_item(FuncSpec-ArgSpecs, Term, TB,
 | 
						|
	       term_position(_,_,FF,FT,ArgPos)) :- !,
 | 
						|
	specified_item(FuncSpec, Term, TB, FF-FT),
 | 
						|
	specified_items(ArgSpecs, Term, TB, ArgPos).
 | 
						|
					% Nested for {...}
 | 
						|
specified_item(FuncSpec-[ArgSpec], {Term}, TB,
 | 
						|
	       brace_term_position(F,T,ArgPos)) :- !,
 | 
						|
	specified_item(FuncSpec, {Term}, TB, F-T),
 | 
						|
	specified_item(ArgSpec, Term, TB, ArgPos).
 | 
						|
					% Specified
 | 
						|
specified_item(FuncSpec-ElmSpec, List, TB, list_position(F,T,ElmPos,TailPos)) :- !,
 | 
						|
	FT is F + 1,
 | 
						|
	AT is T - 1,
 | 
						|
	colour_item(FuncSpec, TB, F-FT),
 | 
						|
	colour_item(FuncSpec, TB, AT-T),
 | 
						|
	specified_list(ElmSpec, List, TB, ElmPos, TailPos).
 | 
						|
specified_item(Class, _, TB, Pos) :-
 | 
						|
	colour_item(Class, TB, Pos).
 | 
						|
 | 
						|
%	specified_items(+Spec, +T, +TB, +PosList)
 | 
						|
 | 
						|
specified_items(Specs, Term, TB, PosList) :-
 | 
						|
	is_list(Specs), !,
 | 
						|
	specified_arglist(Specs, 1, Term, TB, PosList).
 | 
						|
specified_items(Spec, Term, TB, PosList) :-
 | 
						|
	specified_argspec(PosList, Spec, 1, Term, TB).
 | 
						|
 | 
						|
 | 
						|
specified_arglist([], _, _, _, _).
 | 
						|
specified_arglist(_, _, _, _, []) :- !.		% Excess specification args
 | 
						|
specified_arglist([S0|ST], N, T, TB, [P0|PT]) :-
 | 
						|
	arg(N, T, Term),
 | 
						|
	specified_item(S0, Term, TB, P0),
 | 
						|
	NN is N + 1,
 | 
						|
	specified_arglist(ST, NN, T, TB, PT).
 | 
						|
 | 
						|
specified_argspec([], _, _, _, _).
 | 
						|
specified_argspec([P0|PT], Spec, N, T, TB) :-
 | 
						|
	arg(N, T, Term),
 | 
						|
	specified_item(Spec, Term, TB, P0),
 | 
						|
	NN is N + 1,
 | 
						|
	specified_argspec(PT, Spec, NN, T, TB).
 | 
						|
 | 
						|
 | 
						|
%	specified_list(+Spec, +List, +TB, +PosList, TailPos)
 | 
						|
 | 
						|
specified_list([], [], _, [], _).
 | 
						|
specified_list([HS|TS], [H|T], TB, [HP|TP], TailPos) :- !,
 | 
						|
	specified_item(HS, H, TB, HP),
 | 
						|
	specified_list(TS, T, TB, TP, TailPos).
 | 
						|
specified_list(Spec, [H|T], TB, [HP|TP], TailPos) :-
 | 
						|
	specified_item(Spec, H, TB, HP),
 | 
						|
	specified_list(Spec, T, TB, TP, TailPos).
 | 
						|
specified_list(_, _, _, [], none) :- !.
 | 
						|
specified_list(Spec, Tail, TB, [], TailPos) :-
 | 
						|
	specified_item(Spec, Tail, TB, TailPos).
 | 
						|
 | 
						|
 | 
						|
		 /*******************************
 | 
						|
		 *	   DESCRIPTIONS		*
 | 
						|
		 *******************************/
 | 
						|
 | 
						|
syntax_message(Class) -->
 | 
						|
	message(Class), !.
 | 
						|
syntax_message(goal(Class, Goal)) --> !,
 | 
						|
	goal_message(Class, Goal).
 | 
						|
syntax_message(class(Type, Class)) --> !,
 | 
						|
	xpce_class_message(Type, Class).
 | 
						|
 | 
						|
goal_message(meta, _) -->
 | 
						|
	[ 'Meta call' ].
 | 
						|
goal_message(recursion, _) -->
 | 
						|
	[ 'Recursive call' ].
 | 
						|
goal_message(undefined, _) -->
 | 
						|
	[ 'Call to undefined predicate' ].
 | 
						|
goal_message(expanded, _) -->
 | 
						|
	[ 'Expanded goal' ].
 | 
						|
goal_message(global, _) -->
 | 
						|
	[ 'Auto-imported from module user' ].
 | 
						|
goal_message(Class, Goal) -->
 | 
						|
	{ predicate_name(Goal, PI) },
 | 
						|
	[ 'Call to ~w predicate ~q'-[Class,PI] ].
 | 
						|
 | 
						|
xpce_class_message(Type, Class) -->
 | 
						|
	[ 'XPCE ~w class ~q'-[Type, Class] ].
 |