35
36:- module(prolog_history,
37 [ prolog_history/1
38 ]). 39:- autoload(library(base32),[base32/2]). 40:- autoload(library(lists),[member/2]). 41:- autoload(library(readutil),[read_line_to_codes/2]). 42
43
44:- multifile
45 prolog:history/2.
61:- create_prolog_flag(save_history, true, [type(boolean)]).
68history_directory(Dir) :-
69 absolute_file_name(user_app_config('dir-history'),
70 Dir,
71 [ access(write),
72 file_type(directory),
73 file_errors(fail)
74 ]),
75 !.
76history_directory(Dir) :-
77 absolute_file_name(user_app_config('.'),
78 ConfigDir,
79 [ access(write),
80 file_type(directory),
81 file_errors(fail)
82 ]),
83 atom_concat(ConfigDir, '/dir-history', Dir),
84 ( exists_directory(Dir)
85 -> '$my_file'(Dir)
86 ; file_directory_name(Dir, Parent),
87 '$my_file'(Parent),
88 make_directory(Dir)
89 ).
96dir_history_file(Dir, File) :-
97 nonvar(Dir),
98 !,
99 history_directory(Base),
100 absolute_file_name(Dir, Path),
101 base32(Path, Encoded),
102 atomic_list_concat([Base, Encoded], /, File).
103dir_history_file(Dir, File) :-
104 history_directory(HDir),
105 directory_files(HDir, Files),
106 '$member'(Base32, Files),
107 base32(Dir, Base32),
108 !,
109 atomic_list_concat([Dir, Base32], /, File).
110
111write_history(File) :-
112 current_prolog_flag(save_history, true),
113 catch(prolog:history(user_input, save(File)), _, true), !.
114write_history(_).
128:- dynamic
129 history_loaded/1. 130
131load_dir_history(File) :-
132 ( exists_file(File),
133 prolog:history(user_input, load(File))
134 -> assertz(history_loaded(File))
135 ; true
136 ).
137
138prolog_history(enable) :-
139 history_loaded(_),
140 !.
141prolog_history(enable) :-
142 catch(dir_history_file('.', File), E,
143 (print_message(warning, E),fail)),
144 catch(load_dir_history(File), E,
145 print_message(warning, E)),
146 !,
147 at_halt(write_history(File)),
148 set_prolog_flag(save_history, true).
149prolog_history(_) :-
150 set_prolog_flag(save_history, false).
151
152 155
156:- if(current_predicate('$rl_history'/1)). 157prolog:history(_, load(File)) :-
158 access_file(File, read),
159 !,
160 setup_call_cleanup(
161 open(File, read, In, [encoding(utf8)]),
162 read_history(In),
163 close(In)).
164prolog:history(_, load(_)).
165
166read_history(In) :-
167 repeat,
168 read_line_to_codes(In, Codes),
169 ( Codes == end_of_file
170 -> !
171 ; atom_codes(Line, Codes),
172 rl_add_history(Line),
173 fail
174 ).
175
176prolog:history(_, save(File)) :-
177 '$rl_history'(Lines),
178 ( Lines \== []
179 -> setup_call_cleanup(
180 open(File, write, Out, [encoding(utf8)]),
181 forall(member(Line, Lines),
182 format(Out, '~w~n', [Line])),
183 close(Out))
184 ; true
185 ).
186
187:- endif.
Per-directory persistent commandline history
This module implements persistency of the commandline history over Prolog sessions on Prolog installations that are based on the GNU readline library (default for the development version on Unix systems).
The history is stored in the directory
<config>/dir-history
. For each directory for which it keeps the history, there is file whose name is the base32 encoding of the directory path.This file is normally loaded when Prolog is started if
user_input
is a terminal and the system supports history. */