From 1bb433dc649d9b4bdc147095893d6b52ae1653ab Mon Sep 17 00:00:00 2001 From: sammyette Date: Tue, 10 Jun 2025 18:23:24 -0400 Subject: [PATCH] feat: add processors api (#343) * feat: add processors api * fix: make processor work properly, implement in exec code * feat: add names to processors, allow skipping based on name * feat: add opt to skip processors * feat: allow processors to set if history should be saved --- Taskfile.yaml | 2 +- docs/features/opts.md | 5 ++++ nature/init.lua | 1 + nature/opts/autocd.lua | 35 ++++++++++++++++---------- nature/opts/init.lua | 5 ++-- nature/processors.lua | 57 ++++++++++++++++++++++++++++++++++++++++++ nature/runner.lua | 20 +++++++++++---- 7 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 nature/processors.lua diff --git a/Taskfile.yaml b/Taskfile.yaml index 264e7d51..311d7d76 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -6,7 +6,7 @@ vars: PREFIX: '{{default "/usr/local" .PREFIX}}' bindir__: '{{.PREFIX}}/bin' BINDIR: '{{default .bindir__ .BINDIR}}' - libdir__: '{{.PREFIX}}/share/hilbish' + libdir__: '' LIBDIR: '{{default .libdir__ .LIBDIR}}' goflags__: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"' GOFLAGS: '{{default .goflags__ .GOFLAGS}}' diff --git a/docs/features/opts.md b/docs/features/opts.md index 2fb848de..f975c79e 100644 --- a/docs/features/opts.md +++ b/docs/features/opts.md @@ -76,3 +76,8 @@ of an exact match. #### Default: `true` If this is enabled, when a background job is finished, a [notification](../notifications) will be sent. + +### `processorSkipList` +#### Value: `table` +#### Default: `{}` +A table listing the names of command processors to skip. diff --git a/nature/init.lua b/nature/init.lua index cd4fd7a5..9b75a271 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -19,6 +19,7 @@ table.insert(package.searchers, function(module) end) require 'nature.hilbish' +require 'nature.processors' require 'nature.commands' require 'nature.completions' diff --git a/nature/opts/autocd.lua b/nature/opts/autocd.lua index ce682303..2c8a2b7d 100644 --- a/nature/opts/autocd.lua +++ b/nature/opts/autocd.lua @@ -1,18 +1,27 @@ local fs = require 'fs' -local oldShRunner = hilbish.runner.sh -function hilbish.runner.sh(input) - local res = oldShRunner(input) +hilbish.processors.add { + name = 'hilbish.autocd', + func = function(path) + if hilbish.opts.autocd then + local ok, stat = pcall(fs.stat, path) + if ok and stat.isDir then + local oldPath = hilbish.cwd() - if res.exit ~= 0 and hilbish.opts.autocd then - local ok, stat = pcall(fs.stat, res.input) - if ok and stat.isDir then - -- discard here to not append the cd, which will be in history - local _, exitCode, err = hilbish.runner.sh('cd ' .. res.input) - res.exitCode = exitCode - res.err = err + local absPath = fs.abs(path) + fs.cd(path) + + bait.throw('cd', path, oldPath) + bait.throw('hilbish.cd', absPath, oldPath) + + end + return { + continue = not ok + } + else + return { + continue = true + } end end - - return res -end +} diff --git a/nature/opts/init.lua b/nature/opts/init.lua index d55864f6..ca99caed 100644 --- a/nature/opts/init.lua +++ b/nature/opts/init.lua @@ -2,7 +2,7 @@ hilbish.opts = {} local function setupOpt(name, default) hilbish.opts[name] = default - pcall(require, 'nature.opts.' .. name) + local ok, err = pcall(require, 'nature.opts.' .. name) end local defaultOpts = { @@ -15,7 +15,8 @@ The nice lil shell for {blue}Lua{reset} fanatics! fuzzy = false, notifyJobFinish = true, crimmas = true, - tips = true + tips = true, + processorSkipList = {} } for optsName, default in pairs(defaultOpts) do diff --git a/nature/processors.lua b/nature/processors.lua new file mode 100644 index 00000000..f36d7ace --- /dev/null +++ b/nature/processors.lua @@ -0,0 +1,57 @@ +-- @module hilbish.processors + +hilbish.processors = { + list = {}, + sorted = {} +} + +function hilbish.processors.add(processor) + if not processor.name then + error 'processor is missing name' + end + + if not processor.func then + error 'processor is missing function' + end + + table.insert(hilbish.processors.list, processor) + table.sort(hilbish.processors.list, function(a, b) return a.priority < b.priority end) +end + +local function contains(search, needle) + for _, p in ipairs(search) do + if p == needle then + return true + end + end + + return false +end + +--- Run all command processors, in order by priority. +--- It returns the processed command (which may be the same as the passed command) +--- and a boolean which states whether to proceed with command execution. +function hilbish.processors.execute(command, opts) + opts = opts or {} + opts.skip = opts.skip or {} + + local continue = true + local history + for _, processor in ipairs(hilbish.processors.list) do + if not contains(opts.skip, processor.name) then + local processed = processor.func(command) + if processed.history ~= nil then history = processed.history end + if processed.command then command = processed.command end + if not processed.continue then + continue = false + break + end + end + end + + return { + command = command, + continue = continue, + history = history + } +end diff --git a/nature/runner.lua b/nature/runner.lua index 427fb7e4..cc5b67e0 100644 --- a/nature/runner.lua +++ b/nature/runner.lua @@ -122,12 +122,22 @@ end -- @param input string -- @param priv bool function hilbish.runner.run(input, priv) - local command = hilbish.aliases.resolve(input) - bait.throw('command.preexec', input, command) + bait.throw('command.preprocess', input) + local processed = hilbish.processors.execute(input, { + skip = hilbish.opts.processorSkipList + }) + priv = processed.history ~= nil and (not processed.history) or priv + if not processed.continue then + finishExec(0, '', true) + return + end + + local command = hilbish.aliases.resolve(processed.command) + bait.throw('command.preexec', processed.command, command) ::rerun:: local runner = hilbish.runner.get(currentRunner) - local ok, out = pcall(runner.run, input) + local ok, out = pcall(runner.run, processed.command) if not ok then io.stderr:write(out .. '\n') finishExec(124, out.input, priv) @@ -135,9 +145,9 @@ function hilbish.runner.run(input, priv) end if out.continue then - local contInput = continuePrompt(input, out.newline) + local contInput = continuePrompt(processed.command, out.newline) if contInput then - input = contInput + processed.command = contInput goto rerun end end