[vim] Rendering issues with ligatures (#418)

733 views
Skip to first unread message

Samuel Hodgkins

unread,
Sep 13, 2015, 3:37:36 PM9/13/15
to vim/vim

I am using gvim 7.4.865. When using a font with ligatures (such as Pragmata Pro) rendering issues occur in such a way to make gvim practically unusable. This happens even when gvim is started like this: gvim -N -u NONE
To reproduce. simply start gvim and select a font with ligatures. I've only tried with Pragmata Pro but it should do the same on other fonts. Then enter insert mode and type any text.


Reply to this email directly or view it on GitHub.

ssameer

unread,
Sep 13, 2015, 5:20:41 PM9/13/15
to vim/vim

Is this related to the issue when rendering Complex Text Layout (CTL) languages (eg: Indic languages)? I see rendering issues when pasting or typing (for example this Hindi sentence) रात को ये 6 आसान काम करने से बहुत जल्दी कम हो सकता है पेट

Samuel Hodgkins

unread,
Sep 13, 2015, 5:32:00 PM9/13/15
to vim/vim

Potentially - if the error is the same. I can't say myself though.

Christian Brabandt

unread,
Sep 16, 2015, 12:49:47 PM9/16/15
to vim/vim

To reproduce. simply start gvim and select a font with ligatures. I've only tried with Pragmata Pro but it should do the same on other fonts. Then enter insert mode and type any text.

Is there a free version available, that shows the issue? I only found a commercial version of Pragmata Pro

Giuseppe

unread,
Sep 18, 2015, 6:35:05 AM9/18/15
to vim/vim

This was already discussed in vim_dev some time ago, see [1]

[1] https://groups.google.com/forum/#!topic/vim_dev/0sETSAwe5Wo

Christian Brabandt

unread,
Sep 18, 2015, 6:52:32 AM9/18/15
to vim/vim
Hi Giuseppe!


On Fr, 18 Sep 2015, Giuseppe wrote:

> This was already discussed in vim_dev some time ago, see [1]
>
> [1] https://groups.google.com/forum/#!topic/vim_dev/0sETSAwe5Wo

And this makes font rendering work with ligatures? Can you post a
screenshot of a patched Vim and an unpatched Vim?

Best,
Christian
--
Je mehr der Mensch des ganzen Ernstes fähig ist, desto herzlicher kann
er lachen.
-- Arthur Schopenhauer

Giuseppe

unread,
Sep 18, 2015, 7:09:44 AM9/18/15
to vim/vim

Not really, I've briefly tested the patched vim with the PragmataPro font and it's still unusable [1].
I don't use the ligatures myself but I just stumbled across this problem this morning, when I mistakenly set the font to PragmataPro instead of PragmataPro Mono

[1] http://inky.ws/g/3av

Tony Mechelynck

unread,
Sep 18, 2015, 8:01:11 AM9/18/15
to vim_dev, Giuseppe
On Fri, Sep 18, 2015 at 1:09 PM, Giuseppe <vim-dev...@256bit.org> wrote:

Not really, I've briefly tested the patched vim with the PragmataPro font and it's still unusable [1].
I don't use the ligatures myself but I just stumbled across this problem this morning, when I mistakenly set the font to PragmataPro instead of PragmataPro Mono

[1] http://inky.ws/g/3av

Ah, yes, in most gvim versions you cannot set a font that doesn't declare itself as monospaced. In the GTK2 version you can but the results are ugly (wide letters such as m appear cramped and narrow letters such as i appear too far away from their neighbours, since gvim renders every character in one cell of fixed size (or two cells for "wide" CJK characters).

For best results, I recommend to always set 'guifont' to some fixed-width font: I use Bitstream Vera Sans Mono at the moment; I have also used Lucida Console and Courier New in the past; in general any font whose name ends in "Mono" "Console" or "Typewriter", and a few others, including most variants of the Courier font, are usable; however bold Cyrillic glyphs of the Lucida Console font are just a tiny wee bit wider (one pixel wider, I think) than their unbold counterparts, and that gives rendering problems in gvim.



Best regards,
Tony.

Matěj Cepl

unread,
Jun 1, 2016, 11:58:37 AM6/1/16
to vim/vim
> Is there a free version available, that shows the issue? I only found a commercial version of Pragmata Pro

The same can be achieved using https://github.com/tonsky/FiraCode/ and yes the mentioned patch works for me with 7.4.160 (and other patches from the RHEL-7 package). There are some problems (e.g., ``=~`` shouldn’t be displayed as ``≃``), but otherwise it seems to be working

cheesy

unread,
Sep 17, 2016, 8:42:27 PM9/17/16
to vim/vim

The patch works! Here's a sample with PragmataPro:

2016-09-17-17 40 27


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub

Thedward Blevins

unread,
Nov 15, 2016, 7:39:11 PM11/15/16
to vim/vim

@mcepl

The patch is no longer available via the provided url (http://paste.fedoraproject.org/427667/73785436/), could you put it up again?

Yabes

unread,
Nov 16, 2016, 3:09:41 AM11/16/16
to vim/vim

Matěj Cepl

unread,
Nov 16, 2016, 4:11:56 AM11/16/16
to vim/vim

OK, couple of links:

Alexander Gagarin

unread,
Nov 21, 2016, 12:37:27 AM11/21/16
to vim/vim

@mcepl patched vim from COPR lik above seems to have GUI disabled during compile-time - I couldn't start gvim on fedora 25.

Matěj Cepl

unread,
Nov 21, 2016, 4:42:11 AM11/21/16
to vim/vim

@uentity sorry, I messed up ... due to https://bugzilla.gnome.org/show_bug.cgi?id=773387 (and consequently #1193) I have switched to Gtk2 (it is more or less the same anyway) and forgot to fix BuildRequires. It should be corrected in vim-8.0.0086-1.0.13.

Alexander Gagarin

unread,
Nov 21, 2016, 6:06:56 AM11/21/16
to vim/vim

@mcepl thanks! Installed 1.0.13 and everything seems working great, including rendering speed! Fixed rendering is related to Gtk3 -> Gtk2 switch?

Matěj Cepl

unread,
Nov 21, 2016, 6:12:43 AM11/21/16
to vim/vim

I think so.

JackeJR

unread,
Jul 24, 2017, 12:21:03 PM7/24/17
to vim/vim, Subscribed

Just a heads up that to get ligatures to work in Windows, you have to switch to using directx in renderoption. (see tonsky/FiraCode#462).

Matěj Cepl

unread,
Sep 12, 2017, 3:39:08 PM9/12/17
to vim/vim, Subscribed

Just to say that I have refreshed my RHEL/Fedora vim COPR to the latest patch from this repository (1097) and reapplied suggested patch fixing this issue. It is all on https://copr.fedorainfracloud.org/coprs/mcepl/vim8/ .

Christian Brabandt

unread,
Sep 12, 2017, 3:46:01 PM9/12/17
to vim/vim, Subscribed

Can you post an updated patch please?

Matěj Cepl

unread,
Sep 12, 2017, 4:14:57 PM9/12/17
to vim/vim, Subscribed

Can you post an updated patch please?

There is nothing updated about it. It is still manuelschiller/vim@0c8d6a7 (you can get source RPM from the website of the COPR which includes all patches).

Gaspar Chilingarov

unread,
Sep 24, 2017, 7:18:26 AM9/24/17
to vim/vim, Subscribed

Everyone rejoice! 😃

Here is automated build of ligatures enabled GVim8 deb package from vim/master

You'll need Docker and docker-compose for fully automated experience or just Docker if you don't want to install docker-compose.

If you have a need of RPM package - let me know in issues and I'll try automating it as well.

Matěj Cepl

unread,
Sep 24, 2017, 4:00:18 PM9/24/17
to vim...@vim.org
On 2017-09-24, 11:18 GMT, Gaspar Chilingarov wrote:
> If you have a need of RPM package - let me know in issues and
> I'll try automating it as well.

If you have need for RPM package (and you are on RHEL or Fedora)
you can use my packages at
https://copr.fedorainfracloud.org/coprs/mcepl/vim8/

Best,

Matěj
--
http://matej.ceplovi.cz/blog/, Jabber: mcepl<at>ceplovi.cz
GPG Finger: 3C76 A027 CA45 AD70 98B5 BC1D 7920 5802 880B C9D8

A philosopher like Plato, according to Luther's colorful imagery,
remains like a cow who looks at a new door, refusing to enter?

Matěj Cepl

unread,
Sep 24, 2017, 5:19:39 PM9/24/17
to vim/vim, Subscribed

If you have a need of RPM package - let me know in issues and I'll try automating it as well.

#418 (comment) … or take them from my COPR.

Matěj Cepl

unread,
Oct 7, 2017, 6:27:07 AM10/7/17
to vim/vim, Subscribed

@brammool @chrisbra What’s missing from this patch to be merged? Should I make a pull request?

Marcelo Camargo

unread,
Oct 27, 2017, 8:40:11 PM10/27/17
to vim/vim, Subscribed

Any updates on this and any chance to get the patch on the next Vim release?

Christian Brabandt

unread,
Oct 28, 2017, 9:08:42 AM10/28/17
to vim/vim, Subscribed

last i know, it had some rendering issues and one needs to press Ctrl-L to fix that. Is that still true?

Matěj Cepl

unread,
Oct 28, 2017, 4:47:59 PM10/28/17
to vim/vim, Subscribed

Is that still true?

No, it is not (at least for me on RHEL-7 with Gtk3). I have been using ligatures in my vim builds for more than a year and I have yet to see a problem with it.

Gaspar Chilingarov

unread,
Oct 29, 2017, 3:15:01 PM10/29/17
to vim/vim, Subscribed

@chrosbra - work for me on Ubuntu 16.04 w/o such problem with FiraCode. vim 8.0.1207, libgtk3 - 3.18.9

Franco Biasin

unread,
Nov 12, 2017, 12:51:06 PM11/12/17
to vim/vim, Subscribed

Same as @gasparch. I had to add --enable-gui=gtk3 to the ./configure command (GTK2 didn't seem to work) and let g:gtk_nocache=[0x00000000, 0xfc00ffff, 0xf8000001, 0x78000001] to my .vimrc.

Christian Brabandt

unread,
Nov 13, 2017, 2:12:11 AM11/13/17
to vim/vim, Subscribed

so it only works with the gtk3 build? I suppose it also does not work with a terminal build, right? How hard would it be to make it work with different guis?

Gaspar Chilingarov

unread,
Nov 13, 2017, 3:02:41 AM11/13/17
to vim/vim, Subscribed

@chrisbra for terminal build to work - terminal emulator should support it, there is nothing to be done on vim side. Konsole works fine even with unpatched vim :)

About gtk2 - seems people above reported it working with gtk2 as well.

Christian Brabandt

unread,
Nov 13, 2017, 3:10:25 AM11/13/17
to vim/vim, Subscribed

I am confused. Can we please have some documentation, that describes how the patch is used and where it actually works? I suppose it won't work at least for the old athena and motif guis (which is probably okay), but I wonder if this really works in both gtk2 and gtk3 guis. It should also mention, that setting the g:gtk_nocache won't be needed for terminal vim and describe how to get ligatures working on terminal vim (and of course gtk2 and gtk3). I suppose a test would be nice, as well.

Christian Brabandt

unread,
Nov 13, 2017, 3:12:21 AM11/13/17
to vim/vim, Subscribed

Also the linked patch mentions that rendering artifacts still occur even with this patch. But this comment says it works flawlessly?

Gaspar Chilingarov

unread,
Nov 13, 2017, 3:31:53 AM11/13/17
to vim/vim, Subscribed

Works without problems for me too for half a year of daily use :)

So I see that missing part now is the user-facing documentation, what should be mentioned in documentation?

  1. list of supported frontends? gtk2/gtk3?
  2. what setting to set in .vimrc to enable ligatures - g:gtk_nocache (it does not affect terminal version at all, so may be set in .vimrc and not only in .gvimrc)
  3. references/links to fonts supporting ligatures?
  4. link to supported terminals from FiraCode site (most probably it does not make sense to put list in vim documentation, because then it needs to be maintained :)

In which doc files these should go / in which sections?

Christian Brabandt

unread,
Nov 13, 2017, 3:42:48 AM11/13/17
to vim/vim, Subscribed

I would say, somewhere in gui_x11.txt somewhere below the gui-gtk tag. Add a new tag like gui-gtk-ligatures and then a proper description of the feature and all your points you mentioned. A link to the README from the FiraCode site for the supported terminals is probably okay.

Note, I am only pointing out things that needs to be addressed before this can be merged, however I do not have the power to have this merged, so I cannot promise it will be merged once this has been added. That is Brams responsibility, but showing dedication to have this improved should help :)

Gaspar Chilingarov

unread,
Nov 13, 2017, 4:51:58 AM11/13/17
to vim/vim, Subscribed

Well, it makes sense to have functionality documented :) In worst case scenario - we as community can put more effort in having separate builds available for all major platforms ;)

