Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce GrammarState #712

Merged
merged 3 commits into from
Jun 28, 2024
Merged

feat: introduce GrammarState #712

merged 3 commits into from
Jun 28, 2024

Conversation

antfu
Copy link
Member

@antfu antfu commented Jun 27, 2024

Motivations

Sometimes, we might want to highlight a partial of the code snippet, which might not necessarily be a full language statement.

For example, if we want to highlight a TypeScript type annotation Pick<MyObject, string>[] we might do:

import { codeToHtml } from 'shiki'

const highlighted = await codeToHtml('Pick<MyObject, string>[]', { lang: 'ts', theme: 'github-dark' })

We will get the result like this:

image

This isn't accurate. This is because from the grammar, Shiki doesn't know it's a type annotation already.

Instead, we could append let a: to our code to hint that:

import { codeToHtml } from 'shiki'

const highlighted = await codeToHtml('let a: Pick<MyObject, string>[]', { lang: 'ts', theme: 'github-dark' })

Which will now render:

Screenshot 2024-06-27 at 18 25 47

While the highlighting is now correct, we have another challenge: removing the "temporary snippet" we just added from the highlighted HTML.

Solutions

This PR introduces a new concept, GrammarState, with a few APIs around it. GrammarState is a special token that holds the grammar context and allows you to highlight from an intermediate grammar state, making it easier to highlight code snippets.

For example, you can get the grammar state with the getLastGrammarState method, and pass into the grammarState option:

import { createHighlighter } from 'shiki'

const shiki = await createHighlighter({ langs: ['ts'], themes: ['github-dark'] })

const stateTypeAnnotation = shiki.getLastGrammarState('let a:', { lang: 'ts', theme: 'github-dark' })

const highlightedType = shiki.codeToHtml(
  'Pick<MyObject, string>[]',
  {
     lang: 'ts', 
     theme: 'github-dark',
     grammarState: stateTypeAnnotation // <--- this
  }
)

Now Shiki would highlight correctly as it knows to start as the type annotation. You can keep that grammar state object for multiple uses as well.

image

For one-off grammar context shifting, we also provide a shorthand by the grammarContextCode option:

const highlightedType = shiki.codeToHtml(
  'Pick<MyObject, string>[]',
  {
     lang: 'ts', 
     theme: 'github-dark',
     grammarContextCode: 'let a:' // same as above, a temporary grammar state is created internally
  }
)

Credits

Thanks to @benjamincanac for the idea and discussions

Copy link

codecov bot commented Jun 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.30%. Comparing base (603713d) to head (0953f83).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #712      +/-   ##
==========================================
+ Coverage   96.21%   96.30%   +0.09%     
==========================================
  Files          71       72       +1     
  Lines        6072     6226     +154     
  Branches      805      829      +24     
==========================================
+ Hits         5842     5996     +154     
  Misses        225      225              
  Partials        5        5              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@shikijs shikijs deleted a comment from netlify bot Jun 27, 2024
@shikijs shikijs deleted a comment from netlify bot Jun 27, 2024
@antfu antfu merged commit 8a8faf9 into main Jun 28, 2024
13 checks passed
@antfu antfu deleted the feat/grammar-state branch June 28, 2024 08:06
@orta
Copy link
Contributor

orta commented Jun 28, 2024

Cool idea

