:- consult(pce_file_search_path). :- consult(library(pce)). :- consult(library(process)). :- pce_begin_class(save_dialog, dialog). unlink(D) :-> shell("git reset"), send_super(D, unlink). :- pce_end_class(save_dialog). :- pce_global(@dialog, new(save_dialog('Save'))). :- pce_global(@files, new(chain)). :- pce_global(@commits, new(chain)). :- pce_global(@editor, new(editor)). :- pce_global(@file_browser, new(browser)). :- pce_global(@commit_browser, new(browser)). :- pce_global(@save_button, new(button(save, message(@prolog, save), 'RET'))). main :- pce_main_loop(main). main(_Argv) :- init. init :- shell("git add .", Status), added(Status). added(1) :- send(@display, report, error, 'Files could not be added to index. Ensure Git is in PATH.'). added(0) :- %send(@pce, load_defaults, 'Defaults'), % Right side. send(@file_browser, right, @dialog), send(@commit_browser, right, @dialog), refresh, % Left side. send(@dialog, append, text('Commit message (optional):', left, bold)), send(@dialog, append, @editor), send(@dialog, append, @save_button), send(@dialog, append, button(refresh, and(message(@prolog, refresh)))), send(@dialog, open). refresh :- send(@files, clear), status(@files), send(@file_browser, members(@files)), send(@commits, clear), log(@commits), send(@commit_browser, members(@commits)). status(C) :- setup_call_cleanup( process_create(path(git), ['status', '--porcelain'], [stdout(pipe(Out))]), read_to_chain(Out, C), close(Out)). read_to_chain(S, C) :- read_line_to_codes(S, Cs), ( Cs == end_of_file -> true ; atom_codes(A, Cs), send(C, append, A), read_to_chain(S, C) ). save :- get(@editor?text_buffer, contents, S), send(S, strip), get(S, value, Msg), ( Msg == '' -> chain_atom(@files, A), commit(A) ; commit(Msg) ). chain_atom(C, A) :- chain_atom_x(C, '', A). chain_atom_x(C, A0, A) :- ( get(C, delete_head, A1) -> atom_concat(A0, A1, A2), atom_concat(A2, ' ', A3), chain_atom_x(C, A3, A) ; A = A0 ). commit(Msg) :- process_create(path(git), ['commit', '-m', Msg], [process(PID)]), process_wait(PID, S), commited(S). commited(S) :- dif(S, exit(0)), dif(S, exit(128)), !, send(@display, report, error, 'Files could not be saved.'). commited(_) :- send(@dialog, destroy).