| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- -- package-commands.lua
- -- Editor commands for the package manager
- -- ============================================================================
- -- Get package manager from lumacs global (set by init.lua)
- local package_manager = lumacs.package
- -- ============================================================================
- -- Package Commands
- -- ============================================================================
- -- List installed/loaded packages
- editor:register_command("package-list", "List loaded packages", function(args)
- local loaded = package_manager.list_loaded()
- if #loaded == 0 then
- return {success = true, message = "No packages loaded"}
- end
- local lines = {"Loaded packages:"}
- for _, pkg in ipairs(loaded) do
- local status = pkg.source == "builtin" and "[builtin]" or "[installed]"
- table.insert(lines, string.format(" %s %s", pkg.name, status))
- end
- editor:set_echo_area(lines)
- return {success = true, message = ""}
- end)
- -- Show package info
- editor:register_command("package-info", "Show information about a package", function(args)
- if #args == 0 then
- return {success = true, message = "Usage: package-info <name>"}
- end
- local name = args[1]
- local info = package_manager.info(name)
- local lines = {
- "Package: " .. name,
- "Status: " .. (info.loaded and "loaded" or "not loaded"),
- }
- if info.installed then
- table.insert(lines, "Source: " .. info.source)
- table.insert(lines, "Path: " .. info.path)
- else
- table.insert(lines, "Not installed locally")
- end
- if info.registry then
- table.insert(lines, "Registry: " .. (info.registry.description or "available"))
- if info.registry.url then
- table.insert(lines, "URL: " .. info.registry.url)
- end
- end
- editor:set_echo_area(lines)
- return {success = true, message = ""}
- end, {}, true, "s")
- -- Install a package
- editor:register_command("package-install", "Install a package", function(args)
- if #args == 0 then
- return {success = true, message = "Usage: package-install <name-or-url>"}
- end
- local spec = args[1]
- -- Check if it's a URL
- if spec:match("^https?://") or spec:match("^git@") then
- spec = { url = spec }
- end
- local ok, msg = package_manager.install(spec)
- if ok then
- -- Try to load it
- local load_ok, load_msg = package_manager.load_package(spec)
- if load_ok then
- return {success = true, message = msg .. " and loaded"}
- else
- return {success = true, message = msg .. " (not loaded: " .. load_msg .. ")"}
- end
- else
- return {success = false, message = msg}
- end
- end, {}, true, "s")
- -- Update a package
- editor:register_command("package-update", "Update a package", function(args)
- if #args == 0 then
- return {success = true, message = "Usage: package-update <name>"}
- end
- local name = args[1]
- local ok, msg = package_manager.update(name)
- return {success = ok, message = msg}
- end, {}, true, "s")
- -- Update all packages
- editor:register_command("package-update-all", "Update all installed packages", function(args)
- local loaded = package_manager.list_loaded()
- local updated = 0
- local failed = 0
- for _, pkg in ipairs(loaded) do
- if pkg.source == "installed" then
- local ok, msg = package_manager.update(pkg.name)
- if ok then
- updated = updated + 1
- else
- failed = failed + 1
- end
- end
- end
- return {success = true, message = string.format("Updated %d packages, %d failed", updated, failed)}
- end)
- -- Remove a package
- editor:register_command("package-remove", "Remove an installed package", function(args)
- if #args == 0 then
- return {success = true, message = "Usage: package-remove <name>"}
- end
- local name = args[1]
- -- Check if it's builtin
- local info = package_manager.info(name)
- if info.builtin then
- return {success = false, message = "Cannot remove builtin package: " .. name}
- end
- local ok, msg = package_manager.remove(name)
- return {success = ok, message = msg}
- end, {}, true, "s")
- -- Reload a package
- editor:register_command("package-reload", "Reload a package", function(args)
- if #args == 0 then
- return {success = true, message = "Usage: package-reload <name>"}
- end
- local name = args[1]
- -- Clear from loaded
- package_manager.loaded[name] = nil
- package_manager.packages[name] = nil
- -- Reload
- local ok, msg = package_manager.load_package(name)
- return {success = ok, message = ok and "Reloaded " .. name or msg}
- end, {}, true, "s")
- -- Update registry
- editor:register_command("package-refresh", "Refresh package registry from remote", function(args)
- local ok = package_manager.update_registry()
- if ok then
- local count = 0
- for _ in pairs(package_manager.registry) do count = count + 1 end
- return {success = true, message = "Registry updated: " .. count .. " packages available"}
- else
- return {success = false, message = "Failed to update registry"}
- end
- end)
- -- Search packages in registry
- editor:register_command("package-search", "Search for packages in registry", function(args)
- if #args == 0 then
- -- List all available
- local count = 0
- local lines = {"Available packages:"}
- for name, entry in pairs(package_manager.registry) do
- local desc = entry.description or ""
- if #desc > 40 then desc = desc:sub(1, 37) .. "..." end
- table.insert(lines, string.format(" %s - %s", name, desc))
- count = count + 1
- end
- if count == 0 then
- return {success = true, message = "No packages in registry. Run package-refresh first."}
- end
- table.sort(lines)
- editor:set_echo_area(lines)
- return {success = true, message = ""}
- end
- local query = args[1]:lower()
- local matches = {}
- for name, entry in pairs(package_manager.registry) do
- local desc = (entry.description or ""):lower()
- if name:lower():find(query) or desc:find(query) then
- table.insert(matches, {name = name, description = entry.description or ""})
- end
- end
- if #matches == 0 then
- return {success = true, message = "No packages matching: " .. query}
- end
- local lines = {"Matching packages:"}
- for _, m in ipairs(matches) do
- local desc = m.description
- if #desc > 40 then desc = desc:sub(1, 37) .. "..." end
- table.insert(lines, string.format(" %s - %s", m.name, desc))
- end
- editor:set_echo_area(lines)
- return {success = true, message = ""}
- end, {}, true, "s")
- -- Sync packages (install missing from packages.lua)
- editor:register_command("package-sync", "Sync packages from packages.lua", function(args)
- local installed = 0
- local failed = 0
- local skipped = 0
- for _, spec in ipairs(package_manager.package_specs) do
- local normalized = package_manager.normalize_spec and package_manager.normalize_spec(spec)
- if not normalized then
- -- Try to normalize manually
- if type(spec) == "string" then
- normalized = {name = spec, source = "name"}
- elseif type(spec) == "table" and spec[1] then
- normalized = {name = spec[1], source = "name"}
- end
- end
- if normalized and normalized.enabled ~= false then
- local info = package_manager.info(normalized.name)
- if not info.installed then
- local ok, msg = package_manager.install(spec)
- if ok then
- installed = installed + 1
- else
- failed = failed + 1
- end
- else
- skipped = skipped + 1
- end
- end
- end
- return {success = true, message = string.format("Sync complete: %d installed, %d failed, %d already present", installed, failed, skipped)}
- end)
- -- Create sample packages.lua
- editor:register_command("package-init", "Create a sample packages.lua file", function(args)
- local packages_file = os.getenv("HOME") .. "/.lumacs/packages.lua"
- -- Check if exists
- local f = io.open(packages_file, "r")
- if f then
- f:close()
- return {success = false, message = "packages.lua already exists at ~/.lumacs/packages.lua"}
- end
- -- Create directory
- os.execute("mkdir -p " .. os.getenv("HOME") .. "/.lumacs")
- -- Write sample file
- local sample = [[
- -- Lumacs Package Configuration
- -- ============================================================================
- -- Add packages here. They will be automatically installed and loaded.
- --
- -- Formats:
- -- "package-name" -- From registry
- -- { "package-name", lazy = true } -- Lazy loaded
- -- { url = "https://github.com/user/pkg" } -- Git URL
- -- { dir = "~/my-package" } -- Local directory
- -- ============================================================================
- return {
- -- Example packages (uncomment to enable):
- -- "evil-mode", -- Vim emulation
- -- "magit", -- Git interface
- -- Example with config:
- -- { "which-key",
- -- config = function()
- -- require("which-key").setup({ delay = 500 })
- -- end
- -- },
- }
- ]]
- local file = io.open(packages_file, "w")
- if file then
- file:write(sample)
- file:close()
- return {success = true, message = "Created ~/.lumacs/packages.lua"}
- else
- return {success = false, message = "Failed to create packages.lua"}
- end
- end)
- -- ============================================================================
- -- Keybindings
- -- ============================================================================
- -- No default keybindings - access via M-x
- print("[Lua] package-commands loaded")
|