mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
#6401 correct cursor movement for word forward/backward with enabled Mac style (mac_like_cursor_movement)
The change includes a rewrite of the cursor movement when „mac style“ is enabled and don’t change anything otherwise. The new code for mac uses the document iterator to go forward or backward. The traversal stops at word boundaries. If going forward the position increments until a word is reached (if not already inside) and stops at the end of the word. If going backward it does the same in opposite direction. The cursor jumps over non-editable insets and math. Editable (open) insets are entered and the cursor move detects word boundaries inside them.
This commit is contained in:
parent
b4f3963ab2
commit
320b6b6656
98
src/Text.cpp
98
src/Text.cpp
@ -1146,6 +1146,40 @@ bool Text::cursorForwardOneWord(Cursor & cur)
|
||||
{
|
||||
LBUFERR(this == cur.text());
|
||||
|
||||
if (lyxrc.mac_like_cursor_movement) {
|
||||
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();
|
||||
@ -1159,17 +1193,6 @@ bool Text::cursorForwardOneWord(Cursor & cur)
|
||||
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;
|
||||
} else {
|
||||
LASSERT(pos < lastpos, return false); // see above
|
||||
if (!par.isWordSeparator(pos))
|
||||
while (pos != lastpos && !par.isWordSeparator(pos))
|
||||
@ -1183,7 +1206,6 @@ bool Text::cursorForwardOneWord(Cursor & cur)
|
||||
// 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))
|
||||
@ -1191,15 +1213,49 @@ bool Text::cursorForwardOneWord(Cursor & cur)
|
||||
|
||||
return setCursor(cur, pit, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Text::cursorBackwardOneWord(Cursor & cur)
|
||||
{
|
||||
LBUFERR(this == cur.text());
|
||||
|
||||
pit_type pit = cur.pit();
|
||||
if (lyxrc.mac_like_cursor_movement) {
|
||||
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 & par = cur.paragraph();
|
||||
|
||||
// Paragraph boundary is a word boundary
|
||||
if (pos == 0 && pit != 0) {
|
||||
@ -1210,18 +1266,6 @@ bool Text::cursorBackwardOneWord(Cursor & cur)
|
||||
--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;
|
||||
} else {
|
||||
// Skip over white space
|
||||
while (pos != 0 && par.isSpace(pos - 1))
|
||||
--pos;
|
||||
@ -1234,10 +1278,10 @@ bool Text::cursorBackwardOneWord(Cursor & cur)
|
||||
--pos;
|
||||
else if (pos != 0 && !par.isSpace(pos - 1)) // non-char inset
|
||||
--pos;
|
||||
}
|
||||
|
||||
return setCursor(cur, pit, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Text::cursorVisLeftOneWord(Cursor & cur)
|
||||
|
Loading…
Reference in New Issue
Block a user