diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 875853bd01..86359ce8c9 100644 --- a/src/Cursor.cpp +++ b/src/Cursor.cpp @@ -43,6 +43,7 @@ #include "insets/InsetText.h" #include "mathed/InsetMath.h" +#include "mathed/InsetMathBrace.h" #include "mathed/InsetMathScript.h" #include "mathed/MacroTable.h" #include "mathed/MathData.h" @@ -1208,6 +1209,8 @@ bool Cursor::macroModeClose() return false; InsetMathUnknown * p = activeMacro(); p->finalize(); + MathData selection; + asArray(p->selection(), selection); docstring const s = p->name(); --pos(); cell().erase(pos()); @@ -1225,12 +1228,37 @@ bool Cursor::macroModeClose() if (in && in->interpretString(*this, s)) return true; MathAtom atom = createInsetMath(name); + + // try to put argument into macro, if we just inserted a macro + bool macroArg = false; MathMacro * atomAsMacro = atom.nucleus()->asMacro(); if (atomAsMacro) { - // make non-greedy, i.e. don't eat parameters from the right - atomAsMacro->setDisplayMode(MathMacro::DISPLAY_INTERACTIVE_INIT); + // macros here are still unfolded (in init mode in fact). So + // we have to resolve the macro here manually and check its arity + // to put the selection behind it if arity > 0. + MacroData const * data = buffer().getMacro(atomAsMacro->name()); + if (selection.size() > 0 && data && data->numargs() - data->optionals() > 0) { + macroArg = true; + atomAsMacro->setDisplayMode(MathMacro::DISPLAY_INTERACTIVE_INIT, 1); + } else + // non-greedy case. Do not touch the arguments behind + atomAsMacro->setDisplayMode(MathMacro::DISPLAY_INTERACTIVE_INIT, 0); } + + // insert remembered selection into first argument of a non-macro + else if (atom.nucleus()->nargs() > 0) + atom.nucleus()->cell(0).append(selection); + plainInsert(atom); + + // finally put the macro argument behind, if needed + if (macroArg) { + if (selection.size() > 1) + plainInsert(MathAtom(new InsetMathBrace(selection))); + else + insert(selection); + } + return true; } diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 5910e327b2..a4b42a2d36 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -1423,14 +1423,15 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type c) return true; } - selClearOrDel(cur); - if (c == '\\') { //lyxerr << "starting with macro" << endl; - cur.insert(MathAtom(new InsetMathUnknown(from_ascii("\\"), false))); + docstring const safe = cap::grabAndEraseSelection(cur); + cur.insert(MathAtom(new InsetMathUnknown(from_ascii("\\"), safe, false))); return true; } + selClearOrDel(cur); + if (c == '\n') { if (currentMode() == InsetMath::TEXT_MODE) cur.insert(c); diff --git a/src/mathed/InsetMathUnknown.cpp b/src/mathed/InsetMathUnknown.cpp index 41baefc92c..22ea1fc888 100644 --- a/src/mathed/InsetMathUnknown.cpp +++ b/src/mathed/InsetMathUnknown.cpp @@ -16,11 +16,14 @@ #include "MathStream.h" #include "MathStream.h" +#include "frontends/Painter.h" + namespace lyx { -InsetMathUnknown::InsetMathUnknown(docstring const & nm, bool final, bool black) - : name_(nm), final_(final), black_(black) +InsetMathUnknown::InsetMathUnknown(docstring const & nm, + docstring const & selection, bool final, bool black) + : name_(nm), final_(final), black_(black), selection_(selection) {} @@ -62,7 +65,6 @@ void InsetMathUnknown::draw(PainterInfo & pi, int x, int y) const drawStrBlack(pi, x, y, name_); else drawStrRed(pi, x, y, name_); - setPosCache(pi, x, y); } diff --git a/src/mathed/InsetMathUnknown.h b/src/mathed/InsetMathUnknown.h index d0c8480c78..e6427ea0cb 100644 --- a/src/mathed/InsetMathUnknown.h +++ b/src/mathed/InsetMathUnknown.h @@ -23,6 +23,7 @@ class InsetMathUnknown : public InsetMath { public: /// explicit InsetMathUnknown(docstring const & name, + docstring const & selection = docstring(), bool final = true, bool black = false); /// void metrics(MetricsInfo & mi, Dimension & dim) const; @@ -33,6 +34,9 @@ public: /// docstring name() const; + /// + docstring const & selection() const { return selection_; } + /// identifies UnknownInsets InsetMathUnknown const * asUnknownInset() const { return this; } /// identifies UnknownInsets @@ -54,6 +58,7 @@ public: bool final() const; /// int kerning(BufferView const *) const { return kerning_; } + private: virtual Inset * clone() const; /// @@ -64,6 +69,8 @@ private: bool black_; /// mutable int kerning_; + /// the selection which was replaced by this + docstring selection_; };