Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
vsCode RTL support

vsCode RTL support

Intro

I'm going to use the English language as an example of an LTR language and the Farsi/Persian/فارسی language as an example of an RTL language. When I say "This is how RTL works", what I actually mean is that this is how the Farsi language works. So, there may be some differences between RTL languages that I'm not familiar with.

I may provide a text demo and a screenshot demo. Be aware that the text demo is going to look different than the screenshot demo because GitHub doesn't properly support RTL:). So the screenshot version is the correct one.

There are over 600 million right-to-left (RTL) language speakers worldwide. I'm just letting everyone know that a lot of people are affected by not providing proper RTL support.

Basics

Let's start with the basics, to make sure that we don't have any misunderstanding of how RTL languages work.

Letters, numbers and everything in English, starts from the left and goes to the right. That's why it's called LTR(Left To Right).

In an RTL language, letters are written and read from right to left. But numbers are written and read from left to right. It's a little more complicated than this, so I'll explain it all later.

Some files may only contain RTL or LTR content, and some may contain both languages mixed together, that one of them is going to get the primary language that is going to determine the direction of the document. Also, some may contain a part in RTL and a part in LTR!

Only English(LTR):

Screenshot 2022-05-30 065153-min

Only Farsi(RTL):

Screenshot 2022-05-30 065117-min

Mixed English with Farsi (Primary: English):

Screenshot 2022-05-30 065444-min

Mixed Farsi with English (Primary: Farsi):

Screenshot 2022-05-30 065311-min

A part in English(LTR) and a part in Farsi(RTL) - For example in a .md file:

Screenshot 2022-05-30 065722-min

Numbers

Numbers are simple, so let's start with them. Look at the example below, you can read both of them, right? You may even think they are the same but the second one has a silly font. RTL numbers are the same as the LTR numbers. The only difference is that their alignment will be right if they are being used with an RTL letter/word or inside an RTL sentence. Note that only the alignment will change, not the order of the numbers or anything like that. Even if the alignment of the numbers is equal to right, they are still going to be read from left-to-right.

Note: you can read its text content below.

English    1 2 3
Farsi      ۱ ۲ ۳

Note: you can read its text content below.

1 = ۱
2 = ۲
3 = ۳

Note: you can read its text content below.

1 + 2 = 3
۱ + ۲ = ۳

As I explained earlier, numbers are always written and readen from left-to-right (just like English. dir=ltr). But if you are combining numbers with letters (example: I'm 70 years old), since the letters are written and read from right-to-left, you need to align numbers on the right side with the letters.

Note: you can read its text content below.

Numbers and letters all in English:

0

0 A
A 0

0 A 1
1 A 0

A 0 B
B 0 A

Numbers in Farsi and letters in English - (it's the same as the above example):

۰

۰ A
A ۰

۰ A 1
1 A ۰

A ۰ B
B ۰ A

Numbers in English and letters in Farsi - (compare it with the screenshot above):

0

0 آ
آ 0

0 آ 1
1 آ 0

آ 0 ب
ب 0 آ

Numbers and letters all in Farsi - (compare it with the screenshot above):

۰

۰ آ
آ ۰

۰ آ ۱
۱ آ ۰

آ ۰ ب
ب ۰ آ

Note: you can read its text content below.

Compare this with the screenshot above:

A 0 ب
B 0 آ

A ۰ ب
B ۰ آ

آ ۰ B
ب ۰ A

A ب
آ B

Sometimes in a primarily RTL document, if a sentence starts with something like this (LTR RTL...):

Note: you can read its text content below.

S21 دوربینش خوبه.

<!--
Translation: The S21 has a good camera.
-->

Then the sentence still should be aligned to the right! I know, I said when the first letter is in LTR, then the whole sentence should left-aligned, but in this scenario, since the sentence is primarily is in RTL, it should start from right to left. I don't know how it can grammatically be explained🤷‍♂️.

RTL in Code

Because programing languages (example: .js) are writen in English, they need to be left aligned. There is also other files like .md, that we can write a documentation in Farsi(RTL) and a block of code(LTR) inside it.


Here I'm going to show some incorrect RTL support with a corrected version.

1

This looks fine (Only Farsi):

Note: you can read its text content below.

<body>
  سلام بابک خوبی؟
</body>
<!--
RTL1 RTL2 RTL3
-->

Replace "بابک" with "babakfp" and as you see the result looks completely different.

Note: you can read its text content below.

<body>
  سلام babakfp خوبی؟
</body>
<!--
The order of writing : RTL1 LTR RTL2
What it should look like instead: RTL2 LTR RTL1
-->

What should it look like?

RTL2 LTR RTL1

In HTML you can have something like this:

<div style="text-align:left; direction:rtl">سلام babakfp خوبی؟</div>

Because it starts with an RTL letter, I gave it direction:rtl and because inside the code document any text needs to be left-aligned, I gate it text-align:left.

2

This one is similar to the above example. Let's say that the sentence starts with LTR1 and the above example content comes after, like this: LTR1 RTL1 LTR2 RTL2. This is the example text:

<body>
  Hello سلام babakfp خوبی؟
</body>

This is what it currently looks like:

Note: you can read its text content above.

This is what it should look like:

Note: you can read its text content below.

The code below is altered. Just because I fixed it this way, it doesn't mean that vsCode needs to fix it this way too. Because it's not correct to fix it this way.

<body>
  Hello خوبی؟ babakfp سلام
</body>

You can replicate it with pure HTML and CSS:

LTR1 RTL1 LTR2 RTL2
(LTR1) (RTL1 LTR2 RTL2)
(LTR1{Hello}) (RTL1{سلام} LTR2{babakfp} RTL2{خوبی؟})
<div style="text-align:left; direction:ltr">
  <span>Hello</span>
  <span style="direction:rtl; display:inline-block">سلام babakfp خوبی؟</span>
</div>

Because it starts with an LTR letter, I gave the wrapper direction:ltr. The first code fragment is in LTR (I could give it direction:ltr and text-align:left, but it's not necessary because its parent already has that style). The second code fragment starts with an RTL letter, so I gave it direction:rtl (and display:inline-block so the direction works property).

You can copy-paste the code in the dev tools (Elements tab) and test it there. If you remove display:inline-block, you will see it turs out to look like how vsCode displays the text, because then direction:rtl stops working.


Lets say you are writing a documentation in RTL in a .md file.

Screenshot 2022-05-30 072133-min-min-min

Example HTML code:

<div style="direction: rtl;text-align: right;">
  <span>سلام خوبی؟</span>
  <span style="direction: ltr;display: inline-block;">[Text here](https://example.com)</span>
</div>

Well, You can also write HTML in .md files, shouldon't .md files primarily start from left to right? No.

Keyboard shortcut

We need a keyboard shortcut to be able to change the alignment of a text. This shortcut needs to be easy to use and remember, at the same time it shouldn't be accidentally clickable.

When RTL combined with LTR in a file

Look at how RTL works along with LTR in a file:

171274981-5e7c52b9-6465-48f1-9658-900ebca0b4ec

Line 1 is overflowing and it created a scrollbar. (Ignore line 3 which is wrapped for some reason). Line 4 is touching the right side of the editor and it doesn't follow the right side of the longest line in the document (basically, it doesn't overflow).

@sarmadka
Copy link

sarmadka commented May 29, 2022

This statement is wrong: "The text needs to be left-aligned no matter what."
There are cases where you need the text to be right aligned. For example, editing an MD file or other sorts of documentation. Also editing an HTML document with big blocks of RTL text that would be easier to edit if they are right aligned, etc.

@babakfp
Copy link
Author

babakfp commented May 30, 2022

This statement is wrong: "The text needs to be left-aligned no matter what."
There are cases where you need the text to be right aligned. For example, editing an MD file or other sorts of documentation.

I made some changes.

Also editing an HTML document with big blocks of RTL text that would be easier to edit if they are right aligned, etc.

What do you mean? Do you mean the content of a .html file to be right-aligned? If so, it's not correct because the language of HTML is English(LTR). So it must be left-aligned. (Maybe I understand it wrong🤷‍♂️).

@sarmadka
Copy link

sarmadka commented May 30, 2022

What do you mean? Do you mean the content of a .html file to be right-aligned?

Partially, yes. It might sound odd, but when you see it in an editor that handles RTL correctly it'll make sense. Take a look at how GEdit handles it:
image

However, GEdit's problem is that it determines direction based on the first character in the line, which works for the most part but there are few edge cases where you wish you had more control. The ideal solution would be to have the editor respect the RTL/LTR Unicode markers and give the user an easy way (keyboard shortcut, buttons, etc) to easily and quickly insert those markers. GEdit does indeed respect those markers, but it doesn't have an easy way to enter them (you'll have to manually enter the unicode). Would be good if the proposal for VSCode would be to respect the markers and enable an easy way to enter them.

@sarmadka
Copy link

sarmadka commented May 30, 2022

Also, thanks for spending the time to write this. Hopefully it'll help move this forward.

@babakfp
Copy link
Author

babakfp commented May 31, 2022

What do you mean? Do you mean the content of a .html file to be right-aligned?

Partially, yes. It might sound odd, but when you see it in an editor that handles RTL correctly it'll make sense. Take a look at how GEdit handles it: image

However, GEdit's problem is that it determines direction based on the first character in the line, which works for the most part but there are few edge cases where you wish you had more control. The ideal solution would be to have the editor respect the RTL/LTR Unicode markers and give the user an easy way (keyboard shortcut, buttons, etc) to easily and quickly insert those markers. GEdit does indeed respect those markers, but it doesn't have an easy way to enter them (you'll have to manually enter the unicode). Would be good if the proposal for VSCode would be to respect the markers and enable an easy way to enter them.

Ok so, I misunderstood you. I thought you want to make the whole HTML document aligned to the right. But, what you really meant, makes sense. I was working on a project where I wrote 1 or 2 paragraphs in Farsi(RTL) and It wasn't a great experience (because the text was aligned to the left). So, I think having a keyboard shortcut to change the alignment of the text is a great idea. Something like this is available in Telegram(a messaging app, I'm using the Windows version). Telegram has this problem that sometimes I accidentally activate it! So, vsCode needs to create a shortcut that you can't use by accident, and also it needs to be easy to use and remember. About the scrollbar, I think what Gedit does here is a good idea:

Screenshot 2022-05-31 125534-min

Line 1 is overflowing and it created a scrollbar. (Ignore line 3 which is wrapped for some reason). Line 4 is touching the right side of the editor and it doesn't follow the right side of the longest line in the document.

Also, thanks for spending the time to write this. Hopefully it'll help move this forward.

🙂👍

@zspitz
Copy link

zspitz commented Jun 2, 2022

I haven't had a chance to look this over, but I think there needs to be a common way to express RTL issues across languages. I suggest following the Unicode bidi algorithm page in this:

In this and the following examples, case is used to indicate different implicit character types for those unfamiliar with right-to-left letters. Uppercase letters stand for right-to-left characters (such as Arabic or Hebrew), and lowercase letters stand for left-to-right characters (such as English or Russian).

So, this example:

image

<body>
   Hello سلام babakfp خوبی؟
</body>

could be expressed as follows:

Languages English/Farsi
Text Hello سلام babakfp خوبی؟
Logical abcd ABCD efghijk EFGH?
Expected visual abcd ⸮HGFE efghijk DCBA
Actual visual abcd DCBA efghik ⸮HGFE
Notes Farsi reverses the question mark in RTL contexts.

@amiria703
Copy link

amiria703 commented Jun 3, 2022

Thanks for writing this babak, I hope that this will make sense in supporting RTL not in vscode but in overall.
Due to these issues and some other major and minor problems I had with vscode, I switched to Jetbrains products, one of its features for mixed RTL-LTR content is you can choose that the text should be left-aligned or right-aligned, I think It'd be a good solution also for vscode.
Sorry for my bad English, Hope you understand.

@babakfp
Copy link
Author

babakfp commented Jun 3, 2022

I haven't had a chance to look this over, but I think there needs to be a common way to express RTL issues across languages. I suggest following the Unicode bidi algorithm page in this:

Thanks. My brain isn't capable of understanding this article, but I'm sure if someone from the vsCode team decides to have a look at this proposal, they will check it out.

@babakfp
Copy link
Author

babakfp commented Jun 3, 2022

Thanks for writing this babak, I hope that this will make sense in supporting RTL not in vscode but in overall. Due to these issues and some other major and minor problems I had with vscode, I switched to Jetbrains products, one of its features for mixed RTL-LTR content is you can choose that the text should be left-aligned or right-aligned, I think It'd be a good solution also for vscode. Sorry for my bad English, Hope you understand.

Hey. I'll definitely check it out. I heard many good things about JetBrains products, but I never really used them🤷‍♂️. If I like it, I'll use it too.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment