summaryrefslogtreecommitdiff
path: root/save.pl
blob: a12f6a1a9d2f886071ef9ec40ba35fb492bead7f (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
:- 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'))).
:- pce_global(@refresh_button,
	      new(button(refresh, message(@prolog, refresh)))).

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, @refresh_button),
	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)).

log(C) :-
	setup_call_cleanup(
	    process_create(path(git), ['log', '--format=format:%ai %s'],
			   [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).