this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Neovim: configure tree-sitter highlight for vscode

- Lots of nvim changes here for vscode treesitter highlighting to work
- Update some treesitter queries (e.g. injections) and toggle various
languages
- Move vscode-neovim customizations to a plugin file

TODO: More modularization and cleanup my init.lua a lot

+527 -37
+137
.config/nvim/after/plugin/vscode-custom.lua
··· 1 + if not vim.g.vscode then 2 + return 3 + end 4 + 5 + -- Disable regular syntax highlights, we only care about treesitter 6 + vim.cmd("syntax off") 7 + 8 + -- Languages without vscode highlighting: 9 + local enabled_langs = { "vimdoc", "query" } 10 + -- These languages have a vscode grammar/LSP, but not injection support; we can 11 + -- use treesitter's injection to supplement syntax highlighting (nice!) 12 + local injected_langs = VSCODE_INJECTED_LANGS 13 + 14 + local injection_disabled = { "markdown" } 15 + 16 + -- Wrap this whole thing in a pcall in case treesitter isn't installed 17 + local success, error = pcall(function() 18 + local ts_parsers = require("nvim-treesitter.parsers") 19 + 20 + for _, lang in pairs(ts_parsers.available_parsers()) do 21 + if ts_parsers.has_parser(lang) and not vim.list_contains(enabled_langs, lang) then 22 + -- Disable everything but injections + nvim-surround 23 + for _, query in ipairs({ "locals", "folds", "indents" }) do 24 + vim.treesitter.query.set(lang, query, "") 25 + end 26 + 27 + -- Keep highlights active for injected langs, that's the whole point 28 + if not vim.list_contains(injected_langs, lang) then 29 + vim.treesitter.query.set(lang, "highlights", "") 30 + end 31 + 32 + -- would love to do something like this but there doesn't seem to be 33 + -- a way to go back to parsed query from query info... 34 + --[[ 35 + local q = vim.treesitter.query.get(lang, "highlights") 36 + for _, pattern in pairs(q.info.patterns) do 37 + table.insert(pattern, { "injected?" }) 38 + end 39 + ]] 40 + 41 + if vim.list_contains(injection_disabled, lang) then 42 + vim.treesitter.query.set(lang, "injections", "") 43 + end 44 + end 45 + end 46 + 47 + -- Completely deregister everything vscode-neovim does for highlights 48 + vim.api.nvim_create_augroup("vscode.treesitter", { clear = true }) 49 + local hl_group = vim.api.nvim_create_augroup("vscode.highlight", { clear = true }) 50 + 51 + local function fixup_highlights() 52 + -- And then reimplement a subset of it (i.e. just global highlights) 53 + -- https://github.com/vscode-neovim/vscode-neovim/blob/master/runtime/lua/vscode/highlight.lua#L25 54 + -- Probably this could be upstreamed as a simple config option or something... 55 + for name, value in pairs({ 56 + ColorColumn = {}, 57 + CursorColumn = {}, 58 + CursorLine = {}, 59 + CursorLineNr = {}, 60 + Debug = {}, 61 + EndOfBuffer = {}, 62 + FoldColumn = {}, 63 + Folded = {}, 64 + LineNr = {}, 65 + LineNrAbove = {}, 66 + LineNrBelow = {}, 67 + MatchParen = {}, 68 + MsgArea = {}, 69 + MsgSeparator = {}, 70 + NonText = {}, 71 + Normal = {}, 72 + NormalFloat = {}, 73 + NormalNC = {}, 74 + NormalSB = {}, 75 + Question = {}, 76 + QuickFixLine = {}, 77 + Quote = {}, 78 + Sign = {}, 79 + SignColumn = {}, 80 + Substitute = {}, 81 + Visual = {}, 82 + VisualNC = {}, 83 + VisualNOS = {}, 84 + Whitespace = {}, 85 + 86 + -- make cursor visible for plugins that use fake cursor 87 + Cursor = { reverse = true }, 88 + 89 + ["@markup.link"] = {}, 90 + ["@markup.link.label"] = {}, 91 + ["@markup.link.url"] = {}, 92 + 93 + ["@markup.raw.markdown_inline"] = { 94 + fg = "#FD971F", 95 + bold = false, 96 + italic = false, 97 + }, 98 + ["@markup.strong"] = { fg = "#66D9EF", bold = true }, 99 + ["@markup.italic"] = { fg = "#66D9EF", italic = true }, 100 + }) do 101 + if vim.tbl_isempty(value) then 102 + vim.api.nvim_set_hl(0, name, { link = "VSCodeNone", force = true }) 103 + else 104 + vim.api.nvim_set_hl(0, name, value) 105 + end 106 + end 107 + end 108 + 109 + vim.api.nvim_create_autocmd({ "ColorScheme" }, { group = hl_group, callback = fixup_highlights }) 110 + 111 + vim.api.nvim_create_autocmd({ 112 + "BufEnter", 113 + "BufLeave", 114 + "WinEnter", 115 + "WinLeave", 116 + "BufWinEnter", 117 + "BufWinLeave", 118 + "WinScrolled", 119 + "FocusGained", 120 + "VimEnter", 121 + "UIEnter", 122 + }, { 123 + group = hl_group, 124 + callback = function() 125 + -- There are still some oddities with scrolling etc. for redraw, 126 + -- haven't quite figured out the details yet... 127 + vim.cmd("mode") 128 + vim.cmd("redraw!") 129 + end, 130 + }) 131 + 132 + fixup_highlights() 133 + end) 134 + 135 + if not success then 136 + vim.print("failed to do vscode-hl setup", error) 137 + end
+19
.config/nvim/after/queries/rust/injections.scm
··· 1 + ; extends 2 + 3 + ( 4 + (doc_comment) @injection.content 5 + (#set! injection.language "markdown_inline") 6 + (#set! injection.combined) 7 + ) 8 + 9 + ( 10 + (doc_comment) @injection.content 11 + (#set! injection.language "markdown") 12 + ; (#set! injection.combined) 13 + (#set! priority 110) 14 + ) 15 + 16 + ((macro_invocation 17 + macro: (identifier) @injection.language 18 + (token_tree) @injection.content) 19 + (#any-of? @injection.language "html" "json"))
+99 -37
.config/nvim/init.lua
··· 26 26 require("nvim-surround").setup() 27 27 require("ns-textobject").setup() 28 28 29 + -- Global, used in ./after/lua/vscode-custom.lua 30 + VSCODE_INJECTED_LANGS = {} 31 + 32 + -- Wrap this in a pcall in case treesitter isn't installed 33 + local success, error = pcall(function() 34 + -- langs without vscode equivalent, always enable highlights for these 35 + 36 + if vim.g.vscode then 37 + -- TODO: I'd love to figure out how to disable these at the top-level and only enable for injections 38 + VSCODE_INJECTED_LANGS = { "fish", "bash", "javascript", "vim", "regex", "markdown_inline", "markdown", "lua", "json" } 39 + end 40 + 41 + vim.treesitter.query.add_predicate("vscode?", function() 42 + return vim.g.vscode and true or false 43 + end, { force = true, all = true }) 44 + 45 + vim.treesitter.query.add_predicate("injected?", function(_match, _pattern, buf, pred) 46 + if type(buf) ~= "number" then 47 + return 48 + end 49 + 50 + local parser_ft = vim.filetype.match({ buf = buf }) 51 + local buf_ft = vim.filetype.match({ buf = vim.fn.bufnr() }) 52 + 53 + return buf_ft ~= parser_ft 54 + end, { force = true, all = true }) 55 + 56 + require("nvim-treesitter.configs").setup({ 57 + highlight = { 58 + enable = true, 59 + -- These can be disabled at the top level like this, but they're still allowed 60 + -- as injected languages so e.g. vim.cmd and nix injections work, without 61 + -- taking over highlights in vscode 62 + disable = VSCODE_INJECTED_LANGS, 63 + }, 64 + }) 65 + end) 66 + 67 + if not success then 68 + vim.print("Failed to pcall hl setup!", error) 69 + end 70 + 29 71 -- TODO: convert remainder of this to proper Lua config 30 72 31 73 if not vim.g.vscode then 32 74 -- Default to dark mode if unset 33 75 vim.opt.background = os.getenv("COLOR_THEME") or "dark" 34 76 35 - require("monokai-nightasty").setup({ 36 - on_highlights = function(highlights, colors) 37 - -- It seems like most syntaxes just use String for quotes, but 38 - -- for some (e.g. JSON) they are highlighted differently. 39 - -- This just forces them back to regular String highlight 40 - highlights.Quote = highlights.String 41 - 42 - -- More like the old vim highlighting: 43 - highlights.gitcommitSummary, highlights.gitcommitOverflow = 44 - highlights.gitcommitOverflow, highlights.gitcommitSummary 45 - end, 46 - }) 47 - vim.cmd.colorscheme("monokai-nightasty") 48 - 49 - -- Wrap this in a pcall in case treesitter isn't installed 50 - pcall(function() 51 - require("nvim-treesitter.configs").setup({ 52 - highlight = { enable = true }, 53 - }) 54 - end) 77 + if vim.fn.has("wsl") ~= 0 then 78 + vim.g.clipboard = { 79 + name = "WslClipboard", 80 + copy = { 81 + ["+"] = "clip.exe", 82 + ["*"] = "clip.exe", 83 + }, 84 + paste = { 85 + -- yeesh, is this really the only way to deal with this? See :h clipboard-wsl 86 + -- fish_clipboard_paste looks like it's doing basically the same thing too 87 + ["+"] = 'powershell.exe -c [Console]::Out.Write($(Get-Clipboard -Raw).tostring().replace("`r", ""))', 88 + ["*"] = 'powershell.exe -c [Console]::Out.Write($(Get-Clipboard -Raw).tostring().replace("`r", ""))', 89 + }, 90 + cache_enabled = false, 91 + } 92 + end 55 93 56 94 -- TODO: https://github.com/akinsho/git-conflict.nvim 57 95 else ··· 62 100 63 101 local group = vim.api.nvim_create_augroup("vscode-custom", {}) 64 102 65 - -- https://github.com/vscode-neovim/vscode-neovim/issues/1718 66 - vim.api.nvim_create_autocmd({ "VimEnter", "ModeChanged" }, { 67 - pattern = "*", 103 + -- rust-analyzer commands doesn't play super nice with neovim join/match brace; this autocmd 104 + -- setups up bindings to use the builtin motion commands in operator-pending mode 105 + vim.api.nvim_create_autocmd({ "FileType" }, { 106 + pattern = { "*.rs" }, 68 107 group = group, 69 - callback = function(args) 70 - vscode.call("setContext", { 71 - args = { "neovim.fullMode", vim.fn.mode(1) }, 72 - }) 108 + callback = function() 109 + vim.keymap.set({ "n", "v" }, "%", function() 110 + if vim.fn.state("o") ~= "" then 111 + vscode.action("rust-analyzer.matchingBrace") 112 + return "" 113 + end 114 + 115 + return "%" 116 + end, { silent = true, remap = true, expr = true }) 117 + 118 + vim.keymap.set({ "n", "v" }, "J", function() 119 + if vim.fn.state("o") ~= "" then 120 + vscode.action("rust-analyzer.joinLines") 121 + return "" 122 + end 123 + 124 + return "J" 125 + end, { silent = true, remap = true, expr = true }) 73 126 end, 74 127 }) 75 128 76 129 -- https://github.com/vscode-neovim/vscode-neovim/issues/1718#issuecomment-2078380657 77 - vim.keymap.set("n", "r", function() 78 - vscode.call("setContext", { 79 - args = { "neovim.fullMode", vim.fn.mode(1) .. "r" }, 80 - }) 81 - 82 - vim.api.nvim_feedkeys("r", "n", true) 83 - end) 84 130 85 131 -- For whatever reason, nvim buffers sometimes open without line numbers: 86 132 vim.opt.number = true ··· 112 158 113 159 vim.cmd([[ 114 160 xnoremap <silent> <Esc> :<C-u>call VSCodeNotify('closeFindWidget')<CR> 161 + 115 162 nnoremap <silent> <Esc> :<C-u>call VSCodeNotify('closeFindWidget')<CR> 116 163 117 164 " Disable airline by pretending it's already loaded ··· 138 185 139 186 nmap <D-a> ggVG 140 187 141 - " Move cursor to end of line when making visual selection so % works as expected 142 - nmap V V$ 143 - 144 188 " Remap for append/insert with multi-cursor to avoid extra keystroke 145 189 xmap <expr> a visualmode() ==# 'v' ? 'a' : 'ma' 146 190 xmap <expr> A visualmode() ==# 'v' ? 'A' : 'mA' ··· 200 244 let g:loaded_airline = 1 201 245 ]]) 202 246 end 247 + 248 + -- Do this at the end so ColorScheme autocmds work: 249 + 250 + ---@diagnostic disable-next-line: missing-fields 251 + require("monokai-nightasty").setup({ 252 + on_highlights = function(highlights, colors) 253 + -- It seems like most syntaxes just use String for quotes, but 254 + -- for some (e.g. JSON) they are highlighted differently. 255 + -- This just forces them back to regular String highlight 256 + highlights.Quote = highlights.String 257 + 258 + -- More like the old vim highlighting: 259 + highlights.gitcommitSummary, highlights.gitcommitOverflow = 260 + highlights.gitcommitOverflow, highlights.gitcommitSummary 261 + end, 262 + }) 263 + 264 + vim.cmd.colorscheme("monokai-nightasty")
+5
.config/nvim/queries/lua/highlights.scm
··· 1 + ; Keywords 2 + ( 3 + "return" @function 4 + (#injected?) 5 + )
+124
.config/nvim/queries/markdown/highlights.scm
··· 1 + ;From MDeiml/tree-sitter-markdown & Helix 2 + (setext_heading 3 + (paragraph) @markup.heading.1 4 + (setext_h1_underline) @markup.heading.1) 5 + 6 + (setext_heading 7 + (paragraph) @markup.heading.2 8 + (setext_h2_underline) @markup.heading.2) 9 + 10 + (atx_heading 11 + (atx_h1_marker)) @markup.heading.1 12 + 13 + (atx_heading 14 + (atx_h2_marker)) @markup.heading.2 15 + 16 + (atx_heading 17 + (atx_h3_marker)) @markup.heading.3 18 + 19 + (atx_heading 20 + (atx_h4_marker)) @markup.heading.4 21 + 22 + (atx_heading 23 + (atx_h5_marker)) @markup.heading.5 24 + 25 + (atx_heading 26 + (atx_h6_marker)) @markup.heading.6 27 + 28 + (info_string) @label 29 + 30 + (pipe_table_header 31 + (pipe_table_cell) @markup.heading) 32 + 33 + (pipe_table_header 34 + "|" @punctuation.special) 35 + 36 + (pipe_table_row 37 + "|" @punctuation.special) 38 + 39 + (pipe_table_delimiter_row 40 + "|" @punctuation.special) 41 + 42 + (pipe_table_delimiter_cell) @punctuation.special 43 + 44 + ; Code blocks (conceal backticks and language annotation) 45 + ( 46 + (indented_code_block) @markup.raw.block 47 + (#not-vscode?)) 48 + 49 + ((fenced_code_block) @markup.raw.block 50 + (#set! priority 90) 51 + (#not-vscode?)) 52 + 53 + (fenced_code_block 54 + (fenced_code_block_delimiter) @markup.raw.block 55 + (#set! conceal "")) 56 + 57 + (fenced_code_block 58 + (info_string 59 + (language) @label 60 + (#set! conceal ""))) 61 + 62 + (link_destination) @markup.link.url 63 + 64 + [ 65 + (link_title) 66 + (link_label) 67 + ] @markup.link.label 68 + 69 + ((link_label) 70 + . 71 + ":" @punctuation.delimiter) 72 + 73 + [ 74 + (list_marker_plus) 75 + (list_marker_minus) 76 + (list_marker_star) 77 + (list_marker_dot) 78 + (list_marker_parenthesis) 79 + ] @markup.list 80 + 81 + ; NOTE: The following has been commented out due to issues with spaces in the 82 + ; list marker nodes generated by the parser. If those spaces ever get captured 83 + ; by a different node (e.g. block_continuation) we can safely re-add these 84 + ; conceals. 85 + ; ;; Conceal bullet points 86 + ; ([(list_marker_plus) (list_marker_star)] 87 + ; @punctuation.special 88 + ; (#offset! @punctuation.special 0 0 0 -1) 89 + ; (#set! conceal "•")) 90 + ; ([(list_marker_plus) (list_marker_star)] 91 + ; @punctuation.special 92 + ; (#any-of? @punctuation.special "+" "*") 93 + ; (#set! conceal "•")) 94 + ; ((list_marker_minus) 95 + ; @punctuation.special 96 + ; (#offset! @punctuation.special 0 0 0 -1) 97 + ; (#set! conceal "—")) 98 + ; ((list_marker_minus) 99 + ; @punctuation.special 100 + ; (#eq? @punctuation.special "-") 101 + ; (#set! conceal "—")) 102 + (thematic_break) @punctuation.special 103 + 104 + (task_list_marker_unchecked) @markup.list.unchecked 105 + 106 + (task_list_marker_checked) @markup.list.checked 107 + 108 + ((block_quote) @markup.quote 109 + (#set! priority 90)) 110 + 111 + ([ 112 + (plus_metadata) 113 + (minus_metadata) 114 + ] @keyword.directive 115 + (#set! priority 90)) 116 + 117 + [ 118 + (block_continuation) 119 + (block_quote_marker) 120 + ] @punctuation.special 121 + 122 + (backslash_escape) @string.escape 123 + 124 + (inline) @spell
+143
.config/nvim/queries/markdown_inline/highlights.scm
··· 1 + ; From MDeiml/tree-sitter-markdown 2 + 3 + ( 4 + (link_text (code_span)) @none 5 + (#vscode?) 6 + (#set! priority 110) 7 + ) 8 + 9 + ( 10 + (code_span 11 + (code_span_delimiter) @_delim 12 + (code_span_delimiter) @_delim) @_span 13 + (#not-eq? @_delim "```"); ignore ``` delimiters in vscode, e.g injected rust 14 + (#not-has-parent? @_span link_label link_text) 15 + (#vscode?) 16 + ) @markup.raw @nospell 17 + 18 + ( 19 + (code_span) @markup.raw @nospell 20 + (#not-vscode?) 21 + ) 22 + 23 + (emphasis) @markup.italic 24 + 25 + (strong_emphasis) @markup.strong 26 + 27 + (strikethrough) @markup.strikethrough 28 + 29 + (shortcut_link 30 + (link_text) @nospell) 31 + 32 + [ 33 + (backslash_escape) 34 + (hard_line_break) 35 + ] @string.escape 36 + 37 + ; Conceal codeblock and text style markers 38 + ([ 39 + (code_span_delimiter) 40 + (emphasis_delimiter) 41 + ] @conceal 42 + (#set! conceal "")) 43 + 44 + ; Conceal inline links 45 + (inline_link 46 + [ 47 + "[" 48 + "]" 49 + "(" 50 + (link_destination) 51 + ")" 52 + ] @markup.link 53 + (#set! conceal "")) 54 + 55 + [ 56 + (link_label) 57 + (link_text) 58 + (link_title) 59 + (image_description) 60 + ] @markup.link.label 61 + 62 + 63 + ((inline_link 64 + (link_destination) @_url) @_label 65 + (#set! @_label url @_url)) 66 + 67 + ((image 68 + (link_destination) @_url) @_label 69 + (#set! @_label url @_url)) 70 + 71 + ; Conceal image links 72 + (image 73 + [ 74 + "!" 75 + "[" 76 + "]" 77 + "(" 78 + (link_destination) 79 + ")" 80 + ] @markup.link 81 + (#set! conceal "")) 82 + 83 + ; Conceal full reference links 84 + (full_reference_link 85 + [ 86 + "[" 87 + "]" 88 + (link_label) 89 + ] @markup.link 90 + (#set! conceal "")) 91 + 92 + ; Conceal collapsed reference links 93 + (collapsed_reference_link 94 + [ 95 + "[" 96 + "]" 97 + ] @markup.link 98 + (#set! conceal "")) 99 + 100 + ; Conceal shortcut links 101 + (shortcut_link 102 + [ 103 + "[" 104 + "]" 105 + ] @markup.link 106 + (#set! conceal "")) 107 + 108 + [ 109 + (link_destination) 110 + (uri_autolink) 111 + (email_autolink) 112 + ] @markup.link.url @nospell 113 + 114 + ((uri_autolink) @_url 115 + (#offset! @_url 0 1 0 -1) 116 + (#set! @_url url @_url)) 117 + 118 + (entity_reference) @nospell 119 + 120 + ; Replace common HTML entities. 121 + ((entity_reference) @character.special 122 + (#eq? @character.special "&nbsp;") 123 + (#set! conceal " ")) 124 + 125 + ((entity_reference) @character.special 126 + (#eq? @character.special "&lt;") 127 + (#set! conceal "<")) 128 + 129 + ((entity_reference) @character.special 130 + (#eq? @character.special "&gt;") 131 + (#set! conceal ">")) 132 + 133 + ((entity_reference) @character.special 134 + (#eq? @character.special "&amp;") 135 + (#set! conceal "&")) 136 + 137 + ((entity_reference) @character.special 138 + (#eq? @character.special "&quot;") 139 + (#set! conceal "\"")) 140 + 141 + ((entity_reference) @character.special 142 + (#any-of? @character.special "&ensp;" "&emsp;") 143 + (#set! conceal " "))