Skip to content

Instantly share code, notes, and snippets.

@babakfp
Last active October 21, 2024 12:13
Show Gist options
  • Save babakfp/8a82deca31cae0b5b1477f3453f507b3 to your computer and use it in GitHub Desktop.
Save babakfp/8a82deca31cae0b5b1477f3453f507b3 to your computer and use it in GitHub Desktop.
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).

@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

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

@MuhammadKhizar7
Copy link

I think adding dir="auto" on the text line will do the job of course with one problem which is the start text which determines the direction of text, but I think adding dir="auto" every line might solve this issue instead of complete doc

<div dir="auto"> یہ ایک اردو تحریر ھے</div>
یہ ایک اردو تحریر ھے
<div dir="auto"> This is written in english </div>
This is written in english

@andjc
Copy link

andjc commented Sep 29, 2022

In the Basics section:

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.

This isn't exactly true, although in most RTL writing systems (scripts), numbers are rendered from left to write, at least one RTL writing system/script has numbers that also flow RTL. For example the number 𞣎𞣒𞣉𞣑𞣉, which flows from the right to the left.

@babakfp
Copy link
Author

babakfp commented Sep 30, 2022

In the Basics section:

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.

This isn't exactly true, although in most RTL writing systems (scripts), numbers are rendered from left to write, at least one RTL writing system/script has numbers that also flow RTL. For example the number 𞣎𞣒𞣉𞣑𞣉, which flows from the right to the left.

Screenshot 2022-09-29 204432

Send a screenshot instead.

@sarmadka
Copy link

In the Basics section:

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.

This isn't exactly true, although in most RTL writing systems (scripts), numbers are rendered from left to write, at least one RTL writing system/script has numbers that also flow RTL. For example the number 𞣎𞣒𞣉𞣑𞣉, which flows from the right to the left.

Screenshot 2022-09-29 204432

Send a screenshot instead.

Looks like something is wrong with your system's fonts

image

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