]> git.lyx.org Git - features.git/blobdiff - src/mathed/InsetMathNest.cpp
Fix bug 11667
[features.git] / src / mathed / InsetMathNest.cpp
index b026b888f03046c89ddb4139e63e14ee644c9547..66e900ad52441be1be5c857890172c72268d4cbe 100644 (file)
@@ -118,11 +118,8 @@ InsetMathNest & InsetMathNest::operator=(InsetMathNest const & inset)
 void InsetMathNest::setBuffer(Buffer & buffer)
 {
        InsetMath::setBuffer(buffer);
-       for (idx_type i = 0, n = nargs(); i != n; ++i) {
-               MathData & data = cell(i);
-               for (size_t j = 0; j != data.size(); ++j)
-                       data[j].nucleus()->setBuffer(buffer);
-       }
+       for (MathData & data : cells_)
+               data.setBuffer(buffer);
 }
 
 
@@ -219,7 +216,7 @@ bool InsetMathNest::idxPrev(Cursor & cur) const
        if (cur.idx() == 0)
                return false;
        --cur.idx();
-       cur.pos() = cur.lastpos();
+       cur.pos() = lyxrc.mac_like_cursor_movement ? cur.lastpos() : 0;
        return true;
 }
 
@@ -376,9 +373,10 @@ void InsetMathNest::latex(otexstream & os, OutputParams const & runparams) const
        Changer dummy = wi.changeRowEntry(TexRow::textEntry(runparams.lastid,
                                                            runparams.lastpos));
        write(wi);
-       // Reset parbreak status after a math inset.
+       // Reset parbreak and command termination status after a math inset.
        os.lastChar(0);
        os.canBreakLine(wi.canBreakLine());
+       os.terminateCommand(false);
 }
 
 
@@ -560,7 +558,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_CUT:
                cur.recordUndo();
-               cutSelection(cur, true, true);
+               cutSelection(cur, true);
                cur.message(_("Cut"));
                // Prevent stale position >= size crash
                // Probably not necessary anymore, see eraseSelection (gb 2005-10-09)
@@ -709,12 +707,6 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                        || act == LFUN_PARAGRAPH_UP_SELECT;
                cur.selHandle(select);
 
-               // handle autocorrect:
-               if (lyxrc.autocorrection_math && cur.autocorrect()) {
-                       cur.autocorrect() = false;
-                       cur.message(_("Autocorrect Off ('!' to enter)"));
-               }
-
                // go up/down
                bool up = act == LFUN_UP || act == LFUN_UP_SELECT
                        || act == LFUN_PARAGRAPH_UP || act == LFUN_PARAGRAPH_UP_SELECT;
@@ -796,12 +788,24 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_CELL_FORWARD:
                cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
-               cur.inset().idxNext(cur);
+               cur.selHandle(false);
+               cur.clearTargetX();
+               cur.macroModeClose();
+               if (!cur.inset().idxNext(cur)) {
+                       cur.idx() = firstIdx();
+                       cur.pos() = 0;
+               }
                break;
 
        case LFUN_CELL_BACKWARD:
                cur.screenUpdateFlags(Update::Decoration | Update::FitCursor);
-               cur.inset().idxPrev(cur);
+               cur.selHandle(false);
+               cur.clearTargetX();
+               cur.macroModeClose();
+               if (!cur.inset().idxPrev(cur)) {
+                       cur.idx() = lastIdx();
+                       cur.pos() = lyxrc.mac_like_cursor_movement ? cur.lastpos() : 0;
+               }
                break;
 
        case LFUN_WORD_DELETE_BACKWARD:
@@ -854,40 +858,37 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                break;
 
        case LFUN_SELF_INSERT:
-               if (cmd.argument().size() != 1) {
-                       cur.recordUndoSelection();
-                       docstring const arg = cmd.argument();
-                       if (!interpretString(cur, arg))
-                               cur.insert(arg);
+               // special case first for big delimiters
+               if (cmd.argument().size() != 1 && interpretString(cur, cmd.argument()))
                        break;
-               }
-               // Don't record undo steps if we are in macro mode and thus
-               // cmd.argument is the next character of the macro name.
-               // Otherwise we'll get an invalid cursor if we undo after
-               // the macro was finished and the macro is a known command,
-               // e.g. sqrt. Cursor::macroModeClose replaces in this case
-               // the InsetMathUnknown with name "frac" by an empty
-               // InsetMathFrac -> a pos value > 0 is invalid.
-               // A side effect is that an undo before the macro is finished
-               // undoes the complete macro, not only the last character.
-               // At the time we hit '\' we are not in macro mode, still.
-               if (!cur.inMacroMode())
-                       cur.recordUndoSelection();
 
-               // spacial handling of space. If we insert an inset
-               // via macro mode, we want to put the cursor inside it
-               // if relevant. Think typing "\frac<space>".
-               if (cmd.argument()[0] == ' '
-                   && cur.inMacroMode() && cur.macroName() != "\\"
-                   && cur.macroModeClose() && cur.pos() > 0) {
-                       MathAtom const atom = cur.prevAtom();
-                       if (atom->asNestInset() && atom->isActive()) {
-                               cur.posBackward();
-                               cur.pushBackward(*cur.nextInset());
+               for (char_type c : cmd.argument()) {
+                       // Don't record undo steps if we are in macro mode and thus
+                       // cmd.argument is the next character of the macro name.
+                       // Otherwise we'll get an invalid cursor if we undo after
+                       // the macro was finished and the macro is a known command,
+                       // e.g. sqrt. Cursor::macroModeClose replaces in this case
+                       // the InsetMathUnknown with name "frac" by an empty
+                       // InsetMathFrac -> a pos value > 0 is invalid.
+                       // A side effect is that an undo before the macro is finished
+                       // undoes the complete macro, not only the last character.
+                       // At the time we hit '\' we are not in macro mode, still.
+                       if (!cur.inMacroMode())
+                               cur.recordUndoSelection();
+
+                       // special handling of space. If we insert an inset
+                       // via macro mode, we want to put the cursor inside it
+                       // if relevant. Think typing "\frac<space>".
+                       if (c == ' '
+                           && cur.inMacroMode() && cur.macroName() != "\\"
+                           && cur.macroModeClose() && cur.pos() > 0)
+                               cur.editInsertedInset();
+                       else if (!interpretChar(cur, c)) {
+                               cmd = FuncRequest(LFUN_FINISHED_FORWARD);
+                               cur.undispatched();
+                               // FIXME: can we avoid skipping the end of the string?
+                               break;
                        }
-               } else if (!interpretChar(cur, cmd.argument()[0])) {
-                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
-                       cur.undispatched();
                }
                break;
 
@@ -1091,7 +1092,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
                // check if we have a valid decoration
                if (name != "pmatrix" && name != "bmatrix"
                        && name != "Bmatrix" && name != "vmatrix"
-                       && name != "Vmatrix" && name != "matrix")
+                       && name != "Vmatrix" && name != "matrix"
+                       && name != "smallmatrix")
                        name = from_ascii("matrix");
 
                cur.niceInsert(
@@ -1607,6 +1609,11 @@ void InsetMathNest::lfunMouseRelease(Cursor & cur, FuncRequest & cmd)
 
 bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
 {
+        // try auto-correction
+        if (lyxrc.autocorrection_math && cur.pos() != 0
+                  && math_autocorrect(cur, c))
+                return true;
+
        //lyxerr << "interpret 2: '" << c << "'" << endl;
        docstring save_selection;
        if (c == '^' || c == '_')
@@ -1723,18 +1730,6 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
        }
 
 
-       // leave autocorrect mode if necessary
-       if (lyxrc.autocorrection_math && c == ' ' && cur.autocorrect()) {
-               cur.autocorrect() = false;
-               cur.message(_("Autocorrect Off ('!' to enter)"));
-               return true;
-       }
-       if (lyxrc.autocorrection_math && c == '!' && !cur.autocorrect()) {
-               cur.autocorrect() = true;
-               cur.message(_("Autocorrect On (<space> to exit)"));
-               return true;
-       }
-
        // just clear selection on pressing the space bar
        if (cur.selection() && c == ' ') {
                cur.selection(false);
@@ -1838,7 +1833,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                if (currentMode() == InsetMath::MATH_MODE && Encodings::isUnicodeTextOnly(c)) {
                        MathAtom at = createInsetMath("text", buf);
                        at.nucleus()->cell(0).push_back(MathAtom(new InsetMathChar(c)));
-                       cur.niceInsert(at);
+                       cur.insert(at);
                        cur.posForward();
                        return true;
                }
@@ -1859,20 +1854,8 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                return true;
        }
 
-
-       // try auto-correction
-       if (lyxrc.autocorrection_math && cur.autocorrect() && cur.pos() != 0
-                 && math_autocorrect(cur.prevAtom(), c))
-               return true;
-
        // no special circumstances, so insert the character without any fuss
        cur.insert(c);
-       if (lyxrc.autocorrection_math) {
-               if (!cur.autocorrect())
-                       cur.message(_("Autocorrect Off ('!' to enter)"));
-               else
-                       cur.message(_("Autocorrect On (<space> to exit)"));
-       }
        return true;
 }
 
@@ -1889,6 +1872,7 @@ bool InsetMathNest::interpretString(Cursor & cur, docstring const & str)
                                prev = prev.substr(1);
                                latexkeys const * l = in_word_set(prev);
                                if (l && l->inset == "big") {
+                                       cur.recordUndoSelection();
                                        cur.cell()[cur.pos() - 1] =
                                                MathAtom(new InsetMathBig(prev, str));
                                        return true;