From f6c07fdd7dbcac20e8ea17ce2d89e361eabc54dd Mon Sep 17 00:00:00 2001 From: vdhoeven Date: Mon, 25 May 2009 17:08:25 +0000 Subject: [PATCH] Reorganize archiver by introducing non deterministic patches git-svn-id: svn://svn.savannah.gnu.org/texmacs/trunk@2705 64cb5145-927a-446d-8aed-2fb7b4773692 --- src/TeXmacs/progs/utils/plugins/plugin-eval.scm | 19 +- src/src/Data/History/archiver.cpp | 342 +++++++++++++++--------- src/src/Data/History/archiver.hpp | 20 +- src/src/Data/History/commute.cpp | 33 +++ src/src/Data/History/patch.cpp | 226 +++++++++++++--- src/src/Data/History/patch.hpp | 18 +- src/src/Edit/Modify/edit_modify.cpp | 11 +- src/src/Edit/Modify/edit_modify.hpp | 1 + src/src/Edit/editor.hpp | 1 + src/src/Guile/Glue/build-glue-editor.scm | 2 + src/src/Guile/Glue/glue_editor.cpp | 24 ++ 11 files changed, 514 insertions(+), 183 deletions(-) diff --git a/src/TeXmacs/progs/utils/plugins/plugin-eval.scm b/src/TeXmacs/progs/utils/plugins/plugin-eval.scm index 49b0fff2..dbe2f235 100644 --- a/src/TeXmacs/progs/utils/plugins/plugin-eval.scm +++ b/src/TeXmacs/progs/utils/plugins/plugin-eval.scm @@ -80,16 +80,21 @@ (connection-status lan ses) 2)) +(define (plugin-set-author lan ses) + (with l (pending-ref lan ses) + (when (nnull? l) + (ahash-set! plugin-author (list lan ses) (fifth (caar l)))))) + (define (plugin-start lan ses) (when (!= lan "scheme") - (ahash-set! plugin-author (list lan ses) (new-author)) + (plugin-set-author lan ses) (connection-start lan ses))) (tm-define (plugin-write lan ses t) (ahash-set! plugin-started (list lan ses) (texmacs-time)) (if (!= lan "scheme") (begin - (ahash-set! plugin-author (list lan ses) (new-author)) + (plugin-set-author lan ses) (connection-write lan ses t)) (delayed (connection-notify-status lan ses 3) @@ -138,8 +143,13 @@ (tm-define (plugin-feed lan ses do notify next cancel args) (with l (pending-ref lan ses) - (pending-set lan ses (rcons l (cons (list do notify next cancel) args))) - (if (null? l) (plugin-do lan ses)))) + (with author 0 + (when (!= lan "scheme") + (set! author (new-author)) + (start-slave author)) + (with cb (list do notify next cancel author) + (pending-set lan ses (rcons l (cons cb args))) + (if (null? l) (plugin-do lan ses)))))) (tm-define (plugin-interrupt) (let* ((lan (get-env "prog-language")) @@ -158,6 +168,7 @@ `(with old (get-author) (set-author ,a) (with r (begin ,@body) + (commit-changes) (set-author old) r))) diff --git a/src/src/Data/History/archiver.cpp b/src/src/Data/History/archiver.cpp index 261d901d..c65dcb45 100644 --- a/src/src/Data/History/archiver.cpp +++ b/src/src/Data/History/archiver.cpp @@ -12,15 +12,16 @@ #include "archiver.hpp" extern tree the_et; +static patch empty_patch (); +static patch make_compound (array a); /****************************************************************************** * Constructors and destructors ******************************************************************************/ archiver_rep::archiver_rep (): - before (array ()), - current (array ()), - after (array ()), + archive (empty_patch ()), + current (make_compound (0)), depth (0), last_save (0), last_autosave (0) {} @@ -29,23 +30,85 @@ archiver::archiver (): rep (tm_new ()) {} void archiver_rep::clear () { - before= array (); - current= array (); - after= array (); + archive= empty_patch (); + current= make_compound (0); depth= 0; last_save= -1; last_autosave= -1; } /****************************************************************************** -* Internal subroutines +* Useful subroutines ******************************************************************************/ +static patch +empty_patch () { + return patch (true, array ()); +} + static bool is_empty (patch p) { - return get_type (p) == PATCH_COMPOUND && N (p) == 0; + return get_type (p) == PATCH_BRANCH && N (p) == 0; +} + +static patch +make_compound (array a) { + if (N(a) == 1) return a[0]; + else return patch (false, a); +} + +static patch +make_branches (array a) { + if (N(a) == 1) return a[0]; + else return patch (true, a); +} + +static patch +append_branches (patch p1, patch p2) { + return make_branches (append (branches (p1), branches (p2))); +} + +static patch +make_history (patch undo, patch redo) { + array a; + a << undo << branches (redo); + return make_branches (a); +} + +static patch +car (patch p) { + ASSERT (nr_children (branch (p, 0)) == 2, "car unavailable") + return child (p, 0); +} + +static patch +cdr (patch p) { + ASSERT (nr_children (branch (p, 0)) == 2, "cdr unavailable") + return child (p, 1); } +static patch +get_undo (patch p) { + ASSERT (nr_branches (p) > 0, "undo part unavailable"); + return car (branch (p, 0)); +} + +static patch +get_next (patch p) { + ASSERT (nr_branches (p) > 0, "next part unavailable"); + return cdr (branch (p, 0)); +} + +static patch +get_redo (patch p) { + if (nr_branches (p) == 0) return make_branches (array ()); + return make_branches (branches (p, 1, nr_branches (p))); +} + +/****************************************************************************** +* Internal subroutines +******************************************************************************/ + void archiver_rep::apply (patch p) { // apply a patch, while disabling versioning during the modifications @@ -57,28 +120,31 @@ archiver_rep::apply (patch p) { versioning_busy= old; } -static void -show (patch p) { - if (N(p) == 0) return; - if (N(p) == 2) { - cout << p[0] << LF; - show (p[1]); - } - else { - for (int i=0; i " << p1 << "\n"; + cout << "p2 > " << p2 << "\n"; + return patch (p1, patch (p2, hh[1])); } - } + else return history; } +*/ void archiver_rep::show_all () { - cout << HRULE; - show (before); cout << HRULE; - show (after); cout << HRULE << LF; + cout << HRULE << archive << LF << HRULE << LF; } /****************************************************************************** @@ -86,15 +152,27 @@ archiver_rep::show_all () { ******************************************************************************/ void -archiver_rep::archive (patch p) { - // cout << "Archive [" << get_author () << "] " << p << "\n"; +archiver_rep::add (patch p) { + // cout << "Add [" << get_author () << "] " << p << "\n"; patch q= copy (invert (p, the_et)); current= patch (q, current); } +void +archiver_rep::start_slave (double a) { + patch q (a, false); + current= patch (q, current); +} + bool archiver_rep::active () { - return !is_empty (current); + return nr_children (current) != 0; +} + +bool +archiver_rep::has_history () { + if (is_empty (archive)) return false; + else return !is_empty (branch (archive, 0)); } void @@ -102,18 +180,17 @@ archiver_rep::cancel () { if (active ()) { // cout << "Cancel " << current << "\n"; apply (current); - current= patch (array ()); + current= make_compound (0); } } void archiver_rep::confirm () { if (active ()) { - current= compactify (current); + current= patch (get_author (), compactify (current)); // cout << "Confirm " << current << "\n"; - before= append (array (current, before), get_children (after)); - current= patch (array ()); - after= patch (array ()); + archive= patch (current, archive); + current= make_compound (0); depth++; if (depth <= last_save) last_save= -1; if (depth <= last_autosave) last_autosave= -1; @@ -122,35 +199,22 @@ archiver_rep::confirm () { } void -archiver_rep::merge () { - if (active () && N (before) != 0) { - // cout << "Merge " << current << "\n"; - if (N (after) != 0) { confirm (); return; } - array a= get_children (before); - array b (1); - b[0]= compactify (patch (current, a[0])); - before= patch (append (b, range (a, 1, N(a)))); - current= patch (array ()); - if (depth <= last_save) last_save= -1; - if (depth <= last_autosave) last_autosave= -1; - } -} - -void archiver_rep::retract () { - if (N (before) != 0) { - // cout << "Retract " << before[0] << "\n"; - if (active ()) current= compactify (patch (current, before[0])); - else current= before[0]; - array a; - if (N (after) != 0) { + if (has_history ()) { + patch un= get_undo (archive); + patch re= get_redo (archive); + patch nx= get_next (archive); + //cout << "Retract " << un << "\n"; + if (active ()) current= compactify (patch (current, un)); + else current= un; + if (nr_branches (re) != 0) { patch q= invert (current, the_et); - a= array (q, after); + re= patch (q, re); } - array c= get_children (before); - after= patch (append (a, range (c, 2, N(c)))); - before= before[1]; + if (nr_branches (nx) != 0) nx= branch (nx, 0); + archive= make_history (nx, append_branches (re, get_redo (nx))); depth--; + //show_all (); } } @@ -167,47 +231,24 @@ archiver_rep::forget () { void archiver_rep::simplify () { - if (N (before) == 2 && - N (before[1]) >= 2 && - get_type (before[0]) == PATCH_MODIFICATION && - get_type (before[1][0]) == PATCH_MODIFICATION) + if (has_history () && + nr_branches (get_next (archive)) == 1 && + nr_children (branch (get_next (archive), 0)) == 2) { - modification m1= get_modification (before[0]); - modification m2= get_modification (before[1][0]); - //cout << "m1= " << m1 << "\n"; - //cout << "m2= " << m2 << "\n"; - if (m1->k == MOD_INSERT && - m2->k == MOD_INSERT && - is_atomic (m1->t) && - root (m1) == root (m2) && - (index (m2) == index (m1) || - index (m2) == index (m1) + N (m1->t->label))) - { - string s= m1->t->label * m2->t->label; - if (index (m2) == index (m1)) - s= m2->t->label * m1->t->label; - modification m= mod_insert (root (m1), index (m1), tree (s)); - array a (1); a[0]= m; - array c= get_children (before[1]); - before= patch (append (a, range (c, 1, N(c)))); - depth--; - simplify (); - } - else if (m1->k == MOD_REMOVE && - m2->k == MOD_REMOVE && - is_atomic (subtree (the_et, root (m1))) && - root (m1) == root (m2) && - (index (m1) == index (m2) || - index (m1) == index (m2) + argument (m2))) - { - modification m= mod_remove (root (m2), index (m2), - argument (m1) + argument (m2)); - array a (1); a[0]= m; - array c= get_children (before[1]); - before= patch (append (a, range (c, 1, N(c)))); - depth--; - simplify (); - } + patch p1= get_undo (archive); + patch p2= get_undo (get_next (archive)); + //cout << "p1= " << p1 << "\n"; + //cout << "p2= " << p2 << "\n"; + bool r= join (p1, p2, the_et); + //cout << "pr= " << p1 << "\n"; + if (r) { + patch un= patch (p1, get_next (get_next (archive))); + patch re= get_redo (archive); + archive= make_history (un, re); + //show_all (); + depth--; + simplify (); + } } } @@ -215,40 +256,38 @@ archiver_rep::simplify () { * Undo and redo ******************************************************************************/ -bool -archiver_rep::no_more_undo () { - return N (before) == 0; -} - -bool -archiver_rep::no_more_redo () { - return N (after) == 0; -} - int archiver_rep::undo_possibilities () { - if (no_more_undo ()) return 0; - else return 1; + if (has_history ()) return 1; + else return 0; } int archiver_rep::redo_possibilities () { - return N (after) >> 1; + if (is_empty (archive)) return 0; + else return nr_branches (get_redo (archive)); } path -archiver_rep::undo () { - if (!active () && N (before) != 0) { - ASSERT (is_applicable (before[0], the_et), "history corrupted"); - patch p= before[0]; - // cout << "p= " << p << "\n"; +archiver_rep::undo_one (int i) { + if (active ()) return path (); + if (undo_possibilities () != 0) { + ASSERT (i == 0, "index out of range"); + patch p= get_undo (archive); + //cout << "p= " << p << "\n"; + ASSERT (is_applicable (p, the_et), "history corrupted"); patch q= invert (p, the_et); - // cout << "q= " << q << "\n"; + //cout << "q= " << q << "\n"; apply (p); - array c= get_children (before); - array a= range (c, 2, N(c)); - before= before[1]; - after= append (array (q, after), a); + patch r= patch (q, get_redo (archive)); + //cout << "r= " << r << "\n"; + patch nx= get_next (archive); + if (nr_branches (nx) == 0) + archive= make_history (nx, r); + else { + patch s= append_branches (r, get_redo (nx)); + archive= make_history (branch (nx, 0), s); + } depth--; //show_all (); return cursor_hint (q, the_et); @@ -257,19 +296,24 @@ archiver_rep::undo () { } path -archiver_rep::redo (int i) { - ASSERT (i >= 0 && ((2*i) < N(after)), "index out of range"); - if (!active () && N (after) != 0) { - ASSERT (is_applicable (after[2*i], the_et), "future corrupted"); - patch p= after[2*i]; - // cout << "p= " << p << "\n"; +archiver_rep::redo_one (int i) { + if (active ()) return path (); + int n= redo_possibilities (); + if (n != 0) { + ASSERT (i >= 0 && i < n, "index out of range"); + patch un= branch (archive, 0); + patch re= get_redo (archive); + patch p= car (branch (re, i)); + //cout << "p= " << p << "\n"; + ASSERT (is_applicable (p, the_et), "future corrupted"); patch q= invert (p, the_et); - // cout << "q= " << q << "\n"; + //cout << "q= " << q << "\n"; apply (p); - array c= get_children (after); - array a= append (range (c, 0, 2*i), range (c, 2*i+2, N(c))); - before= patch (append (array (q, before), a)); - after = after[2*i+1]; + patch other= make_branches (append (branches (re, 0, i), branches (re, i+1, n))); + //cout << "other= " << other << "\n"; + patch next= make_history (un, other); + //cout << "next= " << next << "\n"; + archive= make_history (patch (q, next), cdr (branch (re, i))); if (depth <= last_save && i != 0) last_save= -1; if (depth <= last_autosave && i != 0) last_autosave= -1; depth++; @@ -279,6 +323,40 @@ archiver_rep::redo (int i) { return path (); } +path +archiver_rep::undo (int i) { + if (active ()) return path (); + double author= get_author (); + //before= expose (before, author); + while (undo_possibilities () != 0) { + ASSERT (i == 0, "index out of range"); + if (get_author (get_undo (archive)) == author) + return undo_one (i); + else { + (void) undo_one (i); + i= 0; + } + } + return path (); +} + +path +archiver_rep::redo (int i) { + if (active ()) return path (); + path r; + double author= get_author (); + while (redo_possibilities () != 0) { + ASSERT (i >= 0 && i < redo_possibilities (), "index out of range"); + bool ok= (get_author (car (branch (get_redo (archive), i))) == author); + path p= redo_one (i); + if (ok) r= p; + i= 0; + if (redo_possibilities () == 0) break; + if (get_author (car (branch (get_redo (archive), i))) == author) break; + } + return r; +} + /****************************************************************************** * Check changes since last save/autosave ******************************************************************************/ diff --git a/src/src/Data/History/archiver.hpp b/src/src/Data/History/archiver.hpp index aade262d..77fbabeb 100644 --- a/src/src/Data/History/archiver.hpp +++ b/src/src/Data/History/archiver.hpp @@ -14,12 +14,11 @@ #include "patch.hpp" class archiver_rep: public concrete_struct { - patch before; // undo history + patch archive; // undo and redo archive patch current; // current sequence of modifications - patch after; // redo future - int depth; // history depth - int last_save; // history depth at last save - int last_autosave; // history depth at last autosave + int depth; // archive depth + int last_save; // archive depth at last save + int last_autosave; // archive depth at last autosave protected: void apply (patch p); @@ -30,20 +29,21 @@ public: ~archiver_rep (); void clear (); - void archive (patch p); + void add (patch p); + void start_slave (double a); bool active (); + bool has_history (); void cancel (); // cancel current series of modifications void confirm (); // move current modifications to history - void merge (); // merge current modifications with last history item void retract (); // reopen last history item for further modifications void forget (); // undo and forget about last history item void simplify (); - bool no_more_undo (); - bool no_more_redo (); int undo_possibilities (); int redo_possibilities (); - path undo (); + path undo_one (int i); + path redo_one (int i); + path undo (int i=0); path redo (int i=0); void require_save (); diff --git a/src/src/Data/History/commute.cpp b/src/src/Data/History/commute.cpp index 1c2186df..bdd3019f 100644 --- a/src/src/Data/History/commute.cpp +++ b/src/src/Data/History/commute.cpp @@ -290,6 +290,39 @@ commute (modification m1, modification m2) { } /****************************************************************************** +* Joining simple modifications when possible +******************************************************************************/ + +bool +join (modification& m1, modification m2, tree t) { + if (m1->k == MOD_INSERT && + m2->k == MOD_INSERT && + is_atomic (m1->t) && + root (m1) == root (m2) && + (index (m2) == index (m1) || + index (m2) == index (m1) + N (m1->t->label))) + { + string s= m1->t->label * m2->t->label; + if (index (m2) == index (m1)) + s= m2->t->label * m1->t->label; + m1= mod_insert (root (m1), index (m1), tree (s)); + return true; + } + if (m1->k == MOD_REMOVE && + m2->k == MOD_REMOVE && + is_atomic (subtree (t, root (m1))) && + root (m1) == root (m2) && + (index (m1) == index (m2) || + index (m1) == index (m2) + argument (m2))) + { + m1= mod_remove (root (m2), index (m2), + argument (m1) + argument (m2)); + return true; + } + return false; +} + +/****************************************************************************** * Test routines ******************************************************************************/ diff --git a/src/src/Data/History/patch.cpp b/src/src/Data/History/patch.cpp index 78a6c356..8bf6b526 100644 --- a/src/src/Data/History/patch.cpp +++ b/src/src/Data/History/patch.cpp @@ -32,6 +32,15 @@ public: patch get_child (int i) { return a[i]; } }; +class branch_patch_rep: public patch_rep { + array a; +public: + branch_patch_rep (array a2): a (a2) {} + int get_type () { return PATCH_BRANCH; } + int get_arity () { return N(a); } + patch get_child (int i) { return a[i]; } +}; + class birth_patch_rep: public patch_rep { double author; bool birth; @@ -59,6 +68,10 @@ patch::patch (modification mod): rep (tm_new (mod)) { rep->ref_count= 1; } patch::patch (array a): rep (tm_new (a)) { rep->ref_count= 1; } +patch::patch (bool branch, array a): + rep (branch? + ((patch_rep*) tm_new (a)): + ((patch_rep*) tm_new (a))) { rep->ref_count= 1; } patch::patch (patch p1, patch p2): rep (tm_new (array(p1,p2))) { rep->ref_count= 1; } patch::patch (double author, bool create): @@ -66,14 +79,77 @@ patch::patch (double author, bool create): patch::patch (double author, patch p): rep (tm_new (author, p)) { rep->ref_count= 1; } -array -get_children (patch p) { +/****************************************************************************** +* Internal subroutines +******************************************************************************/ + +static array +singleton (patch p) { + array a (1); + a[0]= p; + return a; +} + +static array +get_array (patch p) { int i, n= N(p); array a (n); for (i=0; i +children (patch p) { + if (get_type (p) != PATCH_COMPOUND) return singleton (p); + else return get_array (p); +} + +array +children (patch p, int i, int j) { + ASSERT (0 <= i && i <= nr_children (p), "index out of range"); + ASSERT (i <= j && j <= nr_children (p), "index out of range"); + return range (children (p), i, j); +} + +int +nr_branches (patch p) { + if (get_type (p) != PATCH_BRANCH) return 1; + else return N(p); +} + +patch +branch (patch p, int i) { + ASSERT (0 <= i && i < nr_branches (p), "index out of range"); + if (get_type (p) != PATCH_BRANCH) return p; + else return p[i]; +} + +array +branches (patch p) { + if (get_type (p) != PATCH_BRANCH) return singleton (p); + else return get_array (p); +} + +array +branches (patch p, int i, int j) { + ASSERT (0 <= i && i <= nr_branches (p), "index out of range"); + ASSERT (i <= j && j <= nr_branches (p), "index out of range"); + return range (branches (p), i, j); +} + /****************************************************************************** * Author management ******************************************************************************/ @@ -108,10 +184,20 @@ operator << (ostream& out, patch p) { out << get_modification (p); break; case PATCH_COMPOUND: - out << "Composite" << INDENT; - for (int i=0; i r (n); for (i=0; i a (n); for (int i=0; i=0; i--) { - if (!swap (a[i], p2)) return false; + if (!swap (a[i], p2, a1, a2)) return false; swap_basic (a[i], p2); } p1= p2; @@ -271,7 +372,7 @@ swap (patch& p1, patch& p2) { array a (n); for (int i=0; i r; - insert (r, p); - if (N(r) == 1) return r[0]; - return patch (r); + double a= 0; + for (int i=0; i r; + insert (r, p); + if (N(r) == 1) return r[0]; + return patch (r); + } + else { + array r; + for (int i=0; i r (n); + for (i=0; i a); + patch (bool par, array a); patch (patch p1, patch p2); patch (double author, bool create); patch (double author, patch p); @@ -58,6 +60,15 @@ inline patch patch_rep::get_child (int i) { * Routines on patches ******************************************************************************/ +int nr_children (patch p); +patch child (patch p, int i); +array children (patch p); +array children (patch p, int i, int j); +int nr_branches (patch p); +patch branch (patch p, int i); +array branches (patch p); +array branches (patch p, int i, int j); + double new_author (); void set_author (double author); double get_author (); @@ -65,7 +76,6 @@ double get_author (); ostream& operator << (ostream& out, patch p); patch copy (patch p); patch compactify (patch p); -array get_children (patch p); path cursor_hint (patch p, tree t); inline int get_type (patch p) { @@ -86,8 +96,10 @@ void apply (patch p, tree& t); modification invert (modification m, tree t); bool commute (modification m1, modification m2); bool swap (modification& m1, modification& m2); +bool join (modification& m1, modification m2, tree t); patch invert (patch p, tree t); bool commute (patch p1, patch p2); bool swap (patch& p1, patch& p2); +bool join (patch& p1, patch p2, tree t); #endif // defined PATCH_H diff --git a/src/src/Edit/Modify/edit_modify.cpp b/src/src/Edit/Modify/edit_modify.cpp index 97f05da4..4d804800 100644 --- a/src/src/Edit/Modify/edit_modify.cpp +++ b/src/src/Edit/Modify/edit_modify.cpp @@ -245,6 +245,11 @@ edit_modify_rep::end_editing () { } void +edit_modify_rep::start_slave (double a) { + buf->arch->start_slave (a); +} + +void edit_modify_rep::add_undo_mark () { buf->arch->confirm (); } @@ -258,7 +263,7 @@ void edit_modify_rep::undo (bool redoable) { if (inside_graphics () && !as_bool (eval ("graphics-undo-enabled"))) { eval ("(graphics-reset-context 'undo)"); return; } - if (buf->arch->no_more_undo ()) { + if (buf->arch->undo_possibilities () == 0) { set_message ("No more undo information available", "undo"); return; } if (redoable) { path p= buf->arch->undo (); @@ -295,7 +300,7 @@ edit_modify_rep::redo_possibilities () { void edit_modify_rep::redo (int i) { - if (buf->arch->no_more_redo ()) { + if (buf->arch->redo_possibilities () == 0) { set_message ("No more redo information available", "redo"); return; } path p= buf->arch->redo (i); if (!is_nil (p)) go_to (p); @@ -319,7 +324,7 @@ void archive_announce (tm_buffer buf, modification mod) { ASSERT (buf->rp <= mod->p, "invalid modification"); if (!versioning_busy) - buf->arch->archive (patch (mod)); + buf->arch->add (patch (mod)); } /****************************************************************************** diff --git a/src/src/Edit/Modify/edit_modify.hpp b/src/src/Edit/Modify/edit_modify.hpp index b4a719b0..5a8d6c36 100644 --- a/src/src/Edit/Modify/edit_modify.hpp +++ b/src/src/Edit/Modify/edit_modify.hpp @@ -38,6 +38,7 @@ public: void clear_undo_history (); void start_editing (); void end_editing (); + void start_slave (double a); void add_undo_mark (); void remove_undo_mark (); void undo (bool redoable); diff --git a/src/src/Edit/editor.hpp b/src/src/Edit/editor.hpp index c540e7fe..6adb5953 100644 --- a/src/src/Edit/editor.hpp +++ b/src/src/Edit/editor.hpp @@ -270,6 +270,7 @@ public: virtual double this_author () = 0; virtual void start_editing () = 0; virtual void end_editing () = 0; + virtual void start_slave (double a) = 0; virtual void add_undo_mark () = 0; virtual void remove_undo_mark () = 0; virtual void unredoable_undo () = 0; diff --git a/src/src/Guile/Glue/build-glue-editor.scm b/src/src/Guile/Glue/build-glue-editor.scm index da93a6aa..b959b0fa 100644 --- a/src/src/Guile/Glue/build-glue-editor.scm +++ b/src/src/Guile/Glue/build-glue-editor.scm @@ -206,6 +206,8 @@ ;; undo and redo (clear-undo-history clear_undo_history (void)) + (commit-changes end_editing (void)) + (start-slave start_slave (void double)) (remove-undo-mark remove_undo_mark (void)) (add-undo-mark add_undo_mark (void)) (unredoable-undo unredoable_undo (void)) diff --git a/src/src/Guile/Glue/glue_editor.cpp b/src/src/Guile/Glue/glue_editor.cpp index b745bef2..61048619 100644 --- a/src/src/Guile/Glue/glue_editor.cpp +++ b/src/src/Guile/Glue/glue_editor.cpp @@ -1931,6 +1931,28 @@ tmg_clear_undo_history () { } SCM +tmg_commit_changes () { + // SCM_DEFER_INTS; + get_server()->get_editor()->end_editing (); + // SCM_ALLOW_INTS; + + return SCM_UNSPECIFIED; +} + +SCM +tmg_start_slave (SCM arg1) { + SCM_ASSERT_DOUBLE (arg1, SCM_ARG1, "start-slave"); + + double in1= scm_to_double (arg1); + + // SCM_DEFER_INTS; + get_server()->get_editor()->start_slave (in1); + // SCM_ALLOW_INTS; + + return SCM_UNSPECIFIED; +} + +SCM tmg_remove_undo_mark () { // SCM_DEFER_INTS; get_server()->get_editor()->remove_undo_mark (); @@ -2737,6 +2759,8 @@ initialize_glue_editor () { scm_new_procedure ("clipboard-get-import", (FN) tmg_clipboard_get_import, 0, 0, 0); scm_new_procedure ("clipboard-get-export", (FN) tmg_clipboard_get_export, 0, 0, 0); scm_new_procedure ("clear-undo-history", (FN) tmg_clear_undo_history, 0, 0, 0); + scm_new_procedure ("commit-changes", (FN) tmg_commit_changes, 0, 0, 0); + scm_new_procedure ("start-slave", (FN) tmg_start_slave, 1, 0, 0); scm_new_procedure ("remove-undo-mark", (FN) tmg_remove_undo_mark, 0, 0, 0); scm_new_procedure ("add-undo-mark", (FN) tmg_add_undo_mark, 0, 0, 0); scm_new_procedure ("unredoable-undo", (FN) tmg_unredoable_undo, 0, 0, 0); -- 2.11.4.GIT