diegohaz referenced this pull request in ariakit/ariakit Jul 4, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [shiki](https://togithub.com/shikijs/shiki)
([source](https://togithub.com/shikijs/shiki/tree/HEAD/packages/shiki))
| [`1.7.0` ->
`1.10.1`](https://renovatebot.com/diffs/npm/shiki/1.7.0/1.10.1) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/shiki/1.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/shiki/1.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/shiki/1.7.0/1.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/shiki/1.7.0/1.10.1?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>shikijs/shiki (shiki)</summary>

### [`v1.10.1`](https://togithub.com/shikijs/shiki/releases/tag/v1.10.1)

[Compare
Source](https://togithub.com/shikijs/shiki/compare/v1.10.0...v1.10.1)

#####    🐞 Bug Fixes

- **rehype**: Default export use shared highlighter instance, fix
[#&#8203;714](https://togithub.com/shikijs/shiki/issues/714)  -  by
[@&#8203;antfu](https://togithub.com/antfu) in
[https://github.com/shikijs/shiki/issues/714](https://togithub.com/shikijs/shiki/issues/714)
[<samp>(c4f03)</samp>](https://togithub.com/shikijs/shiki/commit/c4f030d7)

#####     [View changes on
GitHub](https://togithub.com/shikijs/shiki/compare/v1.10.0...v1.10.1)

### [`v1.10.0`](https://togithub.com/shikijs/shiki/releases/tag/v1.10.0)

[Compare
Source](https://togithub.com/shikijs/shiki/compare/v1.9.1...v1.10.0)

#####    🚀 Features

- Introduce `GrammarState`  -  by
[@&#8203;antfu](https://togithub.com/antfu) in
[https://github.com/shikijs/shiki/issues/712](https://togithub.com/shikijs/shiki/issues/712)
[<samp>(8a8fa)</samp>](https://togithub.com/shikijs/shiki/commit/8a8faf9f)
- Expose `getLastGrammarState` shorthand  -  by
[@&#8203;antfu](https://togithub.com/antfu)
[<samp>(f2b39)</samp>](https://togithub.com/shikijs/shiki/commit/f2b39561)
- Update themes and grammars  -  by
[@&#8203;antfu](https://togithub.com/antfu)
[<samp>(02bf0)</samp>](https://togithub.com/shikijs/shiki/commit/02bf0179)

#####    🐞 Bug Fixes

- Expose `createCssVariablesTheme` in `shiki/core` to avoid side-effects
 -  by [@&#8203;antfu](https://togithub.com/antfu)
[<samp>(abe63)</samp>](https://togithub.com/shikijs/shiki/commit/abe639d9)

#####     [View changes on
GitHub](https://togithub.com/shikijs/shiki/compare/v1.9.1...v1.10.0)

### [`v1.9.1`](https://togithub.com/shikijs/shiki/releases/tag/v1.9.1)

[Compare
Source](https://togithub.com/shikijs/shiki/compare/v1.9.0...v1.9.1)

#####    🚀 Features

- Remove notation escape  -  by
[@&#8203;sor4chi](https://togithub.com/sor4chi) in
[https://github.com/shikijs/shiki/issues/709](https://togithub.com/shikijs/shiki/issues/709)
[<samp>(dbc1f)</samp>](https://togithub.com/shikijs/shiki/commit/dbc1fa1d)

#####     [View changes on
GitHub](https://togithub.com/shikijs/shiki/compare/v1.9.0...v1.9.1)

### [`v1.9.0`](https://togithub.com/shikijs/shiki/releases/tag/v1.9.0)

[Compare
Source](https://togithub.com/shikijs/shiki/compare/v1.8.0...v1.9.0)

#####    🚨 Breaking Changes

- Rename `getHighlighter` to `createHighlighter`  -  by
[@&#8203;antfu](https://togithub.com/antfu) in
[https://github.com/shikijs/shiki/issues/702](https://togithub.com/shikijs/shiki/issues/702)
[<samp>(faf3b)</samp>](https://togithub.com/shikijs/shiki/commit/faf3bd2f)

#####     [View changes on
GitHub](https://togithub.com/shikijs/shiki/compare/v1.8.0...v1.9.0)

### [`v1.8.0`](https://togithub.com/shikijs/shiki/releases/tag/v1.8.0)

[Compare
Source](https://togithub.com/shikijs/shiki/compare/v1.7.0...v1.8.0)

#####    🚀 Features

- **core**: Expose `dispose` function  -  by
[@&#8203;antfu](https://togithub.com/antfu) in
[https://github.com/shikijs/shiki/issues/707](https://togithub.com/shikijs/shiki/issues/707)
[<samp>(2c5b3)</samp>](https://togithub.com/shikijs/shiki/commit/2c5b3873)

#####     [View changes on
GitHub](https://togithub.com/shikijs/shiki/compare/v1.7.0...v1.8.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/ariakit/ariakit).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40MTMuMiIsInVwZGF0ZWRJblZlciI6IjM3LjQyMS45IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.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.

2 participants