Matěj Cepl

unread,
Nov 13, 2017, 7:01:18 AM11/13/17
to vim/vim, Subscribed

I am confused. Can we please have some documentation, that describes how the patch is used and where it actually works?

Tested only on RHEL-7 and Fedora 26 (I believe) with builds from https://copr.fedorainfracloud.org/coprs/mcepl/vim8/ (COPR is something like PPA but for Fedora/RHEL). The process of applying is shown in the SPEC file.

I suppose it won't work at least for the old athena and motif guis (which is probably okay), but I wonder if this really works in both gtk2 and gtk3 guis. It should also mention, that setting the g:gtk_nocache won't be needed for terminal vim and describe how to get ligatures working on terminal vim (and of course gtk2 and gtk3). I suppose a test would be nice, as well.

I think terminal is completely orthogonal to vim, isn't it? It just depends on the terminal used (and unfortunately my gnome-terminal doesn’t support it.

Status of Gtk2 is weird … how much is further development of it even supported? Isn’t it bugfixes only at this time? BTW, just a off-topic question, why does vim supports gtk2 still? What are the platforms having gtk2 and not gtk3?

Christian Brabandt

unread,
Nov 13, 2017, 9:59:57 AM11/13/17
to vim/vim, Subscribed

I think terminal is completely orthogonal to vim, isn't it? It just depends on the terminal used (and unfortunately my gnome-terminal doesn’t support it.

Yes, but it should be mentioned that this feature only works in the Gui and terminal vim depends entirely on the terminal emulator used.

Status of Gtk2 is weird … how much is further development of it even supported? Isn’t it bugfixes only at this time? BTW, just a off-topic question, why does vim supports gtk2 still? What are the platforms having gtk2 and not gtk3?

Some people still like to use gtk2 gui (for performance or smoothness reasons or whatever else) and nobody has yet requested to remove it. So unless the gtk2 libraries are not available anymore, we still like to give the users the chance to use whatever they like.

Alexander Gagarin

unread,
Nov 13, 2017, 1:06:10 PM11/13/17
to vim/vim, Subscribed
I personally don't use latest reincarnation of this patch, especially with
GTK3. Because with all that enabled vim on my system becomes
slooooooowwwwww as hell. Even cursor movement delays heavily.
Instead I build my own vim with GTK2 and prev unconditional version of
patch (without defining variables in .vimrc). And that way it works, but
occasional rendering corruption becomes very noticable. Anyway that's
better that strong lag.

IMHO this patch implements some kind of imroper/not effective way to do
ligatures rendering. Maybe some more deep changes are needed? BTW I'm NOT a
vim expert and can't suggest anything. This is just my feelings about this
patch.
> You are receiving this because you were mentioned.

> Reply to this email directly, view it on GitHub
> <https://github.com/vim/vim/issues/418#issuecomment-343944888>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AAEWuPu7tJENhTDhP5t8-yGbfjn1YXazks5s2FlpgaJpZM4F8eg0>
> .
>



--
С уважением,
Александр Гагарин.

Christian Brabandt

unread,
Nov 13, 2017, 3:36:35 PM11/13/17
to vim/vim, Subscribed

sounds like the patch is not quite ready to be included...

Matěj Cepl

unread,
Nov 13, 2017, 5:00:57 PM11/13/17
to vim/vim, Subscribed

Ingo Weiss

unread,
Oct 26, 2018, 2:55:14 AM10/26/18
to vim/vim, Subscribed

@mcepl The COPR repo doesn't exist anymore. Does it live somewhere else?

Matěj Cepl

unread,
Oct 26, 2018, 6:10:47 AM10/26/18
to vim/vim, Subscribed

The COPR repo doesn't exist anymore. Does it live somewhere else?

@iweiss Sorry, I stopped using vim at all and switched to neovim. https://github.com/daa84/neovim-gtk supports ligatures, although daa84/neovim-gtk#143 makes thing complicated.

Er Galvão Abbott

unread,
Feb 8, 2019, 4:20:34 AM2/8/19
to vim/vim, Subscribed

Any chance we can see this getting done? I mean, I'm aware it's not a critical thing - after all we can still do our jobs without it - but it would be really nice to see ligatures working on vim/gVim.

Matěj Cepl

unread,
Feb 8, 2019, 5:55:06 AM2/8/19
to vim/vim, Subscribed

@galvao https://github.com/daa84/neovim-gtk/ works just fine. Sorry for advertising.

Christian Brabandt

unread,
Jan 30, 2021, 12:41:02 PM1/30/21
to vim/vim, Subscribed

latest version of the patch seems to be: manuelschiller@81ca0b4


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

dusanx

unread,
Sep 23, 2021, 7:18:32 AM9/23/21
to vim/vim, Subscribed

I can confirm, building gvim on Arch linux with patch manuelschiller@81ca0b4 works flawlessly. I don't see any performance losses.

Only thing that could possibly optimize things further is extracting

static char_u* vname = (char_u*) "g:gtk_nocache";
	dictitem_T *di = find_var(vname, NULL, FALSE);
	list_T* l = (NULL == di || VAR_LIST != di->di_tv.v_type) ?
	    NULL : di->di_tv.vval.v_list;

somewhere more global, so it doesn't happen on every gui_gtk2_draw_string().

For what it's worth, I cast my vote to get this merged into stock production code. Ty.


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.

dusanx

unread,
Sep 27, 2021, 11:55:02 AM9/27/21
to vim/vim, Subscribed

Reading some more of that patch, it can be affected by processor endianness, big-endian (BE) and little-endian (LE) processors can interpret mask differently. While we stay on Intel/AMD it will work but on ARM it can fail because of hardcoded bit positions.

Give me few days, I think I can optimize this and get it ready for production.

Manuel Schiller

unread,
Sep 27, 2021, 3:55:40 PM9/27/21
to vim/vim, Subscribed

Reading some more of that patch, it can be affected by processor endianness, big-endian (BE) and little-endian (LE) processors can interpret mask differently.

Unless I misread my own code which I admittedly wrote a number of years ago, I do not think that can happen. I tried this patch in house on both x86_64 (LE) and ultrasparc (BE) when I wrote it, and I didn't see different behaviour. Are you sure you're not misreading what happens? To have endianness issues, the code would need to interpret some kind of multi-byte integer at the level of bytes in memory (i.e. to do some form of type punning, either through byte-wise memory access, changing the type of a pointer, or through a union) which it does not do. The code just stays with the integers it gets from the list, and works with those. I think if there are portability issues, they're not due to processor endianness. OTOH, it's late, so let me know if I'm mistaken. :)

By the way, I'm working (when I can find a moment) on some docs as well, see 808515e and 7f85e32. Unfortunately, I don't have much time due to constraints at work, so if you want to run with these two newer pointers, be my guest.

dusanx

unread,
Sep 27, 2021, 4:59:49 PM9/27/21
to vim/vim, Subscribed

Maybe I misread, sorry if I did -- if you tested in both variants and it works then it works.
Thing that raised concern for me is shifting

if (*p & 0x80 || (1 & (bmap[*p >> 5] >> (*p & 31))))

and hex definitions of four unsigned 32bit integers -- possible cause of problems if you shift and mask in the wrong direction on wrong architecture.

I am using your patch for quite some time and it is working without any problems. What I would love to do is to avoid reading g: variable in each pass and to avoid falling back to goto not_ascii; too often. Altrough I just learned gvim is not caching bold and italic so anything but plain ascii falls back there anyway.

I am just testing what *s in gui_gtk2_draw_string holds and we could as well just disable normal cached glyph output alltogether:

    if (!(flags & DRAW_ITALIC)
	    && !((flags & DRAW_BOLD) && gui.font_can_bold)
	    && gui.ascii_glyphs != NULL
	    && 0)

So I would reuse some of your logic but not code, will try to fall back to 'quick' output more often. Give me few days to see what I can come up with. Oh and certainly sometime in the future we have to cache bold and (maybe)italic -- current output just flushes bold to not_ascii which is very not quick with any theme that uses bold (like gruvbox I am using, all function names are bold so they fall to pango.

dusanx

unread,
Sep 27, 2021, 5:13:28 PM9/27/21
to vim/vim, Subscribed

TIL & fun fact: stock unpatched gvim with color scheme that draws any italic or bold, falls down to goto not_ascii for any such string. Just typing -> or >= inside bold/italic block will show ligatures. I'll try optimizing that too after working on ligatures.

Manuel Schiller

unread,
Sep 27, 2021, 5:16:40 PM9/27/21
to vim/vim, Subscribed

No worries, it's quite late for me, too, so I might have been wrong about the portability issue. As far as I can reconstruct my logic four years after initially writing the patch: For the masking: This cannot go wrong, a bitwise and is the same everywhere. The shifts could go wrong in the high bits, but that's unlikely, since bmap is unsigned (see above). Moreover, I isolate a single bit with the masking (the least significant one after shifting), so whatever gets shifted in the top bits is ignored. And we cannot shift too much, since the shift count is clamped to the range from 0 to 31 inclusive.
About the cached glyph output: You're right, on a modern machine, you won't feel a difference when you ignore the cache and just shape everything. But if you're sitting on an old 300 MHz machine with little RAM like I sometimes do, these things do make a difference. Please think twice before you throw out the glyph cache, and benchmark on an old machine under load.

dusanx

unread,
Sep 27, 2021, 5:42:16 PM9/27/21
to vim/vim, Subscribed

About the cached glyph output: You're right, on a modern machine, you won't feel a difference when you ignore the cache and just shape everything. But if you're sitting on an old 300 MHz machine with little RAM like I sometimes do, these things do make a difference. Please think twice before you throw out the glyph cache, and benchmark on an old machine under load.

Quite the opposite, I want to make more use of the cache, we are falling too fast and too often to not_ascii. See my test vim script:
https://gist.github.com/dusanx/9ee6a5ba5a4b0d82714a68d8d35694e2
with masked space (32) we are falling back to pango all the time, for any string containing space. I'd like to revert that, use more cache, keep logic and optimize stuff in next several days.

Bram Moolenaar

unread,
Sep 27, 2021, 5:45:11 PM9/27/21
to vim/vim, Subscribed

This mechanism of specifying a sequence of characters with hex numbers is weird. I'm not sure why you are not using a list of characters or character ranges, like we have in some options. E.g. with 'isfname'. Making this an option makes it easy to parse the value only when it is changed.

dusanx

unread,
Sep 27, 2021, 5:47:23 PM9/27/21
to vim/vim, Subscribed

Exactly working on that, see LIGATURE2 function in my gist,

let l:mask = "!"#$%&'()*+,-./:;<=>?@[]^_`{|}~"

so going from there, will parse and use string like that. It will be pre-processed/cached so no performance penalties.

dusanx

unread,
Sep 28, 2021, 4:35:25 AM9/28/21
to vim/vim, Subscribed

Work in progress. Just a short question to someone more experienced with gvim: is there a reason we don't cache bold and itailc same way as we do for normal text, in ascii_glyph_table_init? If no reason I would like to add those two (can gvim do bold+italic?) so we don't fall to not_ascii that often.

dusanx

unread,
Sep 28, 2021, 3:42:55 PM9/28/21
to vim/vim, Subscribed

No idea why my vim-dev mails don't work, trying to subscribe again says I am already subscribed. First mail I sent isn't yet visible anywhere. Anyway here is rock solid and very speedy ligatures/utf-8 patch, so far with hard coded ligature characters (since I first opened vim code day ago I don't know how to expose global "set something = 'string'" variable yet. Only needs global variable, some pre-processing so we don't memchr too much, then some documentation.

Anybody interested can try, it is good code already.

Tree:
https://github.com/dusanx/vim/tree/gvim-ligatures

Commit:
dusanx@a00791c

This code makes sure that gvim uses cached glyphs as much as possible and falls down to slower Pango only for utf-8 or ligature substrings. Comments, help and contributors welcome -- main issue being I'll need to spend another day to figure out how to expose global set variable, something in the spirit of guifont or isfname.

Christian Brabandt

unread,
Sep 28, 2021, 3:55:36 PM9/28/21
to vim/vim, Subscribed

First mail needs to be approved. I did so now, because I haven't received a notification yet about a pending mail :/

Christian Brabandt

unread,
Sep 28, 2021, 4:02:44 PM9/28/21
to vim/vim, Subscribed

nit: looks like there are some white space issues (tabs and non tabs mixed). Also I think the coding style can be improved (e.g. one statement per line), check :h coding-style (or have a look around other code)

Christian Brabandt

unread,
Sep 28, 2021, 4:07:47 PM9/28/21
to vim/vim, Subscribed

Comments, help and contributors welcome -- main issue being I'll need to spend another day to figure out how to expose global set variable, something in the spirit of guifont or isfname.

I suppose a global-option is fine here? I think you need to define it in option.h and optionsdefs.h like all the other ones. The add a check around optionstr.c for doing the error checking of that option. And then you can use it instead of the hard-coded value. Add a section to the help option.txt.

I usually just use one similar option and copy and paste and adjust it then where needed :)

dusanx

unread,
Sep 28, 2021, 4:19:22 PM9/28/21
to vim/vim, Subscribed

Thanks about mail. Yes. I will fix indentation of course, tabs/spaces always cause trouble. Tbh looking at code I couldn't figure out what the standard is -> will format everything properly of course.

Thanks for the hints about global option, that's exactly the pointer I need to avoid looking where is what. I'll have variable handling soon.

Manuel Schiller

unread,
Sep 28, 2021, 4:28:47 PM9/28/21
to vim/vim, Subscribed

I'll test-drive your patch later in the evening. One thing I think I can see already is that some fonts have really funny ligatures like "[INFO]" or "[DEBUG]" (yes, that's a multi-character ligature beast). Your code seems to assume that you'll only ever have a handful characters that can occur in a ligature, so memchr is a viable solution. But if that's not true (and I think you cannot assume it is if you make the list of potentially ligatured characters user-tunable), I'm not sure that memchr is a good solution. You may have to go back to the mask idea. (I'd be happy to provide some code tonight that would only replace your memchr call with something else, if you think it useful.)

dusanx

unread,
Sep 28, 2021, 4:31:33 PM9/28/21
to vim/vim, Subscribed

:h coding-style

Super useful, thanks.

dusanx

unread,
Sep 28, 2021, 4:40:29 PM9/28/21
to vim/vim, Subscribed

funny ligatures like "[INFO]" or "[DEBUG]"

I am using all kinds of ligature capable fonts for quite some time and never seen this. Can you please share few of the funny fonts (names/links), I'd like to take a look? Do we really want to index something very niche (since Victor Mono, Cascadia or Fira Code don't have [INFO]) that will slow down output significantly?

https://github.com/tonsky/FiraCode is pretty much gold standard of what is expected of ligatures, please show links.

I would certainly avoid to fall down to Pango in 99% of cases just to catch [DEBUG] ligature.

Manuel Schiller

unread,
Sep 28, 2021, 4:43:46 PM9/28/21
to vim/vim, Subscribed

Well, my daily driver is Pragmata Pro (just search the web), which is admittedly a bit crazy, but really nice to work with... And I'd like to keep working with it in vim.

dusanx

unread,
Sep 28, 2021, 4:53:50 PM9/28/21
to vim/vim, Subscribed

Depending on community thoughts, furthest I am willing to risk speed and performance is to add something like
set ligature_start = '['
ret ligature_end = ']'
and to process anything in between with Pango -- which would solve Pragmata Pro exceptions.
However this two would be optional since other fonts don't have such ligatures.

Anything more than that and we could as well disable glyphs and render everything trough not_ascii/Pango, which is not very optimal.

Manuel Schiller

unread,
Sep 28, 2021, 5:02:31 PM9/28/21
to vim/vim, Subscribed

It would not be sufficient - it also does special things like ligatures for some C/C++ keywords, and some other crazy things. I think if you let people choose the ligature string, you're fine. Most people won't need it, and the ones that think they do also go away happy.

dusanx

unread,
Sep 28, 2021, 5:06:12 PM9/28/21
to vim/vim, Subscribed

Is this list up to date?

https://gist.github.com/fabrizioschiavi/f40a54c8211833c75c81ec82f0c0dd1c

If not can you please provide link to current list for Pragmata Pro?

Manuel Schiller

unread,
Sep 28, 2021, 5:10:00 PM9/28/21
to vim/vim, Subscribed

I believe it is, but that's a bit beside the point. One cannot make assumptions on what people will use in their ligatures. If you do, sooner or later somebody will come up with a font that breaks those assumptions, and you'll get a bug report. That's why this list needs to be user settable, and why it would be desirable to have an algorithm that will give people the freedom to either not pay the ligature penalty, or as much of it as they want.

dusanx

unread,
Sep 28, 2021, 5:23:57 PM9/28/21
to vim/vim, Subscribed

I believe it is, but that's a bit beside the point

it also does special things like ligatures for some C/C++ keywords, and some other crazy things

I don't see ligatures for C/C++ keywords in the list, everything besides [something] is very much standard.

I am not sure what are we discussing here. I was happily using your patch 808515e but after examination it is rendering nearly everything in Pango. With standard space ' ' being marked as ligature character in the default let g:gtk_nocache=[0x00000000, 0xfc00ffff, 0xf8000001, 0x78000001] and with code that falls down to Pango as soon as single character in the entire string fits the criteria, all the lines that contain space or any of the other characters from gtk_nocache are rendered with Pango. Having [INFO] working with your patch is only because string already contains [, falls back to Pango and renders entire line with it. Run simple printf and see how much content is Pango and how much is trough glyphs, I did. Do we at least agree that using Pango for 99% of screen drawings is bad? As I said before drawing everything trough Pango is valid but away from optimal, we could make switch for that.

If you don't mind I'd like to take a break and see what anybody else in the community has to say,

Manuel Schiller

unread,
Sep 28, 2021, 5:28:15 PM9/28/21
to vim/vim, Subscribed

We agree, and I'm about to hack your propose ligature string to see if I can get things to work for me. In the meantime, I ran with your code, but reinstated the bitmap - memchr is a bit wasteful for long ligature strings. See 1299ec1 for details. NB: this patch to your patch leaves your algorithm in place, but should be quite a bit faster because memchr has to search the entire ligature string for each character you want to print that's not in the ligature string. The bitmap does that in a single probe. :) Oh, and I also fixed a couple of compiler warning I got.

Manuel Schiller

unread,
Sep 28, 2021, 5:35:56 PM9/28/21
to vim/vim, Subscribed

Okay, with user-tunable ligature string (and the bitmap thing I proposed), I'm happy with your patch. I can run with my stuff and have pango render much on fast machines, and switch to a much abbreviated ligature string on slow machines. Nice work, and your code is much clearer than what I found before I put in my hack! :)

dusanx

unread,
Sep 28, 2021, 5:36:51 PM9/28/21
to vim/vim, Subscribed

Thanks for the packing algorithm, I'll need something like that after I add global option -- parsing/packing has to go somewhere global too. Just give me couple of days to prepare next commit.

dusanx

unread,
Sep 28, 2021, 5:39:00 PM9/28/21
to vim/vim, Subscribed

Okay, with user-tunable ligature string (and the bitmap thing I proposed)

Please show that somewhere when you get time. I am very cautious about searching trough lists in tight screen drawing loop. Bit compare trough array or bitmap equivalent is quick, comparing two strings is very CPU intensive.

Manuel Schiller

unread,
Sep 28, 2021, 5:40:44 PM9/28/21
to vim/vim, Subscribed

No worries, it's my pleasure. :) Tonight, I'm not too tired to some coding up the sharp end, and have a bit of time to listen to the White Album, so the thing about pleasure is actually more than just words. Thanks for picking this stuff up - I was kind of despairing because I never found the time to polish my original patch. Part of it was likely also the impression that not many people would be interested in a solution, but it appears time has changed that. 👍

Manuel Schiller

unread,
Sep 28, 2021, 5:50:02 PM9/28/21
to vim/vim, Subscribed

Okay, with user-tunable ligature string (and the bitmap thing I proposed)

Please show that somewhere when you get time. I am very cautious about searching trough lists in tight screen drawing loop. Bit compare trough array or bitmap equivalent is quick, comparing two strings is very CPU intensive.

Show what exactly? If you are wondering about memchr vs the bitmap approach, I can run a quick valgrind or something, if that helps. But for anything but a very short ligature string (I guess 2-4 characters), the bitmap is going to beat the memchr version because memchr contains a loop.

Well, in any case, your new code is certainly no worse than the code I originally proposed. I don't think we can prevent people to shoot themselves in the foot on slow machines unless we go for something that's a bit heavier on data structures, e.g. something that goes through the font, extracts the ligatures, or takes a list from the user, and then uses some kind of hash trick to check if there's a match in the current string to be printed. I'd be hesitant to stick such a monster in the drawing code. But that's what would be needed to do a proper job in all cases.

That said, I think your algorithm is good enough, and fast enough for the use case you have in mind (and I've just verified that on my machine with my strange fonts, it's also very usable).

dusanx

unread,
Sep 28, 2021, 5:59:23 PM9/28/21
to vim/vim, Subscribed

You said

Okay, with user-tunable ligature string (and the bitmap thing I proposed), I'm happy with your patch. I can run with my stuff and have pango render much on fast machines,

So I was assuming you made searchable dictionary of chars + stuff like [INFO]. If I misunderstood my bad, if you made it it is not public so I can't take a look. Of course bitmap or packed record is needed for quick indexing and I will use that certainly, with help of your code but I am curious if we can efficient [INFO] search / I am skeptical however that it can be efficient. Or you just added 'INFO' at the end of the ligatures string, which would result of rendering [INFO] as intended? That could work.

Manuel Schiller

unread,
Sep 28, 2021, 6:02:25 PM9/28/21
to vim/vim, Subscribed

No, sorry, I did not express myself clearly. I just set the ligature string back to something equivalent to my old default mask. My bad for not being clearer. No new code is involved, just a different string.
In any case, once you've got the option thing for the string implemented (and you can potentially hook the bitmap generation code into changes to that string), I think you've solved this for at least the next five years...

dusanx

unread,
Sep 28, 2021, 6:11:03 PM9/28/21
to vim/vim, Subscribed

and you can potentially hook the bitmap generation code into changes to that string

Yes, exactly the plan, global option, then moving bitmap generation somewhere global so it doesn't calculate with every string and we are done (+ some documentation).

dusanx

unread,
Sep 29, 2021, 8:27:18 AM9/29/21
to vim/vim, Subscribed

Update in https://github.com/dusanx/vim/tree/gvim-ligatures

  • Production ready code, not ready for PR.
  • Optimized to push bare minimum trough slower Pango pipe, everything else as ascii.
  • Even single ligature char between two ascii chars is not actual ligature and goes trough ascii pipe.
  • Missing global option.
  • Missing documentation.
  • Using 128 bytes to map ligatures, still undecided if we should use that or tighter packed bitmap. Bitmap is shorter but requires more CPU and code is more complicated to read, byte array is 112 bytes longer than bitmap but simpler to read and quicker to access.

Work in progress but ready to test in production, testers welcome.

dusanx

unread,
Sep 29, 2021, 7:48:49 PM9/29/21
to vim/vim, Subscribed

https://github.com/dusanx/vim/tree/gvim-ligatures-global-option

Enable:

:set guiligatures=!\"#$%&()*+-./:<=>?@[]^_{\|~

Disable:

:set guiligatures=

Assuming that I didn't mess anything with P_* flags in optiondefs.h this only needs documentation.
Some kind experienced sould should take a look at this commit and check flags:
dusanx@8351819

Anybody volunteering to add option documentation for this beauty? PR welcome.

That's it, :set guiligatures= work well, gtk output is optimized even when not using ligatures, let's wrap this

dusanx

unread,
Sep 30, 2021, 4:11:27 AM9/30/21
to vim/vim, Subscribed

@chrisbra I am not sure where help info for global options should be edited, spent 20 minutes last night typing most beautiful explanation for :set guiligatures only to find that make overwrites that file :/ Can you point me in the right direction please?

Christian Brabandt

unread,
Sep 30, 2021, 5:07:04 AM9/30/21
to vim/vim, Subscribed

just put it into options.txt

Options are sorted by alphabet. Should look like this template:

			*'guiligatures'* *'<shortname>'* *'noguiligatures'* *'no<shortname>'*
'guiligatures' '<shortname>'	string (default "something")
			global
	<Paragraph describing the option values and effects, mention it only works on GTK Gui>

Note: the shortname is usually the name of the option in the source code minus the prefix p_

dusanx

unread,
Sep 30, 2021, 12:39:29 PM9/30/21
to vim/vim, Subscribed

PR done and ready, will amend if needed but in general that's it.

#8933

Bram Moolenaar

unread,
Sep 30, 2021, 2:02:55 PM9/30/21
to vim/vim, Subscribed


> Update in https://github.com/dusanx/vim/tree/gvim-ligatures

Thanks for working on this.

> - Production ready code, not ready for PR.
> - Optimized to push bare minimum trough slower Pango pipe, everything else as ascii.
> - Even single ligature char between two ascii chars is not actual ligature and goes trough ascii pipe.
> - Missing global option.
> - Missing documentation.
> - Using 128 bytes to map ligatures, still undecided if we should use

> that or tighter packed bitmap. Bitmap is shorter but requires more CPU
> and code is more complicated to read, byte array is 112 bytes longer
> than bitmap but simpler to read and quicker to access.

128 bytes is nothing these days, optimize for speed.

--
From "know your smileys":
:^[/ mean-smiley-with-cigarette

/// Bram Moolenaar -- ***@***.*** -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Alexander Gagarin

unread,
Oct 1, 2021, 6:58:06 AM10/1/21
to vim/vim, Subscribed

@dusanx @manuelschiller big thanks for resurrecting this work!

@manuelschiller I'm also using PragmataPro everywhere, so please share your settings with this latest patch revision =)

dusanx

unread,
Oct 1, 2021, 7:10:53 AM10/1/21
to vim/vim, Subscribed

Pragmata Pro, full set is this (with space at the beginning!):

 !"#$%&()*+-./:<=>?@ABCDEFGHIKLMNOPRSTUVWX[]^_{|~

but I am really cringing at so many normal ascii chars used, however not a problem on a quick machine -- pick your setup.

dusanx

unread,
Oct 1, 2021, 7:25:53 AM10/1/21
to vim/vim, Subscribed

JS gist is for Pragmata Pro but really works for any set of ligatures, just save the file, edit the list then node ligatures-test.js to see the final result to be fed to :set guiligatures. Please make sure to backslash escape things in JS and also escape what's needed in final result in vim.

https://gist.github.com/dusanx/10aec304ba2bdabdb1c552d9031138a3

Alexander Gagarin

unread,
Oct 2, 2021, 4:17:04 PM10/2/21
to vim/vim, Subscribed

Pragmata Pro, full set is this (with space at the beginning!):

 !"#$%&()*+-./:<=>?@ABCDEFGHIKLMNOPRSTUVWX[]^_{|~

but I am really cringing at so many normal ascii chars used, however not a problem on a quick machine -- pick your setup.

Seems that I can't install string with space in the beginning. You default value works though and make ligatures enabled, but maybe not all.

dusanx

unread,
Oct 2, 2021, 4:22:21 PM10/2/21
to vim/vim, Subscribed

Space ( ), double quotes (") and bar (|) need to be escaped by putting backslash () in front of such character. So if you try backslash then space it will work.

When you set string and you are happy with it, check if all characters made it with set giligatures? -- it will print string as vim sees it. Escaping with backslash is standard vim syntax.

dusanx

unread,
Oct 2, 2021, 4:25:43 PM10/2/21
to vim/vim, Subscribed

maybe not all

If you spot something not working that means some character is missing from guiligatures, most probably space in your case.
Try

\ !\"#$%&()*+-./:<=>?@ABCDEFGHIKLMNOPRSTUVWX[]^_{\|~

and let me know, that is escaped string.

dusanx

unread,
Oct 2, 2021, 4:33:29 PM10/2/21
to vim/vim, Subscribed

Space ( ), double quotes (") and bar (|) need to be escaped by putting backslash () in front of such character. So if you try backslash then space it will work.

When you set string and you are happy with it, check if all characters made it with set giligatures? -- it will print string as vim sees it. Escaping with backslash is standard vim syntax.

Sorry I meant check with set guiligatures? - typing without my glasses on wasn't good idea.

dusanx

unread,
Oct 3, 2021, 6:14:42 AM10/3/21
to vim/vim, Subscribed

Gist updated to output escaped string ready for vim, so now final output looks like:

Final command, with escaped characters:
:set guiligatures=\ !\"#$%&()*+-./:<=>?@ABCDEFGHIKLMNOPRSTUVWX[]^_{\|~

dusanx

unread,
Oct 3, 2021, 6:36:53 AM10/3/21
to vim/vim, Subscribed

As a general rule, I would always try minimizing number of characters used. Of course faster computers will be quicker to output everything trough Pango but, for example, C++ syntax doesn't need two thirds of the ligatures listed in gist.

Alexander Gagarin

unread,
Oct 3, 2021, 12:10:15 PM10/3/21
to vim/vim, Subscribed

maybe not all

If you spot something not working that means some character is missing from guiligatures, most probably space in your case. Try

\ !\"#$%&()*+-./:<=>?@ABCDEFGHIKLMNOPRSTUVWX[]^_{\|~

and let me know, that is escaped string.

Thanks, works perfectly. I rarely change smth in .vimrc so already stared to forget Vim basics =)
Also checked ligatures from your gist -- seems that everything is OK.
BTW you should start using PragmataPro -- it's really great.

Manuel Schiller

unread,
Oct 15, 2021, 5:53:31 AM10/15/21
to vim/vim, Subscribed

I'm also using PragmataPro everywhere, so please share your settings with this latest patch revision =)

Here's what I use at the moment (now that I finally have a chance to revisit it):

set guiligatures=!\"$%&\'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~

I think that's roughly what my old version did, minus all the numbers (there's nothing happening to numbers in PragmataPro AFAICT). It has all the lowercase letters, so you get the improvements in kerning for certain keywords (try typing "virtual" or "public" with these settings and PragmataPro, and watch the word while typing the last letter, and be amazed...).

Thanks everybody for the hard work, especially @dusanx.

Alexander Gagarin

unread,
Nov 2, 2021, 3:07:15 AM11/2/21
to vim/vim, Subscribed

@dusanx @manuelschiller do this patch with ligatures support already in upstream?

Manuel Schiller

unread,
Nov 2, 2021, 3:23:52 AM11/2/21
to vim/vim, Subscribed

Yes, it is. Have fun with it!

Christian Brabandt

unread,
Nov 2, 2021, 4:38:50 AM11/2/21
to vim/vim, Subscribed

included as of 4eeedc0

It is loading more messages.
0 new messages