Skip to content

feat(highlights)!: Use treesitter highlights #676

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

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 73 additions & 49 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ Enabled:
If this highlight group does not suit you, you can apply different highlight group to it:

```lua
vim.cmd[[autocmd ColorScheme * hi link OrgHideLeadingStars MyCustomHlGroup]]
vim.cmd[[autocmd ColorScheme * hi link @org.leading.stars MyCustomHlGroup]]
```

#### **org_hide_emphasis_markers**
Expand Down Expand Up @@ -1315,67 +1315,91 @@ Currently, these things are formatted:
## User interface

### Colors
Most of the highlight groups are linked to treesitter highlights where applicable (see `:h treesitter-highlight`).

The following highlight groups are used:

* `@org.headline.level.1`: Headline at level 1 - `linked to Title`
* `@org.headline.level.2`: Headline at level 2 - `linked to Constant`
* `@org.headline.level.3`: Headline at level 3 - `linked to Identifier`
* `@org.headline.level.4`: Headline at level 4 - `linked to Statement`
* `@org.headline.level.5`: Headline at level 5 - `linked to PreProc`
* `@org.headline.level.6`: Headline at level 6 - `linked to Type`
* `@org.headline.level.7`: Headline at level 7 - `linked to Special`
* `@org.headline.level.8`: Headline at level 8 - `linked to String`
* `@org.timestamp.active`: An active timestamp - linked to `@keyword`
* `@org.timestamp.inactive`: An inactive timestamp - linked to `@comment`
* `@org.keyword.todo`: TODO keywords color - Parsed from `Error` (see note below)
* `@org.keyword.done`: DONE keywords color - Parsed from `DiffAdd` (see note below)
* `@org.bullet`: A normal bullet under a header item - linked to `@markup.list`
* `@org.properties`: Property drawer start/end delimiters - linked to `@property`
* `@org.drawer`: Drawer start/end delimiters - linked to `@property`
* `@org.tag`: A tag for a headline item, shown on the righthand side like `:foo:` - linked to `@tag.attribute`
* `@org.plan`: `SCHEDULED`, `DEADLINE`, `CLOSED`, etc. keywords - linked to `Constant`
* `@org.comment`: A comment block - linked to `@comment`
* `@org.latex_env`: LaTeX block - linked to `@markup.environment`
* `@org.directive`: Blocks starting with `#+` - linked to `@comment`
* `@org.checkbox`: The default checkbox highlight, including square brackets - linked to `@markup.list.unchecked`
* `@org.checkbox.halfchecked`: A checkbox status (marker between `[]`) checked with `[-]` - linked to `@markup.list.unchecked`
* `@org.checkbox.checked`: A checkbox status (marker between `[]`) checked with either `[x]` or `[X]` - linked to `@markup.list.checked`
* `@org.bold`: **bold** text - linked to `@markup.strong`,
* `@org.bold.delimiter`: bold text delimiter `*` - linked to `@markup.strong`,
* `@org.italic`: *italic* text - linked to `@markup.italic`,
* `@org.italic.delimiter`: italic text delimiter `/` - linked to `@markup.italic`,
* `@org.strikethrough`: ~strikethrough~ text - linked to `@markup.strikethrough`,
* `@org.strikethrough.delimiter`: strikethrough text delimiter `+` - linked to `@markup.strikethrough`,
* `@org.underline`: <u>underline<u/> text - linked to `@markup.underline`,
* `@org.underline.delimiter`: underline text delimiter `_` - linked to `@markup.underline`,
* `@org.code`: `code` text - linked to `@markup.raw`,
* `@org.code.delimiter`: code text delimiter `~` - linked to `@markup.raw`,
* `@org.verbatim`: `verbatim` text - linked to `@markup.raw`,
* `@org.verbatim.delimiter`: verbatim text delimiter `=` - linked to `@markup.raw`,
* `@org.hyperlink`: [link](link) text - linked to `@markup.link.url`,
* `@org.latex`: Inline latex - linked to `@markup.math`,
* `@org.table.delimiter` - `|` and `-` delimiters in tables - linked to `@punctuation.special`,
* `@org.table.heading` - Table headings - linked to `@markup.heading`,
* `@org.edit_src` - The highlight for the source content in an _Org_ buffer while it is being edited in an edit special buffer - linked to `Visual`,
* `@org.agenda.deadline`: A item deadline in the agenda view - Parsed from `Error` (see note below)
* `@org.agenda.scheduled`: A scheduled item in the agenda view - Parsed from `DiffAdd` (see note dbelow)
* `@org.agenda.scheduled_past`: A item past its scheduled date in the agenda view - Parsed from `WarningMsg` (see note below)

