#include "insets/InsetText.h"
#include "mathed/InsetMath.h"
+#include "mathed/InsetMathBrace.h"
#include "mathed/InsetMathScript.h"
#include "mathed/MacroTable.h"
#include "mathed/MathData.h"
// store some values to be used inside of the handlers
beforeDispatchCursor_ = *this;
- for (; depth(); pop()) {
+ for (; depth(); pop(), boundary(false)) {
LYXERR(Debug::DEBUG, "Cursor::dispatch: cmd: "
<< cmd0 << endl << *this);
BOOST_ASSERT(pos() <= lastpos());
void Cursor::push(Inset & p)
{
push_back(CursorSlice(p));
+ p.setBuffer(bv_->buffer());
}
{
cell().insert(pos(), t);
++pos();
+ inset().setBuffer(bv_->buffer());
+ inset().initView();
}
}
-void Cursor::insert(Inset * inset)
+void Cursor::insert(Inset * inset0)
{
+ BOOST_ASSERT(inset0);
if (inMathed())
- insert(MathAtom(inset));
- else
- text()->insertInset(*this, inset);
+ insert(MathAtom(inset0));
+ else {
+ text()->insertInset(*this, inset0);
+ inset0->setBuffer(bv_->buffer());
+ inset0->initView();
+ }
}
return false;
InsetMathUnknown * p = activeMacro();
p->finalize();
+ MathData selection;
+ asArray(p->selection(), selection);
docstring const s = p->name();
--pos();
cell().erase(pos());
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;
}
if (pit() + 1 >= int(text()->paragraphs().size()) &&
row + 1 >= int(pm.rows().size()))
return false;
- }
+ }
// with and without selection are handled differently
if (!selection()) {
top().pos() = min(tm.x2pos(pit(), row - 1, xo), top().lastpos());
} else if (pit() > 0) {
--pit();
- ParagraphMetrics const & pmcur = bv_->parMetrics(text(), pit());
+ TextMetrics & tm = bv_->textMetrics(text());
+ if (!tm.contains(pit()))
+ tm.newParMetricsUp();
+ ParagraphMetrics const & pmcur = tm.parMetrics(pit());
top().pos() = min(tm.x2pos(pit(), pmcur.rows().size() - 1, xo), top().lastpos());
}
} else {
top().pos() = min(tm.x2pos(pit(), row + 1, xo), top().lastpos());
} else if (pit() + 1 < int(text()->paragraphs().size())) {
++pit();
+ TextMetrics & tm = bv_->textMetrics(text());
+ if (!tm.contains(pit()))
+ tm.newParMetricsDown();
top().pos() = min(tm.x2pos(pit(), 0, xo), top().lastpos());
}
}
&& !cur.buffer().isClean()
&& cur.inTexted() && old.inTexted()
&& cur.pit() != old.pit()) {
- old.paragraph().updateWords(old.buffer(), old.top());
+ old.paragraph().updateWords(old.top());
return false;
}
void Cursor::checkBufferStructure()
{
- if (paragraph().layout()->toclevel == Layout::NOT_IN_TOC)
+ if (paragraph().layout().toclevel == Layout::NOT_IN_TOC)
return;
Buffer const * master = buffer().masterBuffer();
master->tocBackend().updateItem(ParConstIterator(*this));