yazi: upgrade

This commit is contained in:
2026-01-02 06:40:13 +01:00
parent a987041647
commit 0a02ae14bb
7 changed files with 403 additions and 19 deletions
+1 -1
View File
@@ -1 +1 @@
@import 'colors.css'; @import 'colors.css';
+10 -10
View File
@@ -1,13 +1,13 @@
-- require("yaziline"):setup({ require("yaziline"):setup({
-- separator_style = "angly", separator_style = "angly",
-- select_symbol = "", select_symbol = "",
-- yank_symbol = "󰆐", yank_symbol = "󰆐",
-- filename_max_length = 24, -- trim when filename > 24 filename_max_length = 24, -- trim when filename > 24
-- filename_trim_length = 6, -- trim 6 chars from both ends filename_trim_length = 6, -- trim 6 chars from both ends
-- }) })
-- require("starship"):setup { require("starship"):setup {
-- config_file = "~/.config/yazi/starship.toml", config_file = "~/.config/yazi/starship.toml",
-- } }
require("git"):setup({}) require("git"):setup({})
Status:children_add(function() Status:children_add(function()
+5
View File
@@ -23,5 +23,10 @@ use = "llanosrocas/yaziline"
rev = "6266926" rev = "6266926"
hash = "9917ab5cb9bdbab7ca7f2501f84f0f11" hash = "9917ab5cb9bdbab7ca7f2501f84f0f11"
[[plugin.deps]]
use = "Rolv-Apneseth/starship"
rev = "eca1861"
hash = "e519d894e94ded741e06aae4d4775981"
[flavor] [flavor]
deps = [] deps = []
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Rolv Apneseth
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,116 @@
# starship.yazi
Starship prompt plugin for [Yazi](https://github.com/sxyazi/yazi)
<https://github.com/Rolv-Apneseth/starship.yazi/assets/69486699/f7314687-5cb1-4d66-8d9d-cca960ba6716>
## Requirements
- [Yazi](https://github.com/sxyazi/yazi) (v25.4.8+)
- [starship](https://github.com/starship/starship)
## Installation
```bash
ya pkg add Rolv-Apneseth/starship
```
### Manual
```sh
# Linux / MacOS
git clone https://github.com/Rolv-Apneseth/starship.yazi.git ~/.config/yazi/plugins/starship.yazi
# Windows
git clone https://github.com/Rolv-Apneseth/starship.yazi.git %AppData%\yazi\config\plugins\starship.yazi
```
## Usage
Add this to `~/.config/yazi/init.lua`:
```lua
require("starship"):setup()
```
Make sure you have [starship](https://github.com/starship/starship) installed and in your `PATH`.
## Config
Here is an example with all available config options:
```lua
require("starship"):setup({
-- Hide flags (such as filter, find and search). This can be beneficial for starship themes
-- which are intended to go across the entire width of the terminal.
hide_flags = false,
-- Whether to place flags after the starship prompt. False means the flags will be placed before the prompt.
flags_after_prompt = true,
-- Custom starship configuration file to use
config_file = "~/.config/starship_full.toml", -- Default: nil
-- Whether to enable support for starship's right prompt (i.e. `starship prompt --right`).
show_right_prompt = false,
-- Whether to hide the count widget, in case you want only your right prompt to show up. Only has
-- an effect when `show_right_prompt = true`
hide_count = false,
-- Separator to place between the right prompt and the count widget. Use `count_separator = ""`
-- to have no space between the widgets.
count_separator = " ",
})
```
## Extra
If you use a `starship` theme with a background colour, it might look a bit to cramped on just the one line `Yazi` gives the header by default. To fix this, you can add this to your `init.lua`:
<details>
<summary>Click to expand</summary>
```lua
local old_build = Tab.build
Tab.build = function(self, ...)
local bar = function(c, x, y)
if x <= 0 or x == self._area.w - 1 then
return ui.Bar(ui.Bar.TOP):area(ui.Rect.default)
end
return ui.Bar(ui.Bar.TOP)
:area(ui.Rect({
x = x,
y = math.max(0, y),
w = ya.clamp(0, self._area.w - x, 1),
h = math.min(1, self._area.h),
}))
:symbol(c)
end
local c = self._chunks
self._chunks = {
c[1]:pad(ui.Pad.y(1)),
c[2]:pad(ui.Pad(1, c[3].w > 0 and 0 or 1, 1, c[1].w > 0 and 0 or 1)),
c[3]:pad(ui.Pad.y(1)),
}
local style = th.mgr.border_style
self._base = ya.list_merge(self._base or {}, {
ui.Bar(ui.Bar.RIGHT):area(self._chunks[1]):style(style),
ui.Bar(ui.Bar.LEFT):area(self._chunks[1]):style(style),
bar("", c[1].right - 1, c[1].y),
bar("", c[1].right - 1, c[1].bottom - 1),
bar("", c[2].right, c[2].y),
bar("", c[2].right, c[2].bottom - 1),
})
old_build(self, ...)
end
```
</details>
> [!NOTE]
> This works by overriding your `Tab.build` function so make sure this is the only place you're doing that in your config. For example, this would be incompatible with the [full-border plugin](https://github.com/yazi-rs/plugins/tree/main/full-border.yazi)
## Thanks
- [sxyazi](https://github.com/sxyazi) for providing the code for this plugin and the demo video [in this comment](https://github.com/sxyazi/yazi/issues/767#issuecomment-1977082834)
@@ -0,0 +1,242 @@
--- @since 25.4.8
-- For development
--[[ local function notify(message) ]]
--[[ ya.notify({ title = "Starship", content = message, timeout = 3 }) ]]
--[[ end ]]
local save = ya.sync(function(st, outputs)
st.output_left = outputs.left
st.output_right = outputs.right
-- Support for versions later than v25.5.31 (not yet a full release as of writing this comment)
local render = ui.render or ya.render
render()
end)
-- Helper function for accessing the `config_file` state variable
---@return string
local get_config_file = ya.sync(function(st)
return st.config_file
end)
--- Helper function for accessing `show_right_prompt` state variable
---@return boolean
local should_show_right_prompt = ya.sync(function(st)
return st.show_right_prompt
end)
return {
---User arguments for setup method
---@class SetupArgs
---@field config_file string Absolute path to a starship config file.
---@field hide_flags boolean Whether to hide all flags (such as filter and search). Default value is false.
---@field flags_after_prompt boolean Whether to place flags (such as filter and search) after the starship prompt. Default value is true.
---@field show_right_prompt boolean Whether to enable starship right prompt support. Default value is false.
---@field hide_count boolean Whether to hide the count widget. Only has an effect when show_right_prompt is true. Default value is false.
---@field count_separator string Set a custom separator between the count widget and the right prompt. Default value is " ", set to "" for no space.
--- Setup plugin
--- @param st table State
--- @param args SetupArgs|nil
setup = function(st, args)
local hide_flags = false
local flags_after_prompt = true
local hide_count = false
local count_separator = " "
-- Check setup args
if args ~= nil then
if args.config_file ~= nil then
local url = Url(args.config_file)
if url.is_regular then
local config_file = args.config_file
-- Manually replace '~' and '$HOME' at the start of the path with the OS environment variable
local home = os.getenv("HOME")
if home then
home = tostring(home)
config_file = config_file:gsub("^~", home):gsub("^$HOME", home)
end
st.config_file = config_file
end
end
if args.show_right_prompt ~= nil then
-- Save directly to the plugin state so it can be accessed
-- read from the entry function
st.show_right_prompt = args.show_right_prompt
end
if args.hide_count ~= nil then
hide_count = args.hide_count
end
if args.count_separator ~= nil then
count_separator = args.count_separator
end
if args.hide_flags ~= nil then
hide_flags = args.hide_flags
end
if args.flags_after_prompt ~= nil then
flags_after_prompt = args.flags_after_prompt
end
end
-- Replace default left header widget
Header:children_remove(1, Header.LEFT)
Header:children_add(function(self)
if hide_flags or not st.output_left then
return ui.Line.parse(st.output_left or "")
end
-- Split `st.output` at the first line break (or keep as is if none was found)
local output = st.output_left:match("([^\n]*)\n?") or st.output_left
local flags = self:flags()
if flags_after_prompt then
output = output .. " " .. flags
else
output = flags .. " " .. output
end
local line = ui.Line.parse(output)
if line:width() > self._area.w then
return ""
end
return line
end, 1000, Header.LEFT)
-- Support for right prompt, if enabled
if st.show_right_prompt then
-- Remove the default count widget
Header:children_remove(1, Header.RIGHT)
-- Replace with a custom widget combining the right prompt and the count widget
Header:children_add(function(self)
if not st.output_right then
st.output_right = ""
end
local output = st.output_right:match("([^\n]*)\n?") or st.output_right
local line = ui.Line.parse(output)
-- Custom count widget so that we can measure the combined width
if not hide_count then
local yanked = #cx.yanked
local count, style
if yanked == 0 then
count = #self._tab.selected
style = th.mgr.count_selected
elseif cx.yanked.is_cut then
count = yanked
style = th.mgr.count_cut
else
count = yanked
style = th.mgr.count_copied
end
-- Append custom count widget
if count ~= 0 then
line = ui.Line({
line,
ui.Span(count_separator),
ui.Span(string.format(" %d ", count)):style(style),
})
end
end
-- Give precedence to the left header widget(s), hiding this component entirely if
-- there is no room for both
local right_width = line:width()
if self._left_width then
local max = self._area.w - self._left_width
if max < right_width then
return ""
end
end
return line
end, 1000, Header.RIGHT)
-- Override the header's redraw method, since we want the left side of the header to have
-- precedence over the right, unlike the default behaviour of hiding the left side if
-- there isn't room for both.
function Header:redraw()
local left = self:children_redraw(self.LEFT)
self._left_width = left:width()
local right = self:children_redraw(self.RIGHT)
return {
ui.Line(left):area(self._area),
ui.Line(right):area(self._area):align(ui.Align.RIGHT),
}
end
end
-- Pass current working directory and custom config path (if specified) to the plugin's entry point
---Callback for subscribers to update the prompt
local callback = function()
local cwd = cx.active.current.cwd
if st.cwd ~= cwd then
st.cwd = cwd
-- `ya.emit` as of 25.5.28
local emit = ya.emit or ya.manager_emit
emit("plugin", {
st._id,
ya.quote(tostring(cwd), true),
})
end
end
-- Subscribe to events
ps.sub("cd", callback)
ps.sub("tab", callback)
end,
entry = function(_, job)
local args = job.args
-- Setup commands for left and right prompts
local function base_command()
return Command("starship")
:arg("prompt")
:stdin(Command.INHERIT)
:cwd(args[1])
:env("STARSHIP_SHELL", "")
:env("PWD", args[1])
end
local command_left = base_command()
local command_right = base_command():arg("--right")
-- Point to custom starship config for both commands
local config_file = get_config_file()
if config_file then
command_left = command_left:env("STARSHIP_CONFIG", config_file)
command_right = command_right:env("STARSHIP_CONFIG", config_file)
end
-- Execute left prompt command and save output
local outputs = { left = "", right = "" }
local output_left = command_left:output()
if output_left then
outputs.left = output_left.stdout:gsub("^%s+", "")
end
-- If support for right prompt is enabled, execute right prompt command and save output
local show_right_prompt = should_show_right_prompt()
if show_right_prompt then
local output_right = command_right:output()
if output_right then
outputs.right = output_right.stdout:gsub("^%s+", "")
end
end
save(outputs)
end,
}
+8 -8
View File
@@ -23,7 +23,6 @@ max_height = 900
cache_dir = "" cache_dir = ""
image_filter = "triangle" image_filter = "triangle"
image_quality = 75 image_quality = 75
sixel_fraction = 15
ueberzug_scale = 1 ueberzug_scale = 1
ueberzug_offset = [0, 0, 0, 0] ueberzug_offset = [0, 0, 0, 0]
@@ -57,7 +56,7 @@ play = [
[open] [open]
rules = [ rules = [
# Folder # Folder
{ name = "*/", use = ["edit", "open", "reveal"] }, { url = "*/", use = ["edit", "open", "reveal"] },
# Text # Text
{ mime = "text/*", use = ["edit", "reveal"] }, { mime = "text/*", use = ["edit", "reveal"] },
# Image # Image
@@ -73,7 +72,7 @@ rules = [
# Empty file # Empty file
{ mime = "inode/empty", use = ["edit", "reveal"] }, { mime = "inode/empty", use = ["edit", "reveal"] },
# Fallback # Fallback
{ name = "*", use = ["edit", "open", "reveal"] }, { url = "*", use = ["edit", "open", "reveal"] },
] ]
[tasks] [tasks]
@@ -87,9 +86,10 @@ suppress_preload = false
[plugin] [plugin]
fetchers = [ fetchers = [
# Mimetype # Mimetype
{ id = "mime", name = "*", run = "mime", if = "!mime", prio = "high" }, { id = "mime", url = "*/", run = "mime.dir", prio = "high" },
{ id = "git", name = "*", run = "git", prio = "normal" }, { id = "mime", url = "*", run = "mime.local", if = "!mime", prio = "high" },
{ id = "git", name = "*/", run = "git", prio = "normal" }, { id = "git", url = "*", run = "git", prio = "normal" },
{ id = "git", url = "*/", run = "git", prio = "normal" },
] ]
preloaders = [ preloaders = [
# Image # Image
@@ -104,7 +104,7 @@ preloaders = [
{ mime = "application/vnd.ms-opentype", run = "font" }, { mime = "application/vnd.ms-opentype", run = "font" },
] ]
previewers = [ previewers = [
{ name = "*/", run = "folder", sync = true }, { url = "*/", run = "folder", sync = true },
# Code # Code
{ mime = "text/*", run = "code" }, { mime = "text/*", run = "code" },
{ mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code" }, { mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code" },
@@ -126,7 +126,7 @@ previewers = [
# Empty file # Empty file
{ mime = "inode/x-empty", run = "empty" }, { mime = "inode/x-empty", run = "empty" },
# Fallback # Fallback
{ name = "*", run = "file" }, { url = "*", run = "file" },
] ]
[input] [input]