Note:

Colors used for todo keywords and agenda states (deadline, schedule ok, schedule warning)
are parsed from the current colorsheme from several highlight groups (Error, WarningMsg, DiffAdd, etc.).
If those colors are not suitable you can override them like this:
are parsed from the current colorscheme from several highlight groups (Error, WarningMsg, DiffAdd, etc.).

```vim
autocmd ColorScheme * call s:setup_org_colors()

function! s:setup_org_colors() abort
hi OrgAgendaDeadline guifg=#FFAAAA
hi OrgAgendaScheduled guifg=#AAFFAA
hi OrgAgendaScheduledPast guifg=Orange
endfunction
#### Overriding colors
All colors can be overridden by either setting new values or linking to another highlight group:
```lua
vim.api.nvim_create_autocmd('ColorScheme', {
pattern = '*',
callback = function()
-- Define own colors
vim.api.nvim_set_hl(0, '@org.agenda.deadline', { fg = '#FFAAAA' })
vim.api.nvim_set_hl(0, '@org.agenda.scheduled', { fg = '#AAFFAA' })
-- Link to another highlight group
vim.api.nvim_set_hl(0, '@org.agenda.scheduled_past', { link = 'Statement' })
end
})
```

or you can link it to another highlight group:
Or in Vimscript:

```vim
autocmd ColorScheme * call s:setup_org_colors()

function! s:setup_org_colors() abort
hi link OrgAgendaDeadline Error
hi link OrgAgendaScheduled DiffAdd
hi link OrgAgendaScheduledPast Statement
" Define own colors
hi @org.agenda.deadline guifg=#FFAAAA
hi @org.agenda.scheduled guifg=#AAFFAA
" Link to another highlight group
hi link @org.agenda.scheduled_past Statement
endfunction
```

For adding/changing TODO keyword colors see [org-todo-keyword-faces](#org_todo_keyword_faces)

#### Highlight Groups

* The following highlight groups are based on _Treesitter_ query results, hence when setting up _Orgmode_ these
highlights must be enabled by removing `disable = {'org'}` from the default recommended _Treesitter_ configuration.

* `OrgTSTimestampActive`: An active timestamp
* `OrgTSTimestampInactive`: An inactive timestamp
* `OrgTSBullet`: A normal bullet under a header item
* `OrgTSPropertyDrawer`: Property drawer start/end delimiters
* `OrgTSDrawer`: Drawer start/end delimiters
* `OrgTSTag`: A tag for a headline item, shown on the righthand side like `:foo:`
* `OrgTSPlan`: `SCHEDULED`, `DEADLINE`, `CLOSED`, etc. keywords
* `OrgTSComment`: A comment block
* `OrgTSLatex`: LaTeX block
* `OrgTSDirective`: Blocks starting with `#+`
* `OrgTSCheckbox`: The default checkbox highlight, overridden if any of the below groups are specified
* `OrgTSCheckboxChecked`: A checkbox checked with either `[x]` or `[X]`
* `OrgTSCheckboxHalfChecked`: A checkbox checked with `[-]`
* `OrgTSCheckboxUnchecked`: A empty checkbox
* `OrgTSHeadlineLevel1`: Headline at level 1
* `OrgTSHeadlineLevel2`: Headline at level 2
* `OrgTSHeadlineLevel3`: Headline at level 3
* `OrgTSHeadlineLevel4`: Headline at level 4
* `OrgTSHeadlineLevel5`: Headline at level 5
* `OrgTSHeadlineLevel6`: Headline at level 6
* `OrgTSHeadlineLevel7`: Headline at level 7
* `OrgTSHeadlineLevel8`: Headline at level 8

* The following use vanilla _Vim_ syntax matching, and will work without _Treesitter_ highlighting enabled.

* `OrgEditSrcHighlight`: The highlight for the source content in an _Org_ buffer while it is being edited in an edit special buffer
* `OrgAgendaDeadline`: A item deadline in the agenda view
* `OrgAgendaScheduled`: A scheduled item in the agenda view
* `OrgAgendaScheduledPast`: A item past its scheduled date in the agenda view

### Menu

The menu is used when selecting further actions in `agenda`, `capture` and `export`. Here is an example of the menu you see when opening `agenda`:
Expand Down
2 changes: 1 addition & 1 deletion lua/orgmode/agenda/views/agenda.lua
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function AgendaView:build()

if is_today or is_weekend then
table.insert(highlights, {
hlgroup = 'OrgBold',
hlgroup = '@org.bold',
range = Range:new({
start_line = #content + 1,
end_line = #content + 1,
Expand Down
4 changes: 2 additions & 2 deletions lua/orgmode/clock/report.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function ClockReport:draw_for_agenda(start_line)
range.start_col = range.start_col + 1
range.end_col = range.end_col + 2
table.insert(highlights, {
hlgroup = 'OrgBold',
hlgroup = '@org.bold',
range = range,
})
end
Expand All @@ -67,7 +67,7 @@ function ClockReport:draw_for_agenda(start_line)
range.start_col = range.start_col + 1
range.end_col = range.end_col + 2
table.insert(highlights, {
hlgroup = 'OrgUnderline',
hlgroup = '@org.hyperlink',
range = range,
})
end
Expand Down
4 changes: 0 additions & 4 deletions lua/orgmode/colors/highlighter/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ end

---@private
function OrgHighlighter:_setup()
local ts_highlights_enabled = config:ts_highlights_enabled()
if not ts_highlights_enabled then
return
end
self.stars = require('orgmode.colors.highlighter.stars'):new({ highlighter = self })
self.markup = require('orgmode.colors.highlighter.markup'):new({ highlighter = self })
self.todos = require('orgmode.colors.highlighter.todos'):new()
Expand Down
2 changes: 1 addition & 1 deletion lua/orgmode/colors/highlighter/markup/dates.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function OrgDates:highlight(highlights, bufnr)
vim.api.nvim_buf_set_extmark(bufnr, namespace, entry.from.line, entry.from.start_col, {
ephemeral = ephemeral,
end_col = entry.to.end_col,
hl_group = entry.char == '>' and 'OrgTSTimestampActive' or 'OrgTSTimestampInactive',
hl_group = entry.char == '>' and '@org.timestamp.active' or '@org.timestamp.inactive',
priority = 110,
})
end
Expand Down
33 changes: 8 additions & 25 deletions lua/orgmode/colors/highlighter/markup/emphasis.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,28 @@ local valid_post_marker_chars =

local markers = {
['*'] = {
hl_name = 'org_bold',
hl_cmd = 'hi def %s term=bold cterm=bold gui=bold',
hl_name = '@org.bold',
nestable = true,
},
['/'] = {
hl_name = 'org_italic',
hl_cmd = 'hi def %s term=italic cterm=italic gui=italic',
hl_name = '@org.italic',
nestable = true,
},
['_'] = {
hl_name = 'org_underline',
hl_cmd = 'hi def %s term=underline cterm=underline gui=underline',
hl_name = '@org.underline',
nestable = true,
},
['+'] = {
hl_name = 'org_strikethrough',
hl_cmd = 'hi def %s term=strikethrough cterm=strikethrough gui=strikethrough',
hl_name = '@org.strikethrough',
nestable = true,
},
['~'] = {
hl_name = 'org_code',
hl_cmd = 'hi def link %s String',
hl_name = '@org.code',
nestable = false,
spell = false,
},
['='] = {
hl_name = 'org_verbatim',
hl_cmd = 'hi def link %s String',
hl_name = '@org.verbatim',
nestable = false,
spell = false,
},
Expand All @@ -51,7 +45,6 @@ function OrgEmphasis:new(opts)
}
setmetatable(data, self)
self.__index = self
data:_add_hl_groups()
return data
end

Expand All @@ -68,7 +61,7 @@ function OrgEmphasis:highlight(highlights, bufnr)
vim.api.nvim_buf_set_extmark(bufnr, namespace, entry.from.line, entry.from.start_col, {
ephemeral = ephemeral,
end_col = entry.from.end_col,
hl_group = markers[entry.char].hl_name .. '_delimiter',
hl_group = markers[entry.char].hl_name .. '.delimiter',
spell = markers[entry.char].spell,
priority = 110 + entry.from.start_col,
conceal = conceal,
Expand All @@ -78,7 +71,7 @@ function OrgEmphasis:highlight(highlights, bufnr)
vim.api.nvim_buf_set_extmark(bufnr, namespace, entry.from.line, entry.to.start_col, {
ephemeral = ephemeral,
end_col = entry.to.end_col,
hl_group = markers[entry.char].hl_name .. '_delimiter',
hl_group = markers[entry.char].hl_name .. '.delimiter',
spell = markers[entry.char].spell,
priority = 110 + entry.from.start_col,
conceal = conceal,
Expand Down Expand Up @@ -136,14 +129,4 @@ function OrgEmphasis:is_valid_end_node(entry, bufnr)
and end_text:sub(1, 1) ~= ' '
end

function OrgEmphasis:_add_hl_groups()
for _, marker in pairs(markers) do
vim.cmd(string.format(marker.hl_cmd, marker.hl_name))
if marker.delimiter_hl then
vim.cmd(string.format(marker.hl_cmd, marker.hl_name .. '_delimiter'))
end
end
vim.cmd('hi def link org_hyperlink Underlined')
end

return OrgEmphasis
7 changes: 1 addition & 6 deletions lua/orgmode/colors/highlighter/markup/latex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ function OrgLatex:new(opts)
}
setmetatable(data, self)
self.__index = self
data:_add_hl_groups()
return data
end

Expand Down Expand Up @@ -89,10 +88,6 @@ function OrgLatex:parse_node(node)
return info
end

function OrgLatex:_add_hl_groups()
vim.cmd('hi def link org_latex OrgTSLatex')
end

---@param highlights OrgMarkupHighlight[]
---@param bufnr number
function OrgLatex:highlight(highlights, bufnr)
Expand All @@ -102,7 +97,7 @@ function OrgLatex:highlight(highlights, bufnr)
vim.api.nvim_buf_set_extmark(bufnr, namespace, entry.from.line, entry.from.start_col - 1, {
ephemeral = ephemeral,
end_col = entry.to.end_col,
hl_group = 'org_latex',
hl_group = '@org.latex',
spell = false,
priority = 110 + entry.from.start_col,
})
Expand Down
2 changes: 1 addition & 1 deletion lua/orgmode/colors/highlighter/markup/link.lua
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function OrgLink:highlight(highlights, bufnr)
vim.api.nvim_buf_set_extmark(bufnr, namespace, entry.from.line, entry.from.start_col, {
ephemeral = ephemeral,
end_col = entry.to.end_col,
hl_group = 'org_hyperlink',
hl_group = '@org.hyperlink',
priority = 110,
})

Expand Down
2 changes: 1 addition & 1 deletion lua/orgmode/colors/highlighter/stars.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function OrgStars:on_line(bufnr, line)
vim.api.nvim_buf_set_extmark(bufnr, self.highlighter.namespace, line, 0, {
end_line = line,
end_col = end_col - 1,
hl_group = 'OrgHideLeadingStars',
hl_group = '@org.leading_stars',
ephemeral = true,
})
end
Expand Down
4 changes: 2 additions & 2 deletions lua/orgmode/colors/highlighter/todos.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function OrgTodos:_add_highlights()
if not query_files or #query_files == 0 then
return
end
local faces = highlights.parse_todo_keyword_faces()
local faces = highlights.define_todo_keyword_faces()
if not faces or vim.tbl_isempty(faces) then
return
end
Expand All @@ -35,7 +35,7 @@ function OrgTodos:_add_highlights()
for face_name, face_hl in pairs(faces) do
table.insert(
lines,
string.format([[(item . (expr) @%s @nospell (#eq? @%s %s))]], face_hl, face_hl, face_name)
string.format([[(item . (expr) %s @nospell (#eq? %s %s))]], face_hl, face_hl, face_name)
)
end
return lines
Expand Down
Loading