Open angerman opened 9 years ago
The pictures you saw were from a modification of Haskell-font-lock (part of Haskell-mode). It works by assigning the ligatures custom unicode code points and substituting to them. (ie. /= to slash_equals) This is not a complete solution as it messes with the font advancement in the console and there's some funny rendering issues in GUI emacs.
As a solution, I'm thinking of splitting all the symbols up in one-character-width sections, assigning all of them unicode points and use something like haskell-font-lock to substitute ligatures to that. (ie. /= to first_slash_equals second_slash_equals)
Chopping up the symbols takes a lot of time and would have to be redone for all changes in each weight, so I've been looking into scripting this in some way. At the same time, I've been distracted by trying to graduate and progress has stalled.
My emacs lisp skills are limited, so if you or some one else can write the, emacs side of things, perhaps so that people can load it up independently of haskell-mode, that would be great!
..also if someone knows how to script Fontlab, that help is much appreciated as well :)
So if I understand this right, the proper solution would be emacs ligature support. Such that fi
would be turned into fi
and likewise ->
would be turned into the proper right arrow ligature, which the font would provide, right?
Because emacs lacks ligature support, this whole approach does not work (yet). A solution you tried was to replace the "to be ligatures" with unicode code points substituting the ligatures. Which does not work due to the font handling in emacs (which to me sounds like a bug in emacs).
And lastly you are proposing that the solution could be chopping up the ligatures glyphs into double (or more) characters to be displayed.
How Editing with ligatures works makes kinda sense to me (you are breaking apart the ligature anyway), with the unicode substitution, that would have to work similar to the current symbols approach, while the complely broken apart code points would probably have to work similarly as well.
Do you have any research on the ligature handling in emacs? Or is that something that should be researched in detail, if it's lack of interest by the community or strong technical difficulties supporting that in emacs?
Otherwise maybe one can fix the second approach?
So if I understand this right, the proper solution would be emacs ligature support. Such that fi would be turned into fi and likewise -> would be turned into the proper right arrow ligature, which the font would provide, right?
Yes, the proper solution absolutely would be proper support for OpenType ligatures, but it just simply isn't a high priority for most.
A solution you tried was to replace the "to be ligatures" with unicode code points substituting the ligatures. Which does not work due to the font handling in emacs (which to me sounds like a bug in emacs).
Well, it pretty much does work in GUI emacs with Hasklig 0.5 and the script I linked, since there is support for variable-width characters. However, each ligature is treated as just one character once it substitutes. This means it's impossible to select half of a ligature once it's in place, and >>=
will be counted as only one character, not three. It's definitely manageable if you're not particular about this and you can start using it today.
The main reason to not settle for this solution is that by chopping the ligature in pieces it's possible to add support for editors that don't support ligatures or variable-width glyphs. In practice it would mean support for every implementation of emacs or vim, command-line or otherwise.
I'll give Hasklig 0.5 with the adjusted script a try. I will also try to understand the OpenType Ligature support issues with emacs better.
The main reason to not settle for this solution is that by chopping the ligature in pieces it's possible to add support for editors that don't support ligatures or variable-width glyphs. In practice it would mean support for every implementation of emacs or vim, command-line or otherwise.
In that light, the approach makes a lot of sense obviously. Thanks!
any news?
Any way I could contribute to help this go forward?
@ticviking Thanks for the offer! Making the functionality in the gist I mentioned above available in either haskell-mode or as a standalone emacs module would probably be the best way forward for emacs support.
(Chopping the characters into pieces proved to be a dead end.)
standalone emacs module would be great, so people could reuse it from clojure/other languages
I agree with @yawnt, standalone is definitely preferable.
Thanks for the direction.
I'll spend some time at lunch and see what turning that gist into a minor mode would take
any update on this one ? ^_^
mb this helps https://github.com/tonsky/FiraCode/wiki/Setting-up-Emacs
I posted a related question to Emacs StackExchange about a year ago. It's been the top unanswered question for a while now.
What would be needed for this to happen? Can it be done in ELISP or will it have to be in the Emacs codebase itself?
@Tritlo , see this gist, which shows how to augment haskell-font-lock.el
, part of emacs haskell-mode, to enable ligature support: https://gist.github.com/i-tu/3e835955d0db554d76b7#file-gistfile1-el-L112
What that script does is pattern match ligatures and then replace their representation (but not the text itself), with certain arbitrarily assigned unicode code points corresponding to the correct symbols.
If someone would recreate that functionality without haskell-mode, we would be taking tangible steps towards emacs support. There's some complications on the terminal under this scheme because of no support for variable-width fonts, but we would be making progress.
That being said, at this point the easiest way of getting ligatures on emacs is using a terminal which supports ligatures, such as OSX Terminal, Konsole or Black Screen, and using Hasklig 1.0 beta.
@i-tu Would you mind if I posted that gist as a comment to this StackExchange question? It would provide useful domain information.
Not at all @matthew-piziak , feel free :)
Is this version compatible with the latest haskell-font-lock.el
https://github.com/haskell/haskell-mode/blob/master/haskell-font-lock.el? I tried to replace just the definition of haskell-font-lock-symbols-alist
and got empty rectangles. I am using emacs on Windows with Hasklig 1.0 beta.
@alexvorobiev, It should be. I opened the otf file in a font editor to make sure the right unicode code points are there. I have no idea what would have changed between now and then.
Troubleshooting time.
A
, like so: (cons "++" (decode-char 'ucs #X0041))
. The text ++
should change into A
. If so, it's an issue in Hasklig (or the wrong font being loaded) and you can stop here.(decode-char 'ucs #XE100)
and we would need to narrow down further whether this is platform-specific or not. I don't really know Emacs, so someone who knows it better should be able to suggest something in this case, hopefully.Let me know what you find out.
@i-tu First of all, let me apologize for the confusion: it turned out my emacs configuration had a line which was re-setting the default font so I didn't use Hasklig at all! With the culprit removed I do see the ligatures but, unfortunately, each ligature gets "overtyped", it appears on top of the preceding character. For instance, if I have (<*>)
, the *
gets positioned on top of (
.
No worries @alexvorobiev, these things happen.
There's two important variables in how Hasklig is rendered on emacs right now.
Hasklig 0.9 and 1.0 have the same ligatures, but the difference, due to the substitution scheme in the font (opentype calt vs liga) is that in 0.9 correct width of the characters is reported, in 1.0 the last bounding box is defined around the last "character" of the ligature.
The reason for this is a bit obscure, so I won't go into it.
Versions of Hasklig up to 0.9 should look like this when substituted in the emacs terminal and GUI: https://twitter.com/voodoosoop/status/523783970920878080
Based on your description, I would imagine you are using Hasklig 1.0. It is possible to add the correctly bounded characters from 0.9 to 1.0, so you can use them in the GUI version. See if 0.9 works, and if so, we can add those and have a somewhat working version for the Emacs GUI!
The ligature from 0.9 will be treated in emacs entirely as one character, and that will likely annoy some. Additionally, this will not bring terminal support, in fact it will break any terminal support which otherwise would be working.
It may be possible to add some spaces when substituting the 1.0 glyph, in order to render everything correctly. Deletion of an added space should result in the ligature getting the corresponding character deleted from it. I don't know how hard this would be to do in emacs.
@i-tu I installed 0.9 and now have the opposite effect: in (<*>)
, the *
gets positioned on top of )
. I am using GUI Emacs in Windows 7.
Regarding emacs support, I can report that Hasklig works beautifully on a mac, using emacs-mac (eg. brew install emacs-mac) and intero.
Adding the following to you .emacs (apologies to elispers for this hack :) ) disables haskell-font-lock-symbols
in favour of Hasklig based rendering if you have Hasklig set as the default font.
(if (string-match-p (regexp-quote "Hasklig")
(aref (query-font (face-attribute 'default :font)) 0))
(setq haskell-font-lock-symbols nil)
(setq haskell-font-lock-symbols 'unicode))
I use the following to set my font, choosing Hasklig if I have it installed, followed by a descending list of preferred fonts:
(use-package cl-lib :ensure t)
(defun font-existsp (font)
"Check to see if the named FONT is available."
(if (null (x-list-fonts font))
nil t))
(defun font-avail (fonts)
"Finds the available fonts."
(cl-remove-if-not 'font-existsp fonts))
(defvar font-preferences
'( "Hasklig"
"Inconsolata"
"Source Code Pro"
"Fira Code"
"PragmataPro"))
(unless (eq window-system nil)
(let ((fonts (font-avail font-preferences)))
(unless (null fonts)
(progn
(set-face-attribute 'default nil :font (car fonts))
(set-face-attribute 'default nil :weight 'thin)))))
Thanks so much for your work on Hasklig.
The combination that's worked best for me is
emacs-mac
(mac-auto-operator-composition-mode)
in my init.elWithout that last step, it fails to render the ligatures. With Hasklig 0.9, emacs would treat a ligature as a single character, where with 1.0 it works just as expected.
See #84
I still have no idea how to get the Hasklig ligatures to work on Emacs for macOS.
For anyone who randomly found this like me, if you are using emacs within iTerm2 on a Mac, you can easily enable ligatures through in iTerm2 when selecting the font, and ligatures show up in emacs just fine:
On twitter a few images of hasklig and emacs are floating around. And it says here that emacs support is in progress. What is the current state? And is there a way to help?