#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());
}
bool Cursor::popBackward()
{
BOOST_ASSERT(!empty());
- //lyxerr << "Leaving inset from in front" << endl;
- inset().notifyCursorLeaves(*this);
if (depth() == 1)
return false;
pop();
BOOST_ASSERT(!empty());
//lyxerr << "Leaving inset from in back" << endl;
const pos_type lp = (depth() > 1) ? (*this)[depth() - 2].lastpos() : 0;
- inset().notifyCursorLeaves(*this);
if (depth() == 1)
return false;
pop();
// known position around the cursor:
pos_type known_pos = boundary() ? pos() - 1 : pos();
+ // edge case: if we're at the end of the paragraph, things are a little
+ // different (because lastpos is a position which does not really "exist"
+ // --- there's no character there yet).
+ if (known_pos == lastpos()) {
+ if (par.isRTL(buf.params())) {
+ left_pos = -1;
+ right_pos = bidi.vis2log(row.pos());
+ }
+ else { // LTR paragraph
+ right_pos = -1;
+ left_pos = bidi.vis2log(row.endpos() - 1);
+ }
+ return;
+ }
+
// Whether 'known_pos' is to the left or to the right of the cursor depends
// on whether it is an RTL or LTR character...
bool const cur_is_RTL =
// determine the other one:
if (known_pos_on_right) {
- // edge-case: we're at the end of the paragraph, there isn't really any
- // position any further to the right
- if (known_pos == lastpos()) {
- right_pos = -1;
- left_pos = row.endpos() - 1;
- return;
- }
- // the normal case
right_pos = known_pos;
// *visual* position of 'left_pos':
pos_type v_left_pos = bidi.log2vis(right_pos) - 1;
}
}
else { // known_pos is on the left
- // edge-case: we're at the end of the paragraph, there isn't really any
- // position any further to the left
- if (known_pos == lastpos()) {
- left_pos = -1;
- right_pos = row.endpos() - 1;
- return;
- }
- // the normal case
left_pos = known_pos;
// *visual* position of 'right_pos'
pos_type v_right_pos = bidi.log2vis(left_pos) + 1;
{
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;
}
return docstring();
if (inTexted()) {
- Buffer const & buffer = bv().buffer();
ParagraphList const & pars = text()->paragraphs();
// should be const ...
size_t const endpos = selEnd().pos();
if (startpit == endpit)
- return pars[startpit].asString(buffer, startpos, endpos, label);
+ return pars[startpit].asString(startpos, endpos, label);
// First paragraph in selection
docstring result = pars[startpit].
- asString(buffer, startpos, pars[startpit].size(), label)
+ asString(startpos, pars[startpit].size(), label)
+ parbreak(pars[startpit]);
// The paragraphs in between (if any)
for (pit_type pit = startpit + 1; pit != endpit; ++pit) {
Paragraph const & par = pars[pit];
- result += par.asString(buffer, 0, par.size(), label)
+ result += par.asString(0, par.size(), label)
+ parbreak(pars[pit]);
}
// Last paragraph in selection
- result += pars[endpit].asString(buffer, 0, endpos, label);
+ result += pars[endpit].asString(0, endpos, label);
return result;
}
}
-bool notifyCursorLeaves(DocIterator const & old, Cursor & cur)
+bool notifyCursorLeaves(Cursor const & old, Cursor & cur)
{
// find inset in common
size_type i;
if (&old[i].inset() != &cur[i].inset())
break;
}
+
+ // update words if we just moved to another paragraph
+ if (i == old.depth() && i == cur.depth()
+ && !cur.buffer().isClean()
+ && cur.inTexted() && old.inTexted()
+ && cur.pit() != old.pit()) {
+ old.paragraph().updateWords(old.top());
+ return false;
+ }
// notify everything on top of the common part in old cursor,
// but stop if the inset claims the cursor to be invalid now
for (; i < old.depth(); ++i) {
- if (old[i].inset().notifyCursorLeaves(cur))
+ Cursor insetPos = old;
+ insetPos.cutOff(i);
+ if (old[i].inset().notifyCursorLeaves(insetPos, cur))
return true;
}
// get font
BufferParams const & bufparams = buffer().params();
current_font = par.getFontSettings(bufparams, cpos);
- real_current_font = tm.getDisplayFont(cpit, cpos);
+ real_current_font = tm.displayFont(cpit, cpos);
// special case for paragraph end
if (cs.pos() == lastpos()