>>>>> "Enrico" == Enrico Forestieri <[EMAIL PROTECTED]> writes:
Enrico> This patch fixes it. However, as I am a bad guy, I found
Enrico> another problem ;-) (I wish I have a better grasp of the
Enrico> sources such that to be helpful instead of simply reporting
Enrico> misbehavior)
Enrico> With this patch applied:
Enrico> 1) Ctrl-N (new document) 2) Shift-Ctrl-M (math display) 3) y^2
Enrico> 4) Cursor down (cursor is to the left of y but outside the
Enrico> scriptinset) 5) Cursor right (cursor is to the left of y but
Enrico> inside the scriptinset) 6) type x (now we have {xy}^2, i.e.,
Enrico> the scriptinset nucleus is xy) 7) Cursor up (cursor is to the
Enrico> left of the 2) 8) Del (to delete the 2) 9) Cursor down 10)
Enrico> Undo
OK, this new patch fixes this problem too. There are two parts:
- easy one: export x^2, but {xy}^2 and {x^{2}}^2 (this last one has
only one element in the nucleus, but we want braces nevertheless.
- more tricky part: when a ^ or _ is encountered, it the previous
inset is a MathBraceInset (which encloses in {}), use only the
inside of the inset as nucleus. This is done twice, in the parser
(for when reading files or doing undo, cutnpaste) and in mathinset
(for interactive entry).
I think it works well, and now at least it is possible to enter things
like {x'}^2 (although not as easily as one could have hoped).
I am going to start applying this by bits.
JMarc
Index: src/insets/insetbase.h
===================================================================
--- src/insets/insetbase.h (revision 14774)
+++ src/insets/insetbase.h (working copy)
@@ -170,7 +170,8 @@ public:
/// number of columns in gridlike structures
virtual size_t ncols() const { return 0; }
/// is called when the cursor leaves this inset
- virtual void notifyCursorLeaves(LCursor &) {}
+ // returns true if cursor is now invalid.
+ virtual bool notifyCursorLeaves(LCursor &) { return false; }
/// request "external features"
virtual void validate(LaTeXFeatures &) const {}
Index: src/mathed/math_scriptinset.C
===================================================================
--- src/mathed/math_scriptinset.C (revision 14774)
+++ src/mathed/math_scriptinset.C (working copy)
@@ -19,6 +19,7 @@
#include "cursor.h"
#include "debug.h"
#include "funcrequest.h"
+#include "undo.h"
#include <boost/assert.hpp>
@@ -417,7 +418,11 @@ bool MathScriptInset::idxUpDown(LCursor
void MathScriptInset::write(WriteStream & os) const
{
if (nuc().size()) {
- os << nuc();
+ if (nuc().size() == 1
+ && ! nuc().begin()->nucleus()->asScriptInset())
+ os << nuc();
+ else
+ os << '{' << nuc() << '}';
//if (nuc().back()->takesLimits()) {
if (limits_ == -1)
os << "\\nolimits ";
@@ -432,10 +437,10 @@ void MathScriptInset::write(WriteStream
os << "{}";
}
- if (hasDown() && down().size())
+ if (hasDown() /*&& down().size()*/)
os << "_{" << down() << '}';
- if (hasUp() && up().size())
+ if (hasUp() /*&& up().size()*/)
os << "^{" << up() << '}';
if (lock_ && !os.latex())
@@ -552,7 +557,7 @@ void MathScriptInset::infoize2(std::ostr
}
-void MathScriptInset::notifyCursorLeaves(LCursor & cur)
+bool MathScriptInset::notifyCursorLeaves(LCursor & cur)
{
MathNestInset::notifyCursorLeaves(cur);
@@ -563,17 +568,34 @@ void MathScriptInset::notifyCursorLeaves
// Case of two scripts. In this case, 1 = super, 2 = sub
if (cur.idx() == 2 && cell(2).empty()) {
// must be a subscript...
+ recordUndoInset(cur);
removeScript(false);
+ return true;
} else if (cur.idx() == 1 && cell(1).empty()) {
// must be a superscript...
+ recordUndoInset(cur);
removeScript(true);
+ return true;
}
} else if (nargs() > 1 && cur.idx() == 1 && cell(1).empty()) {
// could be either subscript or super script
+ recordUndoInset(cur);
removeScript(cell_1_is_up_);
-}
+ // Let the script inset commit suicide. This is
+ // modelled on LCursor.pullArg(), but tries not to
+ // invoke notifyCursorLeaves again and does not touch
+ // cur (since the top slice will be deleted
+ // afterwards))
+ MathArray ar = cell(0);
+ LCursor tmpcur = cur;
+ tmpcur.pop();
+ tmpcur.cell().erase(tmpcur.pos());
+ tmpcur.cell().insert(tmpcur.pos(), ar);
+ return true;
+ }
//lyxerr << "MathScriptInset::notifyCursorLeaves: 2 " << cur << endl;
+ return false;
}
Index: src/mathed/math_scriptinset.h
===================================================================
--- src/mathed/math_scriptinset.h (revision 14774)
+++ src/mathed/math_scriptinset.h (working copy)
@@ -121,8 +121,8 @@ private:
int ndes() const;
/// where do we have to draw the scripts?
bool hasLimits() const;
- /// clean up empty cells
- void notifyCursorLeaves(LCursor & cur);
+ /// clean up empty cells and return true if a cell has been deleted.
+ bool notifyCursorLeaves(LCursor & cur);
/// possible subscript (index 0) and superscript (index 1)
bool cell_1_is_up_;
Index: src/mathed/math_hullinset.C
===================================================================
--- src/mathed/math_hullinset.C (revision 14774)
+++ src/mathed/math_hullinset.C (working copy)
@@ -383,7 +383,7 @@ void MathHullInset::addPreview(lyx::grap
}
-void MathHullInset::notifyCursorLeaves(LCursor & cur)
+bool MathHullInset::notifyCursorLeaves(LCursor & cur)
{
if (RenderPreview::status() == LyXRC::PREVIEW_ON) {
Buffer const & buffer = cur.buffer();
@@ -391,6 +391,7 @@ void MathHullInset::notifyCursorLeaves(L
preview_->addPreview(snippet, buffer);
preview_->startLoading(buffer);
}
+ return false;
}
Index: src/mathed/math_hullinset.h
===================================================================
--- src/mathed/math_hullinset.h (revision 14774)
+++ src/mathed/math_hullinset.h (working copy)
@@ -113,7 +113,7 @@ public:
OutputParams const &) const;
/// get notification when the cursor leaves this inset
- void notifyCursorLeaves(LCursor & cur);
+ bool notifyCursorLeaves(LCursor & cur);
///
//bool insetAllowed(Code code) const;
///
Index: src/mathed/math_parser.C
===================================================================
--- src/mathed/math_parser.C (revision 14774)
+++ src/mathed/math_parser.C (working copy)
@@ -796,6 +796,7 @@ void Parser::parse1(MathGridInset & grid
else if (t.cat() == catSuper || t.cat() == catSub) {
bool up = (t.cat() == catSuper);
+ lyxerr << "handling supersub, cell=" << asString(*cell) <<endl;
// we need no new script inset if the last thing was a scriptinset,
// which has that script already not the same script already
if (!cell->size())
@@ -810,10 +811,9 @@ void Parser::parse1(MathGridInset & grid
MathScriptInset * p = cell->back().nucleus()->asScriptInset();
// special handling of {}-bases
// is this always correct?
- // It appears that this is wrong (Dekel)
- //if (p->nuc().size() == 1 && p->nuc().back()->asNestInset() &&
- // p->nuc().back()->extraBraces())
- // p->nuc() = p->nuc().back()->asNestInset()->cell(0);
+ if (p->nuc().size() == 1
+ && p->nuc().back()->asBraceInset())
+ p->nuc() = p->nuc().back()->asNestInset()->cell(0);
parse(p->cell(p->idxOfScript(up)), FLAG_ITEM, mode);
if (limits) {
p->limits(limits);
Index: src/mathed/math_nestinset.C
===================================================================
--- src/mathed/math_nestinset.C (revision 14774)
+++ src/mathed/math_nestinset.C (working copy)
@@ -344,7 +344,7 @@ int MathNestInset::latex(Buffer const &,
}
-void MathNestInset::notifyCursorLeaves(LCursor & cur)
+bool MathNestInset::notifyCursorLeaves(LCursor & cur)
{
#ifdef WITH_WARNINGS
#warning look here
@@ -373,6 +373,7 @@ void MathNestInset::notifyCursorLeaves(L
}
}
#endif
+ return false;
}
@@ -1271,6 +1272,12 @@ bool MathNestInset::script(LCursor & cur
}
--cur.pos();
MathScriptInset * inset = cur.nextAtom().nucleus()->asScriptInset();
+ // special handling of {}-bases
+ // is this always correct?
+ if (inset->nuc().size() == 1
+ && inset->nuc().back()->asBraceInset())
+ inset->nuc() = inset->nuc().back()->asNestInset()->cell(0);
+
cur.push(*inset);
cur.idx() = 1;
cur.pos() = 0;
Index: src/mathed/math_nestinset.h
===================================================================
--- src/mathed/math_nestinset.h (revision 14774)
+++ src/mathed/math_nestinset.h (working copy)
@@ -65,7 +65,7 @@ public:
/// access to the lock
void lock(bool);
/// get notification when the cursor leaves this inset
- void notifyCursorLeaves(LCursor & cur);
+ bool notifyCursorLeaves(LCursor & cur);
/// direct access to the cell
MathArray & cell(idx_type);
Index: src/undo.C
===================================================================
--- src/undo.C (revision 14774)
+++ src/undo.C (working copy)
@@ -168,6 +168,7 @@ bool textUndoOrRedo(BufferView & bv,
// We stored the full cell here as there is not much to be
// gained by storing just 'a few' paragraphs (most if not
// all math inset cells have just one paragraph!)
+ //lyxerr << "undo.array=" << undo.array <<endl;
asArray(undo.array, dit.cell());
} else {
// Some finer machinery is needed here.
@@ -251,7 +252,9 @@ void recordUndoInset(LCursor & cur, Undo
{
LCursor c = cur;
c.pop();
- recordUndo(c, kind);
+ Buffer * buf = cur.bv().buffer();
+ doRecordUndo(kind, c, c.pit(), c.pit(), cur,
+ buf->params(), false, buf->undostack());
}
Index: src/BufferView.C
===================================================================
--- src/BufferView.C (revision 14774)
+++ src/BufferView.C (working copy)
@@ -327,11 +327,13 @@ void BufferView::mouseSetCursor(LCursor
BOOST_ASSERT(&cur.bv() == this);
// Has the cursor just left the inset?
+ bool badcursor = false;
if (&cursor().inset() != &cur.inset())
- cursor().inset().notifyCursorLeaves(cursor());
+ badcursor = cursor().inset().notifyCursorLeaves(cursor());
// do the dEPM magic if needed
- if (cursor().inTexted())
+ // FIXME: move this to InsetText::notifyCursorLeaves?
+ if (!badcursor && cursor().inTexted())
cursor().text()->deleteEmptyParagraphMechanism(cur, cursor());
cursor() = cur;