summaryrefslogtreecommitdiff
path: root/save.pl
blob: 2e6a8d873d7c0c7add267b230d7623c48e04246a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
:- consult(pce_file_search_path).
:- consult(library(pce)).
:- consult(library(process)).

:- pce_global(@dialog, new(dialog('Save'))).

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'),
	new(D, @dialog),

	% File browser.
	new(C, chain),
	status(C),
	send(new(B, browser), right, D),
	send(B, members(C)),

	% Input fields.
	send(D, append, text('Commit message (optional):',
			     left,
			     bold)),
	send(D, append, new(E, editor)),
	send(D, append, button(save,
			       message(@prolog, save, E, C))),
	send(D, append, button(cancel,
			       and(message(@prolog, reset),
				   message(D, destroy)))),
	send(D, open).

reset :-
	shell("git reset").

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(Editor, Chain) :-
	get(Editor?text_buffer, contents, S),
	send(S, strip),
	get(S, value, Msg),
	(   Msg == ''
	->  chain_atom(Chain, 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).