Closed Profpatsch closed 3 weeks ago
Is there a reason why prettify-symbols-mode is not being used for this?
Probably not, no. But it looks awesome.
I'm not sure if that's the right solution here, as it looks like prettify-symbols-mode alters the number of characters per row, while the ligature rendering preserves that property. For instance, using FiraCode in Konsole would make "->" become an arrow but still take up two characters. Similarly, "::", ">>=", et al. conserve that many characters, keeping the spacing correct. However, if prettify-symbols-mode can keep the character count, then that works too.
So to install and use Fira code with spacemacs, does one follow the instructions for emacs from the fira code project site [1], or there is already some mechanism in spacemacs that can use fira code so that the user only needs to "helm xselect font" the Fira Code Retina? I would very much like to use Fira Code in Spacemacs, but am trying not to break anything. I am just coming from Vim, and know almost nothing about Lisp except what is taught in Wikipedia. I tried putting the first snippet provided in that page to my .spacemacs file within the user-config() function, but after restarting, when I restart spacemacs and type "=>", nothing changes (I do not see a ligature).
[1] https://github.com/tonsky/FiraCode/wiki/Setting-up-Emacs
I haven’t yet looked at it any further, maybe the regex-method works, but I suspect it to severely slow down every kind of text display. (It’s essentially running a couple dozen matches on every substring in each buffer…)
News! https://ekaschalk.github.io/post/prettify-mode/
It seems to work with firacode now. If anyone wants to take a look: go for it!
Another update: Hasklig seems to have moved to the FiraCode mechanism with 1.0 as well. So getting this to work would give us two fonts to choose from.
Unfortunately that method still does not allow multiple blocks to be taken up by a single ligature (from the website @Profpatsch linked to). This is problematic for coding:
For ligatures, the number of visual points composing the replacement is the same as its composing characters. For instance, the ligature for -> occupies two spaces.
But this is not the case for prettify-symbols or pretty-mode. Both alpha and not in are reduced to one character.
So the line width you see may not be the same as its actual width.
This has two effects:
A line could then exceed 80 characters with prettify-mode disabled. Indentation is performed using the Unicode replacements, not actual spacing.
Oh no. Maybe it can be patched?
I think that prettify would have to support adding in the lost space.
Well, these fonts make the ligatures exactly as wide as the normal combinations, so it must support multi-width characters as well.
Hi I wrote the blog on pretty-mode linked earlier.
The options as I see it are:
I took a shot at the hook:
(defun test-fontlock-fix-before ()
(font-lock-mode -1)
(spacemacs/indent-region-or-buffer))
(defun test-fontlock-fix-after ()
(font-lock-mode 1)
(sit-for 1) ; Without the sleep it doesnt reindent.
(spacemacs/indent-region-or-buffer))
(add-hook 'before-save-hook 'test-fontlock-fix-before)
(add-hook 'after-save-hook 'test-fontlock-fix-after)
This works in all cases that (spacemacs/indent-region-or-buffer)
does, which I found it is not everytime.
The glaring flaws are the sleep and that save-file cannot tell anymore when your file hasn't changed, especially annoying with eg magit.
Number 6 is the only true solution I see to this problem but it seems quite involved.
Any other thoughts on how spacing could be handled?
I implemented the visual spacing solution: https://github.com/Profpatsch/blog/blob/master/posts/ligature-emulation-in-emacs/post.md
I only afterwards noticed that it’s not perfect, but it works fine for me right now with Hasklig.
My idea would be to switch back to non-visual and tag every symbol with the number of spaces it occupies, then prefix them with spaces accordingly. I think I’m gonna try that next.
When I use Fira Code in Spacemacs even without ligature support sometimes the character alignment is off, specifically where line 1 uses bold for some characters, and line 2 doesn't have bold, then they don't line up vertically. What could be causing this?
@Profpatsch did you considered making a MELPA package from your code?
@root42 No, not really. But if you want one, go ahead. You have my blessing. :) It’s MIT-licensed anyway.
@Profpatsch How can I plug that into my .spacemacs
?
@honza Just copy the code verbatim, then Spc f e R
or Spc r R
if that does not work.
Putting this code:
(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)))
(setq my-fira-code-ligatures
(let* ((ligs '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\"
"{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}"
"--" "---" "-->" "->" "->>" "-<" "-<<" "-~"
"#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_("
".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*"
"/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||="
"|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "=="
"===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">="
">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>"
"<$" "<$>" "<!--" "<-" "<--" "<->" "<+" "<+>" "<="
"<==" "<=>" "<=<" "<>" "<<" "<<-" "<<=" "<<<" "<~"
"<~~" "</" "</>" "~@" "~-" "~=" "~>" "~~" "~~>" "%%"
"x" ":" "+" "+" "*")))
(my-correct-symbol-bounds (my-ligature-list ligs #Xe100))))
to the (defun dotspacemacs/user-config ())
section, and restarting Emacs has no effect. I also set the font to Fira Code
.
You forgot the code that adds it to the hooks that are called when you enable a mode.
;; 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)
For FiraCode change accordingly.
@Profpatsch Ah, thanks! I was hoping to enable it globally.
I can confirm that works wonderfully. Thanks @Profpatsch <3
Afaik inherits every mode from fundamental-mode
and every programming language mode from prog-mode
. So (maybe?) hooking it into one of these makes it work globally.
I've developed a proof of concept fix to ligature indentation that you all might find interesting: http://www.modernemacs.com/post/lig-spacing/
Won’t that require support from language modes, who can tell you how many lines down spaces should be collapsed?
The ligature code in this issue is all based on the assumption that ligatures have exactly the same width as the naïve code, which is true of all ligatures in FiraCode or Hasklig.
Won’t that require support from language modes
It's major mode agnostic.
which is true of all ligatures in FiraCode or Hasklig.
FiraCode and Hasklig aren't the only fonts to implement ligatures - see PragmataPro.
Spaced ligatures do not imply correct visual indentation/grouping. For example, start a form with the .-
ligature or use the +++
ligature and check an org-table.
This is as much a post about the more general prettify-mode
which not only has incorrect visual, but also incorrect true indentation. If the restriction surrounding incorrect true indentation is removed, then ligature/symbol-based programming becomes more reasonable.
I tried this for both Fira Code and Hasklig, but my output is definitely unexpected:
I've placed the code from here as-is into my user-config
, and my font settings look like:
dotspacemacs-default-font '("Hasklig"
:size 13
:weight normal
:width normal
:powerline-scale 1.75)
Any ideas?
Interestingly, if I switch my font back to Source Code Pro
but leave in the custom elisp, the weird replacements from above still show. So, I know that Spacemacs can see Hasklig
, since changing it to say Hasklig Foo
and restarting throws warnings, but just Hasklig
does not. I installed Hasklig
from an Arch Linux AUR package. I also know that the ligature replacement mechanism is in place, but for some reason it's not finding the right ligatures.
@fosskers which version of Hasklig do you have installed? They changed the way ligatures worked after 1.0
I think, currently I use 1.1
.
I've got 1.1
from this package.
Hm, the PKGBUILD
seems to do exactly the same stuff the nixpkgs
build file does.
Maybe try rebuilding your fontconfig caches? Have you logged out or rebooted after installing the font?
Success! I just needed to reboot my machine. Things look great, thanks for your help.
Works out-of-the-box for Scala too! Just add:
(add-hook 'scala-mode-hook 'my-set-hasklig-ligatures)
to your user-config
.
@Profpatsch @honza so I added the following code to .spacemacs:
(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)))
(setq my-fira-code-ligatures
(let* ((ligs '("www" "**" "***" "**/" "*>" "*/" "\\\\" "\\\\\\"
"{-" "[]" "::" ":::" ":=" "!!" "!=" "!==" "-}"
"--" "---" "-->" "->" "->>" "-<" "-<<" "-~"
"#{" "#[" "##" "###" "####" "#(" "#?" "#_" "#_("
".-" ".=" ".." "..<" "..." "?=" "??" ";;" "/*"
"/**" "/=" "/==" "/>" "//" "///" "&&" "||" "||="
"|=" "|>" "^=" "$>" "++" "+++" "+>" "=:=" "=="
"===" "==>" "=>" "=>>" "<=" "=<<" "=/=" ">-" ">="
">=>" ">>" ">>-" ">>=" ">>>" "<*" "<*>" "<|" "<|>"
"<$" "<$>" "<!--" "<-" "<--" "<->" "<+" "<+>" "<="
"<==" "<=>" "<=<" "<>" "<<" "<<-" "<<=" "<<<" "<~"
"<~~" "</" "</>" "~@" "~-" "~=" "~>" "~~" "~~>" "%%"
"x" ":" "+" "+" "*")))
(my-correct-symbol-bounds (my-ligature-list ligs #Xe100))))
;; nice glyphs for haskell with hasklig
(defun my-set-fira-code-ligatures ()
"Add fira-code ligatures for use with prettify-symbols-mode."
(setq prettify-symbols-alist
(append my-fira-code-ligatures prettify-symbols-alist))
(prettify-symbols-mode))
(add-hook 'prog-mode-hook 'my-set-fira-code-ligatures)
and I get something that looks like this:
any ideas as to how i can fix this? thanks!
@fazilz Have you rebooted? (You don’t have to reboot if you know how to rebuild your fontconfig cache.)
@Profpatsch yes I have rebooted. also cleared font caches by running (not sure how to rebuild fontconfig cache though)
sudo atsutil databases -remove
still the same result
I poked around a little bit and found that fontconfig cache lives in
/opt/local/var/cache
(If you installed it via macports) and deleted the cache and restarted but still get weird symbols. interestingly enough lambda gets rendered properly.
Sorry for spamming like this I really want to make this thing work.
(If you installed it via macports)
Ah, can’t help you on Darwin, sorry.
Ah, can’t help you on Darwin, sorry.
If I solve this somehow, I'll post the solution here, thanks for the original code!
I got this working on macOS by following the instructions from this issue.
dotspacemacs/user-config
:
(if (eq system-type 'darwin)
(mac-auto-operator-composition-mode))
dotspacemacs/init
:
dotspacemacs-default-font '("Fira Code"
:size 12
:weight normal
:width normal
:powerline-scale 1.1)
The www
and x
ligatures don't work, since they aren't operators.
thank you so muc @gustavAR also emacs-mac seems to be a lot faster than emacs-app from macports so thats a nice side effect.
@gustavAR when I start spacemacs it says: (Spacemacs) Error in dotspacemacs/user-config: Symbol’s function definition is void: mac-auto-operator-composition-mode
@romariolopezc That is the exact error you get if you aren't running emacs-mac. Are you sure you are running emacs-mac? If so, the top of your window should be black like this: As opposed to the normal border which looks like this:
@gustavAR I installed emacs-mac, but I think I'm not running emacs-mac. How do I run it? Isn't just open spacemacs? I have installed emacs-plus
I already had spacemacs installed. Do I need to uninstall, and then install emacs-mac?
emacs-mac
doesn't override your old emacs installation automatically.
Homebrew has probably installed emacs-mac
in /usr/local/opt/emacs-mac/
.
so you're going to want to create an alias of Emacs.app by right-clicking it:
Move the alias to your Applications folder and make sure it's the only one. I tried doing this automatically by using brew linkapps
, but for some reason this command prioritised my pre-existing installation of emacs-plus
.
You might also want to make the emacs
command refer to your new installation. If so, add an alias to your ~/.bashrc
, which can be done by running the following command in your terminal and restarting your terminals.
echo "alias emacs=\"/usr/local/opt/emacs-mac/bin/emacs\"" >> ~/.bashrc
Fixed! Thanks @gustavAR 👍
Btw now my themes are displaying correctly, and is faster than before!
This issue is quite long and there are many comments, some specific to macOS and some not.
As a debian spacemacs user, is there a known solution/workaround to make FiraCode work in (spac)emacs with ligatures not affecting line length?
@abeluck Have you tried this and followed the conversation for a few messages from this timestamp?
@gustavAR As far as I know, emacs-mac
and emacs-plus
were two different distributions of Emacs on mac. Any caveats of switching from one to the another? I couldn't find any detailed comparison between both sadly.
I made a ticket about this, i.e. a specific implementation already exists https://github.com/syl20bnr/spacemacs/issues/11639
FiraCode is a nice derivation from Fira Mono that adds many ligatures for a nice code look. It uses Unicode ligatures, but Emacs sadly doesn’t support them (yet). I’d like to add a layer to Spacemacs to support that.
There is a page about integration into Emacs via font-lock, and the second example is also how Hasklig can be made to work with Emacs. I noticed integrating too many ligatures that way makes font rendering very slow.