AutoYADM commit: 2025-02-12 12:15:06
This commit is contained in:
parent
a01694f82b
commit
5237f0f99b
5 changed files with 466 additions and 0 deletions
223
.config/yazi/plugins/custom-shell.yazi/main.lua
Normal file
223
.config/yazi/plugins/custom-shell.yazi/main.lua
Normal file
|
@ -0,0 +1,223 @@
|
|||
local state_option = ya.sync(function(state, attr)
|
||||
return state[attr]
|
||||
end)
|
||||
|
||||
local function shell_choice(shell_val)
|
||||
-- input is in lowercase always
|
||||
local alt_name_map = {
|
||||
kornshell = "ksh",
|
||||
powershell = "pwsh",
|
||||
nushell = "nu",
|
||||
}
|
||||
|
||||
local shell_map = {
|
||||
bash = { shell_val = "bash", supporter = "-ic", wait_cmd = "read", separator = ";" },
|
||||
zsh = { shell_val = "zsh", supporter = "-ic", wait_cmd = "read", separator = ";" },
|
||||
fish = { shell_val = "fish", supporter = "-c", wait_cmd = "read", separator = ";" },
|
||||
pwsh = { shell_val = "pwsh", supporter = "-Command", wait_cmd = "Read-Host", separator = ";" },
|
||||
sh = { shell_val = "sh", supporter = "-c", wait_cmd = "read", separator = ";" },
|
||||
ksh = { shell_val = "ksh", supporter = "-c", wait_cmd = "read", separator = ";" },
|
||||
csh = { shell_val = "csh", supporter = "-c", wait_cmd = "$<", separator = ";" },
|
||||
tcsh = { shell_val = "tcsh", supporter = "-c", wait_cmd = "$<", separator = ";" },
|
||||
dash = { shell_val = "dash", supporter = "-c", wait_cmd = "read", separator = ";" },
|
||||
nu = { shell_val = "nu", supporter = "-l -i -c", wait_cmd = "input", separator = "| print;" },
|
||||
}
|
||||
|
||||
shell_val = alt_name_map[shell_val] or shell_val
|
||||
local shell_info = shell_map[shell_val]
|
||||
|
||||
if shell_info then
|
||||
return shell_info.shell_val, shell_info.supporter, shell_info.wait_cmd, shell_info.separator
|
||||
else
|
||||
return nil, "-c", "read"
|
||||
end
|
||||
end
|
||||
|
||||
local function manage_extra_args(job)
|
||||
-- function for dealing with --option, --option=boolean, nil
|
||||
local function tobool(arg, default)
|
||||
if type(arg) == "boolean" then
|
||||
return arg
|
||||
elseif type(arg) == "string" then
|
||||
return arg:lower() == "true"
|
||||
end
|
||||
-- Fallback in case of nil
|
||||
return default
|
||||
end
|
||||
|
||||
local block = tobool(job.args.block, true)
|
||||
local orphan = tobool(job.args.orphan, false)
|
||||
local wait = tobool(job.args.wait, false)
|
||||
local interactive = tobool(job.args.confirm, false)
|
||||
|
||||
return block, orphan, wait, interactive
|
||||
end
|
||||
|
||||
local function manage_additional_title_text(block, wait)
|
||||
local txt = ""
|
||||
if block or wait then
|
||||
txt = "(" .. (block and wait and "block and wait" or block and "block" or "") .. ")"
|
||||
end
|
||||
return txt
|
||||
end
|
||||
|
||||
local function history_add(history_path, cmd_run)
|
||||
local history_file = history_path
|
||||
local history = {}
|
||||
|
||||
-- Ensure the history file exists
|
||||
local file = io.open(history_file, "a+")
|
||||
if file then
|
||||
file:close()
|
||||
end
|
||||
|
||||
-- Read existing history
|
||||
for line in io.lines(history_file) do
|
||||
-- add line if it is not empty
|
||||
if line:match("%S") then
|
||||
table.insert(history, line)
|
||||
end
|
||||
end
|
||||
|
||||
if cmd_run == nil then
|
||||
return history
|
||||
end
|
||||
|
||||
-- Append the new command to the history if it doesn't already exist
|
||||
local command_exists = false
|
||||
for _, cmd in ipairs(history) do
|
||||
if cmd == cmd_run then
|
||||
command_exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not command_exists then
|
||||
file = io.open(history_file, "a")
|
||||
if file then
|
||||
file:write(cmd_run .. "\n")
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
return history
|
||||
end
|
||||
|
||||
local function history_prev(history_path)
|
||||
-- get the history commands
|
||||
local history_cmds = history_add(history_path)
|
||||
if #history_cmds < 1 then
|
||||
ya.notify({ title = "Custom-Shell", content = "History is Empty.", timeout = 3 })
|
||||
return
|
||||
end
|
||||
-- preview the commands list in fzf and return selected cmd
|
||||
for i, cmd in ipairs(history_cmds) do
|
||||
history_cmds[i] = cmd:gsub("'", "'\\''") -- Escape single quotes
|
||||
end
|
||||
local permit = ya.hide()
|
||||
|
||||
local cmd = string.format('%s < "%s"', "fzf", history_path)
|
||||
local handle = io.popen(cmd, "r")
|
||||
|
||||
local his_cmd = ""
|
||||
if handle then
|
||||
-- strip
|
||||
his_cmd = string.gsub(handle:read("*all") or "", "^%s*(.-)%s*$", "%1")
|
||||
handle:close()
|
||||
end
|
||||
|
||||
permit:drop()
|
||||
return his_cmd
|
||||
end
|
||||
|
||||
local function entry(_, job)
|
||||
local shell_env = os.getenv("SHELL"):match(".*/(.*)")
|
||||
local shell_value, cmd, custom_shell_cmd = "", "", ""
|
||||
|
||||
local history_path, save_history = state_option("history_path"), state_option("save_history")
|
||||
|
||||
if job.args[1] == "auto" or job.args[1] == "history" then
|
||||
shell_value = shell_env:lower()
|
||||
elseif job.args[1] == "custom" then
|
||||
shell_value = job.args[2]
|
||||
cmd = job.args[3]
|
||||
-- when the first param is a shell name
|
||||
elseif job.args[1] ~= "history" then
|
||||
shell_value = job.args[1]:lower()
|
||||
end
|
||||
|
||||
local shell_val, supp, wait_cmd, separator = shell_choice(shell_value:lower())
|
||||
|
||||
if job.args[1] == "history" then
|
||||
local his_cmd = history_prev(history_path)
|
||||
if his_cmd == nil then
|
||||
return
|
||||
end
|
||||
local value, event = ya.input({
|
||||
title = "Custom-Shell History",
|
||||
position = { "top-center", y = 3, w = 40 },
|
||||
value = his_cmd,
|
||||
})
|
||||
if event == 1 then
|
||||
-- this may lead to nested zsh -c "zsh -c 'zsh -c ...'"
|
||||
-- But that's not a problem
|
||||
cmd = value
|
||||
end
|
||||
end
|
||||
if shell_val == nil then
|
||||
ya.notify("Unsupported shell: " .. shell_value .. "Choosing Default Shell: " .. shell_env)
|
||||
shell_val, supp = shell_choice(shell_env)
|
||||
end
|
||||
|
||||
local block, orphan, wait, interactive = manage_extra_args(job) -- , confirm
|
||||
local additional_title_text = manage_additional_title_text(block, wait)
|
||||
local input_title = shell_value .. " Shell " .. additional_title_text .. ": "
|
||||
local event = 1
|
||||
|
||||
if job.args[1] ~= "custom" and job.args[1] ~= "history" then
|
||||
cmd, event = ya.input({
|
||||
title = input_title,
|
||||
position = { "top-center", y = 3, w = 40 },
|
||||
})
|
||||
end
|
||||
|
||||
if event == 1 then
|
||||
local after_cmd = separator .. (wait and wait_cmd or "exit")
|
||||
-- for history also, this will be added.
|
||||
custom_shell_cmd = shell_val .. " " .. supp .. " " .. ya.quote(cmd .. after_cmd, true)
|
||||
|
||||
ya.manager_emit("shell", {
|
||||
custom_shell_cmd,
|
||||
block = block,
|
||||
interactive = interactive,
|
||||
orphan = orphan,
|
||||
})
|
||||
|
||||
if save_history then
|
||||
if job.args[1] == "history" then
|
||||
-- to avoid nested "zsh -c 'zsh -c ...'"
|
||||
history_add(history_path, cmd)
|
||||
else
|
||||
history_add(history_path, custom_shell_cmd)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- @since 25.2.7
|
||||
|
||||
return {
|
||||
setup = function(state, options)
|
||||
local default_history_path = (
|
||||
ya.target_family() == "windows"
|
||||
and os.getenv("APPDATA") .. "\\yazi\\config\\plugins\\custom-shell.yazi\\yazi_cmd_history"
|
||||
) or (os.getenv("HOME") .. "/.config/yazi/plugins/custom-shell.yazi/yazi_cmd_history")
|
||||
|
||||
state.history_path = options.history_path or default_history_path
|
||||
if state.history_path:lower() == "default" then
|
||||
state.history_path = default_history_path
|
||||
end
|
||||
state.save_history = options.save_history and true
|
||||
end,
|
||||
entry = entry,
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue