#include "Author.h"
#include "Buffer.h"
-#include "buffer_funcs.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "Changes.h"
#include "CompletionList.h"
#include "Cursor.h"
+#include "CursorSlice.h"
#include "CutAndPaste.h"
-#include "DispatchResult.h"
#include "Encoding.h"
#include "ErrorList.h"
-#include "FuncRequest.h"
#include "factory.h"
-#include "InsetList.h"
+#include "Font.h"
+#include "FuncRequest.h"
#include "Language.h"
#include "Layout.h"
-#include "Length.h"
#include "Lexer.h"
#include "lyxfind.h"
#include "LyXRC.h"
#include "Paragraph.h"
#include "ParagraphParameters.h"
-#include "ParIterator.h"
#include "TextClass.h"
#include "TextMetrics.h"
-#include "WordLangTuple.h"
#include "WordList.h"
+#include "insets/Inset.h"
#include "insets/InsetText.h"
-#include "insets/InsetBibitem.h"
#include "insets/InsetCaption.h"
-#include "insets/InsetNewline.h"
-#include "insets/InsetNewpage.h"
-#include "insets/InsetArgument.h"
#include "insets/InsetIPAMacro.h"
-#include "insets/InsetSpace.h"
#include "insets/InsetSpecialChar.h"
#include "insets/InsetTabular.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/docstream.h"
+#include "support/docstring.h"
#include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h"
-#include "support/lyxalgo.h"
#include "support/lyxtime.h"
#include "support/textutils.h"
#include "support/unique_ptr.h"
ParagraphList & pars, pit_type pit, pos_type pos)
{
// create a new paragraph
- Paragraph & tmp = *pars.insert(lyx::next(pars.begin(), pit + 1),
- Paragraph());
+ Paragraph & tmp = *pars.insert(pars.iterator_at(pit + 1), Paragraph());
Paragraph & par = pars[pit];
tmp.setInsetOwner(&par.inInset());
// move the change of the end-of-paragraph character
par.setChange(par.size(), change);
- pars.erase(lyx::next(pars.begin(), par_offset + 1));
+ pars.erase(pars.iterator_at(par_offset + 1));
}
Text::Text(InsetText * owner, Text const & text)
: owner_(owner), pars_(text.pars_)
{
- ParagraphList::iterator const end = pars_.end();
- ParagraphList::iterator it = pars_.begin();
- for (; it != end; ++it)
- it->setInsetOwner(owner);
+ for (auto & p : pars_)
+ p.setInsetOwner(owner);
}
}
+int Text::getEndLabel(pit_type p) const
+{
+ pit_type pit = p;
+ depth_type par_depth = pars_[p].getDepth();
+ while (pit != pit_type(pars_.size())) {
+ Layout const & layout = pars_[pit].layout();
+ int const endlabeltype = layout.endlabeltype;
+
+ if (endlabeltype != END_LABEL_NO_LABEL) {
+ if (p + 1 == pit_type(pars_.size()))
+ return endlabeltype;
+
+ depth_type const next_depth =
+ pars_[p + 1].getDepth();
+ if (par_depth > next_depth ||
+ (par_depth == next_depth && layout != pars_[p + 1].layout()))
+ return endlabeltype;
+ break;
+ }
+ if (par_depth == 0)
+ break;
+ pit = outerHook(pit);
+ if (pit != pit_type(pars_.size()))
+ par_depth = pars_[pit].getDepth();
+ }
+ return END_LABEL_NO_LABEL;
+}
+
+
static void acceptOrRejectChanges(ParagraphList & pars,
BufferParams const & bparams, Text::ChangeOp op)
{
}
}
// Final change goes to paragraph break:
- par.setChange(par.size(), change);
+ if (inset().allowMultiPar())
+ par.setChange(par.size(), change);
// Initialize begin_of_body_ on load; redoParagraph maintains
par.setBeginOfBody();
virtual ~TextCompletionList() {}
///
- virtual bool sorted() const { return true; }
+ bool sorted() const override { return true; }
///
- virtual size_t size() const
+ size_t size() const override
{
return list_.size();
}
///
- virtual docstring const & data(size_t idx) const
+ docstring const & data(size_t idx) const override
{
return list_.word(idx);
}
ParagraphList & pars = text.paragraphs();
// create a new paragraph, and insert into the list
ParagraphList::iterator tmp =
- pars.insert(lyx::next(pars.begin(), par_offset + 1),
- Paragraph());
+ pars.insert(pars.iterator_at(par_offset + 1), Paragraph());
Paragraph & par = pars[par_offset];
tmp->params().depth(par.params().depth());
tmp->params().noindent(par.params().noindent());
+ tmp->params().spacing(par.params().spacing());
// move everything behind the break position
// to the new paragraph
pit_type pit = cur.pit();
pos_type pos = cur.pos();
+ // The special chars we handle
+ static map<wchar_t, InsetSpecialChar::Kind> specialchars = {
+ { 0x200c, InsetSpecialChar::LIGATURE_BREAK },
+ { 0x200b, InsetSpecialChar::ALLOWBREAK },
+ { 0x2026, InsetSpecialChar::LDOTS },
+ { 0x2011, InsetSpecialChar::NOBREAKDASH }
+ };
+
// insert the string, don't insert doublespace
bool space_inserted = true;
- for (docstring::const_iterator cit = str.begin();
- cit != str.end(); ++cit) {
+ for (auto const & ch : str) {
Paragraph & par = pars_[pit];
- if (*cit == '\n') {
+ if (ch == '\n') {
if (inset().allowMultiPar() && (!par.empty() || par.allowEmpty())) {
lyx::breakParagraph(*this, pit, pos,
par.layout().isEnvironment());
continue;
}
// do not insert consecutive spaces if !free_spacing
- } else if ((*cit == ' ' || *cit == '\t') &&
+ } else if ((ch == ' ' || ch == '\t') &&
space_inserted && !par.isFreeSpacing()) {
continue;
- } else if (*cit == '\t') {
+ } else if (ch == '\t') {
if (!par.isFreeSpacing()) {
// tabs are like spaces here
par.insertChar(pos, ' ', font, bparams.track_changes);
++pos;
space_inserted = true;
} else {
- par.insertChar(pos, *cit, font, bparams.track_changes);
+ par.insertChar(pos, ch, font, bparams.track_changes);
++pos;
space_inserted = true;
}
- } else if (!isPrintable(*cit)) {
- // Ignore unprintables
+ } else if (specialchars.find(ch) != specialchars.end()
+ && (par.insertInset(pos, new InsetSpecialChar(specialchars.find(ch)->second),
+ font, bparams.track_changes
+ ? Change(Change::INSERTED)
+ : Change(Change::UNCHANGED)))) {
+ ++pos;
+ space_inserted = false;
+ } else if (!isPrintable(ch)) {
+ // Ignore (other) unprintables
continue;
} else {
// just insert the character
- par.insertChar(pos, *cit, font, bparams.track_changes);
+ par.insertChar(pos, ch, font, bparams.track_changes);
++pos;
- space_inserted = (*cit == ' ');
+ space_inserted = (ch == ' ');
}
}
setCursor(cur, pit, pos);
"beginning of a paragraph. Please read the Tutorial."));
return false;
}
- // LASSERT: Is it safe to continue here?
- LASSERT(cur.pos() > 0, /**/);
+ // If something is wrong, ignore this character.
+ LASSERT(cur.pos() > 0, return false);
if ((par.isLineSeparator(cur.pos() - 1) || par.isNewline(cur.pos() - 1))
&& !par.isDeleted(cur.pos() - 1)) {
cur.message(_(
if (lyxrc.auto_number) {
static docstring const number_operators = from_ascii("+-/*");
static docstring const number_unary_operators = from_ascii("+-");
- static docstring const number_separators = from_ascii(".,:");
+ // Common Number Separators: comma, dot etc.
+ // European Number Terminators: percent, permille, degree, euro etc.
if (cur.current_font.fontInfo().number() == FONT_ON) {
if (!isDigitASCII(c) && !contains(number_operators, c) &&
- !(contains(number_separators, c) &&
+ !(isCommonNumberSeparator(c) &&
cur.pos() != 0 &&
cur.pos() != cur.lastpos() &&
tm.displayFont(pit, cur.pos()).fontInfo().number() == FONT_ON &&
+ tm.displayFont(pit, cur.pos() - 1).fontInfo().number() == FONT_ON) &&
+ !(isEuropeanNumberTerminator(c) &&
+ cur.pos() != 0 &&
+ tm.displayFont(pit, cur.pos()).fontInfo().number() == FONT_ON &&
tm.displayFont(pit, cur.pos() - 1).fontInfo().number() == FONT_ON)
)
number(cur); // Set current_font.number to OFF
) {
setCharFont(pit, cur.pos() - 1, cur.current_font,
tm.font_);
- } else if (contains(number_separators, ch)
+ } else if (isCommonNumberSeparator(ch)
&& cur.pos() >= 2
&& tm.displayFont(pit, cur.pos() - 2).fontInfo().number() == FONT_ON) {
setCharFont(pit, cur.pos() - 1, cur.current_font,
&& par.isWordSeparator(cur.pos() - 1)) {
// get the word in front of cursor
LBUFERR(this == cur.text());
- cur.paragraph().updateWords();
+ par.updateWords();
}
}
{
LBUFERR(this == cur.text());
- pos_type const lastpos = cur.lastpos();
- pit_type pit = cur.pit();
- pos_type pos = cur.pos();
- Paragraph const & par = cur.paragraph();
-
- // Paragraph boundary is a word boundary
- if (pos == lastpos || (pos + 1 == lastpos && par.isEnvSeparator(pos))) {
- if (pit != cur.lastpit())
- return setCursor(cur, pit + 1, 0);
- else
- return false;
- }
-
if (lyxrc.mac_like_cursor_movement) {
- // Skip through trailing punctuation and spaces.
- while (pos != lastpos && (par.isChar(pos) || par.isSpace(pos)))
- ++pos;
-
- // Skip over either a non-char inset or a full word
- if (pos != lastpos && par.isWordSeparator(pos))
- ++pos;
- else while (pos != lastpos && !par.isWordSeparator(pos))
- ++pos;
+ DocIterator dit(cur);
+ DocIterator prv(cur);
+ bool inword = false;
+ bool intext = dit.inTexted();
+ while (!dit.atEnd()) {
+ if (dit.inTexted()) { // no paragraphs in mathed
+ Paragraph const & par = dit.paragraph();
+ pos_type const pos = dit.pos();
+
+ if (!par.isDeleted(pos)) {
+ bool wordsep = par.isWordSeparator(pos);
+ if (inword && wordsep)
+ break; // stop at word end
+ else if (!inword && !wordsep)
+ inword = true;
+ }
+ intext = true;
+ } else if (intext) {
+ // move to end of math
+ while (!dit.inTexted() && !dit.atEnd()) dit.forwardPos();
+ break;
+ }
+ prv = dit;
+ dit.forwardPosIgnoreCollapsed();
+ }
+ if (dit.atEnd()) dit = prv;
+ if (dit == cur) return false; // we didn't move
+ Cursor orig(cur);
+ cur.setCursor(dit);
+ // see comment above
+ cur.bv().checkDepm(cur, orig);
+ return true;
} else {
+ pos_type const lastpos = cur.lastpos();
+ pit_type pit = cur.pit();
+ pos_type pos = cur.pos();
+ Paragraph const & par = cur.paragraph();
+
+ // Paragraph boundary is a word boundary
+ if (pos == lastpos || (pos + 1 == lastpos && par.isEnvSeparator(pos))) {
+ if (pit != cur.lastpit())
+ return setCursor(cur, pit + 1, 0);
+ else
+ return false;
+ }
+
LASSERT(pos < lastpos, return false); // see above
if (!par.isWordSeparator(pos))
while (pos != lastpos && !par.isWordSeparator(pos))
// Skip over white space
while (pos != lastpos && par.isSpace(pos))
++pos;
- }
- // Don't skip a separator inset at the end of a paragraph
- if (pos == lastpos && pos && par.isEnvSeparator(pos - 1))
- --pos;
+ // Don't skip a separator inset at the end of a paragraph
+ if (pos == lastpos && pos && par.isEnvSeparator(pos - 1))
+ --pos;
- return setCursor(cur, pit, pos);
+ return setCursor(cur, pit, pos);
+ }
}
{
LBUFERR(this == cur.text());
- pit_type pit = cur.pit();
- pos_type pos = cur.pos();
- Paragraph & par = cur.paragraph();
-
- // Paragraph boundary is a word boundary
- if (pos == 0 && pit != 0) {
- Paragraph & prevpar = getPar(pit - 1);
- pos = prevpar.size();
- // Don't stop after an environment separator
- if (pos && prevpar.isEnvSeparator(pos - 1))
- --pos;
- return setCursor(cur, pit - 1, pos);
- }
-
if (lyxrc.mac_like_cursor_movement) {
- // Skip through punctuation and spaces.
- while (pos != 0 && (par.isChar(pos - 1) || par.isSpace(pos - 1)))
- --pos;
-
- // Skip over either a non-char inset or a full word
- if (pos != 0 && par.isWordSeparator(pos - 1) && !par.isChar(pos - 1))
- --pos;
- else while (pos != 0 && !par.isWordSeparator(pos - 1))
- --pos;
+ DocIterator dit(cur);
+ bool inword = false;
+ bool intext = dit.inTexted();
+ while (!dit.atBegin()) {
+ DocIterator prv(dit);
+ dit.backwardPosIgnoreCollapsed();
+ if (dit.inTexted()) { // no paragraphs in mathed
+ Paragraph const & par = dit.paragraph();
+ pos_type pos = dit.pos();
+
+ if (!par.isDeleted(pos)) {
+ bool wordsep = par.isWordSeparator(pos);
+ if (inword && wordsep) {
+ dit = prv;
+ break; // stop at word begin
+ } else if (!inword && !wordsep)
+ inword = true;
+ }
+ intext = true;
+ } else if (intext) {
+ // move to begin of math
+ while (!dit.inTexted() && !dit.atBegin()) dit.backwardPos();
+ break;
+ }
+ }
+ if (dit == cur) return false; // we didn't move
+ Cursor orig(cur);
+ cur.setCursor(dit);
+ // see comment above cursorForwardOneWord
+ cur.bv().checkDepm(cur, orig);
+ return true;
} else {
+ Paragraph const & par = cur.paragraph();
+ pit_type const pit = cur.pit();
+ pos_type pos = cur.pos();
+
+ // Paragraph boundary is a word boundary
+ if (pos == 0 && pit != 0) {
+ Paragraph & prevpar = getPar(pit - 1);
+ pos = prevpar.size();
+ // Don't stop after an environment separator
+ if (pos && prevpar.isEnvSeparator(pos - 1))
+ --pos;
+ return setCursor(cur, pit - 1, pos);
+ }
// Skip over white space
while (pos != 0 && par.isSpace(pos - 1))
- --pos;
+ --pos;
if (pos != 0 && !par.isWordSeparator(pos - 1))
while (pos != 0 && !par.isWordSeparator(pos - 1))
--pos;
else if (pos != 0 && !par.isSpace(pos - 1)) // non-char inset
--pos;
- }
- return setCursor(cur, pit, pos);
+ return setCursor(cur, pit, pos);
+ }
}
pos_type endPos = cur.selectionEnd().pos();
// keep selection info, because endPos becomes invalid after the first loop
- bool endsBeforeEndOfPar = (endPos < pars_[endPit].size());
+ bool const endsBeforeEndOfPar = (endPos < pars_[endPit].size());
// first, accept/reject changes within each individual paragraph (do not consider end-of-par)
for (pit_type pit = begPit; pit <= endPit; ++pit) {
if (pit == endPit && endPos == 0)
break; // last iteration anyway
- pos_type left = (pit == begPit ? begPos : 0);
- pos_type right = (pit == endPit ? endPos : parSize);
+ pos_type const left = (pit == begPit ? begPos : 0);
+ pos_type const right = (pit == endPit ? endPos : parSize);
if (left == right)
// there is no change here
}
// finally, invoke the DEPM
- deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().track_changes);
+ deleteEmptyParagraphMechanism(begPit, endPit, begPos, endPos,
+ cur.buffer()->params().track_changes);
cur.finishUndo();
cur.clearSelection();
cursorForwardOneWord(cur);
cur.setSelection();
if (force || !cur.confirmDeletion()) {
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
cur.checkBufferStructure();
}
}
cursorBackwardOneWord(cur);
cur.setSelection();
if (force || !cur.confirmDeletion()) {
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
cur.checkBufferStructure();
}
}
if (cur.pit() == 0)
return false;
- bool needsUpdate = false;
-
BufferParams const & bufparams = cur.buffer()->params();
- DocumentClass const & tclass = bufparams.documentClass();
ParagraphList & plist = cur.text()->paragraphs();
Paragraph const & par = cur.paragraph();
Cursor prevcur = cur;
if (cur.lastpos() == 0
|| (cur.lastpos() == 1 && par.isSeparator(0))) {
cur.recordUndo(prevcur.pit());
- plist.erase(lyx::next(plist.begin(), cur.pit()));
- needsUpdate = true;
+ plist.erase(plist.iterator_at(cur.pit()));
}
// is previous par empty?
else if (prevcur.lastpos() == 0
|| (prevcur.lastpos() == 1 && prevpar.isSeparator(0))) {
cur.recordUndo(prevcur.pit());
- plist.erase(lyx::next(plist.begin(), prevcur.pit()));
- needsUpdate = true;
+ plist.erase(plist.iterator_at(prevcur.pit()));
}
// FIXME: Do we really not want to allow this???
// Pasting is not allowed, if the paragraphs have different
// word processors to allow it. It confuses the user.
// Correction: Pasting is always allowed with standard-layout
// or the empty layout.
- else if (par.layout() == prevpar.layout()
- || tclass.isDefaultLayout(par.layout())
- || tclass.isPlainLayout(par.layout())) {
+ else {
cur.recordUndo(prevcur.pit());
mergeParagraph(bufparams, plist, prevcur.pit());
- needsUpdate = true;
}
- if (needsUpdate) {
- cur.forceBufferUpdate();
- setCursorIntern(cur, prevcur.pit(), prevcur.pos());
- }
+ cur.forceBufferUpdate();
+ setCursorIntern(cur, prevcur.pit(), prevcur.pos());
- return needsUpdate;
+ return true;
}
Cursor prev_cur = cur;
--prev_cur.pit();
- if (!prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) {
+ if (!cur.paragraph().empty()
+ && !prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) {
cur.recordUndo(prev_cur.pit(), prev_cur.pit());
prev_cur.paragraph().setChange(prev_cur.lastpos(), Change(Change::DELETED));
setCursorIntern(cur, prev_cur.pit(), prev_cur.lastpos());
needsUpdate |= handleBibitems(cur);
// A singlePar update is not enough in this case.
-// cur.screenUpdateFlags(Update::Force);
+ // cur.screenUpdateFlags(Update::Force);
cur.top().setPitPos(cur.pit(), cur.pos());
return needsUpdate;
// save position inside inset
pos_type spos = cur.pos();
pit_type spit = cur.pit();
- ParagraphList plist;
- if (cur.lastpit() != 0 || cur.lastpos() != 0)
- plist = paragraphs();
+ bool const inset_non_empty = cur.lastpit() != 0 || cur.lastpos() != 0;
cur.popBackward();
// update cursor offset
if (spit == 0)
++cur.pos();
Buffer & b = *cur.buffer();
- if (!plist.empty()) {
+ // Is there anything in this text?
+ if (inset_non_empty) {
// see bug 7319
// we clear the cache so that we won't get conflicts with labels
// that get pasted into the buffer. we should update this before
// but we'll try the cheaper solution here.
cur.buffer()->clearReferenceCache();
+ ParagraphList & plist = paragraphs();
+ if (!lyxrc.ct_markup_copied)
+ // Do not revive deleted text
+ lyx::acceptChanges(plist, b.params());
+
// ERT paragraphs have the Language latex_language.
// This is invalid outside of ERT, so we need to
// change it to the buffer language.
- ParagraphList::iterator it = plist.begin();
- ParagraphList::iterator it_end = plist.end();
- for (; it != it_end; ++it)
- it->changeLanguage(b.params(), latex_language, b.language());
+ for (auto & p : plist)
+ p.changeLanguage(b.params(), latex_language, b.language());
+
+ /* If the inset is the only thing in paragraph and the layout
+ * is not plain, then the layout of the first paragraph of
+ * inset should be remembered.
+ * FIXME: this does not work as expected when change tracking
+ * is on However, we do not really know what to do in this
+ * case.
+ */
+ DocumentClass const & tclass = cur.buffer()->params().documentClass();
+ if (inset_it.lastpos() == 1
+ && !tclass.isPlainLayout(plist[0].layout())
+ && !tclass.isDefaultLayout(plist[0].layout())) {
+ // Copy all parameters except depth.
+ Paragraph & par = cur.paragraph();
+ par.setLayout(plist[0].layout());
+ depth_type const dpth = par.getDepth();
+ par.params() = plist[0].params();
+ par.params().depth(dpth);
+ }
pasteParagraphList(cur, plist, b.params().documentClassPtr(),
+ b.params().authors(),
b.errorList("Paste"));
}
}
+bool Text::splitInset(Cursor & cur)
+{
+ LASSERT(this == cur.text(), return false);
+
+ if (isMainText() || cur.inset().nargs() != 1)
+ return false;
+
+ cur.recordUndo();
+ if (cur.selection()) {
+ // start from selection begin
+ setCursor(cur, cur.selBegin().pit(), cur.selBegin().pos());
+ cur.clearSelection();
+ }
+ // save split position inside inset
+ // (we need to copy the whole inset first)
+ pos_type spos = cur.pos();
+ pit_type spit = cur.pit();
+ // some things only need to be done if the inset has content
+ bool const inset_non_empty = cur.lastpit() != 0 || cur.lastpos() != 0;
+
+ // move right before the inset
+ cur.popBackward();
+ cur.resetAnchor();
+ // remember position outside inset
+ pos_type ipos = cur.pos();
+ pit_type ipit = cur.pit();
+ // select inset ...
+ ++cur.pos();
+ cur.setSelection();
+ // ... and copy
+ cap::copySelectionToTemp(cur);
+ cur.clearSelection();
+ cur.resetAnchor();
+ // paste copied inset
+ cap::pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
+ cur.forceBufferUpdate();
+
+ // if the inset has text, cut after split position
+ // and paste to new inset
+ if (inset_non_empty) {
+ // go back to first inset
+ cur.text()->setCursor(cur, ipit, ipos);
+ cur.forwardPos();
+ setCursor(cur, spit, spos);
+ cur.resetAnchor();
+ setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size());
+ cur.setSelection();
+ cap::cutSelectionToTemp(cur);
+ cur.setMark(false);
+ cur.selHandle(false);
+ cur.resetAnchor();
+ bool atlastpos = false;
+ if (cur.pos() == 0 && cur.pit() > 0) {
+ // if we are at par start, remove this par
+ cur.text()->backspace(cur);
+ cur.forceBufferUpdate();
+ } else if (cur.pos() == cur.lastpos())
+ atlastpos = true;
+ // Move out of and jump over inset
+ cur.popBackward();
+ ++cur.pos();
+
+ // enter new inset
+ cur.forwardPos();
+ cur.setCursor(cur);
+ cur.resetAnchor();
+ cur.text()->selectAll(cur);
+ cutSelection(cur, false);
+ cap::pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
+ cur.text()->setCursor(cur, 0, 0);
+ if (atlastpos && cur.paragraph().isFreeSpacing() && cur.paragraph().empty()) {
+ // We started from par end, remove extra empty par in free spacing insets
+ cur.text()->erase(cur);
+ cur.forceBufferUpdate();
+ }
+ }
+
+ cur.finishUndo();
+ return true;
+}
+
+
void Text::getWord(CursorSlice & from, CursorSlice & to,
word_location const loc) const
{
}
-// Returns the current font and depth as a message.
+// Returns the current state (font, depth etc.) as a message for status bar.
docstring Text::currentState(CursorData const & cur, bool devel_mode) const
{
LBUFERR(this == cur.text());
os << bformat(_("Font: %1$s"), font.stateText(&buf.params()));
// The paragraph depth
- int depth = cur.paragraph().getDepth();
+ int depth = par.getDepth();
if (depth > 0)
os << bformat(_(", Depth: %1$d"), depth);
}
}
+ // Custom text style
+ InsetLayout const & layout = cur.inset().getLayout();
+ if (layout.lyxtype() == InsetLyXType::CHARSTYLE)
+ os << _(", Style: ") << translateIfPossible(layout.labelstring());
+
if (devel_mode) {
os << _(", Inset: ") << &cur.inset();
if (cur.lastidx() > 0)
// We need a unique label
docstring label = text;
int i = 1;
- while (cur.buffer()->insetLabel(label)) {
+ while (cur.buffer()->activeLabel(label)) {
label = text + '-' + convert<docstring>(i);
++i;
}
}
-docstring Text::previousWord(CursorSlice const & sl) const
-{
- CursorSlice from = sl;
- CursorSlice to = sl;
- getWord(from, to, PREVIOUS_WORD);
- if (sl == from || to == from)
- return docstring();
-
- Paragraph const & par = sl.paragraph();
- return par.asString(from.pos(), to.pos());
-}
-
-
bool Text::completionSupported(Cursor const & cur) const
{
Paragraph const & par = cur.paragraph();
- return cur.pos() > 0
+ return !cur.selection()
+ && cur.pos() > 0
&& (cur.pos() >= par.size() || par.isWordSeparator(cur.pos()))
&& !par.isWordSeparator(cur.pos() - 1);
}
docstring Text::completionPrefix(Cursor const & cur) const
{
- return previousWord(cur.top());
+ CursorSlice from = cur.top();
+ CursorSlice to = from;
+ getWord(from, to, PREVIOUS_WORD);
+
+ return cur.paragraph().asString(from.pos(), to.pos());
}
} // namespace lyx