imrove support for yap-win
This commit is contained in:
parent
b7fbd08f7a
commit
aba6d5741e
1
swi/library/Makefile.in
Normal file → Executable file
1
swi/library/Makefile.in
Normal file → Executable file
@ -31,6 +31,7 @@ PROGRAMS= \
|
|||||||
$(srcdir)/ctypes.pl \
|
$(srcdir)/ctypes.pl \
|
||||||
$(srcdir)/date.pl \
|
$(srcdir)/date.pl \
|
||||||
$(srcdir)/debug.pl \
|
$(srcdir)/debug.pl \
|
||||||
|
$(srcdir)/edit.pl \
|
||||||
$(srcdir)/error.pl \
|
$(srcdir)/error.pl \
|
||||||
$(srcdir)/main.pl \
|
$(srcdir)/main.pl \
|
||||||
$(srcdir)/maplist.pl \
|
$(srcdir)/maplist.pl \
|
||||||
|
573
swi/library/edit.pl
Executable file
573
swi/library/edit.pl
Executable file
@ -0,0 +1,573 @@
|
|||||||
|
/* Part of SWI-Prolog
|
||||||
|
|
||||||
|
Author: Jan Wielemaker
|
||||||
|
E-mail: J.Wielemaker@vu.nl
|
||||||
|
WWW: http://www.swi-prolog.org
|
||||||
|
Copyright (C): 1985-2013, 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_edit,
|
||||||
|
[ edit/1, % +Spec
|
||||||
|
edit/0
|
||||||
|
]).
|
||||||
|
:- use_module(library(lists), [append/3, member/2, nth1/3, memberchk/2]).
|
||||||
|
:- use_module(library(maplist)).
|
||||||
|
:- use_module(library(system)).
|
||||||
|
%:- use_module(library(make), [make/0]).
|
||||||
|
:- set_prolog_flag(generate_debug_info, false).
|
||||||
|
|
||||||
|
/** <module> Editor interface
|
||||||
|
|
||||||
|
This module implements the generic editor interface. It consists of two
|
||||||
|
extensible parts with little in between. The first part deals with
|
||||||
|
translating the input into source-location, and the second with starting
|
||||||
|
an editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:- multifile
|
||||||
|
locate/3, % +Partial, -FullSpec, -Location
|
||||||
|
locate/2, % +FullSpec, -Location
|
||||||
|
select_location/3, % +Pairs, +Spec, -Location
|
||||||
|
edit_source/1, % +Location
|
||||||
|
edit_command/2, % +Editor, -Command
|
||||||
|
load/0. % provides load-hooks
|
||||||
|
|
||||||
|
%% edit(+Spec)
|
||||||
|
%
|
||||||
|
% Edit indicated object.
|
||||||
|
|
||||||
|
edit(Spec) :-
|
||||||
|
notrace(edit_no_trace(Spec)).
|
||||||
|
|
||||||
|
edit_no_trace(Spec) :-
|
||||||
|
var(Spec), !,
|
||||||
|
throw(error(instantiation_error, _)).
|
||||||
|
edit_no_trace(Spec) :-
|
||||||
|
load_extensions,
|
||||||
|
findall(Location-FullSpec,
|
||||||
|
locate(Spec, FullSpec, Location),
|
||||||
|
Pairs0),
|
||||||
|
merge_locations(Pairs0, Pairs),
|
||||||
|
do_select_location(Pairs, Spec, Location),
|
||||||
|
do_edit_source(Location).
|
||||||
|
|
||||||
|
%% edit
|
||||||
|
%
|
||||||
|
% Edit associated or script file. This is the Prolog file opened
|
||||||
|
% by double-clicking or the file loaded using
|
||||||
|
%
|
||||||
|
% ==
|
||||||
|
% % swipl [-s] file.pl
|
||||||
|
% ==
|
||||||
|
|
||||||
|
edit :-
|
||||||
|
current_prolog_flag(associated_file, File), !,
|
||||||
|
edit(file(File)).
|
||||||
|
edit :-
|
||||||
|
fail, '$cmd_option_val'(script_file, OsFiles),
|
||||||
|
OsFiles = [OsFile], !,
|
||||||
|
prolog_to_os_filename(File, OsFile),
|
||||||
|
edit(file(File)).
|
||||||
|
edit :-
|
||||||
|
throw(error(context_error(edit, no_default_file), _)).
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* LOCATE *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
%% locate(+Spec, -FullSpec, -Location)
|
||||||
|
|
||||||
|
locate(FileSpec:Line, file(Path, line(Line)), [file(Path), line(Line)]) :-
|
||||||
|
integer(Line), Line >= 1,
|
||||||
|
ground(FileSpec), !, % so specific; do not try alts
|
||||||
|
locate(FileSpec, _, [file(Path)]).
|
||||||
|
locate(FileSpec:Line:LinePos,
|
||||||
|
file(Path, line(Line), linepos(LinePos)),
|
||||||
|
[file(Path), line(Line), linepos(LinePos)]) :-
|
||||||
|
integer(Line), Line >= 1,
|
||||||
|
integer(LinePos), LinePos >= 1,
|
||||||
|
ground(FileSpec), !, % so specific; do not try alts
|
||||||
|
locate(FileSpec, _, [file(Path)]).
|
||||||
|
locate(Path, file(Path), [file(Path)]) :-
|
||||||
|
atom(Path),
|
||||||
|
exists_file(Path),
|
||||||
|
\+ exists_directory(Path).
|
||||||
|
locate(Pattern, file(Path), [file(Path)]) :-
|
||||||
|
atom(Pattern),
|
||||||
|
catch(expand_file_name(Pattern, Files), _, fail),
|
||||||
|
member(Path, Files),
|
||||||
|
exists_file(Path),
|
||||||
|
\+ exists_directory(Path).
|
||||||
|
locate(FileBase, file(File), [file(File)]) :-
|
||||||
|
atom(FileBase),
|
||||||
|
absolute_file_name(FileBase,
|
||||||
|
[ file_type(prolog),
|
||||||
|
access(read),
|
||||||
|
file_errors(fail)
|
||||||
|
],
|
||||||
|
File),
|
||||||
|
\+ exists_directory(File).
|
||||||
|
locate(FileSpec, file(File), [file(File)]) :-
|
||||||
|
catch(absolute_file_name(FileSpec,
|
||||||
|
[ file_type(prolog),
|
||||||
|
access(read),
|
||||||
|
file_errors(fail)
|
||||||
|
],
|
||||||
|
File),
|
||||||
|
_, fail).
|
||||||
|
locate(FileBase, source_file(Path), [file(Path)]) :-
|
||||||
|
atom(FileBase),
|
||||||
|
source_file(Path),
|
||||||
|
file_base_name(Path, File),
|
||||||
|
( File == FileBase
|
||||||
|
-> true
|
||||||
|
; file_name_extension(FileBase, _, File)
|
||||||
|
).
|
||||||
|
locate(FileBase, include_file(Path), [file(Path)]) :-
|
||||||
|
atom(FileBase),
|
||||||
|
setof(Path, include_file(Path), Paths),
|
||||||
|
member(Path, Paths),
|
||||||
|
file_base_name(Path, File),
|
||||||
|
( File == FileBase
|
||||||
|
-> true
|
||||||
|
; file_name_extension(FileBase, _, File)
|
||||||
|
).
|
||||||
|
locate(Name, FullSpec, Location) :-
|
||||||
|
atom(Name),
|
||||||
|
locate(Name/_, FullSpec, Location).
|
||||||
|
locate(Name/Arity, Module:Name/Arity, Location) :-
|
||||||
|
locate(Module:Name/Arity, Location).
|
||||||
|
locate(Name//DCGArity, FullSpec, Location) :-
|
||||||
|
( integer(DCGArity)
|
||||||
|
-> Arity is DCGArity+2,
|
||||||
|
locate(Name/Arity, FullSpec, Location)
|
||||||
|
; locate(Name/_, FullSpec, Location) % demand arity >= 2
|
||||||
|
).
|
||||||
|
locate(Name/Arity, library(File), [file(PlPath)]) :-
|
||||||
|
atom(Name),
|
||||||
|
fail, %'$in_library'(Name, Arity, Path),
|
||||||
|
( absolute_file_name(library(.),
|
||||||
|
[ file_type(directory),
|
||||||
|
solutions(all)
|
||||||
|
],
|
||||||
|
Dir),
|
||||||
|
atom_concat(Dir, File0, Path),
|
||||||
|
atom_concat(/, File, File0)
|
||||||
|
-> absolute_file_name(Path,
|
||||||
|
[ file_type(prolog),
|
||||||
|
access(read),
|
||||||
|
file_errors(fail)
|
||||||
|
],
|
||||||
|
PlPath)
|
||||||
|
; fail
|
||||||
|
).
|
||||||
|
locate(Module:Name, Module:Name/Arity, Location) :-
|
||||||
|
locate(Module:Name/Arity, Location).
|
||||||
|
locate(Module:Head, Module:Name/Arity, Location) :-
|
||||||
|
callable(Head),
|
||||||
|
functor(Head, Name, Arity),
|
||||||
|
locate(Module:Name/Arity, Location).
|
||||||
|
locate(Spec, module(Spec), Location) :-
|
||||||
|
locate(module(Spec), Location).
|
||||||
|
locate(Spec, Spec, Location) :-
|
||||||
|
locate(Spec, Location).
|
||||||
|
|
||||||
|
include_file(Path) :-
|
||||||
|
source_file_property(Path, included_in(_,_)).
|
||||||
|
|
||||||
|
|
||||||
|
%% locate(+Spec, -Location)
|
||||||
|
%
|
||||||
|
% Locate object from the specified location.
|
||||||
|
|
||||||
|
locate(file(File, line(Line)), [file(File), line(Line)]).
|
||||||
|
locate(file(File), [file(File)]).
|
||||||
|
locate(Module:Name/Arity, [file(File), line(Line)]) :-
|
||||||
|
( atom(Name), integer(Arity)
|
||||||
|
-> functor(Head, Name, Arity)
|
||||||
|
; Head = _ % leave unbound
|
||||||
|
),
|
||||||
|
( ( var(Module)
|
||||||
|
; var(Name)
|
||||||
|
)
|
||||||
|
-> NonImport = true
|
||||||
|
; NonImport = false
|
||||||
|
),
|
||||||
|
current_predicate(Name, Module:Head),
|
||||||
|
\+ ( NonImport == true,
|
||||||
|
Module \== system,
|
||||||
|
predicate_property(Module:Head, imported_from(_))
|
||||||
|
),
|
||||||
|
functor(Head, Name, Arity), % bind arity
|
||||||
|
predicate_property(Module:Head, file(File)),
|
||||||
|
predicate_property(Module:Head, line_count(Line)).
|
||||||
|
locate(module(Module), [file(Path)|Rest]) :-
|
||||||
|
atom(Module),
|
||||||
|
module_property(Module, file(Path)),
|
||||||
|
( module_property(Module, line_count(Line))
|
||||||
|
-> Rest = [line(Line)]
|
||||||
|
; Rest = []
|
||||||
|
).
|
||||||
|
locate(breakpoint(Id), Location) :-
|
||||||
|
integer(Id),
|
||||||
|
breakpoint_property(Id, clause(Ref)),
|
||||||
|
( breakpoint_property(Id, file(File)),
|
||||||
|
breakpoint_property(Id, line_count(Line))
|
||||||
|
-> Location = [file(File),line(Line)]
|
||||||
|
; locate(clause(Ref), Location)
|
||||||
|
).
|
||||||
|
locate(clause(Ref), [file(File), line(Line)]) :-
|
||||||
|
clause_property(Ref, file(File)),
|
||||||
|
clause_property(Ref, line_count(Line)).
|
||||||
|
locate(clause(Ref, _PC), [file(File), line(Line)]) :- % TBD: use clause
|
||||||
|
clause_property(Ref, file(File)),
|
||||||
|
clause_property(Ref, line_count(Line)).
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* EDIT *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
%% do_edit_source(+Location)
|
||||||
|
%
|
||||||
|
% Actually call the editor to edit Location, a list of Name(Value)
|
||||||
|
% that contains file(File) and may contain line(Line). First the
|
||||||
|
% multifile hook edit_source/1 is called. If this fails the system
|
||||||
|
% checks for XPCE and the prolog-flag editor. If the latter is
|
||||||
|
% built_in or pce_emacs, it will start PceEmacs.
|
||||||
|
%
|
||||||
|
% Finally, it will get the editor to use from the prolog-flag
|
||||||
|
% editor and use edit_command/2 to determine how this editor
|
||||||
|
% should be called.
|
||||||
|
|
||||||
|
do_edit_source(Location) :- % hook
|
||||||
|
edit_source(Location), !.
|
||||||
|
do_edit_source(Location) :- % PceEmacs
|
||||||
|
current_prolog_flag(editor, Editor),
|
||||||
|
pceemacs(Editor),
|
||||||
|
current_prolog_flag(gui, true), !,
|
||||||
|
memberchk(file(File), Location),
|
||||||
|
( memberchk(line(Line), Location)
|
||||||
|
-> ( memberchk(linepos(LinePos), Location)
|
||||||
|
-> Pos = (File:Line:LinePos)
|
||||||
|
; Pos = (File:Line)
|
||||||
|
)
|
||||||
|
; Pos = File
|
||||||
|
),
|
||||||
|
in_pce_thread(emacs(Pos)).
|
||||||
|
do_edit_source(Location) :- % External editor
|
||||||
|
external_edit_command(Location, Command),
|
||||||
|
print_message(informational, edit(waiting_for_editor)),
|
||||||
|
( catch(system(Command), E,
|
||||||
|
(print_message(warning, E),
|
||||||
|
fail))
|
||||||
|
-> print_message(informational, edit(make)),
|
||||||
|
make
|
||||||
|
; print_message(informational, edit(canceled))
|
||||||
|
).
|
||||||
|
|
||||||
|
external_edit_command(Location, Command) :-
|
||||||
|
memberchk(file(File), Location),
|
||||||
|
memberchk(line(Line), Location),
|
||||||
|
editor(Editor),
|
||||||
|
file_base_name(Editor, EditorFile),
|
||||||
|
file_name_extension(Base, _, EditorFile),
|
||||||
|
edit_command(Base, Cmd),
|
||||||
|
prolog_to_os_filename(File, OsFile),
|
||||||
|
atom_codes(Cmd, S0),
|
||||||
|
substitute('%e', Editor, S0, S1),
|
||||||
|
substitute('%f', OsFile, S1, S2),
|
||||||
|
substitute('%d', Line, S2, S), !,
|
||||||
|
atom_codes(Command, S).
|
||||||
|
external_edit_command(Location, Command) :-
|
||||||
|
memberchk(file(File), Location),
|
||||||
|
editor(Editor),
|
||||||
|
file_base_name(Editor, EditorFile),
|
||||||
|
file_name_extension(Base, _, EditorFile),
|
||||||
|
edit_command(Base, Cmd),
|
||||||
|
prolog_to_os_filename(File, OsFile),
|
||||||
|
atom_codes(Cmd, S0),
|
||||||
|
substitute('%e', Editor, S0, S1),
|
||||||
|
substitute('%f', OsFile, S1, S),
|
||||||
|
\+ substitute('%d', 1, S, _), !,
|
||||||
|
atom_codes(Command, S).
|
||||||
|
external_edit_command(Location, Command) :-
|
||||||
|
memberchk(file(File), Location),
|
||||||
|
editor(Editor),
|
||||||
|
atomic_list_concat(['"', Editor, '" "', File, '"'], Command).
|
||||||
|
|
||||||
|
pceemacs(pce_emacs).
|
||||||
|
pceemacs(built_in).
|
||||||
|
|
||||||
|
%% editor(-Editor)
|
||||||
|
%
|
||||||
|
% Determine the external editor to run.
|
||||||
|
|
||||||
|
editor(Editor) :- % $EDITOR
|
||||||
|
current_prolog_flag(editor, Editor),
|
||||||
|
( sub_atom(Editor, 0, _, _, $)
|
||||||
|
-> sub_atom(Editor, 1, _, 0, Var),
|
||||||
|
catch(getenv(Var, Editor), _, fail), !
|
||||||
|
; Editor == default
|
||||||
|
-> catch(getenv('EDITOR', Editor), _, fail), !
|
||||||
|
; \+ pceemacs(Editor)
|
||||||
|
-> !
|
||||||
|
).
|
||||||
|
editor(Editor) :- % User defaults
|
||||||
|
getenv('EDITOR', Editor), !.
|
||||||
|
editor(vi) :- % Platform defaults
|
||||||
|
current_prolog_flag(unix, true), !.
|
||||||
|
editor(notepad) :-
|
||||||
|
current_prolog_flag(windows, true), !.
|
||||||
|
editor(_) :- % No luck
|
||||||
|
throw(error(existence_error(editor), _)).
|
||||||
|
|
||||||
|
%% edit_command(+Editor, -Command)
|
||||||
|
%
|
||||||
|
% This predicate should specify the shell-command called to invoke
|
||||||
|
% the user's editor. The following substitutions will be made:
|
||||||
|
%
|
||||||
|
% | %e | Path name of the editor |
|
||||||
|
% | %f | Path name of the file to be edited |
|
||||||
|
% | %d | Line number of the target |
|
||||||
|
|
||||||
|
|
||||||
|
edit_command(vi, '%e +%d \'%f\'').
|
||||||
|
edit_command(vi, '%e \'%f\'').
|
||||||
|
edit_command(emacs, '%e +%d \'%f\'').
|
||||||
|
edit_command(emacs, '%e \'%f\'').
|
||||||
|
edit_command(notepad, '"%e" "%f"').
|
||||||
|
edit_command(wordpad, '"%e" "%f"').
|
||||||
|
edit_command(uedit32, '%e "%f/%d/0"'). % ultraedit (www.ultraedit.com)
|
||||||
|
edit_command(jedit, '%e -wait \'%f\' +line:%d').
|
||||||
|
edit_command(jedit, '%e -wait \'%f\'').
|
||||||
|
edit_command(edit, '%e %f:%d'). % PceEmacs client script
|
||||||
|
edit_command(edit, '%e %f').
|
||||||
|
|
||||||
|
edit_command(emacsclient, Command) :- edit_command(emacs, Command).
|
||||||
|
edit_command(vim, Command) :- edit_command(vi, Command).
|
||||||
|
|
||||||
|
substitute(FromAtom, ToAtom, Old, New) :-
|
||||||
|
atom_codes(FromAtom, From),
|
||||||
|
( atom(ToAtom)
|
||||||
|
-> atom_codes(ToAtom, To)
|
||||||
|
; number_codes(ToAtom, To)
|
||||||
|
),
|
||||||
|
append(Pre, S0, Old),
|
||||||
|
append(From, Post, S0) ->
|
||||||
|
append(Pre, To, S1),
|
||||||
|
append(S1, Post, New), !.
|
||||||
|
substitute(_, _, Old, Old).
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* SELECT *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
merge_locations(Pairs0, Pairs) :-
|
||||||
|
keysort(Pairs0, Pairs1),
|
||||||
|
merge_locations2(Pairs1, Pairs).
|
||||||
|
|
||||||
|
merge_locations2([], []).
|
||||||
|
merge_locations2([H0|T0], [H|T]) :-
|
||||||
|
remove_same_location(H0, H, T0, T1),
|
||||||
|
merge_locations2(T1, T).
|
||||||
|
|
||||||
|
remove_same_location(Pair0, H, [Pair1|T0], L) :-
|
||||||
|
merge_locations(Pair0, Pair1, Pair2), !,
|
||||||
|
remove_same_location(Pair2, H, T0, L).
|
||||||
|
remove_same_location(H, H, L, L).
|
||||||
|
|
||||||
|
merge_locations(Loc1-Spec1, Loc2-Spec2, Loc-Spec) :-
|
||||||
|
same_location(Loc1, Loc2, Loc), !,
|
||||||
|
( merge_specs(Spec1, Spec2, Spec)
|
||||||
|
; merge_specs(Spec2, Spec1, Spec)
|
||||||
|
; Spec = Spec1
|
||||||
|
), !.
|
||||||
|
merge_locations([file(X)]-_, Loc-Spec, Loc-Spec) :-
|
||||||
|
memberchk(file(X), Loc),
|
||||||
|
memberchk(line(_), Loc).
|
||||||
|
|
||||||
|
same_location(L, L, L).
|
||||||
|
same_location([file(F1)], [file(F2)], [file(F)]) :-
|
||||||
|
best_same_file(F1, F2, F).
|
||||||
|
same_location([file(F1),line(L)], [file(F2)], [file(F),line(L)]) :-
|
||||||
|
best_same_file(F1, F2, F).
|
||||||
|
same_location([file(F1)], [file(F2),line(L)], [file(F),line(L)]) :-
|
||||||
|
best_same_file(F1, F2, F).
|
||||||
|
|
||||||
|
best_same_file(F1, F2, F) :-
|
||||||
|
catch(same_file(F1, F2), _, fail), !,
|
||||||
|
atom_length(F1, L1),
|
||||||
|
atom_length(F2, L2),
|
||||||
|
( L1 < L2
|
||||||
|
-> F = F1
|
||||||
|
; F = F2
|
||||||
|
).
|
||||||
|
|
||||||
|
merge_specs(source_file(Path), _, source_file(Path)).
|
||||||
|
|
||||||
|
%% select_location(+Pairs, +UserSpec, -Location)
|
||||||
|
|
||||||
|
do_select_location(Pairs, Spec, Location) :-
|
||||||
|
select_location(Pairs, Spec, Location), !, % HOOK
|
||||||
|
Location \== [].
|
||||||
|
do_select_location([], Spec, _) :- !,
|
||||||
|
print_message(warning, edit(not_found(Spec))),
|
||||||
|
fail.
|
||||||
|
do_select_location([Location-_Spec], _, Location) :- !.
|
||||||
|
do_select_location(Pairs, _, Location) :-
|
||||||
|
print_message(help, edit(select)),
|
||||||
|
list_pairs(Pairs, 0, N),
|
||||||
|
print_message(help, edit(prompt_select)),
|
||||||
|
read_number(N, I),
|
||||||
|
nth1(I, Pairs, Location-_Spec), !.
|
||||||
|
|
||||||
|
list_pairs([], N, N).
|
||||||
|
list_pairs([H|T], N0, N) :-
|
||||||
|
NN is N0 + 1,
|
||||||
|
list_pair(H, NN),
|
||||||
|
list_pairs(T, NN, N).
|
||||||
|
|
||||||
|
list_pair(Pair, N) :-
|
||||||
|
print_message(help, edit(target(Pair, N))).
|
||||||
|
|
||||||
|
|
||||||
|
read_number(Max, X) :-
|
||||||
|
Max < 10, !,
|
||||||
|
get_single_char(C),
|
||||||
|
between(0'0, 0'9, C),
|
||||||
|
X is C - 0'0.
|
||||||
|
read_number(_, X) :-
|
||||||
|
read_line(Chars),
|
||||||
|
name(X, Chars),
|
||||||
|
integer(X).
|
||||||
|
|
||||||
|
read_line(Chars) :-
|
||||||
|
get0(user_input, C0),
|
||||||
|
read_line(C0, Chars).
|
||||||
|
|
||||||
|
read_line(10, []) :- !.
|
||||||
|
read_line(-1, []) :- !.
|
||||||
|
read_line(C, [C|T]) :-
|
||||||
|
get0(user_input, C1),
|
||||||
|
read_line(C1, T).
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* MESSAGES *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
:- multifile
|
||||||
|
prolog:message/3.
|
||||||
|
|
||||||
|
prolog:message(edit(not_found(Spec))) -->
|
||||||
|
[ 'Cannot find anything to edit from "~p"'-[Spec] ],
|
||||||
|
( { atom(Spec) }
|
||||||
|
-> [ nl, ' Use edit(file(~q)) to create a new file'-[Spec] ]
|
||||||
|
; []
|
||||||
|
).
|
||||||
|
prolog:message(edit(select)) -->
|
||||||
|
[ 'Please select item to edit:', nl, nl ].
|
||||||
|
prolog:message(edit(prompt_select)) -->
|
||||||
|
[ nl, 'Your choice? ', flush ].
|
||||||
|
prolog:message(edit(target(Location-Spec, N))) -->
|
||||||
|
[ '~t~d~3| '-[N]],
|
||||||
|
edit_specifier(Spec),
|
||||||
|
[ '~t~32|' ],
|
||||||
|
edit_location(Location).
|
||||||
|
prolog:message(edit(waiting_for_editor)) -->
|
||||||
|
[ 'Waiting for editor ... ', flush ].
|
||||||
|
prolog:message(edit(make)) -->
|
||||||
|
[ 'Running make to reload modified files' ].
|
||||||
|
prolog:message(edit(canceled)) -->
|
||||||
|
[ 'Editor returned failure; skipped make/0 to reload files' ].
|
||||||
|
|
||||||
|
edit_specifier(Module:Name/Arity) --> !,
|
||||||
|
[ '~w:~w/~w'-[Module, Name, Arity] ].
|
||||||
|
edit_specifier(file(_Path)) --> !,
|
||||||
|
[ '<file>' ].
|
||||||
|
edit_specifier(source_file(_Path)) --> !,
|
||||||
|
[ '<loaded file>' ].
|
||||||
|
edit_specifier(include_file(_Path)) --> !,
|
||||||
|
[ '<included file>' ].
|
||||||
|
edit_specifier(Term) -->
|
||||||
|
[ '~p'-[Term] ].
|
||||||
|
|
||||||
|
edit_location(Location) -->
|
||||||
|
{ memberchk(file(File), Location),
|
||||||
|
memberchk(line(Line), Location),
|
||||||
|
short_filename(File, Spec)
|
||||||
|
}, !,
|
||||||
|
[ '~q:~d'-[Spec, Line] ].
|
||||||
|
edit_location(Location) -->
|
||||||
|
{ memberchk(file(File), Location),
|
||||||
|
short_filename(File, Spec)
|
||||||
|
}, !,
|
||||||
|
[ '~q'-[Spec] ].
|
||||||
|
|
||||||
|
short_filename(Path, Spec) :-
|
||||||
|
absolute_file_name('', Here),
|
||||||
|
atom_concat(Here, Local0, Path), !,
|
||||||
|
remove_leading_slash(Local0, Spec).
|
||||||
|
short_filename(Path, Spec) :-
|
||||||
|
findall(LenAlias, aliased_path(Path, LenAlias), Keyed),
|
||||||
|
keysort(Keyed, [_-Spec|_]).
|
||||||
|
short_filename(Path, Path).
|
||||||
|
|
||||||
|
aliased_path(Path, Len-Spec) :-
|
||||||
|
setof(Alias, file_alias_path(Alias), Aliases),
|
||||||
|
member(Alias, Aliases),
|
||||||
|
Alias \== autoload, % confusing and covered by something else
|
||||||
|
Term =.. [Alias, '.'],
|
||||||
|
absolute_file_name(Term,
|
||||||
|
[ file_type(directory),
|
||||||
|
file_errors(fail),
|
||||||
|
solutions(all)
|
||||||
|
], Prefix),
|
||||||
|
atom_concat(Prefix, Local0, Path),
|
||||||
|
remove_leading_slash(Local0, Local),
|
||||||
|
atom_length(Local, Len),
|
||||||
|
Spec =.. [Alias, Local].
|
||||||
|
|
||||||
|
file_alias_path(Alias) :-
|
||||||
|
user:file_search_path(Alias, _).
|
||||||
|
|
||||||
|
remove_leading_slash(Path, Local) :-
|
||||||
|
atom_concat(/, Local, Path), !.
|
||||||
|
remove_leading_slash(Path, Path).
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* LOAD EXTENSIONS *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
load_extensions :-
|
||||||
|
load,
|
||||||
|
fail.
|
||||||
|
load_extensions.
|
||||||
|
|
||||||
|
:- load_extensions.
|
@ -35,7 +35,8 @@
|
|||||||
]).
|
]).
|
||||||
|
|
||||||
:- meta_predicate
|
:- meta_predicate
|
||||||
win_insert_menu_item(+,+,+,:).
|
prolog:win_insert_menu_item(+,+,+,0).
|
||||||
|
|
||||||
%:- multifile
|
%:- multifile
|
||||||
% prolog:on_menu/1.
|
% prolog:on_menu/1.
|
||||||
:- dynamic
|
:- dynamic
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
/* $Id$
|
/* Part of SWI-Prolog
|
||||||
|
|
||||||
Part of SWI-Prolog
|
|
||||||
|
|
||||||
Author: Jan Wielemaker
|
Author: Jan Wielemaker
|
||||||
E-mail: jan@swi.psy.uva.nl
|
E-mail: J.Wielemaker@vu.nl
|
||||||
WWW: http://www.swi-prolog.org
|
WWW: http://www.swi-prolog.org
|
||||||
Copyright (C): 1985-2002, University of Amsterdam
|
Copyright (C): 1985-2013, University of Amsterdam
|
||||||
|
VU University Amsterdam
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
@ -29,73 +28,128 @@
|
|||||||
the GNU General Public License.
|
the GNU General Public License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
:- module(win_menu,
|
:- module(win_menu,
|
||||||
[ init_win_menus/0
|
[ init_win_menus/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
:- use_module(library(lists)).
|
:- use_module(library(lists)).
|
||||||
|
:- use_module(library(apply)).
|
||||||
|
:- use_module(library(error)).
|
||||||
:- use_module(library(www_browser)).
|
:- use_module(library(www_browser)).
|
||||||
|
:- use_module(library(edit)).
|
||||||
:- set_prolog_flag(generate_debug_info, false).
|
:- set_prolog_flag(generate_debug_info, false).
|
||||||
:- op(200, fy, @).
|
:- op(200, fy, @).
|
||||||
:- op(990, xfx, :=).
|
:- op(990, xfx, :=).
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
/** <module> Console window menu
|
||||||
This library sets up the menu of PLWIN.EXE. It is called from the system
|
|
||||||
initialisation file plwin.rc, predicate gui_setup_/0.
|
This library sets up the menu of *swipl-win.exe*. It is called from the
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
system initialisation file =plwin-win.rc=, predicate gui_setup_/0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
:- if(current_prolog_flag(console_menu_version, qt)).
|
||||||
|
% The traditional swipl-win.exe predefines some menus. The Qt version
|
||||||
|
% does not. Here, we predefine the same menus to make the remainder
|
||||||
|
% compatiple.
|
||||||
|
menu('&File',
|
||||||
|
[ 'E&xit' = pqConsole:quit_console
|
||||||
|
],
|
||||||
|
[
|
||||||
|
]).
|
||||||
|
menu('&Edit',
|
||||||
|
[ '&Copy' = pqConsole:copy,
|
||||||
|
'&Paste' = pqConsole:paste
|
||||||
|
],
|
||||||
|
[]).
|
||||||
|
menu('&Settings',
|
||||||
|
[ '&Font ...' = pqConsole:select_font,
|
||||||
|
'&Colors ...' = pqConsole:select_ANSI_term_colors
|
||||||
|
],
|
||||||
|
[]).
|
||||||
|
menu('&Run',
|
||||||
|
[ '&Interrupt' = interrupt,
|
||||||
|
'&New thread' = interactor
|
||||||
|
],
|
||||||
|
[]).
|
||||||
|
|
||||||
|
menu(File,
|
||||||
|
[ '&Consult ...' = action(user:consult(+file(open,
|
||||||
|
'Load file into Prolog'))),
|
||||||
|
'&Reconsult ...' = action(user:reconsult(+file(open,
|
||||||
|
'Reload file into Prolog'))),
|
||||||
|
'&Edit ...' = action(prolog_edit:edit(+file(open,
|
||||||
|
'Edit existing file'))),
|
||||||
|
'&New ...' = action(edit_new(+file(save,
|
||||||
|
'Create new Prolog source'))),
|
||||||
|
--
|
||||||
|
| MRU
|
||||||
|
], []) :-
|
||||||
|
File = '&File',
|
||||||
|
findall(Mru=true, mru_info(File, Mru, _, _, _), MRU, MRUTail),
|
||||||
|
MRUTail = [ --,
|
||||||
|
'&Reload modified files' = user:make,
|
||||||
|
--,
|
||||||
|
'&Navigator ...' = prolog_ide(open_navigator),
|
||||||
|
--
|
||||||
|
].
|
||||||
|
|
||||||
|
:- else.
|
||||||
|
|
||||||
menu('&File',
|
menu('&File',
|
||||||
[ '&Consult ...' = win_menu:action(user:compile(+file(open,
|
[ '&Compile ...' = action(user:compile(+file(open,
|
||||||
'Load file into Prolog'))),
|
'Load file into Prolog'))),
|
||||||
% '&Edit ...' = win_menu:action(user:edit(+file(open,
|
'&Consult ...' = action(user:consult(+file(open,
|
||||||
% 'Edit existing file'))),
|
'Load file into Prolog'))),
|
||||||
% '&New ...' = win_menu:action(edit_new(+file(save,
|
'&Edit ...' = action(prolog_edit:edit(+file(open,
|
||||||
% 'Create new Prolog source'))),
|
'Edit existing file'))),
|
||||||
|
'&New ...' = action(edit_new(+file(save,
|
||||||
|
'Create new Prolog source'))),
|
||||||
--,
|
--,
|
||||||
'&Reload modified files' = user:make,
|
'&Reload modified files' = user:make,
|
||||||
% --,
|
%% --,
|
||||||
% '&Navigator ...' = prolog_ide(open_navigator),
|
%% '&Navigator ...' = prolog_ide(open_navigator),
|
||||||
--
|
--
|
||||||
],
|
],
|
||||||
[ before_item('&Exit')
|
[ before_item('E&xit')
|
||||||
]).
|
]).
|
||||||
/*
|
:- endif.
|
||||||
|
|
||||||
menu('&Settings',
|
menu('&Settings',
|
||||||
[ --,
|
[ --,
|
||||||
'&User init file ...' = prolog_edit_preferences(prolog)
|
'&User init file ...' = prolog_edit_preferences(prolog) %,
|
||||||
% '&GUI preferences ...' = prolog_edit_preferences(xpce)
|
% '&GUI preferences ...' = prolog_edit_preferences(xpce)
|
||||||
],
|
],
|
||||||
[]).
|
[]).
|
||||||
menu('&Debug',
|
menu('&Debug',
|
||||||
[ %'&Trace' = trace,
|
[ '&Trace' = trace,
|
||||||
%'&Debug mode' = debug,
|
'&Debug mode' = debug,
|
||||||
%'&No debug mode' = nodebug,
|
'&No debug mode' = nodebug %,
|
||||||
'&Edit spy points ...' = user:prolog_ide(open_debug_status),
|
%% '&Edit spy points ...' = user:prolog_ide(open_debug_status),
|
||||||
'&Edit exceptions ...' = user:prolog_ide(open_exceptions(@on)),
|
%% '&Edit exceptions ...' = user:prolog_ide(open_exceptions(@on)),
|
||||||
'&Threads monitor ...' = user:prolog_ide(thread_monitor),
|
%% '&Threads monitor ...' = user:prolog_ide(thread_monitor),
|
||||||
'Debug &messages ...' = user:prolog_ide(debug_monitor),
|
%% 'Debug &messages ...' = user:prolog_ide(debug_monitor),
|
||||||
'Cross &referencer ...'= user:prolog_ide(xref),
|
%% 'Cross &referencer ...'= user:prolog_ide(xref),
|
||||||
--,
|
%% --,
|
||||||
'&Graphical debugger' = user:guitracer
|
%% '&Graphical debugger' = user:guitracer
|
||||||
],
|
],
|
||||||
[ before_menu(-)
|
[ before_menu(-)
|
||||||
]).
|
]).
|
||||||
*/
|
|
||||||
menu('&Help',
|
menu('&Help',
|
||||||
[ '&About ...' = about,
|
[ '&About ...' = about,
|
||||||
'&Help ...' = help,
|
%'&Help ...' = help,
|
||||||
'YAP &Manual (on www) ...' = win_menu:www_open(yap_man),
|
%'Browse &PlDoc ...' = doc_browser,
|
||||||
--,
|
--,
|
||||||
'YAP &WWW home (on www) ...' = win_menu:www_open(yap),
|
'YAP website ...' = www_open(yap),
|
||||||
'YAP &GIT (on www) ...' = win_menu:www_open(yap_git),
|
' &Manual ...' = www_open(yap_man),
|
||||||
% 'YAP Mailing &List (on www) ...' = win_menu:www_open(swipl_mail),
|
' &SWI Manual ...' = www_open(swipl_man),
|
||||||
'YAP &Download (on www) ...' = win_menu:www_open(yap_download),
|
% ' &FAQ ...' = www_open(swipl_faq),
|
||||||
--,
|
% ' &Quick Start ...' = www_open(swipl_quick),
|
||||||
% '&XPCE (GUI) Manual ...' = manpce,
|
' Mailing &List ...' = www_open(yap_mail),
|
||||||
|
' &Download ...' = www_open(yap_download),
|
||||||
|
' &Extension packs ...' = www_open(swipl_pack),
|
||||||
% --,
|
% --,
|
||||||
'Submit &Bug report (on www) ...' = win_menu:www_open(yap_bugs)
|
% '&XPCE (GUI) Manual ...' = manpce,
|
||||||
|
--,
|
||||||
|
'Submit &Bug report ...' = www_open(yap_bugs)
|
||||||
],
|
],
|
||||||
[ before_menu(-)
|
[ before_menu(-)
|
||||||
]).
|
]).
|
||||||
@ -108,10 +162,11 @@ init_win_menus :-
|
|||||||
; Before = (-)
|
; Before = (-)
|
||||||
),
|
),
|
||||||
( memberchk(before_menu(BM), Options)
|
( memberchk(before_menu(BM), Options)
|
||||||
-> system:win_insert_menu(Menu, BM)
|
-> true
|
||||||
; true
|
; BM = (-)
|
||||||
),
|
),
|
||||||
( member(Item, Items),
|
system:win_insert_menu(Menu, BM),
|
||||||
|
( lists:member(Item, Items),
|
||||||
( Item = (Label = Action)
|
( Item = (Label = Action)
|
||||||
-> true
|
-> true
|
||||||
; Item == --
|
; Item == --
|
||||||
@ -122,22 +177,34 @@ init_win_menus :-
|
|||||||
; true
|
; true
|
||||||
),
|
),
|
||||||
fail
|
fail
|
||||||
|
; current_prolog_flag(associated_file, File),
|
||||||
|
add_to_mru(load, File)
|
||||||
; insert_associated_file
|
; insert_associated_file
|
||||||
).
|
),
|
||||||
|
refresh_mru.
|
||||||
|
|
||||||
|
associated_file(File) :-
|
||||||
|
current_prolog_flag(associated_file, File), !.
|
||||||
|
associated_file(File) :-
|
||||||
|
fail, '$cmd_option_val'(script_file, O1sFiles),
|
||||||
|
OsFiles = [OsFile], !,
|
||||||
|
prolog_to_os_filename(File, OsFile).
|
||||||
|
|
||||||
insert_associated_file :-
|
insert_associated_file :-
|
||||||
current_prolog_flag(associated_file, File),
|
associated_file(File), !,
|
||||||
file_base_name(File, Base),
|
file_base_name(File, Base),
|
||||||
atom_concat('Edit &', Base, Label),
|
atom_concat('Edit &', Base, Label),
|
||||||
win_insert_menu_item('&File', Label, '&New ...', edit(file(File))).
|
system:win_insert_menu_item('&File', Label, '&New ...', edit(file(File))).
|
||||||
insert_associated_file.
|
insert_associated_file.
|
||||||
|
|
||||||
|
|
||||||
|
:- if(current_predicate(win_has_menu/0)).
|
||||||
:- initialization
|
:- initialization
|
||||||
( win_has_menu
|
( system:win_has_menu
|
||||||
-> init_win_menus
|
-> init_win_menus
|
||||||
; true
|
; true
|
||||||
).
|
).
|
||||||
|
:- endif.
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* ACTIONS *
|
* ACTIONS *
|
||||||
@ -157,9 +224,40 @@ html_open(Spec) :-
|
|||||||
absolute_file_name(Spec, [access(read)], Path),
|
absolute_file_name(Spec, [access(read)], Path),
|
||||||
call(win_shell(open, Path)).
|
call(win_shell(open, Path)).
|
||||||
|
|
||||||
|
:- if(current_predicate(win_message_box/2)).
|
||||||
|
|
||||||
|
about :-
|
||||||
|
message_to_string(about, AboutSWI),
|
||||||
|
( current_prolog_flag(console_menu_version, qt)
|
||||||
|
-> message_to_string(about_qt, AboutQt),
|
||||||
|
format(atom(About), '<p>~w\n<p>~w', [AboutSWI, AboutQt])
|
||||||
|
; About = AboutSWI
|
||||||
|
),
|
||||||
|
atomic_list_concat(Lines, '\n', About),
|
||||||
|
atomic_list_concat(Lines, '<br>', AboutHTML),
|
||||||
|
win_message_box(
|
||||||
|
AboutHTML,
|
||||||
|
[ title('About swipl-win'),
|
||||||
|
image(':/swipl.png'),
|
||||||
|
min_width(700)
|
||||||
|
]).
|
||||||
|
|
||||||
|
:- else.
|
||||||
|
|
||||||
about :-
|
about :-
|
||||||
print_message(informational, about).
|
print_message(informational, about).
|
||||||
|
|
||||||
|
:- endif.
|
||||||
|
|
||||||
|
load(Path) :-
|
||||||
|
( \+ current_prolog_flag(associated_file, _)
|
||||||
|
-> file_directory_name(Path, Dir),
|
||||||
|
working_directory(_, Dir),
|
||||||
|
set_prolog_flag(associated_file, Path)
|
||||||
|
; true
|
||||||
|
),
|
||||||
|
user:load_files(Path).
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* HANDLE CALLBACK *
|
* HANDLE CALLBACK *
|
||||||
@ -170,7 +268,7 @@ action(Action) :-
|
|||||||
Plain =.. [Name|Args],
|
Plain =.. [Name|Args],
|
||||||
gather_args(Args, Values),
|
gather_args(Args, Values),
|
||||||
Goal =.. [Name|Values],
|
Goal =.. [Name|Values],
|
||||||
Module:Goal.
|
call(Module:Goal).
|
||||||
|
|
||||||
gather_args([], []).
|
gather_args([], []).
|
||||||
gather_args([+H0|T0], [H|T]) :- !,
|
gather_args([+H0|T0], [H|T]) :- !,
|
||||||
@ -179,28 +277,61 @@ gather_args([+H0|T0], [H|T]) :- !,
|
|||||||
gather_args([H|T0], [H|T]) :-
|
gather_args([H|T0], [H|T]) :-
|
||||||
gather_args(T0, T).
|
gather_args(T0, T).
|
||||||
|
|
||||||
|
:- if(current_prolog_flag(console_menu_version, qt)).
|
||||||
|
|
||||||
|
gather_arg(file(open, Title), File) :- !,
|
||||||
|
source_types_desc(Desc),
|
||||||
|
pqConsole:getOpenFileName(Title, _, Desc, File),
|
||||||
|
add_to_mru(edit, File).
|
||||||
|
|
||||||
|
gather_arg(file(save, Title), File) :-
|
||||||
|
source_types_desc(Desc),
|
||||||
|
pqConsole:getSaveFileName(Title, _, Desc, File),
|
||||||
|
add_to_mru(edit, File).
|
||||||
|
|
||||||
|
source_types_desc(Desc) :-
|
||||||
|
findall(Pattern, prolog_file_pattern(Pattern), Patterns),
|
||||||
|
atomic_list_concat(Patterns, ' ', Atom),
|
||||||
|
format(atom(Desc), 'Prolog Source (~w)', [Atom]).
|
||||||
|
|
||||||
|
:- else.
|
||||||
|
|
||||||
gather_arg(file(Mode, Title), File) :-
|
gather_arg(file(Mode, Title), File) :-
|
||||||
findall(tuple('Prolog Source', Pattern),
|
findall(tuple('Prolog Source', Pattern),
|
||||||
prolog_file_pattern(Pattern),
|
prolog_file_pattern(Pattern),
|
||||||
Tuples),
|
Tuples),
|
||||||
append(Tuples, [tuple('All files', '*.*')], AllTuples),
|
lists:append(Tuples, [tuple('All files', '*.*')], AllTuples),
|
||||||
Filter =.. [chain|AllTuples],
|
|
||||||
current_prolog_flag(hwnd, HWND),
|
current_prolog_flag(hwnd, HWND),
|
||||||
working_directory(CWD, CWD),
|
working_directory(CWD, CWD),
|
||||||
% filter(AllTuples, Filter),
|
system:win_file_name(
|
||||||
win_open_file_name(HWND, CWD, File).
|
Mode, AllTuples, Title,
|
||||||
%% call(get(@display, win_file_name, % avoid autoloading
|
CWD,
|
||||||
%% Mode, Filter, Title,
|
HWND,
|
||||||
%% directory := CWD,
|
File).
|
||||||
%% owner := HWND,
|
|
||||||
%% File)).
|
:- if( current_prolog_flag( dialect, swi ) ).
|
||||||
|
win_file_name(
|
||||||
|
Mode, AllTuples, Title,
|
||||||
|
CWD,
|
||||||
|
HWND,
|
||||||
|
File) :-
|
||||||
|
% avoid autoloading
|
||||||
|
Filter =.. [chain|AllTuples],
|
||||||
|
call(get(@display, win_file_name, % avoid autoloading
|
||||||
|
Mode, Filter, Title,
|
||||||
|
directory := CWD,
|
||||||
|
owner := HWND,
|
||||||
|
File)).
|
||||||
|
:- endif.
|
||||||
|
|
||||||
|
:- endif.
|
||||||
|
|
||||||
prolog_file_pattern(Pattern) :-
|
prolog_file_pattern(Pattern) :-
|
||||||
user:prolog_file_type(Ext, prolog),
|
user:prolog_file_type(Ext, prolog),
|
||||||
atom_concat('*.', Ext, Pattern).
|
atom_concat('*.', Ext, Pattern).
|
||||||
|
|
||||||
|
|
||||||
|
:- if(current_prolog_flag(windows, true)).
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* APPLICATION *
|
* APPLICATION *
|
||||||
@ -214,9 +345,7 @@ prolog_file_pattern(Pattern) :-
|
|||||||
init_win_app :-
|
init_win_app :-
|
||||||
current_prolog_flag(associated_file, _), !.
|
current_prolog_flag(associated_file, _), !.
|
||||||
init_win_app :-
|
init_win_app :-
|
||||||
current_prolog_flag(argv, Argv),
|
fail, '$cmd_option_val'(win_app, true), !,
|
||||||
append(Pre, ['--win_app'|_Post], Argv),
|
|
||||||
\+ member(--, Pre), !,
|
|
||||||
catch(my_prolog, E, print_message(warning, E)).
|
catch(my_prolog, E, print_message(warning, E)).
|
||||||
init_win_app.
|
init_win_app.
|
||||||
|
|
||||||
@ -238,6 +367,138 @@ ensure_dir(Dir) :-
|
|||||||
:- initialization
|
:- initialization
|
||||||
init_win_app.
|
init_win_app.
|
||||||
|
|
||||||
|
:- endif. /*windows*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
* MacOS *
|
||||||
|
*******************************/
|
||||||
|
|
||||||
|
:- if(current_prolog_flag(console_menu_version, qt)).
|
||||||
|
|
||||||
|
:- multifile
|
||||||
|
prolog:file_open_event/1.
|
||||||
|
|
||||||
|
:- create_prolog_flag(app_open_first, load, []).
|
||||||
|
:- create_prolog_flag(app_open, edit, []).
|
||||||
|
|
||||||
|
%% prolog:file_open_event(+Name)
|
||||||
|
%
|
||||||
|
% Called when opening a file from the MacOS finder. The action
|
||||||
|
% depends on whether this is the first file or not, and defined by
|
||||||
|
% one of these flags:
|
||||||
|
%
|
||||||
|
% - =app_open_first= defines the action for the first open event
|
||||||
|
% - =app_open= defines the action for subsequent open event
|
||||||
|
%
|
||||||
|
% On the _first_ open event, the working directory of the process
|
||||||
|
% is changed to the directory holding the file. Action is one of
|
||||||
|
% the following:
|
||||||
|
%
|
||||||
|
% * load
|
||||||
|
% Load the file into Prolog
|
||||||
|
% * edit
|
||||||
|
% Open the file in the editor
|
||||||
|
% * new_instance
|
||||||
|
% Open the file in a new instance of Prolog and load it there.
|
||||||
|
|
||||||
|
prolog:file_open_event(Path) :-
|
||||||
|
( current_prolog_flag(associated_file, _)
|
||||||
|
-> current_prolog_flag(app_open, Action)
|
||||||
|
; current_prolog_flag(app_open_first, Action),
|
||||||
|
file_directory_name(Path, Dir),
|
||||||
|
working_directory(_, Dir),
|
||||||
|
set_prolog_flag(associated_file, Path),
|
||||||
|
insert_associated_file
|
||||||
|
),
|
||||||
|
must_be(oneof([edit,load,new_instance]), Action),
|
||||||
|
file_open_event(Action, Path).
|
||||||
|
|
||||||
|
file_open_event(edit, Path) :-
|
||||||
|
edit(Path).
|
||||||
|
file_open_event(load, Path) :-
|
||||||
|
add_to_mru(load, Path),
|
||||||
|
user:load_files(Path).
|
||||||
|
:- if(current_prolog_flag(apple, true)).
|
||||||
|
file_open_event(new_instance, Path) :-
|
||||||
|
current_app(Me),
|
||||||
|
print_message(informational, new_instance(Path)),
|
||||||
|
process_create(path(open), [ '-n', '-a', Me, Path ], []).
|
||||||
|
:- else.
|
||||||
|
file_open_event(new_instance, Path) :-
|
||||||
|
current_prolog_flag(executable, Exe),
|
||||||
|
process_create(Exe, [Path], [process(_Pid)]).
|
||||||
|
:- endif.
|
||||||
|
|
||||||
|
|
||||||
|
:- if(current_prolog_flag(apple, true)).
|
||||||
|
current_app(App) :-
|
||||||
|
current_prolog_flag(executable, Exe),
|
||||||
|
file_directory_name(Exe, MacOSDir),
|
||||||
|
atom_concat(App, '/Contents/MacOS', MacOSDir).
|
||||||
|
|
||||||
|
%% go_home_on_plain_app_start is det.
|
||||||
|
%
|
||||||
|
% On Apple, we start in the users home dir if the application is
|
||||||
|
% started by opening the app directly.
|
||||||
|
|
||||||
|
go_home_on_plain_app_start :-
|
||||||
|
current_prolog_flag(os_argv, [_Exe]),
|
||||||
|
current_app(App),
|
||||||
|
file_directory_name(App, Above),
|
||||||
|
working_directory(PWD, PWD),
|
||||||
|
same_file(PWD, Above),
|
||||||
|
expand_file_name(~, [Home]), !,
|
||||||
|
working_directory(_, Home).
|
||||||
|
go_home_on_plain_app_start.
|
||||||
|
|
||||||
|
:- initialization
|
||||||
|
go_home_on_plain_app_start.
|
||||||
|
|
||||||
|
:- endif.
|
||||||
|
:- endif.
|
||||||
|
|
||||||
|
:- if(current_predicate(win_current_preference/3)).
|
||||||
|
|
||||||
|
mru_info('&File', 'Edit &Recent', 'MRU2', path, edit).
|
||||||
|
mru_info('&File', 'Load &Recent', 'MRULoad', path, load).
|
||||||
|
|
||||||
|
add_to_mru(Action, File) :-
|
||||||
|
mru_info(_Top, _Menu, PrefGroup, PrefKey, Action),
|
||||||
|
( win_current_preference(PrefGroup, PrefKey, CPs), nonvar(CPs)
|
||||||
|
-> ( select(File, CPs, Rest)
|
||||||
|
-> Updated = [File|Rest]
|
||||||
|
; length(CPs, Len),
|
||||||
|
Len > 10
|
||||||
|
-> append(CPs1, [_], CPs),
|
||||||
|
Updated = [File|CPs1]
|
||||||
|
; Updated = [File|CPs]
|
||||||
|
)
|
||||||
|
; Updated = [File]
|
||||||
|
),
|
||||||
|
win_set_preference(PrefGroup, PrefKey, Updated),
|
||||||
|
refresh_mru.
|
||||||
|
|
||||||
|
refresh_mru :-
|
||||||
|
( mru_info(FileMenu, Menu, PrefGroup, PrefKey, Action),
|
||||||
|
win_current_preference(PrefGroup, PrefKey, CPs),
|
||||||
|
maplist(action_path_menu(Action), CPs, Labels, Actions),
|
||||||
|
win_insert_menu_item(FileMenu, Menu/Labels, -, Actions),
|
||||||
|
fail
|
||||||
|
; true
|
||||||
|
).
|
||||||
|
|
||||||
|
action_path_menu(ActionItem, Path, Label, win_menu:Action) :-
|
||||||
|
file_base_name(Path, Label),
|
||||||
|
Action =.. [ActionItem, Path].
|
||||||
|
|
||||||
|
:- else.
|
||||||
|
|
||||||
|
add_to_mru(_, _).
|
||||||
|
refresh_mru.
|
||||||
|
|
||||||
|
:- endif.
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
* MESSAGES *
|
* MESSAGES *
|
||||||
@ -250,3 +511,9 @@ prolog:message(opening_url(Url)) -->
|
|||||||
[ 'Opening ~w ... '-[Url], flush ].
|
[ 'Opening ~w ... '-[Url], flush ].
|
||||||
prolog:message(opened_url(_Url)) -->
|
prolog:message(opened_url(_Url)) -->
|
||||||
[ at_same_line, 'ok' ].
|
[ at_same_line, 'ok' ].
|
||||||
|
prolog:message(new_instance(Path)) -->
|
||||||
|
[ 'Opening new Prolog instance for ~p'-[Path] ].
|
||||||
|
:- if(current_prolog_flag(console_menu_version, qt)).
|
||||||
|
prolog:message(about_qt) -->
|
||||||
|
[ 'Qt-based console by Carlo Capelli' ].
|
||||||
|
:- endif.
|
||||||
|
@ -198,8 +198,9 @@ user:url_path(yap, 'http://www.dcc.fc.up.pt/~vsc/Yap').
|
|||||||
|
|
||||||
user:url_path(yap_download, 'http://www.dcc.fc.up.pt/~vsc/Yap/downloads.html').
|
user:url_path(yap_download, 'http://www.dcc.fc.up.pt/~vsc/Yap/downloads.html').
|
||||||
user:url_path(yap_man, yap('documentation.html')).
|
user:url_path(yap_man, yap('documentation.html')).
|
||||||
|
user:url_path(yap_mail, 'https://lists.sourceforge.net/lists/listinfo/yap-users').
|
||||||
user:url_path(yap_bugs, 'http://sourceforge.net/tracker/?group_id=24437&atid=381483').
|
user:url_path(yap_bugs, 'http://sourceforge.net/tracker/?group_id=24437&atid=381483').
|
||||||
user:url_path(yap_git, 'http://yap.git.sourceforge.net/git/gitweb-index.cgi').
|
user:url_path(yap_git, 'http://sourceforge.net/p/yap/yap-6.3/ref/master/').
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user