Do not use backslash-b to select backspaces.
[mp-5.x.git] / mp_vcs.mpsl
blobaed7197d0de70c40e8fd01c71c17fce1e20ba4ee
1 /*
3     Minimum Profit 5.x
4     A Programmer's Text Editor
6     Version Control System support
8     Copyright (C) 1991-2012 Angel Ortega <angel@triptico.com>
10     This program is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     as published by the Free Software Foundation; either version 2
13     of the License, or (at your option) any later version.
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24     http://www.triptico.com
28 /** data **/
30 mp.vcs = {
31     git: {
32         id:     'Git',
33         check:  [ '.git', '../.git', '../../.git' ],
34         opts:   {
35             'git diff'          => NULL,
36             'git status'        => NULL,
37             'git log'           => NULL,
38             "git diff '%s'"     => NULL,
39             "git log '%s'"      => NULL,
40             "git add '%s'"      => NULL,
41             "git blame '%s'"    => NULL,
42             "git checkout '%s'" => NULL,
43             "git stash"         => NULL,
44             "git stash apply"   => NULL,
45             "git push"          => NULL,
46             "git pull"          => NULL,
47             "git commit -a"     => {
48                 pre:    sub (doc) {
49                     mp.vcs_commit_on_close(doc, "git commit -a -F '%s'");
50                 }
51             }
52         }
53     },
54     svn: {
55         id:     'SVN',
56         check:  [ '.svn' ],
57         opts:   {
58             'svn diff'          => NULL,
59             'svn status'        => NULL,
60             'svn log'           => NULL,
61             "svn diff '%s'"     => NULL,
62             "svn log '%s'"      => NULL,
63             "svn add '%s'"      => NULL,
64             "svn annotate '%s'" => NULL,
65             "svn update"        => NULL,
66             "svn commit"        => {
67                 pre:    sub (doc) {
68                     mp.vcs_commit_on_close(doc, "svn commit -F '%s'");
69                 }
70             }
71         }
72     },
73     mercurial: {
74         id:     'Mercurial',
75         check:  [ '.hg', '../.hg', '../../.hg' ],
76         opts:   {
77             'hg diff'          => NULL,
78             'hg status'        => NULL,
79             'hg log'           => NULL,
80             "hg diff '%s'"     => NULL,
81             "hg log '%s'"      => NULL,
82             "hg add '%s'"      => NULL,
83             "hg push"          => NULL,
84             "hg pull"          => NULL,
85             "hg annotate '%s'" => NULL,
86             "hg commit -A"     => {
87                 pre:    sub (doc) {
88                     mp.vcs_commit_on_close(doc, "hg commit -A -l '%s'");
89                 }
90             }
91         }
92     }
95 /** editor actions **/
97 mp.actions['vcs'] = sub (d) {
98     local v = NULL;
100     foreach (k, keys(mp.vcs)) {
101         local n = mp.vcs[k];
103         foreach (d, n.check) {
104             if (stat(d) != NULL) {
105                 v = n;
106                 break;
107             }
108         }
110         if (v != NULL)
111             break;
112     }
114     if (v == NULL)
115         mp.alert(L("This directory is not under a supported version control system"));
116     else {
117         local l = sort(keys(v.opts));
119         local t = mp.form(
120             [
121                 {
122                     label:  sprintf(L("Available %s commands"), v.id),
123                     type:   'list',
124                     list:   l,
125                     value:  mp.vcs_target
126                 }
127             ]
128         );
130         if (t != NULL) {
131             mp.vcs_target = t[0];
133             local cmd = sprintf(l[mp.vcs_target], d.name);
135             /* if a 'pre' hook exists, run it and get the
136                cmd to be executed (NULL if none) */
137             if (v.opts[cmd].pre) {
138                 cmd = v.opts[cmd].pre(d);
139             }
141             if (cmd != NULL) {
142                 local log = mp.open(sprintf(L("<%s output>"), cmd));
144                 log.txt.lines   = [ '' ];
145                 log.txt.y       = 0;
147                 if (v.opts[cmd] == NULL) {
148                     mp.actions.exec_command(log, cmd);
149                 }
151                 mp.detect_syntax(log);
152                 mp.move_bof(log);
153                 log.txt.mod     = 0;
154                 log.undo        = [];
155                 log.read_only   = 1;
156             }
157         }
158     }
161 /** default key bindings **/
163 mp.keycodes['ctrl-p'] = 'vcs';
165 /** action descriptions **/
167 mp.keycodes['vcs'] = LL("Version Control...");
169 /** code **/
171 sub mp.vcs_commit_on_close(doc, cmd)
172 /* on_close handler for commit message documents */
174     /* create a commit message */
175     local ci = mp.open('.COMMIT_MESSAGE');
177     ci.commit_cmd = cmd;
179     /* and add an on_close handler */
180     push(ci.on_close,
181         sub (doc) {
182             local ret = 1;
184             if (stat(doc.name)) {
185                 doc.txt.lines   = [ '' ];
186                 doc.txt.y       = 0;
187                 mp.actions.exec_command(doc, sprintf(doc.commit_cmd, doc.name));
189                 mp.detect_syntax(doc);
190                 mp.move_bof(doc);
191                 doc.txt.mod     = 0;
192                 doc.undo        = [];
193                 doc.read_only   = 1;
195                 doc.name = sprintf(L("<%s output>"), doc.commit_cmd);
197                 /* reject closing (file has been modified) */
198                 ret = 0;
199             }
201             unlink('.COMMIT_MESSAGE');
203             /* delete this on_close handler */
204             pop(doc.on_close);
206             return ret;
207         }
208     );
210     return NULL;