Hi!

The attached patch gets rid of some of the LTR bias which currently exists in the code. What I mean is, there are various places in the code where Right or Left are mentioned, where what we actually mean is forward or backwards. In LTR documents it's the same thing, but in RTL or BiDi documents, Left is not necessarily Backwards and Right is not necessarily Forward.

This is in preparation of adding a "visual mode" of the cursor movement in BiDi text: we currently only support "logical mode", where pressing the Left or Right keys moves Backwards or Forwards, depending on the paragraph's direction (in an LTR paragraph, Left is backwards and Right is forwards; in an RTL paragraph, the directions are reversed). Visual mode is more complicated to implement, though somewhat more intuitive for the user (though it has it's complications for the user, too): Left moves left and Right moves right. What complicates things from the programmer's point of view is that in order to maintain visually contiguous movement, the cursor sometimes actually has to "jump" in terms of the logical position in the buffer (this occurs at transitions between LTR and RTL text).

So as a first step towards this goal, making this distinction in the code between forward / backward and left / right will make future changes more clear.

Here's an overview of the changes being made in the current patch (note that so far, behavior should remain absolutely unchanged):

*) Change the behavior of the existing CHAR_FORWARD/BACKWARD LFUNs, and add LFUNs for CHAR_LEFT/RIGHT: whereas each of the former LFUNs used to move sometimes forward and sometimes backward, depending on the direction of the paragraph, they now do exactly what their name implies: FORWARD always move logically forward, and BACKWARD always moves logically back. The new LFUNs, CHAR_LEFT/RIGHT now behave the way the former ones used to: they dispatch either a FORWARD or a BACKWARD request, depending on the direction of the paragraph. When visual mode is added, this will slightly change: if visual mode is active, they will perform visual movement, moving exactly LEFT or RIGHT as requested; and if visual mode is inactive, they will continue to behave as they do now.

*) Similarly, LFUNs called FINISHED_FORWARD/BACKWARD have been added, which provide the logical forward/backward behavior. Note that there are no calls anymore to the already existing LFUNs FINISHED_LEFT/RIGHT, but I have not removed these, since I suspect that they will come in handy for visual mode.

*) The keybindings were changed to reflect the above changes: LEFT and RIGHT arrow keys now call the CHAR_LEFT/RIGHT LFUNs. Thus, they will get visual behavior when visual mode is activated. Note that other references to CHAR_FORWARD/BACKWARD remain unchanged: I think that only the arrow keys should have visual movement, but other bindings to CHAR_FORWARD/BACKWARD should still work in logical mode.

*) The cursorLeft/Right functions have been renamed cursorForward/Backward, to reflect what they really do: move logically forward or backward. And of course, all references to these functions have been changed appropriately.

I am aware of a few remaining places in the code which still have an LTR bias; notably, the WORD_FORWARD/BACKWARD LFUNs and related functions. I will try to fix these in a followup patch.

I will commit in the next few days if I don't get any objections.

Dov
diff -r 6613f7c40381 lib/bind/cua.bind
--- a/lib/bind/cua.bind Sat Oct 20 16:56:46 2007 +0200
+++ b/lib/bind/cua.bind Sat Oct 20 18:39:44 2007 +0200
@@ -126,8 +126,8 @@
 # Motion + select group
 #
 
-\bind "S-Right"                        "forward-select"
-\bind "S-Left"                 "backward-select"
+\bind "S-Right"                        "right-select"
+\bind "S-Left"                 "left-select"
 \bind "S-Up"                   "up-select"
 \bind "S-Down"                 "down-select"
 \bind "S-C-Right"              "word-forward-select"
@@ -145,8 +145,8 @@
 \bind "S-Delete"               "cut"
 
 # Numeric keypad (if Shift+KP_XXX does not switch the NumLock state)
-\bind "S-KP_Right"              "forward-select"
-\bind "S-KP_Left"               "backward-select"
+\bind "S-KP_Right"              "right-select"
+\bind "S-KP_Left"               "left-select"
 \bind "S-KP_Up"                 "up-select"
 \bind "S-KP_Down"               "down-select"
 \bind "S-C-KP_Right"            "word-forward-select"
