Le 12/04/2019 à 05:23, Isaac Oscar Gariano a écrit :
The main reason I made this change was because I am a frequent Micrsofot
Word user, however at work I do not have windows and am usually required
to write things following LaTeX styles, hence I wanted to use lyx (which
works great!). However, I relly heavily on Microsoft Word's math
equation features as I use it's WYSYWIG features to work out what an
equation should be as writing it, rather than just typeseting an
equation I allready have in my head. In particular its autocorrect has
several features that the lyx one is lacking:
* It supports autocorrect from an arbitrarilly long sequence of
unicode characters.
* It supports undoing the autocorrect with Ctrl-Z
So, let us start with those two issues. Attached is a simple revision of
your own patch with two changes
* a warning fixed
* I use MathData::erase instead of CursorData::backspace. There is no
specific reason for that, but backspace does complicated things
depending on context and I figured that we'd rather avoid that.
Then the second patch implements the undo behavior you were looking for.
Could you please test these two patch before I push them to master?
I will need two other things:
* a more consistent commit log for your patch
* a message from you to the lyx-devel list asserting
"I hereby grant permission to license my contributions to LyX
under the GNU General Public License, version 2 or later."
The next thing we will need is an actual set of bindings that use the
new feature...
JMarc
From d60c51d819bc4f22add91d921dadd9bfd4f7922a Mon Sep 17 00:00:00 2001
From: Isaac <[email protected]>
Date: Tue, 9 Apr 2019 13:48:46 +1200
Subject: [PATCH 1/2] Make math autocorrrect work with more than 2 chars
---
src/mathed/InsetMathNest.cpp | 2 +-
src/mathed/MathAutoCorrect.cpp | 44 +++++++++++++++++++++++++-----------------
src/mathed/MathAutoCorrect.h | 4 ++--
3 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp
index 798ca89..85e4dd7 100644
--- a/src/mathed/InsetMathNest.cpp
+++ b/src/mathed/InsetMathNest.cpp
@@ -1868,7 +1868,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
// try auto-correction
if (lyxrc.autocorrection_math && cur.autocorrect() && cur.pos() != 0
- && math_autocorrect(cur.prevAtom(), c))
+ && math_autocorrect(cur, c))
return true;
// no special circumstances, so insert the character without any fuss
diff --git a/src/mathed/MathAutoCorrect.cpp b/src/mathed/MathAutoCorrect.cpp
index fc4ad44..be5aeb4 100644
--- a/src/mathed/MathAutoCorrect.cpp
+++ b/src/mathed/MathAutoCorrect.cpp
@@ -10,6 +10,7 @@
#include <config.h>
+#include "Cursor.h"
#include "MathAutoCorrect.h"
#include "MathData.h"
#include "InsetMath.h"
@@ -38,18 +39,18 @@ public:
/// \brief Correction
Correction() : from2_(0) {}
///
- bool correct(MathAtom & at, char_type c) const;
+ bool correct(Cursor & cur, char_type c) const;
///
bool read(idocstream & is);
///
void write(odocstream & os) const;
private:
///
- MathAtom from1_;
+ MathData from1_;
///
char_type from2_;
///
- MathAtom to_;
+ MathData to_;
};
@@ -64,26 +65,35 @@ bool Correction::read(idocstream & is)
MathData ar1, ar3;
mathed_parse_cell(ar1, s1);
mathed_parse_cell(ar3, s3);
- if (ar1.size() != 1 || ar3.size() != 1)
- return false;
- from1_ = ar1.front();
+ from1_ = ar1;
from2_ = s2[0];
- to_ = ar3.front();
+ to_ = ar3;
return true;
}
-bool Correction::correct(MathAtom & at, char_type c) const
+bool Correction::correct(Cursor & cur, char_type c) const
{
//LYXERR(Debug::MATHED,
// "trying to correct ar: " << at << " from: '" << from1_ << '\'');
if (from2_ != c)
return false;
- if (asString(at) != asString(from1_))
+ pos_type n = from1_.size();
+ if (cur.pos() < pos_type(from1_.size())) // not enough to match
return false;
- LYXERR(Debug::MATHED, "match found! subst in " << at
+ pos_type start = cur.pos() - from1_.size();
+
+ for (pos_type i = 0; i < n; i++)
+ if (asString(cur.cell()[start + i]) != asString(from1_[i]))
+ return false;
+
+ LYXERR(Debug::MATHED, "match found! subst in " << cur.cell()
<< " from: '" << from1_ << "' to '" << to_ << '\'');
- at = to_;
+
+ cur.cell().erase(cur.pos() - n, cur.pos());
+ cur.pos() -= n;
+
+ cur.insert(to_);
return true;
}
@@ -121,17 +131,17 @@ public:
///
void insert(const Correction & corr) { data_.push_back(corr); }
///
- bool correct(MathAtom & at, char_type c) const;
+ bool correct(Cursor & cur, char_type c) const;
private:
///
vector<Correction> data_;
};
-bool Corrections::correct(MathAtom & at, char_type c) const
+bool Corrections::correct(Cursor & cur, char_type c) const
{
for (const_iterator it = data_.begin(); it != data_.end(); ++it)
- if (it->correct(at, c))
+ if (it->correct(cur, c))
return true;
return false;
}
@@ -172,7 +182,7 @@ void initAutoCorrect()
} // namespace
-bool math_autocorrect(MathAtom & at, char_type c)
+bool math_autocorrect(Cursor & cur, char_type c)
{
static bool initialized = false;
@@ -181,8 +191,6 @@ bool math_autocorrect(MathAtom & at, char_type c)
initialized = true;
}
- return theCorrections.correct(at, c);
+ return theCorrections.correct(cur, c);
}
-
-
} // namespace lyx
diff --git a/src/mathed/MathAutoCorrect.h b/src/mathed/MathAutoCorrect.h
index 679e837..a782d67 100644
--- a/src/mathed/MathAutoCorrect.h
+++ b/src/mathed/MathAutoCorrect.h
@@ -16,10 +16,10 @@
namespace lyx {
-class MathAtom;
+class Cursor;
// make "corrections" according to file lib/autocorrect
-bool math_autocorrect(MathAtom & at, char_type c);
+bool math_autocorrect(Cursor & cur, char_type c);
} // namespace lyx
--
2.7.4
From e66e05964b1074742308b4e88b607bf4130b05c7 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <[email protected]>
Date: Mon, 15 Apr 2019 11:12:25 +0200
Subject: [PATCH 2/2] Allow to undo partly math autocorrect
To this end, introduce Undo::splitUndoGroup, which ends currently
group and creates a new one with same nesting level.
---
src/Cursor.cpp | 6 ++++++
src/Cursor.h | 2 ++
src/Undo.cpp | 10 ++++++++++
src/Undo.h | 2 ++
src/mathed/MathAutoCorrect.cpp | 13 +++++++++++--
5 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 56a9dd8..735ee34 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -607,6 +607,12 @@ void CursorData::endUndoGroup() const
}
+void CursorData::splitUndoGroup() const
+{
+ buffer()->undo().splitUndoGroup(*this);
+}
+
+
void CursorData::recordUndo(pit_type from, pit_type to) const
{
buffer()->undo().recordUndo(*this, from, to);
diff --git a/src/Cursor.h b/src/Cursor.h
index 38ddad3..3d3db5d 100644
--- a/src/Cursor.h
+++ b/src/Cursor.h
@@ -183,6 +183,8 @@ public:
void beginUndoGroup() const;
/// end the current undo group
void endUndoGroup() const;
+ /// end abruptly the current group and create a new one wih the same nesting level
+ void splitUndoGroup() const;
/// The general case: prepare undo for an arbitrary range.
void recordUndo(pit_type from, pit_type to) const;
diff --git a/src/Undo.cpp b/src/Undo.cpp
index 5d613f2..a9e0bba 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -610,6 +610,16 @@ void Undo::endUndoGroup(CursorData const & cur_after)
}
+void Undo::splitUndoGroup(CursorData const & cur)
+{
+ size_t const level = d->group_level_;
+ d->group_level_ = 1;
+ endUndoGroup(cur);
+ beginUndoGroup(cur);
+ d->group_level_ = level;
+}
+
+
bool Undo::activeUndoGroup() const
{
return d->group_level_ > 0
diff --git a/src/Undo.h b/src/Undo.h
index dd70358..c2b9b5d 100644
--- a/src/Undo.h
+++ b/src/Undo.h
@@ -96,6 +96,8 @@ public:
void endUndoGroup();
/// end the current undo group and set UndoElement::cur_after if necessary.
void endUndoGroup(CursorData const & cur_after);
+ /// end abruptly the current group and create a new one wih the same nesting level
+ void splitUndoGroup(CursorData const & cur);
/// return true if an undo group is open and contains at least one element
bool activeUndoGroup() const;
diff --git a/src/mathed/MathAutoCorrect.cpp b/src/mathed/MathAutoCorrect.cpp
index be5aeb4..77e5fef 100644
--- a/src/mathed/MathAutoCorrect.cpp
+++ b/src/mathed/MathAutoCorrect.cpp
@@ -90,8 +90,17 @@ bool Correction::correct(Cursor & cur, char_type c) const
LYXERR(Debug::MATHED, "match found! subst in " << cur.cell()
<< " from: '" << from1_ << "' to '" << to_ << '\'');
- cur.cell().erase(cur.pos() - n, cur.pos());
- cur.pos() -= n;
+ /* To allow undoing the completion, we proceed in 4 steps
+ * - inset the raw character
+ * - split undo group so that we have two separate undo actions
+ * - record undo, delete the character we just entered and the from1_ part
+ * - finally, do the insertion of the correction.
+ */
+ cur.insert(c);
+ cur.splitUndoGroup();
+ cur.recordUndoSelection();
+ cur.cell().erase(cur.pos() - n - 1, cur.pos());
+ cur.pos() -= n + 1;
cur.insert(to_);
return true;
--
2.7.4