Hasklig
Hasklig copied to clipboard
works for emacs
Hi, just noticed that your readme does not list emacs as an editor your font works with. I can confirm that it works very well, stable and with no problems at all, for emacs 25.2.1.
thanks, Stephen.
Ps. For Haskell, I love your '***'. I wonder could you do something similar for '&&&' ?
Does that mean emacs has ligature support now? What version of hasklig did you install?
Emacs has ligature support. I'm using Emacs 25.2.1, using the emacs-mac port for mac. Note that I have not got ligatures working for emacs in a terminal shell, so can't comment on that.
I've been using Hasklig for about 6 months now. I did initially have some problems, and I recall some reports of occasional hangs etc. from mid 2016, but I can happily report that for about 4 months I've had absolutely no problems. Can't say for certain whether it was a problem with ligatures or something else - stability just improved vastly.
The Hasklig font files sugest that they were created December 31st 2015. I think I downloaded them at some point about 6 months ago.
It does indeed work for Emacs, with a little work.
We first define a function that can work around this problem which caused the multi-column symbols to have a width of only one column and being moved to the left.
Then my-ligature-list
turns a list of ligature strings to an alist with the correct code-points as values.
Finally we combine all that, starting from code point #Xe100
and set up prettify-symbols-mode
correctly for haskell-mode
.
(defun my-correct-symbol-bounds (pretty-alist)
"Prepend a TAB character to each symbol in this alist,
this way compose-region called by prettify-symbols-mode
will use the correct width of the symbols
instead of the width measured by char-width."
(mapcar (lambda (el)
(setcdr el (string ?\t (cdr el)))
el)
pretty-alist))
(defun my-ligature-list (ligatures codepoint-start)
"Create an alist of strings to replace with
codepoints starting from codepoint-start."
(let ((codepoints (-iterate '1+ codepoint-start (length ligatures))))
(-zip-pair ligatures codepoints)))
; list can be found at https://github.com/i-tu/Hasklig/blob/master/GlyphOrderAndAliasDB#L1588
(setq my-hasklig-ligatures
(let* ((ligs '("&&" "***" "*>" "\\\\" "||" "|>" "::"
"==" "===" "==>" "=>" "=<<" "!!" ">>"
">>=" ">>>" ">>-" ">-" "->" "-<" "-<<"
"<*" "<*>" "<|" "<|>" "<$>" "<>" "<-"
"<<" "<<<" "<+>" ".." "..." "++" "+++"
"/=" ":::" ">=>" "->>" "<=>" "<=<" "<->")))
(my-correct-symbol-bounds (my-ligature-list ligs #Xe100))))
;; nice glyphs for haskell with hasklig
(defun my-set-hasklig-ligatures ()
"Add hasklig ligatures for use with prettify-symbols-mode."
(setq prettify-symbols-alist
(append my-hasklig-ligatures prettify-symbols-alist))
(prettify-symbols-mode))
(add-hook 'haskell-mode-hook 'my-set-hasklig-ligatures)
@Profpatsch The code fixes the ligatures but whenever emacs uses italic font all characters are somehow separated by two spaces...
@alexvorobiev I’ve basically given up on Emacs rendering. The two-space problem is a general Spacemacs problem that has existed for ages. No idea how it can be fixed.
I think I fixed the two-space problem by changing how we compose the region for prettify-symbols-alist
. I used the suggestion here and use spaces to compose instead of tabs. A symbol composure now looks like this
`("&&" . (?\s (Br . Bl) ?\s (Br . Br) ,(decode-char 'ucs #XE100)))
I am sure you could integrate it into your fancy function if it works for you. Works perfect for me
@CeleritasCelery Yeah, that’s an improvement over the code, since the width is a bit off with the leading tab solution.
The problem with too widely spaced italics is a different one. To be honest I haven’t seen that lately, so maybe it was fixed? @alexvorobiev do you still see that with a recent emacs and spacemacs config?
@Profpatsch I do not see any problems with italics in the current emacs (25.3.1 from Nix).
Here's a modification that adds padding based on the number of chars in the input sequence, so that alignment stays intact at the cost of extra whitespace. Basically I combined @CeleritasCelery's idea and @Profpatsch's.
Also, I've never written elisp before so the code is rather ugly. In particular, there has to be a builtin for replicate
but i wasn't able to find it.
(defun replicate (list num)
"Creates a list with `num` replicas of `list`"
(if (<= num 0) '() (append list (replicate list (- num 1)))))
(defun make-spaces (el)
(let ((space-width (string-width (car el))))
(append (replicate '(?\s (Br . Bl)) (- space-width 1))
'(?\s (Br . Br))
(list (decode-char 'ucs (cdr el))))))
(defun make-tabs (el) (string ?\t (cdr el)))
(defun my-correct-symbol-bounds (pretty-alist)
"Prepend a TAB character to each symbol in this alist,
this way compose-region called by prettify-symbols-mode
will use the correct width of the symbols
instead of the width measured by char-width."
;(let ((out (mapcar (lambda (el) (setcdr el (make-tabs el)) el) pretty-alist)))
(let ((out (mapcar (lambda (el) (setcdr el (make-spaces el)) el) pretty-alist)))
(progn (print out) out)))
rohit507 [email protected] čálii:
Also, I've never written elisp before so the code is rather ugly. In particular, there has to be a builtin for
replicate
but i wasn't able to find it.
This should do it:
(make-list (- space-width 1) '(?\s (Br . Bl)))
(there's also make-string, if you ever need to do that)
Note also that elisp doesn't have tail-call optimisation, cf. the recursion.
I took the code from here and put it into a minor mode. It works well on emacs 26.
https://github.com/minad/hasklig-mode/blob/master/hasklig-mode.el
@Profpatsch can you specify where the code you provided above should be placed. I.e. for a total emacs newbie... Would be much appreciated.
can you specify where the code you provided above should be placed.
In your Emacs configuration, that is ~/.emacs
if you use plain Emacs and ~/.spacemacs
if you use Spacemacs.
I don't know how spac/emacs works, but I got it to work. This is with emacs-plus, on a mac, using spacemacs. Some steps might be redundant, or plain mistakes. What I did:
- Downloaded and installed the font.
- Copied this https://github.com/minad/hasklig-mode/blob/master/hasklig-mode.el file to
~/.elisp/
- Went to ~/.spacemacs file (SPC f e d) and added this line:
(push "~/.elisp/" load-path)
- In the same config file changed the font to hasklig:
dotspacemacs-default-font '("Hasklig"
- In the same file, changed the user config function like this:
(defun dotspacemacs/user-config ()
(use-package hasklig-mode
:hook (haskell-mode))
)
- Reloaded, and worked as expected.
I also have haskell
in the dotspacemacs-configuration-layers'(
function, which is probably necessary for this config to work.
It should definitively be written in the README that hasklig-mode
makes it easy to support Hasklig in Emacs.