diff -r 6613f7c40381 lib/bind/emacs.bind
--- a/lib/bind/emacs.bind       Sat Oct 20 16:56:46 2007 +0200
+++ b/lib/bind/emacs.bind       Sat Oct 20 18:39:44 2007 +0200
@@ -182,8 +182,8 @@
 # Motion + select group
 #
 
-\bind "S-Right"                "forward-select"
-\bind "S-Left"                 "backward-select"
+\bind "S-Right"                "right-select"
+\bind "S-Left"                 "left-select"
 \bind "S-C-F"                  "forward-select"
 \bind "S-C-B"                  "backward-select"
 \bind "S-Up"                   "up-select"
@@ -220,8 +220,8 @@
 \bind "Escape"                 "meta-prefix"
 
 # Numeric keypad (if Shift+KP_XXX does not switch the NumLock state)
-\bind "S-KP_Right"              "forward-select"
-\bind "S-KP_Left"               "backward-select"
+\bind "S-KP_Right"              "right-select"
+\bind "S-KP_Left"               "left-select"
 \bind "S-KP_Up"                 "up-select"
 \bind "S-KP_Down"               "down-select"
 \bind "S-C-KP_Right"            "word-forward-select"
diff -r 6613f7c40381 lib/bind/mac.bind
--- a/lib/bind/mac.bind Sat Oct 20 16:56:46 2007 +0200
+++ b/lib/bind/mac.bind Sat Oct 20 18:39:44 2007 +0200
@@ -108,8 +108,8 @@
 # Motion + select group
 #
 
-\bind "S-Right"                        "forward-select"
-\bind "S-Left"                 "backward-select"
+\bind "S-Right"                        "right-select"
+\bind "S-Left"                 "left-select"
 \bind "S-Up"                   "up-select"
 \bind "S-Down"                 "down-select"
 \bind "S-M-Right"              "word-forward-select"
@@ -127,8 +127,8 @@
 \bind "S-Delete"               "cut"
 
 # Numeric keypad (if Shift+KP_XXX does not switch the NumLock state)
-\bind "S-KP_Right"              "forward-select"
-\bind "S-KP_Left"               "backward-select"
+\bind "S-KP_Right"              "right-select"
+\bind "S-KP_Left"               "left-select"
 \bind "S-KP_Up"                 "up-select"
 \bind "S-KP_Down"               "down-select"
 \bind "S-M-KP_Right"            "word-forward-select"
diff -r 6613f7c40381 lib/bind/sciword.bind
--- a/lib/bind/sciword.bind     Sat Oct 20 16:56:46 2007 +0200
+++ b/lib/bind/sciword.bind     Sat Oct 20 18:39:44 2007 +0200
@@ -219,8 +219,8 @@
 
 \bind "M-Up"                   "paragraph-move-up"
 \bind "M-Down"                 "paragraph-move-down"
-\bind "S-KP_Right"                     "forward-select"
-\bind "S-KP_Left"                              "backward-select"
+\bind "S-KP_Right"                     "right-select"
+\bind "S-KP_Left"                              "left-select"
 \bind "S-KP_Up"                                "up-select"
 \bind "S-KP_Down"                              "down-select"
 \bind "S-C-KP_Right"                   "word-forward-select"
diff -r 6613f7c40381 lib/bind/xemacs.bind
--- a/lib/bind/xemacs.bind      Sat Oct 20 16:56:46 2007 +0200
+++ b/lib/bind/xemacs.bind      Sat Oct 20 18:39:44 2007 +0200
@@ -192,8 +192,8 @@
 # Motion + select group
 #
 
-\bind "S-Right"                "forward-select"
-\bind "S-Left"                 "backward-select"
+\bind "S-Right"                "right-select"
+\bind "S-Left"                 "left-select"
 \bind "S-C-F"                  "forward-select"
 \bind "S-C-B"                  "backward-select"
 \bind "S-Up"                   "up-select"
@@ -231,8 +231,8 @@
 \bind "Escape"                 "meta-prefix"
 
 # Numeric keypad (if Shift+KP_XXX does not switch the NumLock state)
-\bind "S-KP_Right"              "forward-select"
-\bind "S-KP_Left"               "backward-select"
+\bind "S-KP_Right"              "right-select"
+\bind "S-KP_Left"               "left-select"
 \bind "S-KP_Up"                 "up-select"
 \bind "S-KP_Down"               "down-select"
 \bind "S-C-KP_Right"            "word-forward-select"
diff -r 6613f7c40381 src/LyX.cpp
--- a/src/LyX.cpp       Sat Oct 20 16:56:46 2007 +0200
+++ b/src/LyX.cpp       Sat Oct 20 18:39:44 2007 +0200
@@ -1017,8 +1017,8 @@ bool LyX::init()
 
 void LyX::defaultKeyBindings(KeyMap  * kbmap)
 {
-       kbmap->bind("Right", FuncRequest(LFUN_CHAR_FORWARD));
-       kbmap->bind("Left", FuncRequest(LFUN_CHAR_BACKWARD));
+       kbmap->bind("Right", FuncRequest(LFUN_CHAR_RIGHT));
+       kbmap->bind("Left", FuncRequest(LFUN_CHAR_LEFT));
        kbmap->bind("Up", FuncRequest(LFUN_UP));
        kbmap->bind("Down", FuncRequest(LFUN_DOWN));
 
@@ -1056,8 +1056,8 @@ void LyX::defaultKeyBindings(KeyMap  * k
        //kbmap->bind("KP_Divide", FuncRequest(LFUN_SELF_INSERT));
        //kbmap->bind("KP_Multiply", FuncRequest(LFUN_SELF_INSERT));
        //kbmap->bind("KP_Subtract", FuncRequest(LFUN_SELF_INSERT));
-       kbmap->bind("KP_Right", FuncRequest(LFUN_CHAR_FORWARD));
-       kbmap->bind("KP_Left", FuncRequest(LFUN_CHAR_BACKWARD));
+       kbmap->bind("KP_Right", FuncRequest(LFUN_CHAR_RIGHT));
+       kbmap->bind("KP_Left", FuncRequest(LFUN_CHAR_LEFT));
        kbmap->bind("KP_Up", FuncRequest(LFUN_UP));
        kbmap->bind("KP_Down", FuncRequest(LFUN_DOWN));
        kbmap->bind("KP_Home", FuncRequest(LFUN_LINE_BEGIN));
diff -r 6613f7c40381 src/LyXAction.cpp
--- a/src/LyXAction.cpp Sat Oct 20 16:56:46 2007 +0200
+++ b/src/LyXAction.cpp Sat Oct 20 18:39:44 2007 +0200
@@ -142,6 +142,10 @@ void LyXAction::init()
                { LFUN_CHAR_DELETE_FORWARD, "delete-forward", SingleParUpdate, 
Edit },
                { LFUN_CHAR_FORWARD, "char-forward", ReadOnly | NoUpdate, Edit 
},
                { LFUN_CHAR_FORWARD_SELECT, "forward-select", ReadOnly | 
SingleParUpdate, Edit },
+               { LFUN_CHAR_LEFT, "char-left", ReadOnly | NoUpdate, Edit },
+               { LFUN_CHAR_LEFT_SELECT, "left-select", ReadOnly | 
SingleParUpdate, Edit },
+               { LFUN_CHAR_RIGHT, "char-right", ReadOnly | NoUpdate, Edit },
+               { LFUN_CHAR_RIGHT_SELECT, "right-select", ReadOnly | 
SingleParUpdate, Edit },
                { LFUN_CLIPBOARD_PASTE, "clipboard-paste", Noop, Edit },
                { LFUN_COMMAND_EXECUTE, "command-execute", NoBuffer, Edit },
                { LFUN_COMMAND_PREFIX, "command-prefix", NoBuffer, Hidden },
@@ -356,6 +360,8 @@ void LyXAction::init()
                { LFUN_BUFFER_NEXT, "buffer-next", ReadOnly, Buffer },
                { LFUN_BUFFER_PREVIOUS, "buffer-previous", ReadOnly, Buffer },
                { LFUN_WORDS_COUNT, "words-count", ReadOnly, System },
+               { LFUN_FINISHED_FORWARD, "", ReadOnly, Hidden },
+               { LFUN_FINISHED_BACKWARD, "", ReadOnly, Hidden },
                { LFUN_FINISHED_RIGHT, "", ReadOnly, Hidden },
                { LFUN_FINISHED_LEFT, "", ReadOnly, Hidden },
                { LFUN_MOUSE_PRESS, "", ReadOnly, Hidden },
diff -r 6613f7c40381 src/Text.cpp
--- a/src/Text.cpp      Sat Oct 20 16:56:46 2007 +0200
+++ b/src/Text.cpp      Sat Oct 20 18:39:44 2007 +0200
@@ -807,7 +807,7 @@ void Text::deleteWordForward(Cursor & cu
 {
        BOOST_ASSERT(this == cur.text());
        if (cur.lastpos() == 0)
-               cursorRight(cur);
+               cursorForward(cur);
        else {
                cur.resetAnchor();
                cur.selection() = true;
@@ -823,7 +823,7 @@ void Text::deleteWordBackward(Cursor & c
 {
        BOOST_ASSERT(this == cur.text());
        if (cur.lastpos() == 0)
-               cursorLeft(cur);
+               cursorBackward(cur);
        else {
                cur.resetAnchor();
                cur.selection() = true;
@@ -1086,9 +1086,9 @@ bool Text::backspace(Cursor & cur)
                // this is the code for a normal backspace, not pasting
                // any paragraphs
                cur.recordUndo(DELETE_UNDO);
-               // We used to do cursorLeftIntern() here, but it is
+               // We used to do cursorBackwardIntern() here, but it is
                // not a good idea since it triggers the auto-delete
-               // mechanism. So we do a cursorLeftIntern()-lite,
+               // mechanism. So we do a cursorBackwardIntern()-lite,
                // without the dreaded mechanism. (JMarc)
                setCursorIntern(cur, cur.pit(), cur.pos() - 1,
                                false, cur.boundary());
diff -r 6613f7c40381 src/Text.h
--- a/src/Text.h        Sat Oct 20 16:56:46 2007 +0200
+++ b/src/Text.h        Sat Oct 20 18:39:44 2007 +0200
@@ -163,16 +163,16 @@ public:
        ///
        void recUndo(Cursor & cur, pit_type first) const;
 
-       /// Move cursor one position left
+       /// Move cursor one position backwards
        /**
         * Returns true if an update is needed after the move.
         */
-       bool cursorLeft(Cursor & cur);
-       /// Move cursor one position right
+       bool cursorBackward(Cursor & cur);
+       /// Move cursor one position forward
        /**
         * Returns true if an update is needed after the move.
         */
-       bool cursorRight(Cursor & cur);
+       bool cursorForward(Cursor & cur);
        ///
        bool cursorLeftOneWord(Cursor & cur);
        ///
diff -r 6613f7c40381 src/Text2.cpp
--- a/src/Text2.cpp     Sat Oct 20 16:56:46 2007 +0200
+++ b/src/Text2.cpp     Sat Oct 20 18:39:44 2007 +0200
@@ -602,7 +602,7 @@ bool Text::checkAndActivateInset(Cursor 
 }
 
 
-bool Text::cursorLeft(Cursor & cur)
+bool Text::cursorBackward(Cursor & cur)
 {
        // Tell BufferView to test for FitCursor in any case!
        cur.updateFlags(Update::FitCursor);
@@ -644,7 +644,7 @@ bool Text::cursorLeft(Cursor & cur)
 }
 
 
-bool Text::cursorRight(Cursor & cur)
+bool Text::cursorForward(Cursor & cur)
 {
        // Tell BufferView to test for FitCursor in any case!
        cur.updateFlags(Update::FitCursor);
diff -r 6613f7c40381 src/Text3.cpp
--- a/src/Text3.cpp     Sat Oct 20 16:56:46 2007 +0200
+++ b/src/Text3.cpp     Sat Oct 20 18:39:44 2007 +0200
@@ -381,15 +381,12 @@ void Text::dispatch(Cursor & cur, FuncRe
                //lyxerr << BOOST_CURRENT_FUNCTION
                //       << " LFUN_CHAR_FORWARD[SEL]:\n" << cur << endl;
                needsUpdate |= cur.selHandle(cmd.action == 
LFUN_CHAR_FORWARD_SELECT);
-               if (reverseDirectionNeeded(cur))
-                       needsUpdate |= cursorLeft(cur);
-               else
-                       needsUpdate |= cursorRight(cur);
+               needsUpdate |= cursorForward(cur);
 
                if (!needsUpdate && oldTopSlice == cur.top()
                                && cur.boundary() == oldBoundary) {
                        cur.undispatched();
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                }
                break;
 
@@ -397,15 +394,40 @@ void Text::dispatch(Cursor & cur, FuncRe
        case LFUN_CHAR_BACKWARD_SELECT:
                //lyxerr << "handle LFUN_CHAR_BACKWARD[_SELECT]:\n" << cur << 
endl;
                needsUpdate |= cur.selHandle(cmd.action == 
LFUN_CHAR_BACKWARD_SELECT);
-               if (reverseDirectionNeeded(cur))
-                       needsUpdate |= cursorRight(cur);
-               else
-                       needsUpdate |= cursorLeft(cur);
+               needsUpdate |= cursorBackward(cur);
 
                if (!needsUpdate && oldTopSlice == cur.top()
                        && cur.boundary() == oldBoundary) {
                        cur.undispatched();
-                       cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                       cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
+               }
+               break;
+
+       case LFUN_CHAR_LEFT:
+       case LFUN_CHAR_LEFT_SELECT:
+               //FIXME: for visual cursor, really move left
+               if (reverseDirectionNeeded(cur)) {
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ? 
+                                       LFUN_CHAR_FORWARD_SELECT : 
LFUN_CHAR_FORWARD));
+               } else {
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ? 
+                                       LFUN_CHAR_BACKWARD_SELECT : 
LFUN_CHAR_BACKWARD));
+               }
+               break;
+
+       case LFUN_CHAR_RIGHT:
+       case LFUN_CHAR_RIGHT_SELECT:
+               //FIXME: for visual cursor, really move right
+               if (reverseDirectionNeeded(cur)) {
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ? 
+                                       LFUN_CHAR_BACKWARD_SELECT : 
LFUN_CHAR_BACKWARD));
+               } else {
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ? 
+                                       LFUN_CHAR_FORWARD_SELECT : 
LFUN_CHAR_FORWARD));
                }
                break;
 
@@ -536,8 +558,8 @@ void Text::dispatch(Cursor & cur, FuncRe
                // Reverse the effect of LFUN_BREAK_PARAGRAPH_SKIP.
                if (!cur.selection()) {
                        if (cur.pos() == cur.lastpos()) {
-                               cursorRight(cur);
-                               cursorLeft(cur);
+                               cursorForward(cur);
+                               cursorBackward(cur);
                        }
                        erase(cur);
                        cur.resetAnchor();
@@ -1390,6 +1412,16 @@ void Text::dispatch(Cursor & cur, FuncRe
                }
                break;
 
+       case LFUN_FINISHED_BACKWARD:
+               LYXERR(Debug::DEBUG) << "handle LFUN_FINISHED_BACKWARD:\n" << 
cur << endl;
+               break;
+
+       case LFUN_FINISHED_FORWARD:
+               LYXERR(Debug::DEBUG) << "handle LFUN_FINISHED_FORWARD:\n" << 
cur << endl;
+               ++cur.pos();
+               cur.setCurrentFont();
+               break;
+
        case LFUN_LAYOUT_PARAGRAPH: {
                string data;
                params2string(cur.paragraph(), data);
@@ -1442,7 +1474,7 @@ void Text::dispatch(Cursor & cur, FuncRe
                        breakParagraph(cur);
 
                        if (cur.lastpos() != 0) {
-                               cursorLeft(cur);
+                               cursorBackward(cur);
                                breakParagraph(cur);
                        }
 
@@ -1510,7 +1542,9 @@ void Text::dispatch(Cursor & cur, FuncRe
                        cur.selection() = false;
                } else {
                        cur.undispatched();
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       // This used to be LFUN_FINISHED_RIGHT, I think FORWARD 
is more
+                       // correct, but I'm not 100% sure -- dov, 071019
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                }
                break;
 
@@ -1851,6 +1885,10 @@ bool Text::getStatus(Cursor & cur, FuncR
        case LFUN_CHAR_FORWARD_SELECT:
        case LFUN_CHAR_BACKWARD:
        case LFUN_CHAR_BACKWARD_SELECT:
+       case LFUN_CHAR_LEFT:
+       case LFUN_CHAR_LEFT_SELECT:
+       case LFUN_CHAR_RIGHT:
+       case LFUN_CHAR_RIGHT_SELECT:
        case LFUN_UP:
        case LFUN_UP_SELECT:
        case LFUN_DOWN:
diff -r 6613f7c40381 src/TextMetrics.cpp
--- a/src/TextMetrics.cpp       Sat Oct 20 16:56:46 2007 +0200
+++ b/src/TextMetrics.cpp       Sat Oct 20 18:39:44 2007 +0200
@@ -1655,8 +1655,8 @@ void TextMetrics::deleteLineForward(Curs
 {
        BOOST_ASSERT(text_ == cur.text());
        if (cur.lastpos() == 0) {
-               // Paragraph is empty, so we just go to the right
-               text_->cursorRight(cur);
+               // Paragraph is empty, so we just go forward
+               text_->cursorForward(cur);
        } else {
                cur.resetAnchor();
                cur.selection() = true; // to avoid deletion
@@ -2080,9 +2080,9 @@ void TextMetrics::drawRowSelection(Paint
        while (cur < end) {
                bool drawNow = false;
                
-               // simplified cursorRight code below which does not
+               // simplified cursorForward code below which does not
                // descend into insets and which does not go into the
-               // next line. Compare the logic with the original cursorRight
+               // next line. Compare the logic with the original cursorForward
                
                // if left of boundary -> just jump to right side
                // but for RTL boundaries don't, because: abc|DDEEFFghi -> 
abcDDEEF|Fghi
diff -r 6613f7c40381 src/insets/InsetTabular.cpp
--- a/src/insets/InsetTabular.cpp       Sat Oct 20 16:56:46 2007 +0200
+++ b/src/insets/InsetTabular.cpp       Sat Oct 20 18:39:44 2007 +0200
@@ -37,6 +37,7 @@
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "Lexer.h"
+#include "LyXFunc.h"
 #include "MetricsInfo.h"
 #include "OutputParams.h"
 #include "paragraph_funcs.h"
@@ -3256,9 +3257,9 @@ void InsetTabular::doDispatch(Cursor & c
        case LFUN_CHAR_FORWARD:
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
-                       isRightToLeft(cur) ? movePrevCell(cur) : 
moveNextCell(cur);
+                       moveNextCell(cur);
                        if (sl == cur.top())
-                               cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                               cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        else
                                cur.dispatched();
                }
@@ -3268,12 +3269,38 @@ void InsetTabular::doDispatch(Cursor & c
        case LFUN_CHAR_BACKWARD:
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
-                       isRightToLeft(cur) ? moveNextCell(cur) : 
movePrevCell(cur);
+                       movePrevCell(cur);
                        if (sl == cur.top())
-                               cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                               cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                        else
                                cur.dispatched();
                }
+               break;
+
+       case LFUN_CHAR_RIGHT_SELECT:
+       case LFUN_CHAR_RIGHT:
+               //FIXME: for visual cursor, really move right
+               if (isRightToLeft(cur))
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ?
+                                       LFUN_CHAR_BACKWARD_SELECT : 
LFUN_CHAR_BACKWARD));
+               else
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ?
+                                       LFUN_CHAR_FORWARD_SELECT : 
LFUN_CHAR_FORWARD));
+               break;
+
+       case LFUN_CHAR_LEFT_SELECT:
+       case LFUN_CHAR_LEFT:
+               //FIXME: for visual cursor, really move left
+               if (isRightToLeft(cur))
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ?
+                                       LFUN_CHAR_FORWARD_SELECT : 
LFUN_CHAR_FORWARD));
+               else
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ?
+                                       LFUN_CHAR_BACKWARD_SELECT : 
LFUN_CHAR_BACKWARD));
                break;
 
        case LFUN_DOWN_SELECT:
@@ -3292,9 +3319,9 @@ void InsetTabular::doDispatch(Cursor & c
                                cur.pos() = tm.x2pos(cur.pit(), 0, 
cur.targetX());
                        }
                if (sl == cur.top()) {
-                       // we trick it to go to the RIGHT after leaving the
+                       // we trick it to go to forward after leaving the
                        // tabular.
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
diff -r 6613f7c40381 src/lfuns.h
--- a/src/lfuns.h       Sat Oct 20 16:56:46 2007 +0200
+++ b/src/lfuns.h       Sat Oct 20 18:39:44 2007 +0200
@@ -404,6 +404,14 @@ enum kb_action {
        LFUN_MASTER_BUFFER_VIEW,         // Tommaso, 20070920
        LFUN_MASTER_BUFFER_UPDATE,       // Tommaso, 20070920
        LFUN_INFO_INSERT,                // bpeng, 20071007
+       // 295
+       LFUN_CHAR_LEFT,                                  // dov, 20071017
+       LFUN_CHAR_LEFT_SELECT,                   // dov, 20071017
+       LFUN_CHAR_RIGHT,                                 // dov, 20071017
+       LFUN_CHAR_RIGHT_SELECT,                  // dov, 20071017
+       LFUN_FINISHED_BACKWARD,                  // dov, 20071017
+       // 300
+       LFUN_FINISHED_FORWARD,                   // dov, 20071017
 
        LFUN_LASTACTION                  // end of the table
 };
diff -r 6613f7c40381 src/mathed/InsetMathGrid.cpp
--- a/src/mathed/InsetMathGrid.cpp      Sat Oct 20 16:56:46 2007 +0200
+++ b/src/mathed/InsetMathGrid.cpp      Sat Oct 20 18:39:44 2007 +0200
@@ -1104,7 +1104,7 @@ void InsetMathGrid::doDispatch(Cursor & 
                // See below.
                cur.selection() = false;
                if (!idxPrev(cur)) {
-                       cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                       cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                        cur.undispatched();
                }
                break;
@@ -1114,7 +1114,7 @@ void InsetMathGrid::doDispatch(Cursor & 
                // hard bound to LFUN_CELL_BACKWARD
                cur.selection() = false;
                if (!idxNext(cur)) {
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
@@ -1136,7 +1136,7 @@ void InsetMathGrid::doDispatch(Cursor & 
                cur.pos() = cur.lastpos();
 
                //mathcursor->normalize();
-               //cmd = FuncRequest(LFUN_FINISHED_LEFT);
+               //cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                break;
        }
 
@@ -1249,6 +1249,7 @@ void InsetMathGrid::doDispatch(Cursor & 
                        cur.undispatched();
                        break;
                }
+               // perhaps this should be FINISHED_BACKWARD -- just for clarity?
                lyxerr << "returning FINISHED_LEFT" << endl;
                break;
        }
@@ -1318,7 +1319,7 @@ void InsetMathGrid::doDispatch(Cursor & 
                        cur.idx() = 0;
                        cur.pos() = 0;
                } else {
-                       cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                       cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                        cur.undispatched();
                }
                break;
@@ -1340,7 +1341,7 @@ void InsetMathGrid::doDispatch(Cursor & 
                        cur.idx() = cur.lastidx();
                        cur.pos() = cur.lastpos();
                } else {
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
diff -r 6613f7c40381 src/mathed/InsetMathHull.cpp
--- a/src/mathed/InsetMathHull.cpp      Sat Oct 20 16:56:46 2007 +0200
+++ b/src/mathed/InsetMathHull.cpp      Sat Oct 20 18:39:44 2007 +0200
@@ -1036,8 +1036,8 @@ void InsetMathHull::doDispatch(Cursor & 
        //lyxerr << "action: " << cmd.action << endl;
        switch (cmd.action) {
 
-       case LFUN_FINISHED_LEFT:
-       case LFUN_FINISHED_RIGHT:
+       case LFUN_FINISHED_BACKWARD:
+       case LFUN_FINISHED_FORWARD:
                //lyxerr << "action: " << cmd.action << endl;
                InsetMathGrid::doDispatch(cur, cmd);
                notifyCursorLeaves(cur);
@@ -1173,8 +1173,8 @@ bool InsetMathHull::getStatus(Cursor & c
                FuncStatus & status) const
 {
        switch (cmd.action) {
-       case LFUN_FINISHED_LEFT:
-       case LFUN_FINISHED_RIGHT:
+       case LFUN_FINISHED_BACKWARD:
+       case LFUN_FINISHED_FORWARD:
        case LFUN_UP:
        case LFUN_DOWN:
                status.enabled(true);
diff -r 6613f7c40381 src/mathed/InsetMathNest.cpp
--- a/src/mathed/InsetMathNest.cpp      Sat Oct 20 16:56:46 2007 +0200
+++ b/src/mathed/InsetMathNest.cpp      Sat Oct 20 18:39:44 2007 +0200
@@ -43,6 +43,7 @@
 #include "DispatchResult.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "LyXFunc.h"
 #include "gettext.h"
 #include "Text.h"
 #include "OutputParams.h"
@@ -490,11 +491,11 @@ void InsetMathNest::doDispatch(Cursor & 
                lfunMouseRelease(cur, cmd);
                break;
 
-       case LFUN_FINISHED_LEFT:
+       case LFUN_FINISHED_BACKWARD:
                cur.bv().cursor() = cur;
                break;
 
-       case LFUN_FINISHED_RIGHT:
+       case LFUN_FINISHED_FORWARD:
                ++cur.pos();
                cur.bv().cursor() = cur;
                break;
@@ -506,10 +507,6 @@ void InsetMathNest::doDispatch(Cursor & 
                cur.autocorrect() = false;
                cur.clearTargetX();
                cur.macroModeClose();
-               if (reverseDirectionNeeded(cur))
-                       goto goto_char_backwards;
-
-goto_char_forwards:
                if (cur.pos() != cur.lastpos() && cur.openable(cur.nextAtom())) 
{
                        cur.pushLeft(*cur.nextAtom().nucleus());
                        cur.inset().idxFirst(cur);
@@ -517,7 +514,7 @@ goto_char_forwards:
                        || cur.popRight() || cur.selection())
                        ;
                else {
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
@@ -529,10 +526,6 @@ goto_char_forwards:
                cur.autocorrect() = false;
                cur.clearTargetX();
                cur.macroModeClose();
-               if (reverseDirectionNeeded(cur))
-                       goto goto_char_forwards;
-
-goto_char_backwards:
                if (cur.pos() != 0 && cur.openable(cur.prevAtom())) {
                        cur.posLeft();
                        cur.push(*cur.nextAtom().nucleus());
@@ -541,9 +534,35 @@ goto_char_backwards:
                        || cur.popLeft() || cur.selection())
                        ;
                else {
-                       cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                       cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                        cur.undispatched();
                }
+               break;
+
+       case LFUN_CHAR_RIGHT:
+       case LFUN_CHAR_RIGHT_SELECT:
+               //FIXME: for visual cursor, really move right
+               if (reverseDirectionNeeded(cur))
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ? 
+                                       LFUN_CHAR_BACKWARD_SELECT : 
LFUN_CHAR_BACKWARD));
+               else 
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ? 
+                                       LFUN_CHAR_FORWARD_SELECT : 
LFUN_CHAR_FORWARD));
+               break;
+
+       case LFUN_CHAR_LEFT:
+       case LFUN_CHAR_LEFT_SELECT:
+               //FIXME: for visual cursor, really move left
+               if (reverseDirectionNeeded(cur))
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ? 
+                                       LFUN_CHAR_FORWARD_SELECT : 
LFUN_CHAR_FORWARD));
+               else 
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ? 
+                                       LFUN_CHAR_BACKWARD_SELECT : 
LFUN_CHAR_BACKWARD));
                break;
 
        case LFUN_DOWN:
@@ -617,7 +636,7 @@ goto_char_backwards:
                        cur.idx() = 0;
                        cur.pos() = 0;
                } else {
-                       cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                       cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                        cur.undispatched();
                }
                break;
@@ -640,18 +659,18 @@ goto_char_backwards:
                        cur.idx() = cur.lastidx();
                        cur.pos() = cur.lastpos();
                } else {
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
 
        case LFUN_SCREEN_UP_SELECT:
-               cmd = FuncRequest(LFUN_FINISHED_LEFT);
+               cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                cur.undispatched();
                break;
 
        case LFUN_SCREEN_DOWN_SELECT:
-               cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+               cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                cur.undispatched();
                break;
 
@@ -697,7 +716,7 @@ goto_char_backwards:
                if (cur.selection())
                        cur.clearSelection();
                else  {
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
@@ -740,7 +759,7 @@ goto_char_backwards:
                                cur.pushLeft(*cur.nextInset());
                        }
                } else if (!interpretChar(cur, cmd.argument()[0])) {
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;

Reply via email to