Skip to content

Add 'macfontfeatures' option for OpenType font features#1689

Open
humblehacker wants to merge 3 commits into
macvim-dev:masterfrom
humblehacker:add-macfontfeatures-option
Open

Add 'macfontfeatures' option for OpenType font features#1689
humblehacker wants to merge 3 commits into
macvim-dev:masterfrom
humblehacker:add-macfontfeatures-option

Conversation

@humblehacker

Copy link
Copy Markdown
Contributor

This adds a new MacVim-specific string option 'macfontfeatures' for enabling OpenType font features — character variants, stylistic sets, etc. — in the Core Text renderer, similar to font feature settings in other editors (e.g. Zed's buffer_font_features, VS Code's fontLigatures).

:set macfontfeatures=cv01,cv09,cv35   " bare tag is equivalent to tag=1
:set macfontfeatures=ss03=2,zero=0    " explicit values; =0 disables a default-on feature
:set macfontfeatures=                 " restore the font's default features

Implementation

The option follows the existing 'macligatures' pattern end to end:

  • A new global string option validated in did_set_macfontfeatures (each entry must be a four-character printable-ASCII tag, optionally =<number>; anything else fails with E474 and the old value is restored).
  • The value is sent to the GUI via a new SetFontFeaturesMsgID (appended before LoopBackMsgID so existing message IDs keep their values across version skew).
  • MMCoreTextView parses the list once into a kCTFontFeatureSettingsAttribute array and applies it in fontVariantForTextFlags: after bold/italic trait conversion, so the base, wide, bold, and italic fonts all pick up the features and they survive NSFontManager trait conversion. The fontVariants and characterLines caches are invalidated when the option changes.
  • The OpenType feature tag API (kCTFontOpenTypeFeatureTag) requires macOS 10.13; older systems ignore the setting via the usual @available guard. The legacy (non-Core Text) renderer ignores the option, matching 'macligatures'.

Testing

  • New assertions in test_macvim.vim (option existence, E474 validation, round-tripping) and value lists in gen_opt_test.vim; both pass, as does test_codestyle.vim.
  • Manually verified with Maple Mono: setting cv01,cv09 changes the rendered variants of @ $ & 7, features apply to bold/italic/wide variants, an unsupported tag renders unchanged, and clearing the option restores defaults.
  • Docs added to options.txt, gui_mac.txt, quickref.txt, doc tags, and the :options window (optwin.vim).

AI disclosure

This contribution was developed with AI assistance (Claude Code); the design, implementation, and documentation were AI-generated under my direction, and I reviewed and tested the result.

🤖 Generated with Claude Code

Add a SetFontFeaturesMsgID message that carries a comma-separated list
of OpenType feature settings ("tag" or "tag=N" entries).  The Core
Text renderer parses the list into a kCTFontFeatureSettingsAttribute
array and applies it when deriving the fonts used for drawing, so the
base, wide, bold and italic fonts all pick up the features.  Requires
macOS 10.13 for the OpenType feature tag API; older systems ignore the
setting.  The legacy renderer does not support font features.

Signed-off-by: David Whetstone <david@humblehacker.com>
The macfontfeatures option is a comma-separated list of OpenType font
features to enable, e.g.:

    :set macfontfeatures=cv01,cv09,ss03=2

Each entry is a four-character feature tag optionally followed by "="
and a number; a bare tag is equivalent to "tag=1".  This allows
selecting character variants and stylistic sets in fonts that provide
them, similar to font feature settings in other editors.  Setting the
option to an empty string restores the font's default features.

Invalid values are rejected with E474.  Includes tests for option
existence, validation and round-tripping.

Signed-off-by: David Whetstone <david@humblehacker.com>
Signed-off-by: David Whetstone <david@humblehacker.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant