monoid icon indicating copy to clipboard operation
monoid copied to clipboard

Add ligatures

Open larsenwork opened this issue 9 years ago • 94 comments

Like e.g. https://github.com/tonsky/FiraCode

I'm still trying to figure out how best to solve it technically though

larsenwork avatar Jun 04 '15 13:06 larsenwork

So I think I've figured out how to do some of it. I'm trying to keep this a strictly monospaced font so hack job like combining two characters in to one wider character isn't kosher. Instead I'm thinking about using contextual substitution like this

feature calt {
  sub less hyphen' by ligaarrowleft;
} calt;
feature calt {
  sub less' ligaarrowleft by space;
} calt;

so that all glyphs still have the same width.

screen shot 2015-06-06 at 07 53 14

larsenwork avatar Jun 06 '15 05:06 larsenwork

monoidvsroboto

I've added these so far but having some issues with "calt" and Atom (editor I'm primarily using)

larsenwork avatar Jun 13 '15 22:06 larsenwork

I wonder if this is going to work in Visual Studio on Windows. Pragmata Pro and Hasklig ligatures seem to work there. In case they work, it would be great to have =>, // and /// for C# in addition to the ones above. Also, for F# (which is cross-platform) |>, <|, <||, <||| (* *), (| |), ::, :>, :=, <<<, >>>, [| |], [< >] etc. would be great. The full list: https://msdn.microsoft.com/en-us/library/dd233228.aspx

glebd avatar Jul 08 '15 01:07 glebd

@glebd can you check the latest version and see if it works on windows with these ligatures https://github.com/larsenwork/monoid/issues/25#issuecomment-111757957

larsenwork avatar Jul 15 '15 15:07 larsenwork

@glebd should => be an arrow like this: ⇒ or what is it used for? I have added // and /// (not pushed yet)

larsenwork avatar Jul 19 '15 05:07 larsenwork

Yes, I think so: => turns into ⇒ across 2 character widths. Thanks!

glebd avatar Jul 19 '15 13:07 glebd

@glebd cheers, did you get to test it on Windows?

larsenwork avatar Jul 19 '15 16:07 larsenwork

Not yet, will do next week

glebd avatar Jul 19 '15 16:07 glebd

:+1:

larsenwork avatar Jul 19 '15 19:07 larsenwork

screen shot 2015-07-19 at 22 26 04

larsenwork avatar Jul 19 '15 20:07 larsenwork

Compared to screen shot 2015-07-19 at 22 33 00

larsenwork avatar Jul 19 '15 20:07 larsenwork

Niiice

glebd avatar Jul 19 '15 20:07 glebd

@glebd I don't know haskell but is this something I should fix (comment about >→) https://news.ycombinator.com/item?id=9718099

And are there other similar issues?

larsenwork avatar Jul 20 '15 12:07 larsenwork

These are lovely!

I'm writing in a language where => and <= are both arrows, and at the moment it's a bit confusing as:

  • <= gets turned into less than/equal to
  • => doesn't seem to be ligatured
  • <- and <-- are correctly ligatured into arrows

Unfortunately, some of this is language and context dependent. For me there are times when <= is an arrow, and times when it is less that or equal to.

Could the download page (which is great, btw) allow a choice of ligatures as well as just on and off?

mo-seph avatar Jul 24 '15 08:07 mo-seph

@mo-seph cheers, => should be a ligature. What editor + OS are you using? screen shot 2015-07-24 at 10 40 30

<= vs ≤ could be a choice, the easiest (and best thing) would be to add it as an stylistic alternate, but that only works if your editor allows you to add your own stylesheet.

It could also be a downloadable choice but problem is we're currently generating all possible versions (current 3200) so adding it as downloadable choice would require it replacing one of the existing options.

larsenwork avatar Jul 24 '15 08:07 larsenwork

What language uses <= as arrow?

larsenwork avatar Jul 24 '15 08:07 larsenwork

An obscure one ;) It's called LCC, and represents messages sent to ( => ) and from ( <= ) agents (https://bitbucket.org/mo_seph/scalsc/wiki/Representing%20Interactions)

