tonsky / FiraCode

Free monospaced font with programming ligatures
SIL Open Font License 1.1
76.08k stars 3.07k forks source link

Is it possible to "locl" feature to provide different ligatures for different programming language? #76

Open be5invis opened 8 years ago

be5invis commented 8 years ago

I am just curious about the language tags in Opentype. Considering the implementation of Serbian Cyrillic variants, they are done in like this:

lookup loclSerbian {
    sub [cyrbe cyrghe cyrde cyrpe cyrte] by [cyrbe.serbian cyrghe.serbian cyrde.serbian cyrpe.serbian cyrte.serbian];
} loclSerbian;

feature locl {
    script cyrl;
        language SRB  exclude_dflt;
            lookup loclSerbian;
} locl;

so if some editor can provide "languages" for Opentype it is possible to use locl feature to provide different ligatures for different languages. This is necessary, for example, in Haskell and JavaScript, the combination /= has different meaning.

flying-sheep commented 8 years ago

maybe the better thing would be using generic font features, as locl seems to be about human languages 😜

your example and others mentioned in #13 could be fixed by using a editor with configurable font features (e.g. atom by using CSS font-feature-settings)

be5invis commented 8 years ago

@flying-sheep My concern is about the meaning of symbols. Given that /= has different meaning in JavaScript and Haskell, providing "localized" variants is necessary.

flying-sheep commented 8 years ago

exactly. my point was that i think this can be done without misusing localization features, and instead using stylistic alternatives (salt) or character variants (cv01-cv99) .

e.g. there could maybe be a stylistic alternative assigned to haskell that could be enabled in atom like this:

.haskell { font-feature-settings: "salt" 2; }
John-Colvin commented 8 years ago

There is one particularly important change necessary for C-based languages: The unary bitwise not operator: ~

a=~a; should definitely not be combined to use a symbol that means approx. equal.

D also has the operator ~= e.g. s1 ~= s2 appends s2 to s1, which again is no good respresented as approx. equal.

flying-sheep commented 8 years ago

i thought this font combines =\~ and not \~=?

/edit: ah ic combines both. hmm, yeah, then this is another valid use case.

DHowett commented 8 years ago

One could argue that a=~a is better solved not by a lack of ligatures but by the introduction of clarifying spacing (a = ~a). I do, however, agree in the general case–fairly few languages seem to use =~ or ~= for approximation, so binding them into an approximate equality ligature might not be the best choice.

MadcapJake commented 8 years ago

In Perl 6, ~= concatenates and assigns. For reference, Perl 6 has =~= or ≅ as approximately-equal operators (texas and unicode form, respectively). Until this ligature is changed, my language-perl6fe grammar will keep these two characters separate to prevent them from combining as it would be too similar to that builtin unicode operator (which is my hackish way of solving the ligature-per-language problem: optimizing the grammar to support certain ligatures and separate ones that don't "fit").

flying-sheep commented 8 years ago

so which languages do use it this way? if there are some, this is a use case for conditional ligature sets. if there aren’t (or only very obscure ones), we should drop the ~= ligature altogether or replace it with one that makes clear it’s an in-place assignment.

Pyrolistical commented 7 months ago

As an alternative, we could do language specific builds.

Editors like VS Code allow language specific fonts.

Combined with #1387, we should be able to make language specific builds which only enable ligatures that make sense for that language. This would also resolve any conflicts.

flying-sheep commented 7 months ago

Same applies to stylistic variants, see e.g. the “Code ligatures” header for monaspace (yeah, I know it’s an abomination that that page has no anchors to link to):

Code ligatures

Monaspace includes code ligatures for a broad variety of languages, organized into stylistic sets that you can enable or disable according to your preferences.

Each stylistic set is roughly designed around the needs of specific languages. For example, ss01 includes ligatures for character sequences commonly seen in JavaScript, and ss05 provides ligatures for operators in F#.

You can enable as many or as few of them as you like.

In addition to the eight stylistic sets, there are two additional utility sets:

calt (contextual alternates) activates ligatures that adjust the visual positioning of some character sequences without altering their shape or appearance. Activating this feature will also enable texture healing.

dlig (discretionary ligatures) activates a basic set of ligatures that are shared by many programming languages and frameworks — mostly sequences of repeating characters.

Visual Studio Code

Choose the stylistic sets you want to enable, and copy the following line into your settings.json:

"editor.fontLigatures": "'ss01', 'ss02', 'ss03', 'ss04', 'ss05', 'ss06', 'ss07', 'ss08', 'calt', 'dlig'",