Arrow keys swapping

So far we dealt with the output part of the story. Let’s take a look at the input component.

There’s one issue about keyboard handling relevant to BiDi: possibly swapping the Left and Right arrow keys.

In BiDi-unaware apps, whenever editing text inside a RTL paragraph (possibly autodetected), the cursor walks in the opposite direction over natural (RTL) text, and in the regular direction over foreign (LTR) text snippets. The expected behavior is the reverse of this.

Obviously in implicit mode we cannot implement visual walking of the cursor in case of mixed directionality paragraphs, the movement is always logical. (BiDi-aware apps in explicit mode are free to implement whatever they want.) In pure RTL or mixed directionality text, if the overall paragraph direction is RTL, the cursor should move according to the pressed key over RTL snippets and in the opposite direction over embedded LTR ones.

I recommend introducing a new mode where the sequences generated by the Left and Right arrows are swapped whenever the cursor is inside a RTL paragraph. (In case of autodetection, it’s the autodetected direction that matters and not the specified fallback.)

Unlike the display bits, I don’t see a point in making this a per-paragraph mode, I think a global mode suffices.

In order for line editing to work as expected in BiDi-unaware apps in RTL direction (such as at the shell prompt, a read -e in a bash script, other readline apps etc.), even when the direction gets autodetected as RTL as the user starts typing, this new arrow key swapping mode needs to be the default. Similarly to why we picked implicit mode as the default, there would be no proper place to toggle the keyboard arrow swapping mode to enable it for BiDi-unaware apps or for RTL (potentially autodetected) paragraphs..

It may sound brave and risky to change the default behavior of the keyboard keys. Here’s why I believe it’s not risky, it is perfectly backwards compatible. By default, autodetecting the paragraph direction is turned off. So if the emulator’s default direction is LTR then all the paragraphs will be in LTR direction (RTL letters inside cannot influence the paragraph direction), and no arrow key swapping occurs. If the emulator’s default direction is RTL, there’s no backwards compatibility to talk about since this possible behavior is newly introduced. With the keyboard arrow swapping mode being the default, one would still need to at least switch to RTL or enable autodetection to make these keys potentially emit the swapped sequences.

There must be a way to turn off this mode. BiDi-aware fullscreen apps (e.g. text editors) might use a mixture of the two paragraph directions. For example, a text editor might use LTR paragraph direction inside its header and footer lines containing its English user interface, while use RTL paragraph direction for the actual content where it displays a Hebrew text file. As such an app paints its screen, the cursor walks through paragraphs of both directions. There’s no way the app could reliably tell when exactly the user pressed the key, that is, whether the emulator sent the regular or the swapped sequence. We don’t lose any functionality here by disabling swapping: BiDi-aware apps can easily swap them themselves.

To be even more certain that we don’t break any existing use of the non-swapped keys, users should be able to disable swapping by emitting the corresponding escape sequences just once in their shell startup file. Ideally no BiDi-aware utility should re-enable it (in case of clean exit). That is, BiDi-aware apps that wish to turn off this mode should on startup save and disable, and on exit restore. (Emulators that don’t implement saving and restoring should go ahead and implement it.)

Note that Home and End should not be swapped.