Here's a screenshot, using Eclipse on OSX 10.10 screen shot 2015-07-24 at 09 50 19

The <= on line 7 has been changed to leq as expected, the => on line 8 is un-liga'd, and the <- on line 9 is great ;)

(BTW, these arrows are clearly an edge case, and I suspect your approach works for 99% of the time ;) )

mo-seph avatar Jul 24 '15 08:07 mo-seph

@mo-seph => should be a ligature. What editor + OS are you using?

larsenwork avatar Jul 24 '15 08:07 larsenwork

Eclipse, OSX 10.10.4

mo-seph avatar Jul 24 '15 09:07 mo-seph

Ligatures are not working here :( (IntelliJ OSX 10.10.4)

flaviotruzzi avatar Jul 24 '15 21:07 flaviotruzzi

@larsenwork ~~It seems like Java doesn't support ligatures, at least not on OS X. Eclipse and IntelliJ are both Java-based.~~

EDIT: Turns out that IntelliJ's rendering engine doesn't support ligatures, Eclipse does in fact.

chase avatar Jul 24 '15 21:07 chase

Crud, I guess that holds true for PHPStorm 9 as well (built on Java).

mikebronner avatar Jul 24 '15 21:07 mikebronner

@mikebronner Since it is a derivative of IntelliJ, I'd say that's safe to assume.

chase avatar Jul 24 '15 21:07 chase

@mikebronner @chase Eclipse is supporting ligatures, just checked. IntelliJ doesn't - they've changed rendering engine. They are working at this. SublimeText too.

rkurbatov avatar Jul 24 '15 22:07 rkurbatov

@rkurbatov Thanks for looking into it!

chase avatar Jul 24 '15 23:07 chase

Please add your findings to the readme #67

larsenwork avatar Jul 25 '15 00:07 larsenwork

@glebd About the // ligature: would it make sense to only activate it if it's preceded/followed by a "space" ?

I want to turn it off for at least http:// which currently look a bit odd with the ligature

larsenwork avatar Jul 25 '15 00:07 larsenwork

Not really, as C-like languages use // for comments which may start at the beginning of the line.

glebd avatar Jul 25 '15 00:07 glebd

@glebd space after?

larsenwork avatar Jul 25 '15 00:07 larsenwork

Hmm, some people don't leave space after //comments.

glebd avatar Jul 25 '15 00:07 glebd

Hmm...they should, looks messy:) Well I can easily "filter out" http:// so I'll just take that approach instead.

larsenwork avatar Jul 25 '15 00:07 larsenwork

Cool.

glebd avatar Jul 25 '15 00:07 glebd

suggested/requested ligatures (mostly from Java and Groovy, see full list here ) ++ (maybe same as with == and --) operators += -= *= /= %= ** **= =~ ==~ <=> "Spaceship-operator", currently this is broken into <= and > for comments (without the spaces) / * , / * * , */ (similar to //) also cool would be ?: ?. !! *. ..<

plgruener avatar Jul 27 '15 10:07 plgruener

One could do the same as == and -- for ++ but not sure. Plus signs have a vertical line making it easy to tell them apart so not sure the ligature is necessary screen shot 2015-07-27 at 12 26 12 Spaceship: We could go crazy and do something like this screen shot 2015-07-27 at 12 25 33 but I'm more inclined to do something like this screen shot 2015-07-27 at 12 28 34 As for the operators we could do narrower +-= signs but not sure it's needed screen shot 2015-07-27 at 12 32 23

larsenwork avatar Jul 27 '15 10:07 larsenwork

Spaceship: that indeed looks crazy somehow :D But I'd also go with the (sane) second version. ++ and ** : right, probably not needed. But it looked slightly strange because all others (==, --) have these little gaps.

Same goes for *= %= etc. Not really necessary, but I think a little gap (narrower = signs) would make it prettier (just my personal opinion, you're the font expert ;)

plgruener avatar Jul 27 '15 11:07 plgruener

Been looking at it and I might just change the default =+- to the narrower versions

larsenwork avatar Jul 27 '15 11:07 larsenwork

So it'd be like so: screen shot 2015-07-27 at 13 49 54

larsenwork avatar Jul 27 '15 11:07 larsenwork

Well, that'd save you some work with the ligatures. However, I don't quite like that asymmetrical plus sign, looks a bit odd to me. I don't know about your build process, but maybe you can offer an alternate version with narrow +-= signs, so some more people can test it (at different sizes).

plgruener avatar Jul 27 '15 12:07 plgruener

Yeah...I actually like the narrower equalsign as default and then keeping the + and - unchanged but have the ligature for --

screen shot 2015-07-27 at 14 52 53 screen shot 2015-07-27 at 14 54 27 screen shot 2015-07-27 at 14 55 31

larsenwork avatar Jul 27 '15 12:07 larsenwork

Yes, sounds like a good solution. Do the unligatured versions of >= => etc. still look good with the narrow equal-sign?

plgruener avatar Jul 27 '15 13:07 plgruener

@plgruener I think so - they look like the spaceship (3rd pic): https://github.com/larsenwork/monoid/issues/25#issuecomment-125159686

larsenwork avatar Jul 27 '15 13:07 larsenwork

Ah right. Looks great. (Except the -= has some unfamiliar proportions, but one should get accustomed to it pretty fast.)

plgruener avatar Jul 27 '15 13:07 plgruener

The - in -= could be a hybrid between - and the - in -- screen shot 2015-07-27 at 16 30 26

larsenwork avatar Jul 27 '15 14:07 larsenwork

Moving the first asterisk to the left and the second up and to the right to make more room for the comment screen shot 2015-07-28 at 01 24 55

larsenwork avatar Jul 27 '15 23:07 larsenwork

@plgruener what are ?: ?. !! *. ..< used for? I need some context examples to see what ligatures (if any) will be fitting.

larsenwork avatar Jul 27 '15 23:07 larsenwork

Keep in mind one often formats comments like this:

/**
 *
 */

So I don't know about left/right shifting the asterisk…

plgruener avatar Jul 27 '15 23:07 plgruener

It will look a bit weird but the gain in /Comment/ cases should be worth it.

larsenwork avatar Jul 27 '15 23:07 larsenwork

Well, actually comments like /* ... */ in one line are very discouraged (at least in Java & co.). But we could try it first.

plgruener avatar Jul 27 '15 23:07 plgruener

In css they're everywhere :)

larsenwork avatar Jul 27 '15 23:07 larsenwork

I actually think it works ok:

screen shot 2015-07-28 at 01 57 18

larsenwork avatar Jul 27 '15 23:07 larsenwork

the !! is a bash alias for previous command, it stands alone. And there also seems to be others with ! and a following char, like !? or `!#' – but I doubt they're often used, so it's not urgent. (Although sometimes I comment things with "what's that for?!" ;) )

Examples for the others:

def name = person?.name (assign name only if person is not null) def fun = str.&toUpperCase (used to store a method pointer) def makes = cars*.make (apply make to all elements of the cars-collection) def range = 0..<5 numbers 0 to 5 exclusively (in contrast to 0..5 which are 0 to 5 inclusively)

Most of them look ok without ligatures, except for ..<

plgruener avatar Jul 28 '15 00:07 plgruener

There are also tempting syntaxes that use {!! some command here !!} and {{ some command here }} and {{{ some command here }}}. Would these be suited for ligatures as well?

mikebronner avatar Jul 28 '15 01:07 mikebronner

@plgruener screen shot 2015-07-28 at 03 13 33 screen shot 2015-07-28 at 03 12 03 screen shot 2015-07-28 at 02 43 43

Diacritics are almost done screen shot 2015-07-28 at 03 15 33

@mikebronner I think they could be improved...stay tuned :smile:

larsenwork avatar Jul 28 '15 01:07 larsenwork

Hmm, the same would apply for any amount of opening/closing brackets. I mean ()))) is also not uncommon, as well as ({}) or something. I understand your approach of defining new ligatures is to assign a special sequence of characters to a new one. This wouldn't be suited for "any amount of brackets", would it?

plgruener avatar Jul 28 '15 08:07 plgruener

@larsenwork subtle differences, but looks good to me. Did you alter the position of the ..< ?

plgruener avatar Jul 28 '15 08:07 plgruener

I was looking at Haskell-ligatures (not using it, but these folks seem to like ligatures), and I think the following need fixing: =:= center colon between the equalsigns, :: squeeze them a bit together, <== ==> should render to long double arrows like =>, >>= =<< are broken by the existing <= ligatures

evtl also <<< , >>> , -< , >- , -<< , >>-

plgruener avatar Jul 28 '15 09:07 plgruener

@plgruener any-amount: ligatures are only really suited for 2-3(-4) characters. I'm currently building an update that fixes e.g. &&& (currently broken) ..< problem was ".." got recognised first and then left the "<" hanging. =:= can be centred although the : will not be as sharp. Seems like a good tradeoff though. <== ==> >>= =<< should be an easy fix

larsenwork avatar Jul 28 '15 09:07 larsenwork

screen shot 2015-07-29 at 00 29 32

larsenwork avatar Jul 28 '15 22:07 larsenwork

@Fequois I've done the same as with hyphens (make them narrower when more than one) so it's easier to see how many underscores there are

screen shot 2015-07-29 at 16 38 48

larsenwork avatar Jul 29 '15 14:07 larsenwork

compared to screen shot 2015-07-29 at 16 39 57

larsenwork avatar Jul 29 '15 14:07 larsenwork

nah...can be better, two sec...

larsenwork avatar Jul 29 '15 14:07 larsenwork

Hahaha, love your workflow. <3

waits for the next set of images

Fequois avatar Jul 29 '15 14:07 Fequois

screen shot 2015-07-29 at 16 50 02

larsenwork avatar Jul 29 '15 14:07 larsenwork

yep, looks clearer now. so this is for any number of underscores (>1) ?

plgruener avatar Jul 29 '15 14:07 plgruener

@plgruener yep but n=2 is a special case screen shot 2015-07-29 at 16 52 39

larsenwork avatar Jul 29 '15 14:07 larsenwork

@larsenwork I like it, too. Very nice.

Fequois avatar Jul 29 '15 14:07 Fequois

hmm, same maybe for ~~ ?

plgruener avatar Jul 29 '15 14:07 plgruener

Thanks, up next is perfect shrug ¯\_(ツ)_/¯ ligature...just because...

larsenwork avatar Jul 29 '15 15:07 larsenwork

@plgruener I think the ~ will get too condensed + it looks ok now because it's not "end-to-end" so it's easier to tell them apart if there are many

larsenwork avatar Jul 29 '15 15:07 larsenwork

https://twitter.com/larsenwork/status/626424006174973952

larsenwork avatar Jul 29 '15 16:07 larsenwork

Yeah, priorities! :+1:

@ ~~ I just wanted to throw in the idea.

plgruener avatar Jul 29 '15 17:07 plgruener

I don't know is this is the right issue but I'm using monoid to develop typescript and the ligatures for the operator !== seems a little odd.

ts

I don't know if is even possible to do something about it, but would be really nice if this could change :)

BTW, awesome font to develop :)

cabralRodrigo avatar Jul 30 '15 14:07 cabralRodrigo

It's how it's designed "notequal + type" "≠="

Any other ideas as to how it could/should look?

larsenwork avatar Jul 30 '15 14:07 larsenwork

I really don't have any ideas, maybe something like this: n

But I can see that this can be a little confusing with the current !=.

And, if this is this way by design I can get used to it.

cabralRodrigo avatar Jul 30 '15 14:07 cabralRodrigo

@cabralRodrigo yep, I deliberately didn't do like e.g. fira mono because I don't want there to be any confusion between !== and !=

larsenwork avatar Aug 01 '15 08:08 larsenwork

@larsenwork Thanks for your time anyway :)

cabralRodrigo avatar Aug 02 '15 19:08 cabralRodrigo

In gEdit ">==>" is rendered like a " ==>" (with leading space) : not that I know of programming language that uses it.

luben avatar Aug 04 '15 20:08 luben

Also "foo <- bar" is rendered as "foo - bar"

luben avatar Aug 17 '15 03:08 luben

Correttion on the previous comment, regarding "foo <- bar". It renders incorrectly with the Retina face but renders correctly with the Regular one. ">==>" renders incorrecly in both of them

luben avatar Aug 22 '15 18:08 luben

@luben cheers, "<-" is fixed in next update Because of my approach (using contextual alternates and not conventional ligatures (read why in the medium articles)) random strings of "<", "=" and ">" will render with errors...not sure how to fix this. Other than to include specific solutions for those combinations used by programming languages (e.g. <==>)

larsenwork avatar Aug 26 '15 13:08 larsenwork

@larsenwork The !== ligature is very confusing to me and was the one thing that stood out to me as something that makes code less readable. To me, and I'm sure many others, it reads pretty much like a broken form of regular "not equals" (because it just has two regular equal signs).

Semantically, identity equals is a three line equals sign (≡) and with a strikethrough it would be equivalent to !==. I would do just like Fira Code does it, which is immediately clear to me:

screen shot 2015-10-29 at 9 41 08 pm

If keeping the current one is something you feel strongly about, could the more semantically correct version perhaps be available as an optional font feature?

blixt avatar Oct 30 '15 01:10 blixt

I agree with @blixt. The first time I saw that !== ligature, I thought it is broken. It is look weird in such perfect font. Double m also confusing me.

in-in avatar Dec 08 '15 20:12 in-in

@blixt a good idea, I will look into it this christmas :+1:

larsenwork avatar Dec 09 '15 14:12 larsenwork

@blixt @in-in I have a problem with the "==" ligature though...it's aesthetically doing what e.g. Fira Code does and merge the two equal signs but then it's only by length that you can distinguish it from a single equal sign...not sure what's the optimal solution

larsenwork avatar Dec 10 '15 20:12 larsenwork

screen shot 2015-12-10 at 22 03 45

larsenwork avatar Dec 10 '15 21:12 larsenwork

You're right, it looks a bit alike. I tried your sample in editor (Fira Code). 2 You can see different height between lines.

in-in avatar Dec 10 '15 21:12 in-in

@larsenwork:

I'm trying to keep this a strictly monospaced font so hack job like combining two characters in to one wider character isn't kosher. Instead I'm thinking about using contextual substitution like this

A belated note of thanks for this idea. That's how I did it in https://github.com/marnen/borg-sans-mono, and I think your work was where I found the technique.

marnen avatar Jan 24 '17 21:01 marnen

@marnen cheers, I've recently changed my opinion about this a bit though so I think I'll make more ligatures that span multiple letters 🤷‍♂️ 😉

larsenwork avatar Feb 18 '17 17:02 larsenwork

@larsenwork Does that mean that you're now doing something like this?

sub a_b.left_half b' by a_b.right_half
sub a' b by a_b.left_half

(If you're curious, here's what I did: https://github.com/marnen/borg-sans-mono/blob/master/BorgSansMono.fea.)

marnen avatar Feb 20 '17 19:02 marnen

@marnen essentially yeah, because more and more editors and terminals support this kind of ligatures now (didn't do that when I created Monoid)

Thanks for the link btw 👍

larsenwork avatar Feb 20 '17 21:02 larsenwork

Right. I don't especially like the idea of the left and right halves being separate glyphs in the font, so I probably wouldn't do it that way unless there were some overwhelming advantage.

marnen avatar Feb 20 '17 21:02 marnen

@marnen they actually aren't in Monoid either — if it's a ligature that spans three letters then the first two are substituted to empty letters and the third one has the entire ligature. But it's complicated to maintain so normal ligatures is obviously they way to go now that editors support it.

larsenwork avatar Feb 20 '17 21:02 larsenwork

Does that work in a monospaced font, though? I wouldn't expect it to, at least not with proper caret positioning, hence the space trick that I use in Borg Sans.

marnen avatar Feb 20 '17 21:02 marnen

that's how all my "ligatures" have been created so far but it's annoying having to substitute with 3 characters instead of just one.

larsenwork avatar Feb 21 '17 07:02 larsenwork