From 24c7b5f2693b69f7c6a99bf38169712a798a07cb Mon Sep 17 00:00:00 2001 From: Mika Vilpas Date: Fri, 6 Dec 2024 08:57:11 +0200 Subject: [PATCH] feat: fall back to regex highlighting when treesitter not available Right now this also needs support from blink. See here: https://github.com/Saghen/blink.cmp/pull/462 --- integration-tests/MyTestDirectory.ts | 7 ++ .../e2e/blink-ripgrep/basic_spec.cy.ts | 30 ++++++ .../test-environment/.config/nvim/init.lua | 1 + .../limited/subproject/example.clj | 23 +++++ lua/blink-ripgrep/init.lua | 96 ++++++++++--------- lua/blink-ripgrep/ripgrep_parser.lua | 9 +- 6 files changed, 116 insertions(+), 50 deletions(-) create mode 100644 integration-tests/test-environment/limited/subproject/example.clj diff --git a/integration-tests/MyTestDirectory.ts b/integration-tests/MyTestDirectory.ts index e41089c..4430f35 100644 --- a/integration-tests/MyTestDirectory.ts +++ b/integration-tests/MyTestDirectory.ts @@ -52,6 +52,12 @@ export const MyTestDirectorySchema = z.object({ name: z.literal("subproject/"), type: z.literal("directory"), contents: z.object({ + "example.clj": z.object({ + name: z.literal("example.clj"), + type: z.literal("file"), + extension: z.literal("clj"), + stem: z.literal("example."), + }), "file1.lua": z.object({ name: z.literal("file1.lua"), type: z.literal("file"), @@ -91,6 +97,7 @@ export const testDirectoryFiles = z.enum([ ".config", "initial-file.txt", "limited/main-project-file.lua", + "limited/subproject/example.clj", "limited/subproject/file1.lua", "limited/subproject/file2.lua", "limited/subproject", diff --git a/integration-tests/cypress/e2e/blink-ripgrep/basic_spec.cy.ts b/integration-tests/cypress/e2e/blink-ripgrep/basic_spec.cy.ts index c73b451..92a081a 100644 --- a/integration-tests/cypress/e2e/blink-ripgrep/basic_spec.cy.ts +++ b/integration-tests/cypress/e2e/blink-ripgrep/basic_spec.cy.ts @@ -81,6 +81,36 @@ describe("searching inside projects", () => { ) }) }) + + describe("syntax highlighting", () => { + it("can highlight file types that don't have a treesitter parser installed", () => { + cy.visit("/") + cy.startNeovim({ filename: "limited/subproject/file1.lua" }).then(() => { + // when opening a file from a subproject, the search should be limited to + // the nearest .git directory (only the files in the same project should + // be searched) + cy.contains("This is text from file1.lua") + createFakeGitDirectoriesToLimitRipgrepScope() + + cy.typeIntoTerminal("o") + // match text inside ../../../test-environment/limited/subproject/example.clj + cy.typeIntoTerminal("Subtraction") + + // make sure the syntax is highlighted + // (needs https://github.com/Saghen/blink.cmp/pull/462) + cy.contains("defn").should( + "have.css", + "color", + rgbify(flavors.macchiato.colors.pink.rgb), + ) + cy.contains("Clojure Calculator").should( + "have.css", + "color", + rgbify(flavors.macchiato.colors.green.rgb), + ) + }) + }) + }) }) function createFakeGitDirectoriesToLimitRipgrepScope() { diff --git a/integration-tests/test-environment/.config/nvim/init.lua b/integration-tests/test-environment/.config/nvim/init.lua index 6a49368..adb0965 100644 --- a/integration-tests/test-environment/.config/nvim/init.lua +++ b/integration-tests/test-environment/.config/nvim/init.lua @@ -34,6 +34,7 @@ vim.o.swapfile = false local plugins = { { "saghen/blink.cmp", + dir = "/Users/mikavilpas/git/blink.cmp/", event = "VeryLazy", -- use a release tag to download pre-built binaries version = "v0.*", diff --git a/integration-tests/test-environment/limited/subproject/example.clj b/integration-tests/test-environment/limited/subproject/example.clj new file mode 100644 index 0000000..025bf0f --- /dev/null +++ b/integration-tests/test-environment/limited/subproject/example.clj @@ -0,0 +1,23 @@ +(ns calculator.core) + +(defn add [a b] + (+ a b)) + +(defn subtract [a b] + (- a b)) + +(defn multiply [a b] + (* a b)) + +(defn divide [a b] + (if (zero? b) + "Cannot divide by zero!" + (/ a b))) + +(defn -main [] + (println "Welcome to the Clojure Calculator!") + (println "Addition: 10 + 5 =" (add 10 5)) + (println "Subtraction: 10 - 5 =" (subtract 10 5)) + (println "Multiplication: 10 * 5 =" (multiply 10 5)) + (println "Division: 10 / 5 =" (divide 10 5)) + (println "Division: 10 / 0 =" (divide 10 0))) diff --git a/lua/blink-ripgrep/init.lua b/lua/blink-ripgrep/init.lua index 6c2ab86..aaab9f1 100644 --- a/lua/blink-ripgrep/init.lua +++ b/lua/blink-ripgrep/init.lua @@ -101,57 +101,59 @@ function RgSource:get_completions(context, resolve) local cmd = self.get_command(context, prefix) vim.system(cmd, nil, function(result) - if result.code ~= 0 then - resolve() - return - end + vim.schedule(function() + if result.code ~= 0 then + resolve() + return + end - local lines = vim.split(result.stdout, "\n") - local cwd = vim.uv.cwd() or "" - - local parsed = require("blink-ripgrep.ripgrep_parser").parse( - lines, - cwd, - self.options.context_size - ) - - ---@type table - local items = {} - for _, file in pairs(parsed.files) do - for _, match in pairs(file.matches) do - local matchkey = match.match.text - - -- PERF: only register the match once - right now there is no useful - -- way to display the same match multiple times - if not items[matchkey] then - local label = match.match.text .. " (rg)" - local docstring = ("```" .. file.language .. "\n") - .. table.concat(match.context_preview, "\n") - .. "```" - - -- the implementation for render_detail_and_documentation: - -- ../../integration-tests/test-environment/.repro/data/nvim/lazy/blink.cmp/lua/blink/cmp/windows/lib/docs.lua - ---@diagnostic disable-next-line: missing-fields - items[matchkey] = { - documentation = { - kind = "markdown", - value = docstring, - }, - detail = file.relative_to_cwd, - source_id = "blink-ripgrep", - label = label, - insertText = matchkey, - } + local lines = vim.split(result.stdout, "\n") + local cwd = vim.uv.cwd() or "" + + local parsed = require("blink-ripgrep.ripgrep_parser").parse( + lines, + cwd, + self.options.context_size + ) + + ---@type table + local items = {} + for _, file in pairs(parsed.files) do + for _, match in pairs(file.matches) do + local matchkey = match.match.text + + -- PERF: only register the match once - right now there is no useful + -- way to display the same match multiple times + if not items[matchkey] then + local label = match.match.text .. " (rg)" + local docstring = ("```" .. file.language .. "\n") + .. table.concat(match.context_preview, "\n") + .. "```" + + -- the implementation for render_detail_and_documentation: + -- ../../integration-tests/test-environment/.repro/data/nvim/lazy/blink.cmp/lua/blink/cmp/windows/lib/docs.lua + ---@diagnostic disable-next-line: missing-fields + items[matchkey] = { + documentation = { + kind = "markdown", + value = docstring, + }, + detail = file.relative_to_cwd, + source_id = "blink-ripgrep", + label = label, + insertText = matchkey, + } + end end end - end - resolve({ - is_incomplete_forward = false, - is_incomplete_backward = false, - items = vim.tbl_values(items), - context = context, - }) + resolve({ + is_incomplete_forward = false, + is_incomplete_backward = false, + items = vim.tbl_values(items), + context = context, + }) + end) end) end diff --git a/lua/blink-ripgrep/ripgrep_parser.lua b/lua/blink-ripgrep/ripgrep_parser.lua index 0b5edde..c51ffb6 100644 --- a/lua/blink-ripgrep/ripgrep_parser.lua +++ b/lua/blink-ripgrep/ripgrep_parser.lua @@ -49,9 +49,12 @@ function M.parse(ripgrep_output, cwd, context_size) relative_filename = filename:sub(#cwd + 2) end - local filetype = vim.fn.fnamemodify(filename, ":e") - local language = vim.treesitter.language.get_lang(filetype or "text") - or "markdown" + local ext = vim.fn.fnamemodify(filename, ":e") + + local ft = vim.filetype.match({ filename = filename }) + local language = ft + or vim.treesitter.language.get_lang(ext or "text") + or ext output.files[filename] = { language = language,