diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | lua/lvim/core/lualine/components.lua | 3 | ||||
| -rw-r--r-- | lua/lvim/core/nvimtree.lua | 9 | ||||
| -rw-r--r-- | lua/lvim/core/telescope.lua | 16 | ||||
| -rw-r--r-- | lua/lvim/core/which-key.lua | 1 | ||||
| -rw-r--r-- | lua/lvim/lsp/config.lua | 1 | ||||
| -rw-r--r-- | lua/lvim/lsp/utils.lua | 2 | ||||
| -rw-r--r-- | lua/lvim/plugins.lua | 16 | ||||
| -rw-r--r-- | snapshots/default.json | 40 | ||||
| -rw-r--r-- | tests/specs/plugins_load_spec.lua | 3 | ||||
| -rw-r--r-- | utils/ci/generate_new_lockfile.lua | 35 | ||||
| -rw-r--r-- | utils/ci/verify_plugins.lua | 134 | ||||
| -rw-r--r-- | utils/ci/verify_plugins.sh | 5 | ||||
| -rwxr-xr-x | utils/installer/install.sh | 13 | 
14 files changed, 225 insertions, 56 deletions
| @@ -28,4 +28,5 @@ lua/lv-user-config/  *.backup  *.old -.luarc.json
\ No newline at end of file +.luarc.json +.luacheckcache diff --git a/lua/lvim/core/lualine/components.lua b/lua/lvim/core/lualine/components.lua index b89bbd36..49a8ff81 100644 --- a/lua/lvim/core/lualine/components.lua +++ b/lua/lvim/core/lualine/components.lua @@ -110,7 +110,8 @@ return {        local supported_linters = linters.list_registered(buf_ft)        vim.list_extend(buf_client_names, supported_linters) -      return "[" .. table.concat(buf_client_names, ", ") .. "]" +      local unique_client_names = vim.fn.uniq(buf_client_names) +      return "[" .. table.concat(unique_client_names, ", ") .. "]"      end,      color = { gui = "bold" },      cond = conditions.hide_in_width, diff --git a/lua/lvim/core/nvimtree.lua b/lua/lvim/core/nvimtree.lua index 7f50f256..9d7ab069 100644 --- a/lua/lvim/core/nvimtree.lua +++ b/lua/lvim/core/nvimtree.lua @@ -148,7 +148,6 @@ function M.config()        },      },    } -  lvim.builtin.which_key.mappings["e"] = { "<cmd>NvimTreeToggle<CR>", "Explorer" }  end  function M.setup() @@ -158,10 +157,14 @@ function M.setup()      return    end -  for opt, val in pairs(lvim.builtin.nvimtree) do -    vim.g["nvim_tree_" .. opt] = val +  if lvim.builtin.nvimtree._setup_called then +    Log:debug "ignoring repeated setup call for nvim-tree, see kyazdani42/nvim-tree.lua#1308" +    return    end +  lvim.builtin.which_key.mappings["e"] = { "<cmd>NvimTreeToggle<CR>", "Explorer" } +  lvim.builtin.nvimtree._setup_called = true +    -- Implicitly update nvim-tree when project module is active    if lvim.builtin.project.active then      lvim.builtin.nvimtree.setup.respect_buf_cwd = true diff --git a/lua/lvim/core/telescope.lua b/lua/lvim/core/telescope.lua index 6a04a866..f556913b 100644 --- a/lua/lvim/core/telescope.lua +++ b/lua/lvim/core/telescope.lua @@ -70,14 +70,14 @@ function M.config()        borderchars = { "─", "│", "─", "│", "â•", "â•®", "╯", "â•°" },        color_devicons = true,        set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil, -      pickers = { -        find_files = { -          hidden = true, -        }, -        live_grep = { -          --@usage don't include the filename in the search results -          only_sort_text = true, -        }, +    }, +    pickers = { +      find_files = { +        hidden = true, +      }, +      live_grep = { +        --@usage don't include the filename in the search results +        only_sort_text = true,        },      },      extensions = { diff --git a/lua/lvim/core/which-key.lua b/lua/lvim/core/which-key.lua index b1ae6f87..3015781b 100644 --- a/lua/lvim/core/which-key.lua +++ b/lua/lvim/core/which-key.lua @@ -244,6 +244,7 @@ M.config = function()          c = { "<cmd>Telescope colorscheme<cr>", "Colorscheme" },          f = { "<cmd>Telescope find_files<cr>", "Find File" },          h = { "<cmd>Telescope help_tags<cr>", "Find Help" }, +        H = { "<cmd>Telescope highlights<cr>", "Find highlight groups" },          M = { "<cmd>Telescope man_pages<cr>", "Man Pages" },          r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },          R = { "<cmd>Telescope registers<cr>", "Registers" }, diff --git a/lua/lvim/lsp/config.lua b/lua/lvim/lsp/config.lua index a0e22107..1f84c4e2 100644 --- a/lua/lvim/lsp/config.lua +++ b/lua/lvim/lsp/config.lua @@ -32,6 +32,7 @@ local skipped_servers = {    "stylelint_lsp",    "tailwindcss",    "tflint", +  "svlangserver",    "verible",    "vuels",  } diff --git a/lua/lvim/lsp/utils.lua b/lua/lvim/lsp/utils.lua index 252e611c..d0e36241 100644 --- a/lua/lvim/lsp/utils.lua +++ b/lua/lvim/lsp/utils.lua @@ -176,7 +176,7 @@ function M.format(opts)    end, clients)    if #clients == 0 then -    vim.notify "[LSP] Format request failed, no matching language servers." +    vim.notify_once "[LSP] Format request failed, no matching language servers."    end    local timeout_ms = opts.timeout_ms or 1000 diff --git a/lua/lvim/plugins.lua b/lua/lvim/plugins.lua index 9397318e..dd40b967 100644 --- a/lua/lvim/plugins.lua +++ b/lua/lvim/plugins.lua @@ -246,9 +246,19 @@ local core_plugins = {    },  } -for _, entry in ipairs(core_plugins) do -  if not os.getenv "LVIM_DEV_MODE" then -    entry["lock"] = true +local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json") +local content = vim.fn.readfile(default_snapshot_path) +local default_sha1 = vim.fn.json_decode(content) + +local get_default_sha1 = function(spec) +  local short_name, _ = require("packer.util").get_plugin_short_name(spec) +  return default_sha1[short_name] and default_sha1[short_name].commit +end + +for _, spec in ipairs(core_plugins) do +  if not vim.env.LVIM_DEV_MODE then +    -- Manually lock the commit hash since Packer's snapshots are unreliable in headless mode +    spec["commit"] = get_default_sha1(spec)    end  end diff --git a/snapshots/default.json b/snapshots/default.json index de28eeaf..533ff25e 100644 --- a/snapshots/default.json +++ b/snapshots/default.json @@ -1,15 +1,15 @@  {    "Comment.nvim": { -    "commit": "bdf9ca6" +    "commit": "3c69bab"    },    "FixCursorHold.nvim": {      "commit": "1bfb32e"    },    "LuaSnip": { -    "commit": "52f4aed" +    "commit": "79b2019"    },    "alpha-nvim": { -    "commit": "4781fcf" +    "commit": "ef27a59"    },    "bufferline.nvim": {      "commit": "c78b3ec" @@ -30,10 +30,10 @@      "commit": "bbda2b0"    },    "friendly-snippets": { -    "commit": "974d792" +    "commit": "d27a83a"    },    "gitsigns.nvim": { -    "commit": "27aeb2e" +    "commit": "c18e016"    },    "lua-dev.nvim": {      "commit": "54149d1" @@ -42,34 +42,34 @@      "commit": "3362b28"    },    "nlsp-settings.nvim": { -    "commit": "f27faa4" +    "commit": "62d72bc"    },    "null-ls.nvim": { -    "commit": "474372a" +    "commit": "ff40739"    },    "nvim-autopairs": { -    "commit": "b9cc0a2" +    "commit": "fa6876f"    },    "nvim-cmp": { -    "commit": "033a817" +    "commit": "df6734a"    },    "nvim-dap": { -    "commit": "688cb52" +    "commit": "014ebd5"    },    "nvim-lsp-installer": { -    "commit": "ce70a78" +    "commit": "2408a0f"    },    "nvim-lspconfig": { -    "commit": "eb03999" +    "commit": "10c3934"    },    "nvim-notify": { -    "commit": "8252aae" +    "commit": "8960269"    },    "nvim-tree.lua": { -    "commit": "1caca62" +    "commit": "bdb6d4a"    },    "nvim-treesitter": { -    "commit": "178f24e" +    "commit": "518e275"    },    "nvim-ts-context-commentstring": {      "commit": "8834375" @@ -84,7 +84,7 @@      "commit": "00ec5ad"    },    "plenary.nvim": { -    "commit": "54b2e3d" +    "commit": "968a4b9"    },    "popup.nvim": {      "commit": "b7404d3" @@ -93,19 +93,19 @@      "commit": "541115e"    },    "schemastore.nvim": { -    "commit": "3a15757" +    "commit": "a32911d"    },    "structlog.nvim": {      "commit": "232a8e2"    },    "telescope-fzf-native.nvim": { -    "commit": "f0dba7d" +    "commit": "6a33ece"    },    "telescope.nvim": { -    "commit": "e6b69b1" +    "commit": "d96eaa9"    },    "toggleterm.nvim": { -    "commit": "5bf839a" +    "commit": "aaeed9e"    },    "which-key.nvim": {      "commit": "f03a259" diff --git a/tests/specs/plugins_load_spec.lua b/tests/specs/plugins_load_spec.lua index 1f11279e..283d5547 100644 --- a/tests/specs/plugins_load_spec.lua +++ b/tests/specs/plugins_load_spec.lua @@ -38,7 +38,8 @@ a.describe("plugin-loader", function()        assert.truthy(package.loaded[plugin])      end    end) -  a.it("should be able to rollback plugins without errors", function() + +  pending("should be able to rollback plugins without errors", function()      local plugin = { name = "onedarker.nvim" }      plugin.path = vim.tbl_filter(function(package)        return package:match(plugin.name) diff --git a/utils/ci/generate_new_lockfile.lua b/utils/ci/generate_new_lockfile.lua index 9f274597..fd10775c 100644 --- a/utils/ci/generate_new_lockfile.lua +++ b/utils/ci/generate_new_lockfile.lua @@ -1,18 +1,18 @@  local sp = os.getenv "SNAPSHOT_PATH"  local function call_proc(process, opts, cb) -  local std_output = "" -  local error_output = "" - -  local function onread(_, is_stderr) -    return function(err, data) -      if data then -        if is_stderr then -          error_output = (error_output or "") .. err -        else -          std_output = (std_output or "") .. data -        end -      end +  local output, error_output = "", "" +  local handle_stdout = function(err, chunk) +    assert(not err, err) +    if chunk then +      output = output .. chunk +    end +  end + +  local handle_stderr = function(err, chunk) +    assert(not err, err) +    if chunk then +      error_output = error_output .. chunk      end    end @@ -26,7 +26,7 @@ local function call_proc(process, opts, cb)    handle = uv.spawn(      process, -    { args = opts.args, cwd = uv.cwd(), stdio = stdio }, +    { args = opts.args, cwd = opts.cwd or uv.cwd(), stdio = stdio },      vim.schedule_wrap(function(code)        if code ~= 0 then          stdout:read_stop() @@ -42,13 +42,13 @@ local function call_proc(process, opts, cb)          end          check:stop()          handle:close() -        cb(code, std_output, error_output) +        cb(code, output, error_output)        end)      end)    ) -  uv.read_start(stdout, onread(handle, false)) -  uv.read_start(stderr, onread(handle, true)) +  uv.read_start(stdout, handle_stdout) +  uv.read_start(stderr, handle_stderr)    return handle  end @@ -91,11 +91,12 @@ local function write_lockfile(verbose)      end      local handle = call_proc("git", { args = { "ls-remote", entry.url, "HEAD" } }, on_done) +    assert(handle)      table.insert(active_jobs, handle)    end    print("active: " .. #active_jobs) -  print("parsers: " .. #default_plugins) +  print("plugins: " .. #default_plugins)    vim.wait(#active_jobs * 60 * 1000, function()      return completed == #active_jobs diff --git a/utils/ci/verify_plugins.lua b/utils/ci/verify_plugins.lua new file mode 100644 index 00000000..c56d85d1 --- /dev/null +++ b/utils/ci/verify_plugins.lua @@ -0,0 +1,134 @@ +local completed = 0 +local collection = {} +local active_jobs = {} + +local fmt = string.format +local core_plugins = require "lvim.plugins" + +local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json") +local fd = io.open(default_snapshot_path, "rb") +local content +if fd then +  content = fd:read "*a" +end +local default_sha1 = vim.json.decode(content) + +local get_short_name = function(spec) +  return spec[1]:match "/(%S*)" +end + +local get_default_sha1 = function(spec) +  local short_name, _ = get_short_name(spec) +  assert(default_sha1[short_name]) +  return default_sha1[short_name].commit +end + +local is_directory = require("lvim.utils").is_directory +-- see packer.init() +local packdir = join_paths(get_runtime_dir(), "site", "pack", "packer") +local packer_config = { opt_dir = join_paths(packdir, "opt"), start_dir = join_paths(packdir, "start") } +local is_optional = function(spec) +  return spec.opt or spec.event or spec.cmd or spec.module +end +local get_install_path = function(spec) +  local prefix = is_optional(spec) and packer_config.opt_dir or packer_config.start_dir +  local path = join_paths(prefix, get_short_name(spec)) +  assert(is_directory(path)) +  return path +end + +local function call_proc(process, opts, cb) +  local output, error_output = "", "" +  local handle_stdout = function(err, chunk) +    assert(not err, err) +    if chunk then +      output = output .. chunk +    end +  end + +  local handle_stderr = function(err, chunk) +    assert(not err, err) +    if chunk then +      error_output = error_output .. chunk +    end +  end + +  local uv = vim.loop +  local handle + +  local stdout = uv.new_pipe(false) +  local stderr = uv.new_pipe(false) + +  local stdio = { nil, stdout, stderr } + +  handle = uv.spawn( +    process, +    { args = opts.args, cwd = opts.cwd or uv.cwd(), stdio = stdio }, +    vim.schedule_wrap(function(code) +      if code ~= 0 then +        stdout:read_stop() +        stderr:read_stop() +      end + +      local check = uv.new_check() +      check:start(function() +        for _, pipe in ipairs(stdio) do +          if pipe and not pipe:is_closing() then +            return +          end +        end +        check:stop() +        handle:close() +        cb(code, output, error_output) +      end) +    end) +  ) + +  uv.read_start(stdout, handle_stdout) +  uv.read_start(stderr, handle_stderr) + +  return handle +end + +local function verify_core_plugins(verbose) +  for _, spec in pairs(core_plugins) do +    if not spec.disable then +      table.insert(collection, { +        name = get_short_name(spec), +        commit = get_default_sha1(spec), +        path = get_install_path(spec), +      }) +    end +  end + +  for _, entry in pairs(collection) do +    local on_done = function(code, result, errors) +      completed = completed + 1 +      if code ~= 0 then +        io.write(errors .. "\n") +        -- os.exit(code) +      else +        if verbose then +          io.write(fmt("verified [%s]\n", entry.name)) +        end +      end +      local current_commit = result:gsub("\n", ""):gsub([[']], [[]]) +      -- just in case there are some extra qutoes or it's a longer commit hash +      if current_commit ~= entry.commit then +        io.write(fmt("mismatch at [%s]: expected [%s], got [%s]\n", entry.name, entry.commit, current_commit)) +        os.exit(1) +      end +    end + +    local handle = call_proc("git", { args = { "log", "--pretty='%h'", "-1" }, cwd = entry.path }, on_done) +    assert(handle) +    table.insert(active_jobs, handle) +  end + +  vim.wait(#active_jobs * 60 * 1000, function() +    return completed == #active_jobs +  end) +end + +verify_core_plugins() +vim.cmd "q" diff --git a/utils/ci/verify_plugins.sh b/utils/ci/verify_plugins.sh new file mode 100644 index 00000000..7d0d764b --- /dev/null +++ b/utils/ci/verify_plugins.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -e + +lvim --headless \ +  -c "luafile ./utils/ci/verify_plugins.lua" diff --git a/utils/installer/install.sh b/utils/installer/install.sh index 66149cf6..ec675e6d 100755 --- a/utils/installer/install.sh +++ b/utils/installer/install.sh @@ -160,7 +160,7 @@ function detect_platform() {        elif [ -f "/etc/fedora-release" ] || [ -f "/etc/redhat-release" ]; then          RECOMMEND_INSTALL="sudo dnf install -y"        elif [ -f "/etc/gentoo-release" ]; then -        RECOMMEND_INSTALL="emerge install -y" +        RECOMMEND_INSTALL="emerge -tv"        else # assume debian based          RECOMMEND_INSTALL="sudo apt install -y"        fi @@ -206,6 +206,15 @@ function check_neovim_min_version() {    fi  } +function verify_core_plugins() { +  msg "Verifying core plugins" +  if ! bash "$LUNARVIM_BASE_DIR/utils/ci/verify_plugins.sh"; then +    echo "[ERROR]: Unable to verify plugins, makde sure to manually run ':PackerSync' when starting lvim for the first time." +    exit 1 +  fi +  echo "Verification complete!" +} +  function validate_lunarvim_files() {    local verify_version_cmd='if v:errmsg != "" | cquit | else | quit | endif'    if ! "$INSTALL_PREFIX/bin/lvim" --headless -c 'LvimUpdate' -c "$verify_version_cmd" &>/dev/null; then @@ -418,6 +427,8 @@ function setup_lvim() {      -c 'PackerSync'    echo "Packer setup complete" + +  verify_core_plugins  }  function print_logo() { | 
