Skip to content

DbProjectDelete don't work #521

@Melal1

Description

@Melal1

Description

Running :DbProjectDelete to remove projects from the dashboard-nvim recent projects list causes an error on the next dashboard load. The issue arises because the cache file (e.g., ~/.cache/nvim/dashboard/cache) is written as binary bytecode using string.dump, which is incompatible with the reading mechanism, resulting in a "malformed bytecode" error.

The traceback is:

Error executing vim.schedule lua callback: ...e/nvim/lazy/dashboard-nvim/lua/dashboard/theme/hyper.lua:131: (binary): cannot load malformed bytecode
stack traceback:
        [C]: in function 'assert'
        ...e/nvim/lazy/dashboard-nvim/lua/dashboard/theme/hyper.lua:131: in function ''
        ...e/nvim/lazy/dashboard-nvim/lua/dashboard/theme/hyper.lua:159: in function ''
        vim/_editor.lua: in function <vim/_editor.lua:0>

This occurs consistently after deleting projects, as the cache is rewritten in binary format, which fails to load correctly on the next dashboard refresh.

Steps to Reproduce

  1. Open Neovim with dashboard-nvim configured to show recent projects.
  2. Open a few projects to populate the cache.
  3. Run :DbProjectDelete 1 to delete one project (this triggers the cache rewrite using string.dump).
  4. Reload the dashboard (e.g., quit and reopen Neovim or trigger a refresh).
  5. Observe the error in the messages.

Environment

  • Neovim version: [v0.11.2]
  • OS: [Linux - NixOS]

Proposed Fix

The issue come from using string.dump as it doesn't return a valid string , So a solution is to return the list as plain text using 'return ' .. vim.inspect(list). This ensures compatibility with loadstring when reading the cache without introducing binary data issues.

In project_delete (around the write step):

-- Original (problematic):
local str = string.dump(assert(loadstring('return ' .. vim.inspect(list))))

-- Fixed:
local str = 'return ' .. vim.inspect(list)

This change avoids those binary stuff, preventing the "malformed bytecode" error .

Additional Feature Suggestion

To improve usability, I’ve modified :DbProjectDelete to support interactive deletion via vim.ui.select when no arguments are provided (e.g., :DbProjectDelete). It falls back to the original count-based deletion when a number is given (e.g., :DbProjectDelete 2). This uses nargs = '?' for optional arguments.

Here’s the updated project_delete function:

local function project_delete()
  api.nvim_create_user_command('DbProjectDelete', function(args)
    local path = utils.path_join(vim.fn.stdpath('cache'), 'dashboard', 'cache')
    utils.async_read(
      path,
      vim.schedule_wrap(function(data)
        local dump = assert(loadstring(data))
        local list = dump()

        local function write_list_to_file(new_list)
          local str = 'return ' .. vim.inspect(new_list)
          local handle = io.open(path, 'w+')
          if not handle then
            return
          end
          handle:write(str)
          handle:close()
        end

        if args.args == '' then
          vim.ui.select(list, { prompt = 'Select projects to delete:' }, function(selected_item)
            if selected_item then
              local index_to_remove = -1
              for i, item in ipairs(list) do
                if item == selected_item then
                  index_to_remove = i
                  break
                end
              end

              if index_to_remove ~= -1 then
                table.remove(list, index_to_remove)
                write_list_to_file(list)
                vim.notify('Project deleted', vim.log.levels.INFO)
              end
            end
          end)
        else
          local count = tonumber(args.args)
          if count then
            if vim.tbl_count(list) < count then
              vim.notify(
                'The list has fewer projects than the number provided',
                vim.log.levels.WARN
              )
              return
            end
          else
            vim.notify('Invalid arguments!', vim.log.levels.WARN)
            return
          end
          list = vim.list_slice(list, count + 1)
          write_list_to_file(list)
          vim.notify(string.format('%d projects deleted', count), vim.log.levels.INFO)
        end
      end)
    )
  end, {
    nargs = '?',
  })
end

This update adds user-friendly interactive project deletion via vim.ui.select while preserving the original count-based functionality. I will submit a pull request with these changes but will keep this issue open, as I’m new to Lua and unsure if the solution with new features has a flaw or smth .

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions