feat: track Decman configuration
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
# Used by the Noctalia Pi Status Bridge adapter and the Hyprland launcher.
|
||||
PI_STATUS_BRIDGE_CLIENT=/home/alex/.npm-global/bin/pi-status-bridge-client
|
||||
PI_STATUS_UI_BINARY=/home/alex/.local/bin/pi-status-ui
|
||||
@@ -0,0 +1,44 @@
|
||||
starship init fish | source
|
||||
set fish_greeting ""
|
||||
|
||||
# Prefer Neovim for both explicit and editor-variable invocations.
|
||||
alias vim nvim
|
||||
set -gx EDITOR nvim
|
||||
set -gx VISUAL nvim
|
||||
|
||||
# pyenv setup
|
||||
while set pyenv_index (contains -i -- "/home/alex/.pyenv/shims" $PATH)
|
||||
set -eg PATH[$pyenv_index]
|
||||
end
|
||||
set -e pyenv_index
|
||||
set -gx PATH '/home/alex/.pyenv/shims' $PATH
|
||||
set -gx PYENV_SHELL fish
|
||||
command pyenv rehash 2>/dev/null
|
||||
function pyenv
|
||||
set command $argv[1]
|
||||
set -e argv[1]
|
||||
|
||||
switch "$command"
|
||||
case rehash shell
|
||||
source (pyenv "sh-$command" $argv|psub)
|
||||
case "*"
|
||||
command pyenv "$command" $argv
|
||||
end
|
||||
end
|
||||
|
||||
# bun
|
||||
set --export BUN_INSTALL "$HOME/.bun"
|
||||
set --export PATH $BUN_INSTALL/bin $PATH
|
||||
|
||||
# opencode
|
||||
fish_add_path /home/alex/.opencode/bin
|
||||
|
||||
# Yazi wrapper that keeps the shell in its selected directory.
|
||||
function y
|
||||
set tmp (mktemp -t "yazi-cwd.XXXXXX")
|
||||
command yazi $argv --cwd-file="$tmp"
|
||||
if read -z cwd <"$tmp"; and [ "$cwd" != "$PWD" ]; and test -d "$cwd"
|
||||
builtin cd -- "$cwd"
|
||||
end
|
||||
command rm -f -- "$tmp"
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
# Non-locking Wayland screen blanker. It covers every monitor in black and
|
||||
# dismisses itself on any key press or mouse click; it never changes DPMS.
|
||||
listener {
|
||||
timeout = 300
|
||||
on-timeout = /home/alex/.local/bin/wayshell-blanker
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
-- Shared Hyprland profile. yadm deploys machine.lua for the active class.
|
||||
--
|
||||
-- Scope: preserve launch, media, directional focus/move, workspace, scratchpad,
|
||||
-- floating, fullscreen, and window-placement muscle memory. i3's split-tree,
|
||||
-- stacking/tabbed, and resize-mode behavior is intentionally deferred.
|
||||
local machine = dofile(os.getenv("HOME") .. "/.config/hypr/machine.lua")
|
||||
|
||||
for _, monitor in ipairs(machine.monitors or {}) do
|
||||
hl.monitor(monitor)
|
||||
end
|
||||
|
||||
local main_mod = "SUPER"
|
||||
local terminal = "kitty"
|
||||
|
||||
local input = {
|
||||
kb_layout = "us",
|
||||
kb_variant = "intl",
|
||||
numlock_by_default = true,
|
||||
}
|
||||
for key, value in pairs(machine.input or {}) do
|
||||
input[key] = value
|
||||
end
|
||||
|
||||
hl.config({
|
||||
input = input,
|
||||
general = {
|
||||
gaps_in = 4,
|
||||
-- Keep a thin black perimeter so the bottom border remains on-screen.
|
||||
gaps_out = 2,
|
||||
border_size = 2,
|
||||
col = {
|
||||
-- Muted Ember tones: visible focus without a high-brightness OLED edge.
|
||||
active_border = "rgba(c9782ed9)",
|
||||
inactive_border = "rgba(2a190fa6)",
|
||||
},
|
||||
},
|
||||
decoration = {
|
||||
rounding = 0,
|
||||
},
|
||||
animations = {
|
||||
enabled = false,
|
||||
},
|
||||
binds = {
|
||||
-- Selecting the current workspace again returns to the last workspace.
|
||||
workspace_back_and_forth = true,
|
||||
},
|
||||
})
|
||||
|
||||
-- Three-finger horizontal swipes change workspaces; touchscreens remain excluded
|
||||
-- by Hyprland's default workspace_swipe_touch = false behavior.
|
||||
hl.gesture({
|
||||
fingers = 3,
|
||||
direction = "horizontal",
|
||||
action = "workspace",
|
||||
})
|
||||
|
||||
-- Dynamically hide the border when a workspace has exactly one tiled app.
|
||||
hl.workspace_rule({
|
||||
workspace = "w[t1]",
|
||||
no_border = true,
|
||||
})
|
||||
|
||||
-- Application and session bindings.
|
||||
local noctalia_ipc = "noctalia msg "
|
||||
local pi_status_ui_toggle = 'ui="${PI_STATUS_UI_BINARY:-$HOME/.local/bin/pi-status-ui}"; if test -x "$ui"; then setsid -f env TMPDIR=/tmp "$ui" --toggle >/tmp/pi-status-ui.log 2>&1; fi'
|
||||
-- Tap and release Super on its own to open Noctalia's control-center home.
|
||||
hl.bind(main_mod .. " + SUPER_L", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle control-center"), { release = true })
|
||||
hl.bind(main_mod .. " + RETURN", hl.dsp.exec_cmd(terminal))
|
||||
hl.bind(main_mod .. " + CTRL + RETURN", hl.dsp.exec_cmd(terminal .. " -e zellij"))
|
||||
hl.bind(main_mod .. " + SHIFT + RETURN", hl.dsp.exec_cmd("rofi -show combi"))
|
||||
hl.bind(main_mod .. " + SPACE", hl.dsp.exec_cmd(pi_status_ui_toggle))
|
||||
hl.bind(main_mod .. " + N", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle alex/knowledge-lookup:panel"))
|
||||
hl.bind(main_mod .. " + S", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle control-center"))
|
||||
hl.bind(main_mod .. " + 0", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle session"))
|
||||
hl.bind(main_mod .. " + SHIFT + F", hl.dsp.exec_cmd(noctalia_ipc .. "bar-toggle main"))
|
||||
hl.bind(main_mod .. " + SHIFT + R", hl.dsp.exec_cmd("hyprctl reload"))
|
||||
hl.bind(main_mod .. " + CTRL + L", hl.dsp.exec_cmd("command -v hyprlock >/dev/null && hyprlock || loginctl lock-session"))
|
||||
hl.bind(main_mod .. " + CTRL + SHIFT + ALT + S", hl.dsp.exec_cmd("systemctl suspend"))
|
||||
hl.bind(main_mod .. " + CTRL + SHIFT + ALT + H", hl.dsp.exec_cmd("systemctl hibernate"))
|
||||
hl.bind(main_mod .. " + SHIFT + C", hl.dsp.window.close())
|
||||
hl.bind(main_mod .. " + CTRL + SHIFT + F", hl.dsp.exec_cmd("/home/alex/.local/bin/screenshot-select"))
|
||||
|
||||
-- Audio, media, brightness, and calculator keys.
|
||||
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true })
|
||||
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true })
|
||||
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true })
|
||||
hl.bind(main_mod .. " + XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true })
|
||||
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
|
||||
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
|
||||
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
|
||||
hl.bind(main_mod .. " + XF86AudioRaiseVolume", hl.dsp.exec_cmd("playerctl next"), { locked = true })
|
||||
hl.bind(main_mod .. " + XF86AudioLowerVolume", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
|
||||
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd('light -A 5'), { locked = true })
|
||||
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd('light -U 5'), { locked = true })
|
||||
hl.bind(main_mod .. " + XF86MonBrightnessDown", hl.dsp.exec_cmd('light -S 0.0'), { locked = true })
|
||||
hl.bind(main_mod .. " + XF86MonBrightnessUp", hl.dsp.exec_cmd('light -S 100'), { locked = true })
|
||||
hl.bind("XF86Calculator", hl.dsp.exec_cmd("qalculate-qt"), { locked = true })
|
||||
|
||||
-- Retain i3's hjkl and arrow-key directional workflow.
|
||||
for _, direction in ipairs({ "left", "down", "up", "right" }) do
|
||||
local key = ({ left = "H", down = "J", up = "K", right = "L" })[direction]
|
||||
hl.bind(main_mod .. " + " .. key, hl.dsp.focus({ direction = direction }))
|
||||
hl.bind(main_mod .. " + " .. direction, hl.dsp.focus({ direction = direction }))
|
||||
end
|
||||
|
||||
for key, direction in pairs({ H = "l", J = "d", K = "u", L = "r", LEFT = "l", DOWN = "d", UP = "u", RIGHT = "r" }) do
|
||||
hl.bind(main_mod .. " + SHIFT + " .. key, hl.dsp.window.move({ direction = direction }))
|
||||
end
|
||||
|
||||
-- Numbered workspaces match the i3 profile. Shift moves; Ctrl moves and follows.
|
||||
for workspace = 1, 9 do
|
||||
local key = tostring(workspace)
|
||||
hl.bind(main_mod .. " + " .. key, hl.dsp.focus({ workspace = workspace }))
|
||||
hl.bind(main_mod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = workspace }))
|
||||
hl.bind(main_mod .. " + CTRL + " .. key, hl.dsp.window.move({ workspace = workspace, follow = true }))
|
||||
end
|
||||
-- Match i3's back-and-forth workflow: Super+Tab switches to the last workspace;
|
||||
-- selecting the current numbered workspace also returns to it.
|
||||
hl.bind(main_mod .. " + TAB", hl.dsp.focus({ workspace = "previous" }))
|
||||
hl.bind(main_mod .. " + CTRL + RIGHT", hl.dsp.focus({ workspace = "+1" }))
|
||||
hl.bind(main_mod .. " + CTRL + LEFT", hl.dsp.focus({ workspace = "-1" }))
|
||||
|
||||
-- Hyprland special workspaces are the Wayland analogue of the i3 scratchpad.
|
||||
hl.bind(main_mod .. " + MINUS", hl.dsp.workspace.toggle_special("scratchpad"))
|
||||
hl.bind(main_mod .. " + SHIFT + MINUS", hl.dsp.window.move({ workspace = "special:scratchpad" }))
|
||||
|
||||
-- Keep the i3 floating and fullscreen shortcuts. Layout-specific binds are deferred.
|
||||
hl.bind(main_mod .. " + F", hl.dsp.window.fullscreen({ action = "toggle" }))
|
||||
hl.bind(main_mod .. " + SHIFT + SPACE", hl.dsp.window.float({ action = "toggle" }))
|
||||
hl.bind(main_mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
|
||||
hl.bind(main_mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
||||
|
||||
-- i3 for_window/assign translations. Verify Wayland class/title values with `hyprctl clients`.
|
||||
local function float_rule(name, match, border_size)
|
||||
hl.window_rule({
|
||||
name = name,
|
||||
match = match,
|
||||
float = true,
|
||||
border_size = border_size,
|
||||
})
|
||||
end
|
||||
|
||||
hl.window_rule({ name = "obsidian-workspace", match = { class = "^obsidian$" }, workspace = "8" })
|
||||
hl.window_rule({ name = "thunderbird-workspace", match = { class = "^Thunderbird$" }, workspace = "9" })
|
||||
float_rule("pi-status-ui", { class = "^(pi-status-ui|Pi-status-ui)$" }, 1)
|
||||
float_rule("alsamixer", { title = "^alsamixer$" }, 1)
|
||||
float_rule("qalculate", { title = "^Qalculate!$" })
|
||||
float_rule("psensor", { class = "^Psensor$" })
|
||||
float_rule("lxrandr", { title = "^lxrandr$" })
|
||||
float_rule("blueman", { class = "^Blueman-manager$" })
|
||||
float_rule("gparted", { class = "^GParted$" })
|
||||
float_rule("pavucontrol", { class = "^pavucontrol$" })
|
||||
float_rule("volume-control", { title = "^Volume Control$" })
|
||||
float_rule("virtualbox", { class = ".*VirtualBox.*" })
|
||||
hl.window_rule({ name = "virtualbox-manager-tiles", match = { class = ".*VirtualBox Manager.*" }, tile = true })
|
||||
hl.window_rule({ name = "virtualbox-machine-tiles", match = { class = ".*VirtualBox Machine.*" }, tile = true })
|
||||
-- Send music clients to the existing scratchpad without stealing startup focus.
|
||||
hl.window_rule({ name = "spotify-music", match = { class = "^Spotify$" }, workspace = "special:scratchpad silent", no_initial_focus = true })
|
||||
hl.window_rule({ name = "deezer-music", match = { class = "^Deezer$" }, workspace = "special:scratchpad silent", no_initial_focus = true })
|
||||
|
||||
hl.on("hyprland.start", function()
|
||||
for _, command in ipairs(machine.startup or {}) do
|
||||
hl.exec_cmd(command)
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,45 @@
|
||||
# Minimal Hyprlock screen using the current desktop as a blurred backdrop.
|
||||
|
||||
$font = Sans
|
||||
|
||||
general {
|
||||
hide_cursor = true
|
||||
}
|
||||
|
||||
background {
|
||||
monitor =
|
||||
path = screenshot
|
||||
blur_passes = 3
|
||||
}
|
||||
|
||||
input-field {
|
||||
monitor =
|
||||
size = 20%, 5%
|
||||
outline_thickness = 2
|
||||
inner_color = rgba(0, 0, 0, 0.25)
|
||||
outer_color = rgba(eeeeeecc)
|
||||
check_color = rgba(8ec07ccc)
|
||||
fail_color = rgba(fb4934cc)
|
||||
|
||||
font_color = rgb(eeeeee)
|
||||
fade_on_empty = false
|
||||
rounding = 12
|
||||
font_family = $font
|
||||
placeholder_text = Input password...
|
||||
fail_text = $PAMFAIL
|
||||
|
||||
position = 0, -20
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
monitor =
|
||||
text = $TIME
|
||||
font_size = 72
|
||||
font_family = $font
|
||||
|
||||
position = 0, 120
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Match the active Alacritty look while retaining Kitty's native graphics protocol.
|
||||
font_family MesloLGS NF
|
||||
font_size 15.0
|
||||
|
||||
# Palette: active ~/.config/alacritty/alacritty.toml plus Noctalia cursor/selection.
|
||||
foreground #FCFCFA
|
||||
background #2D2A2E
|
||||
cursor #fff1e6
|
||||
cursor_text_color #000000
|
||||
selection_foreground #fff1e6
|
||||
selection_background #3b220f
|
||||
|
||||
color0 #403E41
|
||||
color1 #FF6188
|
||||
color2 #A9DC76
|
||||
color3 #FFD866
|
||||
color4 #FC9867
|
||||
color5 #AB9DF2
|
||||
color6 #78DCE8
|
||||
color7 #FCFCFA
|
||||
color8 #727072
|
||||
color9 #FF6188
|
||||
color10 #A9DC76
|
||||
color11 #FFD866
|
||||
color12 #FC9867
|
||||
color13 #AB9DF2
|
||||
color14 #78DCE8
|
||||
color15 #FCFCFA
|
||||
|
||||
# Preserve Alacritty-like minimal window behavior.
|
||||
window_padding_width 0
|
||||
copy_on_select no
|
||||
|
||||
# Keep the shell integration and graphics protocol available to Ranger.
|
||||
shell_integration enabled
|
||||
@@ -0,0 +1,84 @@
|
||||
# Shared Noctalia defaults. Keep GUI experiments in state; promote durable choices here.
|
||||
[shell]
|
||||
setup_wizard_enabled = false
|
||||
offline_mode = true
|
||||
external_ip_enabled = false
|
||||
telemetry_enabled = false
|
||||
|
||||
# Noctalia owns idle handling so ScreenSaver/Wayland idle inhibitors (such as
|
||||
# browser video playback) prevent these actions. Power displays down after five
|
||||
# minutes, lock after ten minutes, then suspend-then-hibernate after thirty.
|
||||
[idle]
|
||||
behavior_order = ["lock", "screen-off", "suspend-then-hibernate"]
|
||||
pre_action_fade_seconds = 2.0
|
||||
|
||||
[idle.behavior.lock]
|
||||
action = "lock"
|
||||
enabled = true
|
||||
timeout = 600
|
||||
|
||||
[idle.behavior.screen-off]
|
||||
action = "screen_off"
|
||||
enabled = true
|
||||
timeout = 300
|
||||
|
||||
[idle.behavior.suspend-then-hibernate]
|
||||
action = "command"
|
||||
command = "loginctl lock-session && systemctl suspend-then-hibernate"
|
||||
enabled = true
|
||||
timeout = 1800
|
||||
|
||||
[theme]
|
||||
mode = "dark"
|
||||
source = "custom"
|
||||
custom_palette = "Ember OLED"
|
||||
pure_black_dark = true
|
||||
|
||||
# Noctalia merges files alphabetically. Keep reusable modules here; machine-specific
|
||||
# layout and hardware settings live in 90-machine.toml, while 99-extend.toml is local.
|
||||
[plugins]
|
||||
enabled = ["alex/system-status", "alex/knowledge-lookup"]
|
||||
|
||||
[widget.cpu]
|
||||
type = "alex/system-status:cpu"
|
||||
|
||||
[widget.ram]
|
||||
type = "alex/system-status:memory"
|
||||
|
||||
[widget.network-rate]
|
||||
type = "alex/system-status:network-rate"
|
||||
|
||||
[widget.idle-inhibitors]
|
||||
type = "alex/system-status:inhibitors"
|
||||
|
||||
[widget.knowledge-lookup]
|
||||
type = "alex/knowledge-lookup:bar"
|
||||
|
||||
[widget.temp]
|
||||
type = "sysmon"
|
||||
stat = "cpu_temp"
|
||||
visualization = "none"
|
||||
show_value = true
|
||||
|
||||
[widget.disk]
|
||||
type = "sysmon"
|
||||
stat = "disk_used_pct"
|
||||
visualization = "none"
|
||||
show_value = true
|
||||
path = "/"
|
||||
|
||||
[desktop_widgets]
|
||||
enabled = false
|
||||
|
||||
[wallpaper]
|
||||
enabled = true
|
||||
fill_color = "#000000"
|
||||
|
||||
[wallpaper.default]
|
||||
path = "color:#000000"
|
||||
|
||||
[nightlight]
|
||||
enabled = true
|
||||
force = false
|
||||
temperature_day = 6500
|
||||
temperature_night = 2500
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"dark": {
|
||||
"mPrimary": "#ff8800",
|
||||
"mOnPrimary": "#1a0d00",
|
||||
"mSecondary": "#ffb05c",
|
||||
"mOnSecondary": "#2b1600",
|
||||
"mTertiary": "#ffcc99",
|
||||
"mOnTertiary": "#2b1600",
|
||||
"mError": "#ff6b4a",
|
||||
"mOnError": "#2b0700",
|
||||
"mSurface": "#050403",
|
||||
"mOnSurface": "#fff1e6",
|
||||
"mSurfaceVariant": "#1a110c",
|
||||
"mOnSurfaceVariant": "#f4c7a1",
|
||||
"mOutline": "#6e4a31",
|
||||
"mShadow": "#000000",
|
||||
"mHover": "#2a190f",
|
||||
"mOnHover": "#fff1e6",
|
||||
"terminal": {
|
||||
"background": "#050403",
|
||||
"foreground": "#fff1e6",
|
||||
"cursor": "#fff1e6",
|
||||
"cursorText": "#050403",
|
||||
"selectionBg": "#3b220f",
|
||||
"selectionFg": "#fff1e6",
|
||||
"normal": {
|
||||
"black": "#050403",
|
||||
"red": "#ff6b4a",
|
||||
"green": "#c98a45",
|
||||
"yellow": "#ffb05c",
|
||||
"blue": "#c97c45",
|
||||
"magenta": "#d98a5c",
|
||||
"cyan": "#e8a76a",
|
||||
"white": "#fff1e6"
|
||||
},
|
||||
"bright": {
|
||||
"black": "#6e4a31",
|
||||
"red": "#ff8f72",
|
||||
"green": "#e8ad68",
|
||||
"yellow": "#ffca80",
|
||||
"blue": "#e8a06a",
|
||||
"magenta": "#f0ad82",
|
||||
"cyan": "#ffd0a0",
|
||||
"white": "#ffffff"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Track session ScreenSaver idle inhibitors for Noctalia
|
||||
After=graphical-session.target
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Service]
|
||||
ExecStart=%h/.local/bin/idle-inhibitor-monitor
|
||||
Restart=on-failure
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Pi Status Bridge home agent
|
||||
After=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment=PATH=/home/alex/.npm-global/bin:/usr/local/bin:/usr/bin:/bin
|
||||
ExecStart=/usr/bin/env pi-status-bridge --session-root %h/.local/state/pi-status-bridge/sessions
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=OpenSSH key agent
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
|
||||
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 yazi-rs
|
||||
|
||||
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.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Catppuccin
|
||||
|
||||
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,36 @@
|
||||
<div align="center">
|
||||
<img src="https://github.com/sxyazi/yazi/blob/main/assets/logo.png?raw=true" alt="Yazi logo" width="20%">
|
||||
</div>
|
||||
|
||||
<h3 align="center">
|
||||
Catppuccin Macchiato Flavor for <a href="https://github.com/sxyazi/yazi">Yazi</a>
|
||||
</h3>
|
||||
|
||||
## 👀 Preview
|
||||
|
||||
<img src="preview.png" width="600" />
|
||||
|
||||
## 🎨 Installation
|
||||
|
||||
```sh
|
||||
ya pkg add yazi-rs/flavors:catppuccin-macchiato
|
||||
```
|
||||
|
||||
## ⚙️ Usage
|
||||
|
||||
Set the content of your `theme.toml` to enable it as your _dark_ flavor:
|
||||
|
||||
```toml
|
||||
[flavor]
|
||||
dark = "catppuccin-macchiato"
|
||||
```
|
||||
|
||||
Make sure your `theme.toml` doesn't contain anything other than `[flavor]`, unless you want to override certain styles of this flavor.
|
||||
|
||||
See the [Yazi flavor documentation](https://yazi-rs.github.io/docs/flavors/overview) for more details.
|
||||
|
||||
## 📜 License
|
||||
|
||||
The flavor is MIT-licensed, and the included tmTheme is also MIT-licensed.
|
||||
|
||||
Check the [LICENSE](LICENSE) and [LICENSE-tmtheme](LICENSE-tmtheme) file for more details.
|
||||
@@ -0,0 +1,215 @@
|
||||
# vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
# : Manager {{{
|
||||
|
||||
[mgr]
|
||||
cwd = { fg = "#8bd5ca" }
|
||||
|
||||
# Find
|
||||
find_keyword = { fg = "#eed49f", bold = true, italic = true, underline = true }
|
||||
find_position = { fg = "#f5bde6", bg = "reset", bold = true, italic = true }
|
||||
|
||||
# Marker
|
||||
marker_copied = { fg = "#a6da95", bg = "#a6da95" }
|
||||
marker_cut = { fg = "#ed8796", bg = "#ed8796" }
|
||||
marker_marked = { fg = "#8bd5ca", bg = "#8bd5ca" }
|
||||
marker_selected = { fg = "#eed49f", bg = "#eed49f" }
|
||||
|
||||
# Count
|
||||
count_copied = { fg = "#24273a", bg = "#a6da95" }
|
||||
count_cut = { fg = "#24273a", bg = "#ed8796" }
|
||||
count_selected = { fg = "#24273a", bg = "#eed49f" }
|
||||
|
||||
# Border
|
||||
border_symbol = "│"
|
||||
border_style = { fg = "#8087a2" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Tabs {{{
|
||||
|
||||
[tabs]
|
||||
active = { fg = "#24273a", bg = "#8aadf4", bold = true }
|
||||
inactive = { fg = "#8aadf4", bg = "#363a4f" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Mode {{{
|
||||
|
||||
[mode]
|
||||
|
||||
normal_main = { fg = "#24273a", bg = "#8aadf4", bold = true }
|
||||
normal_alt = { fg = "#8aadf4", bg = "#363a4f" }
|
||||
|
||||
# Select mode
|
||||
select_main = { fg = "#24273a", bg = "#8bd5ca", bold = true }
|
||||
select_alt = { fg = "#8bd5ca", bg = "#363a4f" }
|
||||
|
||||
# Unset mode
|
||||
unset_main = { fg = "#24273a", bg = "#f0c6c6", bold = true }
|
||||
unset_alt = { fg = "#f0c6c6", bg = "#363a4f" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Status bar {{{
|
||||
|
||||
[status]
|
||||
# Permissions
|
||||
perm_sep = { fg = "#8087a2" }
|
||||
perm_type = { fg = "#8aadf4" }
|
||||
perm_read = { fg = "#eed49f" }
|
||||
perm_write = { fg = "#ed8796" }
|
||||
perm_exec = { fg = "#a6da95" }
|
||||
|
||||
# Progress
|
||||
progress_label = { fg = "#ffffff", bold = true }
|
||||
progress_normal = { fg = "#a6da95", bg = "#494d64" }
|
||||
progress_error = { fg = "#eed49f", bg = "#ed8796" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Pick {{{
|
||||
|
||||
[pick]
|
||||
border = { fg = "#8aadf4" }
|
||||
active = { fg = "#f5bde6", bold = true }
|
||||
inactive = {}
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Input {{{
|
||||
|
||||
[input]
|
||||
border = { fg = "#8aadf4" }
|
||||
title = {}
|
||||
value = {}
|
||||
selected = { reversed = true }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Completion {{{
|
||||
|
||||
[cmp]
|
||||
border = { fg = "#8aadf4" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Tasks {{{
|
||||
|
||||
[tasks]
|
||||
border = { fg = "#8aadf4" }
|
||||
title = {}
|
||||
hovered = { fg = "#f5bde6", bold = true }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Which {{{
|
||||
|
||||
[which]
|
||||
border = { fg = "#8aadf4" }
|
||||
cand = { fg = "#8bd5ca" }
|
||||
rest = { fg = "#939ab7" }
|
||||
desc = { fg = "#f5bde6" }
|
||||
separator = " "
|
||||
separator_style = { fg = "#5b6078" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Help {{{
|
||||
|
||||
[help]
|
||||
on = { fg = "#8bd5ca" }
|
||||
run = { fg = "#f5bde6" }
|
||||
hovered = { reversed = true, bold = true }
|
||||
footer = { fg = "#363a4f", bg = "#cad3f5" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Spotter {{{
|
||||
|
||||
[spot]
|
||||
border = { fg = "#8aadf4" }
|
||||
title = { fg = "#8aadf4" }
|
||||
tbl_col = { fg = "#8bd5ca" }
|
||||
tbl_cell = { fg = "#f5bde6", bg = "#494d64" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : Notification {{{
|
||||
|
||||
[notify]
|
||||
title_info = { fg = "#a6da95" }
|
||||
title_warn = { fg = "#eed49f" }
|
||||
title_error = { fg = "#ed8796" }
|
||||
|
||||
# : }}}
|
||||
|
||||
|
||||
# : File-specific styles {{{
|
||||
|
||||
[filetype]
|
||||
|
||||
rules = [
|
||||
# Image
|
||||
{ mime = "**/image/*", fg = "#8bd5ca" },
|
||||
# Media
|
||||
{ mime = "**/{audio,video}/*", fg = "#eed49f" },
|
||||
# Archive
|
||||
{ mime = "**/application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "#f5bde6" },
|
||||
# Document
|
||||
{ mime = "**/application/{pdf,doc,rtf}", fg = "#a6da95" },
|
||||
# Virtual file system
|
||||
{ mime = "vfs/{absent,stale}", fg = "#939ab7" },
|
||||
# Fallback
|
||||
{ url = "*", fg = "#cad3f5" },
|
||||
{ url = "*/", fg = "#8aadf4" },
|
||||
]
|
||||
|
||||
# : }}}
|
||||
|
||||
[icon]
|
||||
|
||||
dirs = [
|
||||
{ name = ".config", text = "", fg = "#f5bde6" },
|
||||
{ name = ".git", text = "", fg = "#8bd5ca" },
|
||||
{ name = ".github", text = "", fg = "#8aadf4" },
|
||||
{ name = ".npm", text = "", fg = "#8aadf4" },
|
||||
{ name = "Desktop", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Development", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Documents", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Downloads", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Library", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Movies", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Music", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Pictures", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Public", text = "", fg = "#8bd5ca" },
|
||||
{ name = "Videos", text = "", fg = "#8bd5ca" },
|
||||
]
|
||||
conds = [
|
||||
# Special files
|
||||
{ if = "orphan", text = "", fg = "#cad3f5" },
|
||||
{ if = "link", text = "", fg = "#8087a2" },
|
||||
{ if = "block", text = "", fg = "#f0c6c6" },
|
||||
{ if = "char", text = "", fg = "#f0c6c6" },
|
||||
{ if = "fifo", text = "", fg = "#f0c6c6" },
|
||||
{ if = "sock", text = "", fg = "#f0c6c6" },
|
||||
{ if = "sticky", text = "", fg = "#f0c6c6" },
|
||||
{ if = "dummy", text = "", fg = "#ed8796" },
|
||||
|
||||
# Fallback
|
||||
{ if = "dir & hovered", text = "", fg = "#8aadf4" },
|
||||
{ if = "dir", text = "", fg = "#8aadf4" },
|
||||
{ if = "exec", text = "", fg = "#a6da95" },
|
||||
{ if = "!dir", text = "", fg = "#cad3f5" },
|
||||
]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 674 KiB |
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
require("git"):setup {
|
||||
order = 1500,
|
||||
}
|
||||
|
||||
require("githead"):setup {
|
||||
branch_prefix = "on ",
|
||||
branch_symbol = " ",
|
||||
branch_borders = "()",
|
||||
branch_color = "#ffb05c",
|
||||
remote_branch_color = "#f4c7a1",
|
||||
tag_color = "#ffcc99",
|
||||
commit_color = "#f4c7a1",
|
||||
behind_remote_color = "#ff6b4a",
|
||||
ahead_remote_color = "#ff8800",
|
||||
stashes_color = "#c98a45",
|
||||
state_color = "#ff6b4a",
|
||||
staged_color = "#ff8800",
|
||||
unstaged_color = "#ffb05c",
|
||||
untracked_color = "#f4c7a1",
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#:schema https://yazi-rs.github.io/schemas/keymap.json
|
||||
|
||||
[[mgr.prepend_keymap]]
|
||||
on = "l"
|
||||
run = "plugin smart-enter"
|
||||
desc = "Enter the child directory, or open the file"
|
||||
|
||||
[[mgr.prepend_keymap]]
|
||||
on = ["g", "d"]
|
||||
run = "cd ~/downloads"
|
||||
desc = "Cd to Downloads"
|
||||
|
||||
[[mgr.prepend_keymap]]
|
||||
on = ["g", "D"]
|
||||
run = "cd ~/cloud/documents"
|
||||
desc = "Cd to Documents"
|
||||
@@ -0,0 +1,19 @@
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:smart-enter"
|
||||
rev = "0be29a9"
|
||||
hash = "187cc58ba7ac3befd49c342129e6f1b6"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:git"
|
||||
rev = "3f2b882"
|
||||
hash = "336548d9f67926e12d5584f60b790f1"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "llanosrocas/githead"
|
||||
rev = "317d09f"
|
||||
hash = "41dc37a724b2afd21da4f1ea6c1182d8"
|
||||
|
||||
[[flavor.deps]]
|
||||
use = "yazi-rs/flavors:catppuccin-macchiato"
|
||||
rev = "be0b21d"
|
||||
hash = "5b1bf96d1cba26376087c37de993c517"
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 yazi-rs
|
||||
|
||||
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,84 @@
|
||||
# git.yazi
|
||||
|
||||
Show the status of Git file changes as linemode in the file list.
|
||||
|
||||
https://github.com/user-attachments/assets/34976be9-a871-4ffe-9d5a-c4cdd0bf4576
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pkg add yazi-rs/plugins:git
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
Add the following to your `~/.config/yazi/init.lua`:
|
||||
|
||||
```lua
|
||||
require("git"):setup {
|
||||
-- Order of status signs showing in the linemode
|
||||
order = 1500,
|
||||
}
|
||||
```
|
||||
|
||||
And register it as fetchers in your `~/.config/yazi/yazi.toml`:
|
||||
|
||||
```toml
|
||||
[[plugin.prepend_fetchers]]
|
||||
url = "*"
|
||||
run = "git"
|
||||
group = "git"
|
||||
|
||||
[[plugin.prepend_fetchers]]
|
||||
url = "*/"
|
||||
run = "git"
|
||||
group = "git"
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
You can customize the [Style](https://yazi-rs.github.io/docs/configuration/theme#types.style) of the status sign with:
|
||||
|
||||
- `[git].unknown` - status cannot/not yet determined
|
||||
- `[git].modified` - modified file
|
||||
- `[git].added` - added file
|
||||
- `[git].untracked` - untracked file
|
||||
- `[git].ignored` - ignored file
|
||||
- `[git].deleted` - deleted file
|
||||
- `[git].updated` - updated file
|
||||
- `[git].clean` - clean file
|
||||
|
||||
For example:
|
||||
|
||||
```toml
|
||||
# theme.toml / flavor.toml
|
||||
[git]
|
||||
modified = { fg = "blue" }
|
||||
deleted = { fg = "red", bold = true }
|
||||
```
|
||||
|
||||
You can also customize the text of the status sign with:
|
||||
|
||||
- `[git].unknown_sign` - status cannot/not yet determined
|
||||
- `[git].modified_sign` - modified file
|
||||
- `[git].added_sign` - added file
|
||||
- `[git].untracked_sign` - untracked file
|
||||
- `[git].ignored_sign` - ignored file
|
||||
- `[git].deleted_sign` - deleted file
|
||||
- `[git].updated_sign` - updated file
|
||||
- `[git].clean_sign` - clean file
|
||||
|
||||
For example:
|
||||
|
||||
```toml
|
||||
# theme.toml / flavor.toml
|
||||
[git]
|
||||
unknown_sign = " "
|
||||
modified_sign = "M"
|
||||
deleted_sign = "D"
|
||||
clean_sign = "✔"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
@@ -0,0 +1,279 @@
|
||||
--- @since 26.5.6
|
||||
|
||||
local WINDOWS = ya.target_family() == "windows"
|
||||
|
||||
-- The code of supported git status,
|
||||
-- also used to determine which status to show for directories when they contain different statuses
|
||||
-- see `bubble_up`
|
||||
---@enum CODES
|
||||
local CODES = {
|
||||
unknown = 100, -- status cannot/not yet determined
|
||||
excluded = 99, -- ignored directory
|
||||
ignored = 6, -- ignored file
|
||||
untracked = 5,
|
||||
modified = 4,
|
||||
added = 3,
|
||||
deleted = 2,
|
||||
updated = 1,
|
||||
clean = 0,
|
||||
}
|
||||
|
||||
local PATTERNS = {
|
||||
{ "!$", CODES.ignored },
|
||||
{ "?$", CODES.untracked },
|
||||
{ "[MT]", CODES.modified },
|
||||
{ "[AC]", CODES.added },
|
||||
{ "D", CODES.deleted },
|
||||
{ "U", CODES.updated },
|
||||
{ "[AD][AD]", CODES.updated },
|
||||
}
|
||||
|
||||
local function theme()
|
||||
local t = th.git or {}
|
||||
return {
|
||||
[CODES.unknown] = t.unknown or ui.Style(),
|
||||
[CODES.ignored] = t.ignored or ui.Style():fg("darkgray"),
|
||||
[CODES.untracked] = t.untracked or ui.Style():fg("magenta"),
|
||||
[CODES.modified] = t.modified or ui.Style():fg("yellow"),
|
||||
[CODES.added] = t.added or ui.Style():fg("green"),
|
||||
[CODES.deleted] = t.deleted or ui.Style():fg("red"),
|
||||
[CODES.updated] = t.updated or ui.Style():fg("yellow"),
|
||||
[CODES.clean] = t.clean or ui.Style(),
|
||||
}, {
|
||||
[CODES.unknown] = t.unknown_sign or "",
|
||||
[CODES.ignored] = t.ignored_sign or " ",
|
||||
[CODES.untracked] = t.untracked_sign or "? ",
|
||||
[CODES.modified] = t.modified_sign or " ",
|
||||
[CODES.added] = t.added_sign or " ",
|
||||
[CODES.deleted] = t.deleted_sign or " ",
|
||||
[CODES.updated] = t.updated_sign or " ",
|
||||
[CODES.clean] = t.clean_sign or "",
|
||||
}
|
||||
end
|
||||
|
||||
---@param line string
|
||||
---@return CODES, string
|
||||
local function match(line)
|
||||
local signs = line:sub(1, 2)
|
||||
for _, p in ipairs(PATTERNS) do
|
||||
local path, pattern, code = nil, p[1], p[2]
|
||||
if signs:find(pattern) then
|
||||
path = line:sub(4, 4) == '"' and line:sub(5, -2) or line:sub(4)
|
||||
path = WINDOWS and path:gsub("/", "\\") or path
|
||||
end
|
||||
if not path then
|
||||
elseif path:find("[/\\]$") then
|
||||
-- Mark the ignored directory as `excluded`, so we can process it further within `propagate_down`
|
||||
return code == CODES.ignored and CODES.excluded or code, path:sub(1, -2)
|
||||
else
|
||||
return code, path
|
||||
end
|
||||
---@diagnostic disable-next-line: missing-return
|
||||
end
|
||||
end
|
||||
|
||||
---@param cwd Url
|
||||
---@return string?
|
||||
local function root(cwd)
|
||||
local is_worktree = function(url)
|
||||
local file, head = io.open(tostring(url)), nil
|
||||
if file then
|
||||
head = file:read(8)
|
||||
file:close()
|
||||
end
|
||||
return head == "gitdir: "
|
||||
end
|
||||
|
||||
repeat
|
||||
local next = cwd:join(".git")
|
||||
local cha = fs.cha(next)
|
||||
if cha and (cha.is_dir or is_worktree(next)) then
|
||||
return tostring(cwd)
|
||||
end
|
||||
cwd = cwd.parent
|
||||
until not cwd
|
||||
end
|
||||
|
||||
---@param changed Changes
|
||||
---@return Changes
|
||||
local function bubble_up(changed)
|
||||
local new, empty = {}, Url("")
|
||||
for path, code in pairs(changed) do
|
||||
if code ~= CODES.ignored then
|
||||
local url = Url(path).parent
|
||||
while url and url ~= empty do
|
||||
local s = tostring(url)
|
||||
new[s] = (new[s] or CODES.clean) > code and new[s] or code
|
||||
url = url.parent
|
||||
end
|
||||
end
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
---@param excluded string[]
|
||||
---@param cwd Url
|
||||
---@param repo Url
|
||||
---@return Changes
|
||||
local function propagate_down(excluded, cwd, repo)
|
||||
local new, rel = {}, cwd:strip_prefix(repo)
|
||||
for _, path in ipairs(excluded) do
|
||||
if rel:starts_with(path) then
|
||||
-- If `cwd` is a subdirectory of an excluded directory, also mark it as `excluded`
|
||||
new[tostring(cwd)] = CODES.excluded
|
||||
elseif cwd == repo:join(path).parent then
|
||||
-- If `path` is a direct subdirectory of `cwd`, mark it as `ignored`
|
||||
new[path] = CODES.ignored
|
||||
else
|
||||
-- Skipping, we only care about `cwd` itself and its direct subdirectories for maximum performance
|
||||
end
|
||||
end
|
||||
return new
|
||||
end
|
||||
|
||||
---@param cwd string
|
||||
---@param repo string
|
||||
---@param changed Changes
|
||||
local add = ya.sync(function(st, cwd, repo, changed)
|
||||
---@cast st State
|
||||
|
||||
st.dirs[cwd] = repo
|
||||
st.repos[repo] = st.repos[repo] or {}
|
||||
for path, code in pairs(changed) do
|
||||
if code == CODES.clean then
|
||||
st.repos[repo][path] = nil
|
||||
elseif code == CODES.excluded then
|
||||
-- Mark the directory with a special value `excluded` so that it can be distinguished during UI rendering
|
||||
st.dirs[path] = CODES.excluded
|
||||
else
|
||||
st.repos[repo][path] = code
|
||||
end
|
||||
end
|
||||
ui.render()
|
||||
end)
|
||||
|
||||
---@param cwd string
|
||||
local remove = ya.sync(function(st, cwd)
|
||||
---@cast st State
|
||||
|
||||
local repo = st.dirs[cwd]
|
||||
if not repo then
|
||||
return
|
||||
end
|
||||
|
||||
ui.render()
|
||||
st.dirs[cwd] = nil
|
||||
if not st.repos[repo] then
|
||||
return
|
||||
end
|
||||
|
||||
for _, r in pairs(st.dirs) do
|
||||
if r == repo then
|
||||
return
|
||||
end
|
||||
end
|
||||
st.repos[repo] = nil
|
||||
end)
|
||||
|
||||
---@param st State
|
||||
---@param opts Options
|
||||
local function setup(st, opts)
|
||||
st.dirs = {}
|
||||
st.repos = {}
|
||||
|
||||
opts = opts or {}
|
||||
opts.order = opts.order or 1500
|
||||
|
||||
local styles, signs = theme()
|
||||
ps.sub("theme", function()
|
||||
styles, signs = theme()
|
||||
end)
|
||||
|
||||
Linemode:children_add(function(self)
|
||||
if not self._file.in_current then
|
||||
return ""
|
||||
end
|
||||
|
||||
local url = self._file.url
|
||||
local repo = st.dirs[tostring(url.base or url.parent)]
|
||||
local code = CODES.unknown
|
||||
if repo then
|
||||
code = repo == CODES.excluded and CODES.ignored or st.repos[repo][tostring(url):sub(#repo + 2)] or CODES.clean
|
||||
end
|
||||
|
||||
if signs[code] == "" then
|
||||
return ""
|
||||
elseif self._file.is_hovered then
|
||||
return ui.Line { " ", signs[code] }
|
||||
else
|
||||
return ui.Line { " ", ui.Span(signs[code]):style(styles[code]) }
|
||||
end
|
||||
end, opts.order)
|
||||
end
|
||||
|
||||
---@type UnstableFetcher
|
||||
local function fetch(_, job)
|
||||
local cwd = job.files[1].url.base or job.files[1].url.parent
|
||||
local repo = root(cwd)
|
||||
if not repo then
|
||||
remove(tostring(cwd))
|
||||
return true
|
||||
end
|
||||
|
||||
local paths = {}
|
||||
for _, file in ipairs(job.files) do
|
||||
paths[#paths + 1] = tostring(file.url)
|
||||
end
|
||||
|
||||
-- stylua: ignore
|
||||
local output, err = Command("git")
|
||||
:cwd(tostring(cwd))
|
||||
:arg({ "--no-optional-locks", "-c", "core.quotePath=", "status", "--porcelain", "-unormal", "--no-renames", "--ignored=matching" })
|
||||
:arg(paths)
|
||||
:output()
|
||||
if not output then
|
||||
return true, Err("Cannot spawn `git` command, error: %s", err)
|
||||
end
|
||||
|
||||
local changed, excluded = {}, {}
|
||||
for line in output.stdout:gmatch("[^\r\n]+") do
|
||||
local code, path = match(line)
|
||||
if code == CODES.excluded then
|
||||
excluded[#excluded + 1] = path
|
||||
else
|
||||
changed[path] = code
|
||||
end
|
||||
end
|
||||
|
||||
if job.files[1].cha.is_dir then
|
||||
ya.dict_merge(changed, bubble_up(changed))
|
||||
end
|
||||
ya.dict_merge(changed, propagate_down(excluded, cwd, Url(repo)))
|
||||
|
||||
-- Reset the status of any files that don't appear in the output of `git status` to `clean`,
|
||||
-- so that cleaning up outdated statuses from `st.repos`
|
||||
for _, path in ipairs(paths) do
|
||||
local s = path:sub(#repo + 2)
|
||||
changed[s] = changed[s] or CODES.clean
|
||||
end
|
||||
|
||||
add(tostring(cwd), repo, changed)
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- TODO: remove
|
||||
local function fetch_compact(self, job)
|
||||
if ya.throttle then
|
||||
fetch(self, job)
|
||||
return ya.co(function()
|
||||
for _, file in ipairs(job.files) do
|
||||
coroutine.yield(file, { retry = true })
|
||||
end
|
||||
end)
|
||||
else
|
||||
return fetch(self, job)
|
||||
end
|
||||
end
|
||||
|
||||
return { setup = setup, fetch = fetch_compact }
|
||||
@@ -0,0 +1,12 @@
|
||||
---@class State
|
||||
---@field dirs table<string, string|CODES> Mapping between a directory and its corresponding repository
|
||||
---@field repos table<string, Changes> Mapping between a repository and the status of each of its files
|
||||
|
||||
---@class Options
|
||||
---@field order number The order in which the status is displayed
|
||||
---@field renamed boolean Whether to include renamed files in the status (or treat them as modified)
|
||||
|
||||
-- TODO: move this to `types.yazi` once it's get stable
|
||||
---@alias UnstableFetcher fun(self: unknown, job: { files: File[] }): boolean, Error?
|
||||
|
||||
---@alias Changes table<string, CODES>
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 llanosrocas
|
||||
|
||||
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,422 @@
|
||||
# githead.yazi
|
||||
|
||||
Git status header for yazi inspired by [powerlevel10k](https://github.com/romkatv/powerlevel10k?tab=readme-ov-file#what-do-different-symbols-in-git-status-mean).
|
||||
|
||||

|
||||

|
||||
|
||||
All supported features are listed [here](#features). More presets are available [here](#presets).
|
||||
|
||||
## Requirements
|
||||
|
||||
- yazi version >= [26.1.22](https://github.com/sxyazi/yazi/releases/tag/v26.1.22).
|
||||
- Font with symbol support. For example [Nerd Fonts](https://www.nerdfonts.com/).
|
||||
|
||||
## Compatibility
|
||||
|
||||
To keep the plugin up to date, there are two branches: `main` and `nightly`.
|
||||
The `main` branch follows major yazi releases, while `nightly` is linked to specific yazi commits or changes.
|
||||
|
||||
This setup allows shipping stable versions on time, while giving early access to "cutting-edge" changes. See matrix below.
|
||||
|
||||
<details close>
|
||||
<summary>Compatibility matrix</summary>
|
||||
|
||||
| githead | yazi |
|
||||
| :-------------------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------- |
|
||||
| [v2.0.2](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.2) | [v26.1.22](https://github.com/sxyazi/yazi/releases/tag/v26.1.22) |
|
||||
| [v2.0.2](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.2) | [v25.12.29](https://github.com/sxyazi/yazi/releases/tag/v25.12.29) |
|
||||
| [v2.0.2-nightly.292d37c](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.2-nightly.292d37c) | [2f66561](https://github.com/sxyazi/yazi/commit/2f66561a8251f8788b2b0fd366af90555ecafc86) |
|
||||
| [v2.0.2-nightly.292d37c](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.2-nightly.292d37c) | [6cfa92f](https://github.com/sxyazi/yazi/commit/6cfa92f11205d212155579b5b76d4cbabe723829) |
|
||||
| [v2.0.2-nightly.292d37c](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.2-nightly.292d37c) | [292d37c](https://github.com/sxyazi/yazi/commit/292d37ccde5fb09dc7318247caf552213d16ec36) |
|
||||
| [v2.0.1](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.1) | [917e1f5](https://github.com/sxyazi/yazi/commit/917e1f54a10445f2e25147c4b81a3c77d8233632) |
|
||||
| [v2.0.0](https://github.com/llanosrocas/githead.yazi/releases/tag/v2.0.0) | [693dff2](https://github.com/sxyazi/yazi/commit/693dff25e3165e357cc9d0b94ca3f2b176741a36) |
|
||||
| [v1.7.0](https://github.com/llanosrocas/githead.yazi/releases/tag/v1.7.0) | [693dff2](https://github.com/sxyazi/yazi/tree/693dff25e3165e357cc9d0b94ca3f2b176741a36) |
|
||||
| [v1.6.0](https://github.com/llanosrocas/githead.yazi/releases/tag/v1.6.0) | [v25.5.31](https://github.com/sxyazi/yazi/releases/tag/v25.5.31) |
|
||||
|
||||
</details>
|
||||
|
||||
## Installation
|
||||
|
||||
1. Using yazi package manager
|
||||
|
||||
```sh
|
||||
ya pkg add llanosrocas/githead
|
||||
```
|
||||
|
||||
_Or manually copy `main.lua` to the `~/.config/yazi/plugins/githead.yazi/main.lua`_
|
||||
|
||||
2. Add this line to your `~/.config/yazi/init.lua`:
|
||||
|
||||
```lua
|
||||
require("githead"):setup()
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
This is default config, if you want to see copy-paste presets go to [this section](#presets).
|
||||
|
||||
```lua
|
||||
require("githead"):setup({
|
||||
order = {
|
||||
"__spacer__",
|
||||
"branch",
|
||||
"remote",
|
||||
"__spacer__",
|
||||
"tag",
|
||||
"__spacer__",
|
||||
"commit",
|
||||
"__spacer__",
|
||||
"behind_ahead_remote",
|
||||
"__spacer__",
|
||||
"stashes",
|
||||
"__spacer__",
|
||||
"state",
|
||||
"__spacer__",
|
||||
"staged",
|
||||
"__spacer__",
|
||||
"unstaged",
|
||||
"__spacer__",
|
||||
"untracked",
|
||||
},
|
||||
|
||||
show_numbers = true, -- shows staged, unstaged, untracked, stashes count
|
||||
|
||||
show_branch = true,
|
||||
branch_prefix = "",
|
||||
branch_color = "blue",
|
||||
branch_symbol = "",
|
||||
branch_borders = "",
|
||||
|
||||
show_remote_branch = true, -- only shown if different from local branch
|
||||
always_show_remote_branch = false, -- always show remote branch even if it the same as local branch
|
||||
always_show_remote_repo = false, -- Adds `origin/` if `always_show_remote_branch` is enabled
|
||||
remote_branch_prefix = ":",
|
||||
remote_branch_color = "bright magenta",
|
||||
|
||||
show_tag = true, -- only shown if branch is not available
|
||||
always_show_tag = false,
|
||||
tag_color = "magenta",
|
||||
tag_symbol = "#",
|
||||
|
||||
show_commit = true, -- only shown if branch AND tag are not available
|
||||
always_show_commit = false,
|
||||
commit_color = "bright magenta",
|
||||
commit_symbol = "@",
|
||||
|
||||
show_behind_ahead_remote = true,
|
||||
behind_remote_color = "bright magenta",
|
||||
behind_remote_symbol = "⇣",
|
||||
ahead_remote_color = "bright magenta",
|
||||
ahead_remote_symbol = "⇡",
|
||||
|
||||
show_stashes = true,
|
||||
stashes_color = "bright magenta",
|
||||
stashes_symbol = "$",
|
||||
|
||||
show_state = true,
|
||||
show_state_prefix = true,
|
||||
state_color = "red",
|
||||
state_symbol = "~",
|
||||
|
||||
show_staged = true,
|
||||
staged_color = "bright yellow",
|
||||
staged_symbol = "+",
|
||||
|
||||
show_unstaged = true,
|
||||
unstaged_color = "bright yellow",
|
||||
unstaged_symbol = "!",
|
||||
|
||||
show_untracked = true,
|
||||
untracked_color = "blue",
|
||||
untracked_symbol = "?",
|
||||
})
|
||||
```
|
||||
|
||||
```
|
||||
/cwd on ( feature):origin/main #v1.0.0 #1234567 ⇣2⇡3 $1 rebase 1/2 ~2 +4 !1 ?5
|
||||
| | | | ││ | | | | | | | | | | | |
|
||||
| | | | ││ | | | | | | | | | | | └─── untracked_symbol
|
||||
| | | | ││ | | | | | | | | | | └────── unstaged_symbol
|
||||
| | | | ││ | | | | | | | | | └───────── staged_symbol
|
||||
| | | | ││ | | | | | | | | └──────────── state_symbol
|
||||
| | | | ││ | | | | | | | └─────────────────────── state_prefix
|
||||
| | | | ││ | | | | | | └────────────────────────── stashes_symbol
|
||||
| | | | ││ | | | | | └───────────────────────────── ahead_symbol
|
||||
| | | | ││ | | | | └─────────────────────────────── behind_symbol
|
||||
| | | | ││ | | | └──────────────────────────────────────── commit_symbol
|
||||
| | | | ││ | | └──────────────────────────────────────────────── tag_symbol
|
||||
| | | | ││ | └───────────────────────────────────────────────────── remote_branch
|
||||
| | | | ││ └─────────────────────────────────────────────────────────── remote_repo
|
||||
| | | | |└───────────────────────────────────────────────────────────── remote_branch_prefix
|
||||
| | | | └────────────────────────────────────────────────────────────── branch_borders
|
||||
| | | └──────────────────────────────────────────────────────────────────── branch
|
||||
| | └─────────────────────────────────────────────────────────────────────── branch_symbol
|
||||
| └─────────────────────────────────────────────────────────────────────────── branch_prefix
|
||||
└──────────────────────────────────────────────────────────────────────────────── cwd
|
||||
```
|
||||
|
||||
## Presets
|
||||
|
||||
- v1 default (My config)
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Config</summary>
|
||||
|
||||
```lua
|
||||
require("githead"):setup({
|
||||
branch_prefix = "on",
|
||||
branch_symbol = " ",
|
||||
branch_borders = "()",
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- [spaceship-prompt](https://github.com/spaceship-prompt/spaceship-prompt)
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Config</summary>
|
||||
|
||||
```lua
|
||||
require("githead"):setup({
|
||||
order = {
|
||||
"__spacer__",
|
||||
"branch",
|
||||
"remote",
|
||||
"__spacer__",
|
||||
"tag",
|
||||
"__spacer__",
|
||||
"commit",
|
||||
"__spacer__",
|
||||
"behind_ahead_remote",
|
||||
"stashes",
|
||||
"state",
|
||||
"staged",
|
||||
"unstaged",
|
||||
"untracked",
|
||||
},
|
||||
|
||||
show_numbers = false,
|
||||
|
||||
branch_symbol = " ",
|
||||
branch_prefix = "on",
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- [robertgzr/porcelain](https://github.com/robertgzr/porcelain)
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Config</summary>
|
||||
|
||||
```lua
|
||||
require("githead"):setup({
|
||||
order = {
|
||||
"__spacer__",
|
||||
"branch",
|
||||
"commit",
|
||||
"__spacer__",
|
||||
"behind_ahead_remote",
|
||||
"__spacer__",
|
||||
"untracked",
|
||||
"state",
|
||||
"unstaged",
|
||||
"__spacer__",
|
||||
"staged",
|
||||
},
|
||||
|
||||
show_numbers = false,
|
||||
|
||||
show_branch = true,
|
||||
branch_prefix = "",
|
||||
branch_color = "#288BD2",
|
||||
|
||||
always_show_commit = true,
|
||||
commit_color = "#859A00",
|
||||
|
||||
show_behind_ahead_remote = true,
|
||||
behind_remote_symbol = "↓",
|
||||
ahead_remote_symbol = "↑",
|
||||
behind_remote_color = "#DC322E",
|
||||
ahead_remote_color = "#4DB6AC",
|
||||
|
||||
show_state = true,
|
||||
show_state_prefix = false,
|
||||
state_symbol = "!!",
|
||||
state_color = "#B58901",
|
||||
|
||||
staged_symbol = "✔",
|
||||
staged_color = "green",
|
||||
|
||||
unstaged_symbol = "Δ",
|
||||
unstaged_color = "#288BD2",
|
||||
|
||||
untracked_symbol = "?",
|
||||
untracked_color = "#415F65",
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- Minimal (No color)
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Config</summary>
|
||||
|
||||
```lua
|
||||
require("githead"):setup({
|
||||
branch_color = "",
|
||||
|
||||
remote_branch_prefix = "@",
|
||||
remote_branch_color = "",
|
||||
|
||||
tag_color = "",
|
||||
|
||||
commit_color = "",
|
||||
|
||||
ahead_remote_symbol = "+",
|
||||
ahead_remote_color = "",
|
||||
behind_remote_symbol = "-",
|
||||
behind_remote_color = "",
|
||||
|
||||
stashes_symbol = "*",
|
||||
stashes_color = "",
|
||||
|
||||
show_state_prefix = false,
|
||||
state_symbol = "~",
|
||||
state_color = "",
|
||||
|
||||
staged_symbol = "S",
|
||||
staged_color = "",
|
||||
|
||||
unstaged_symbol = "U",
|
||||
unstaged_color = "",
|
||||
|
||||
untracked_symbol = "N",
|
||||
untracked_color = "",
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- Vibrant (Full)
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Config</summary>
|
||||
|
||||
```lua
|
||||
require("githead"):setup({
|
||||
order = {
|
||||
"__spacer__",
|
||||
"stashes",
|
||||
"__spacer__",
|
||||
"state",
|
||||
"__spacer__",
|
||||
"staged",
|
||||
"__spacer__",
|
||||
"unstaged",
|
||||
"__spacer__",
|
||||
"untracked",
|
||||
"__spacer__",
|
||||
"branch",
|
||||
"remote_branch",
|
||||
"__spacer__",
|
||||
"tag",
|
||||
"__spacer__",
|
||||
"commit",
|
||||
"__spacer__",
|
||||
"behind_ahead_remote",
|
||||
"__spacer__",
|
||||
},
|
||||
|
||||
branch_borders = "{}",
|
||||
branch_prefix = "|",
|
||||
branch_color = "#7aa2f7",
|
||||
remote_branch_color = "#9ece6a",
|
||||
always_show_remote_branch = true,
|
||||
always_show_remote_repo = true,
|
||||
|
||||
tag_symbol = "",
|
||||
always_show_tag = true,
|
||||
tag_color = "#bb9af7",
|
||||
|
||||
commit_symbol = "",
|
||||
always_show_commit = true,
|
||||
commit_color = "#e0af68",
|
||||
|
||||
staged_color = "#73daca",
|
||||
staged_symbol = "●",
|
||||
|
||||
unstaged_color = "#e0af68",
|
||||
unstaged_symbol = "✗",
|
||||
|
||||
untracked_color = "#f7768e",
|
||||
untracked_symbol = "?",
|
||||
|
||||
state_color = "#f5c359",
|
||||
state_symbol = "",
|
||||
|
||||
stashes_color = "#565f89",
|
||||
stashes_symbol = "⚑",
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Features
|
||||
|
||||
- [x] Current branch
|
||||
- [x] Remote and remote branch
|
||||
- [x] Latest tag
|
||||
- [x] Latest commit
|
||||
- [x] Behind/Ahead of the remote
|
||||
- [x] Stashes
|
||||
- [x] States
|
||||
- [x] merge
|
||||
- [x] cherry
|
||||
- [x] rebase (+ done counter)
|
||||
- [x] revert
|
||||
- [x] bisect
|
||||
- [x] Staged
|
||||
- [x] Unstaged
|
||||
- [x] Untracked
|
||||
|
||||
### Under the hood
|
||||
|
||||
The goal is to use minimum amount of shell commands.
|
||||
|
||||
- Branch, stashes, staged files, unstaged files, untracked files.
|
||||
|
||||
```shell
|
||||
git status --ignore-submodules=dirty --branch --show-stash --ahead-behind
|
||||
```
|
||||
|
||||
- Remote branch and repo:
|
||||
|
||||
```shell
|
||||
git rev-parse --abbrev-ref --symbolic-full-name @{upstream}
|
||||
```
|
||||
|
||||
- Latest tag and commit:
|
||||
|
||||
```shell
|
||||
git log --format="commit %h%d" -n 1
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
- [yazi source code](https://github.com/sxyazi/yazi)
|
||||
- [powerlevel10k](https://github.com/romkatv/powerlevel10k)
|
||||
- [twio142](https://github.com/twio142/githead.yazi)
|
||||
@@ -0,0 +1,598 @@
|
||||
---@diagnostic disable: undefined-global
|
||||
|
||||
local save = ya.sync(function(this, cwd, output)
|
||||
if cwd:match("%.git[/\\]") or cwd:match("%.git$") then
|
||||
this.output = nil
|
||||
return
|
||||
end
|
||||
if cx.active.current.cwd == Url(cwd) then
|
||||
this.output = output
|
||||
ui.render()
|
||||
end
|
||||
end)
|
||||
|
||||
return {
|
||||
setup = function(this, options)
|
||||
options = options or {}
|
||||
|
||||
local config = {
|
||||
order = options.order or {
|
||||
"__spacer__",
|
||||
"branch",
|
||||
"remote_branch",
|
||||
"__spacer__",
|
||||
"tag",
|
||||
"__spacer__",
|
||||
"commit",
|
||||
"__spacer__",
|
||||
"behind_ahead_remote",
|
||||
"__spacer__",
|
||||
"stashes",
|
||||
"__spacer__",
|
||||
"state",
|
||||
"__spacer__",
|
||||
"staged",
|
||||
"__spacer__",
|
||||
"unstaged",
|
||||
"__spacer__",
|
||||
"untracked",
|
||||
},
|
||||
|
||||
show_numbers = options.show_numbers == nil and true
|
||||
or options.show_numbers,
|
||||
|
||||
show_branch = options.show_branch == nil and true or options.show_branch,
|
||||
branch_prefix = options.branch_prefix or "",
|
||||
branch_color = options.branch_color or "blue",
|
||||
branch_symbol = options.branch_symbol or "",
|
||||
branch_borders = options.branch_borders or "",
|
||||
|
||||
show_remote_branch = options.show_remote_branch == nil and true
|
||||
or options.show_remote_branch,
|
||||
always_show_remote_branch = options.always_show_remote_branch == nil
|
||||
and false
|
||||
or options.always_show_remote_branch,
|
||||
always_show_remote_repo = options.always_show_remote_repo == nil
|
||||
and false
|
||||
or options.always_show_remote_repo,
|
||||
remote_branch_prefix = options.remote_branch_prefix or ":",
|
||||
remote_branch_color = options.remote_branch_color or "bright magenta",
|
||||
|
||||
show_tag = options.show_tag == nil and true or options.show_tag,
|
||||
always_show_tag = options.always_show_tag == nil and false
|
||||
or options.always_show_tag,
|
||||
tag_color = options.tag_color or "magenta",
|
||||
tag_symbol = options.tag_symbol == nil and "#" or options.tag_symbol,
|
||||
|
||||
show_commit = options.show_commit == nil and true or options.show_commit,
|
||||
always_show_commit = options.always_show_commit == nil and false
|
||||
or options.always_show_commit,
|
||||
commit_color = options.commit_color or "bright magenta",
|
||||
commit_symbol = options.commit_symbol == nil and "@"
|
||||
or options.commit_symbol,
|
||||
|
||||
show_behind_ahead_remote = options.show_behind_ahead_remote == nil
|
||||
and true
|
||||
or options.show_behind_ahead_remote,
|
||||
behind_remote_color = options.behind_remote_color or "bright magenta",
|
||||
behind_remote_symbol = options.behind_remote_symbol or "⇣",
|
||||
ahead_remote_color = options.ahead_remote_color or "bright magenta",
|
||||
ahead_remote_symbol = options.ahead_remote_symbol or "⇡",
|
||||
|
||||
show_stashes = options.show_stashes == nil and true
|
||||
or options.show_stashes,
|
||||
stashes_color = options.stashes_color or "bright magenta",
|
||||
stashes_symbol = options.stashes_symbol or "$",
|
||||
|
||||
show_state = options.show_state == nil and true or options.show_state,
|
||||
show_state_prefix = options.show_state_prefix == nil and true
|
||||
or options.show_state_prefix,
|
||||
state_color = options.state_color or "red",
|
||||
state_symbol = options.state_symbol or "~",
|
||||
|
||||
show_staged = options.show_staged == nil and true or options.show_staged,
|
||||
staged_color = options.staged_color or "bright yellow",
|
||||
staged_symbol = options.staged_symbol or "+",
|
||||
|
||||
show_unstaged = options.show_unstaged == nil and true
|
||||
or options.show_unstaged,
|
||||
unstaged_color = options.unstaged_color or "bright yellow",
|
||||
unstaged_symbol = options.unstaged_symbol or "!",
|
||||
|
||||
show_untracked = options.show_untracked == nil and true
|
||||
or options.show_untracked,
|
||||
untracked_color = options.untracked_color or "bright blue",
|
||||
untracked_symbol = options.untracked_symbol or "?",
|
||||
}
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_branch(data)
|
||||
local branch = data.branch
|
||||
|
||||
if not branch then
|
||||
return nil
|
||||
end
|
||||
|
||||
local left_border = config.branch_borders:sub(1, 1)
|
||||
local right_border = config.branch_borders:sub(2, 2)
|
||||
|
||||
local branch_string = ""
|
||||
|
||||
if config.branch_symbol == "" then
|
||||
branch_string = left_border .. branch .. right_border
|
||||
else
|
||||
branch_string = left_border
|
||||
.. config.branch_symbol
|
||||
.. branch
|
||||
.. right_border
|
||||
end
|
||||
|
||||
local branch_prefix = config.branch_prefix == "" and ""
|
||||
or config.branch_prefix .. " "
|
||||
|
||||
return ui.Line({
|
||||
ui.Span(branch_prefix),
|
||||
ui.Span(branch_string):fg(config.branch_color),
|
||||
})
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_remote_branch(data)
|
||||
local branch = data.branch
|
||||
local remote_branch = data.remote_branch
|
||||
local remote_repo = data.remote_repo
|
||||
|
||||
if not remote_branch then
|
||||
return nil
|
||||
end
|
||||
|
||||
local show_remote = config.always_show_remote_branch
|
||||
or branch ~= remote_branch
|
||||
if not show_remote then
|
||||
return nil
|
||||
end
|
||||
|
||||
local remote_branch_label = config.always_show_remote_repo
|
||||
and (remote_repo .. "/" .. remote_branch)
|
||||
or remote_branch
|
||||
|
||||
return ui.Line({
|
||||
ui.Span(config.remote_branch_prefix),
|
||||
ui.Span(remote_branch_label):fg(config.remote_branch_color),
|
||||
})
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_tag(data)
|
||||
local branch = data.branch
|
||||
local tag = data.tag
|
||||
|
||||
if not tag then
|
||||
return nil
|
||||
end
|
||||
|
||||
if not branch or config.always_show_tag then
|
||||
return ui.Line({
|
||||
ui.Span(config.tag_symbol),
|
||||
ui.Span(tag):fg(config.tag_color),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_commit(data)
|
||||
local branch = data.branch
|
||||
local tag = data.tag
|
||||
local commit = data.commit
|
||||
|
||||
if not commit then
|
||||
return nil
|
||||
end
|
||||
|
||||
if (not branch and not tag) or config.always_show_commit then
|
||||
return ui.Line({
|
||||
ui.Span(config.commit_symbol),
|
||||
ui.Span(commit):fg(config.commit_color),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_behind_ahead_remote(data)
|
||||
local behind = data.behind_remote
|
||||
local ahead = data.ahead_remote
|
||||
|
||||
local behind_label = behind
|
||||
and behind > 0
|
||||
and ui.Span(
|
||||
config.behind_remote_symbol .. (config.show_numbers and behind or "")
|
||||
):fg(config.behind_remote_color)
|
||||
|
||||
local ahead_label = ahead
|
||||
and ahead > 0
|
||||
and ui.Span(
|
||||
config.ahead_remote_symbol .. (config.show_numbers and ahead or "")
|
||||
):fg(config.ahead_remote_color)
|
||||
|
||||
if ahead_label and behind_label then
|
||||
return ui.Line({
|
||||
behind_label,
|
||||
ahead_label,
|
||||
})
|
||||
elseif ahead_label then
|
||||
return ahead_label
|
||||
elseif behind_label then
|
||||
return behind_label
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_stashes(data)
|
||||
local stashes_count = data.stashes
|
||||
|
||||
if not stashes_count then
|
||||
return nil
|
||||
end
|
||||
|
||||
local stashes_label = config.stashes_symbol
|
||||
|
||||
if config.show_numbers then
|
||||
stashes_label = stashes_label .. stashes_count
|
||||
end
|
||||
|
||||
return ui.Span(stashes_label):fg(config.stashes_color)
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_state(data)
|
||||
local state_prefix = data.state_prefix
|
||||
local unmerged_count = data.unmerged_count
|
||||
local rebase_done = data.rebase_done
|
||||
local rebase_total = data.rebase_total
|
||||
|
||||
if state_prefix then
|
||||
local state_label = ""
|
||||
if config.show_state_prefix then
|
||||
state_label = state_prefix
|
||||
if
|
||||
state_prefix == "rebase-i"
|
||||
and config.show_numbers
|
||||
and rebase_done
|
||||
and rebase_total
|
||||
then
|
||||
state_label = state_label
|
||||
.. " "
|
||||
.. rebase_done
|
||||
.. "/"
|
||||
.. rebase_total
|
||||
end
|
||||
end
|
||||
|
||||
local unmerged_label = ""
|
||||
local symbol = ""
|
||||
|
||||
if unmerged_count and unmerged_count > 0 then
|
||||
symbol = " " .. config.state_symbol
|
||||
if config.show_numbers then
|
||||
unmerged_label = tostring(unmerged_count)
|
||||
end
|
||||
end
|
||||
|
||||
return ui.Span(state_label .. symbol .. unmerged_label)
|
||||
:fg(config.state_color)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_staged(data)
|
||||
local staged = data.staged
|
||||
|
||||
if staged then
|
||||
local staged_label = config.staged_symbol
|
||||
|
||||
if config.show_numbers then
|
||||
local filtered_staged = staged:gsub("^[%s]*%b()[%s]*", "")
|
||||
|
||||
local staged_count = 0
|
||||
for line in filtered_staged:gmatch("[^\r\n]+") do
|
||||
if line:match("%S") then
|
||||
staged_count = staged_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
staged_label = staged_label .. staged_count
|
||||
end
|
||||
|
||||
return ui.Span(staged_label):fg(config.staged_color)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_unstaged(data)
|
||||
local unstaged = data.unstaged
|
||||
|
||||
if unstaged then
|
||||
local unstaged_label = config.unstaged_symbol
|
||||
|
||||
if config.show_numbers then
|
||||
local filtered_unstaged =
|
||||
unstaged:gsub("^[%s]*%b()[\r\n]*", ""):gsub("^[%s]*%b()[\r\n]*", "")
|
||||
|
||||
local unstaged_count = 0
|
||||
for line in filtered_unstaged:gmatch("[^\r\n]+") do
|
||||
if line:match("%S") then
|
||||
unstaged_count = unstaged_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
unstaged_label = unstaged_label .. unstaged_count
|
||||
end
|
||||
|
||||
return ui.Span(unstaged_label):fg(config.unstaged_color)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- @param data GitStatusData
|
||||
function Header:render_untracked(data)
|
||||
local untracked = data.untracked
|
||||
|
||||
if untracked then
|
||||
local untracked_label = config.untracked_symbol
|
||||
|
||||
if config.show_numbers then
|
||||
local filtered_untracked = untracked:gsub("^[%s]*%b()[\r\n]*", "")
|
||||
local untracked_count = 0
|
||||
|
||||
for line in filtered_untracked:gmatch("[^\r\n]+") do
|
||||
if line:match("%S") then
|
||||
untracked_count = untracked_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
untracked_label = untracked_label .. untracked_count
|
||||
end
|
||||
|
||||
return ui.Span(untracked_label):fg(config.untracked_color)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function Header:githead()
|
||||
--- @type GitStatusData
|
||||
local data = this.output
|
||||
|
||||
if not data then
|
||||
return ui.Line({})
|
||||
end
|
||||
|
||||
local head = {}
|
||||
|
||||
for _, key in ipairs(config.order) do
|
||||
if key == "__spacer__" then
|
||||
if head[#head] ~= " " then
|
||||
table.insert(head, " ")
|
||||
end
|
||||
else
|
||||
local fn = self["render_" .. key]
|
||||
local is_shown = config["show_" .. key]
|
||||
|
||||
if fn and is_shown then
|
||||
local value = fn(self, data)
|
||||
if value then
|
||||
table.insert(head, value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ui.Line(head)
|
||||
end
|
||||
|
||||
Header:children_add(Header.githead, 2000, Header.LEFT)
|
||||
|
||||
local callback = function()
|
||||
local cwd = cx.active.current.cwd
|
||||
ya.emit("plugin", {
|
||||
this._id,
|
||||
ya.quote(tostring(cwd), true),
|
||||
})
|
||||
end
|
||||
|
||||
ps.sub("cd", callback)
|
||||
ps.sub("rename", callback)
|
||||
ps.sub("bulk", callback)
|
||||
ps.sub("move", callback)
|
||||
ps.sub("trash", callback)
|
||||
ps.sub("delete", callback)
|
||||
ps.sub("tab", callback)
|
||||
end,
|
||||
|
||||
entry = function(_, job)
|
||||
local args = job.args or job
|
||||
|
||||
---@class GitStatusData
|
||||
---@field ahead_remote? integer
|
||||
---@field behind_remote? integer
|
||||
---@field branch? string
|
||||
---@field commit? string
|
||||
---@field rebase_done? integer
|
||||
---@field remote_branch? string
|
||||
---@field remote_repo? string
|
||||
---@field staged? string
|
||||
---@field stashes? integer
|
||||
---@field state_prefix? "bisect"|"cherry"|"merge"|"rebase-i"|"revert"
|
||||
---@field tag? string
|
||||
---@field unmerged_count? integer
|
||||
---@field unstaged? string
|
||||
---@field untracked? string
|
||||
local data = {}
|
||||
|
||||
--- @param status string
|
||||
local get_behind_ahead_remote = function(status)
|
||||
local diverged_ahead, diverged_behind =
|
||||
status:match("have (%d+) and (%d+) different")
|
||||
if diverged_ahead and diverged_behind then
|
||||
data.behind_remote = tonumber(diverged_behind)
|
||||
data.ahead_remote = tonumber(diverged_ahead)
|
||||
else
|
||||
local behind_remote = status:match("behind %S+ by (%d+) commits?")
|
||||
local ahead_remote = status:match("ahead of %S+ by (%d+) commits?")
|
||||
|
||||
data.behind_remote = tonumber(behind_remote)
|
||||
data.ahead_remote = tonumber(ahead_remote)
|
||||
end
|
||||
end
|
||||
|
||||
--- @param status string
|
||||
local get_branch = function(status)
|
||||
data.branch = status:match("On branch (%S+)")
|
||||
end
|
||||
|
||||
--- @param status string
|
||||
local get_stashes = function(status)
|
||||
data.stashes = tonumber(status:match("Your stash currently has (%d+)"))
|
||||
end
|
||||
|
||||
--- @param status string
|
||||
local get_state = function(status)
|
||||
local unmerged = status:match("Unmerged paths:%s*(.-)%s*\n\n")
|
||||
if unmerged then
|
||||
local filtered_unmerged =
|
||||
unmerged:gsub("^[%s]*%b()[%s]*", ""):gsub("^[%s]*%b()[%s]*", "")
|
||||
local count = 0
|
||||
for line in filtered_unmerged:gmatch("[^\r\n]+") do
|
||||
if line:match("%S") then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
data.unmerged_count = count
|
||||
end
|
||||
|
||||
if status:find("git merge") then
|
||||
data.state_prefix = "merge"
|
||||
elseif status:find("git cherry%-pick") then
|
||||
data.state_prefix = "cherry"
|
||||
elseif status:find("git rebase") then
|
||||
data.state_prefix = "rebase-i"
|
||||
local commands_done = status:match("%((%d+) commands? done%)")
|
||||
if commands_done then
|
||||
data.rebase_done = commands_done
|
||||
if not data.unmerged_count then
|
||||
data.rebase_total = commands_done
|
||||
else
|
||||
data.rebase_total = data.unmerged_count
|
||||
end
|
||||
end
|
||||
elseif status:find("git revert") then
|
||||
data.state_prefix = "revert"
|
||||
elseif status:find("git bisect") then
|
||||
data.state_prefix = "bisect"
|
||||
end
|
||||
end
|
||||
|
||||
--- @param status string
|
||||
local get_staged = function(status)
|
||||
data.staged = status:match("Changes to be committed:%s*(.-)%s*\n\n")
|
||||
end
|
||||
|
||||
--- @param status string
|
||||
local get_unstaged = function(status)
|
||||
data.unstaged =
|
||||
status:match("Changes not staged for commit:%s*(.-)%s*\n\n")
|
||||
end
|
||||
|
||||
--- @param status string
|
||||
local get_untracked = function(status)
|
||||
data.untracked = status:match("Untracked files:%s*(.-)%s*\n\n")
|
||||
end
|
||||
|
||||
local get_status = function()
|
||||
local cmd = Command("git")
|
||||
:arg({
|
||||
"status",
|
||||
"--ignore-submodules=dirty",
|
||||
"--branch",
|
||||
"--show-stash",
|
||||
"--ahead-behind",
|
||||
})
|
||||
:cwd(args[1])
|
||||
:env("LANGUAGE", "en_US.UTF-8")
|
||||
:stdout(Command.PIPED)
|
||||
local cmd_output = cmd:output()
|
||||
|
||||
if cmd_output then
|
||||
local status = cmd_output.stdout
|
||||
|
||||
get_branch(status)
|
||||
get_behind_ahead_remote(status)
|
||||
get_stashes(status)
|
||||
get_state(status)
|
||||
get_staged(status)
|
||||
get_unstaged(status)
|
||||
get_untracked(status)
|
||||
end
|
||||
end
|
||||
|
||||
local get_remote_branch = function()
|
||||
local cmd = Command("git")
|
||||
:arg({
|
||||
"rev-parse",
|
||||
"--abbrev-ref",
|
||||
"--symbolic-full-name",
|
||||
"@{upstream}",
|
||||
})
|
||||
:cwd(args[1])
|
||||
:env("LANGUAGE", "en_US.UTF-8")
|
||||
:stdout(Command.PIPED)
|
||||
local cmd_output = cmd:output()
|
||||
|
||||
if cmd_output then
|
||||
local remote_branch = cmd_output.stdout
|
||||
|
||||
data.remote_branch =
|
||||
remote_branch:gsub("[\r\n]", ""):match("^[^/]+/(.+)")
|
||||
data.remote_repo = remote_branch:gsub("[\r\n]", ""):match("^([^/]+)/")
|
||||
end
|
||||
end
|
||||
|
||||
--- @param log string
|
||||
local get_tag = function(log)
|
||||
data.tag = log:match("tag: ([^, )]+)")
|
||||
end
|
||||
|
||||
--- @param log string
|
||||
local get_commit = function(log)
|
||||
data.commit = log:match("^commit%s+([a-f0-9]+)")
|
||||
end
|
||||
|
||||
local get_git_log = function()
|
||||
local cmd = Command("git")
|
||||
:arg({ "log", "--format=commit %h%d", "-n", "1" })
|
||||
:cwd(args[1])
|
||||
:env("LANGUAGE", "en_US.UTF-8")
|
||||
:stdout(Command.PIPED)
|
||||
local cmd_output = cmd:output()
|
||||
|
||||
if cmd_output then
|
||||
local log = cmd_output.stdout
|
||||
|
||||
get_tag(log)
|
||||
get_commit(log)
|
||||
end
|
||||
end
|
||||
|
||||
get_status()
|
||||
get_remote_branch()
|
||||
get_git_log()
|
||||
|
||||
save(args[1], data)
|
||||
end,
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 yazi-rs
|
||||
|
||||
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,40 @@
|
||||
# smart-enter.yazi
|
||||
|
||||
[`Open`][open] files or [`enter`][enter] directories all in one key!
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pkg add yazi-rs/plugins:smart-enter
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Bind your <kbd>l</kbd> key to the plugin, in your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[mgr.prepend_keymap]]
|
||||
on = "l"
|
||||
run = "plugin smart-enter"
|
||||
desc = "Enter the child directory, or open the file"
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
By default, `--hovered` is passed to the [`open`][open] action, make the behavior consistent with [`enter`][enter] avoiding accidental triggers,
|
||||
which means both will only target the currently hovered file.
|
||||
|
||||
If you still want `open` to target multiple selected files, add this to your `~/.config/yazi/init.lua`:
|
||||
|
||||
```lua
|
||||
require("smart-enter"):setup {
|
||||
open_multi = true,
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
|
||||
[open]: https://yazi-rs.github.io/docs/configuration/keymap/#mgr.open
|
||||
[enter]: https://yazi-rs.github.io/docs/configuration/keymap/#mgr.enter
|
||||
@@ -0,0 +1,11 @@
|
||||
--- @since 25.5.31
|
||||
--- @sync entry
|
||||
|
||||
local function setup(self, opts) self.open_multi = opts.open_multi end
|
||||
|
||||
local function entry(self)
|
||||
local h = cx.active.current.hovered
|
||||
ya.emit(h and h.cha.is_dir and "enter" or "open", { hovered = not self.open_multi })
|
||||
end
|
||||
|
||||
return { entry = entry, setup = setup }
|
||||
@@ -0,0 +1,125 @@
|
||||
# Ember OLED: aligned with Noctalia's "Ember OLED" palette and tmux status line.
|
||||
[flavor]
|
||||
dark = "catppuccin-macchiato"
|
||||
|
||||
[mgr]
|
||||
cwd = { fg = "#ffb05c", bold = true }
|
||||
find_keyword = { fg = "#ffcc99", bold = true, underline = true }
|
||||
find_position = { fg = "#ff8800", bold = true }
|
||||
marker_copied = { fg = "#c98a45", bg = "#c98a45" }
|
||||
marker_cut = { fg = "#ff6b4a", bg = "#ff6b4a" }
|
||||
marker_marked = { fg = "#ff8800", bg = "#ff8800" }
|
||||
marker_selected = { fg = "#ffcc99", bg = "#ffcc99" }
|
||||
count_copied = { fg = "#050403", bg = "#c98a45" }
|
||||
count_cut = { fg = "#050403", bg = "#ff6b4a" }
|
||||
count_selected = { fg = "#050403", bg = "#ffcc99" }
|
||||
border_symbol = "│"
|
||||
border_style = { fg = "#6e4a31" }
|
||||
|
||||
[tabs]
|
||||
active = { fg = "#fff1e6", bg = "#1a110c", bold = true }
|
||||
inactive = { fg = "#f4c7a1", bg = "#050403" }
|
||||
|
||||
[mode]
|
||||
normal_main = { fg = "#050403", bg = "#ff8800", bold = true }
|
||||
normal_alt = { fg = "#ffb05c", bg = "#1a110c" }
|
||||
select_main = { fg = "#050403", bg = "#ffb05c", bold = true }
|
||||
select_alt = { fg = "#ffb05c", bg = "#1a110c" }
|
||||
unset_main = { fg = "#050403", bg = "#ff6b4a", bold = true }
|
||||
unset_alt = { fg = "#ff6b4a", bg = "#1a110c" }
|
||||
|
||||
[status]
|
||||
perm_sep = { fg = "#6e4a31" }
|
||||
perm_type = { fg = "#ffb05c" }
|
||||
perm_read = { fg = "#fff1e6" }
|
||||
perm_write = { fg = "#ff6b4a" }
|
||||
perm_exec = { fg = "#c98a45" }
|
||||
progress_label = { fg = "#fff1e6", bold = true }
|
||||
progress_normal = { fg = "#ff8800", bg = "#1a110c" }
|
||||
progress_error = { fg = "#fff1e6", bg = "#ff6b4a" }
|
||||
|
||||
[pick]
|
||||
border = { fg = "#ff8800" }
|
||||
active = { fg = "#ffb05c", bold = true }
|
||||
|
||||
[input]
|
||||
border = { fg = "#ff8800" }
|
||||
selected = { fg = "#050403", bg = "#ffb05c" }
|
||||
|
||||
[cmp]
|
||||
border = { fg = "#ff8800" }
|
||||
|
||||
[tasks]
|
||||
border = { fg = "#ff8800" }
|
||||
title = { fg = "#fff1e6" }
|
||||
hovered = { fg = "#ffb05c", bold = true }
|
||||
|
||||
[which]
|
||||
border = { fg = "#ff8800" }
|
||||
cand = { fg = "#ffb05c" }
|
||||
rest = { fg = "#f4c7a1" }
|
||||
desc = { fg = "#fff1e6" }
|
||||
separator = " "
|
||||
separator_style = { fg = "#6e4a31" }
|
||||
|
||||
[help]
|
||||
on = { fg = "#ffb05c" }
|
||||
run = { fg = "#fff1e6" }
|
||||
hovered = { fg = "#050403", bg = "#ffb05c", bold = true }
|
||||
footer = { fg = "#fff1e6", bg = "#1a110c" }
|
||||
|
||||
[spot]
|
||||
border = { fg = "#ff8800" }
|
||||
title = { fg = "#ffb05c" }
|
||||
tbl_col = { fg = "#ffb05c" }
|
||||
tbl_cell = { fg = "#fff1e6", bg = "#1a110c" }
|
||||
|
||||
[notify]
|
||||
title_info = { fg = "#c98a45" }
|
||||
title_warn = { fg = "#ffb05c" }
|
||||
title_error = { fg = "#ff6b4a" }
|
||||
|
||||
[filetype]
|
||||
rules = [
|
||||
{ mime = "**/image/*", fg = "#ffcc99" },
|
||||
{ mime = "**/{audio,video}/*", fg = "#c98a45" },
|
||||
{ mime = "**/application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "#ffb05c" },
|
||||
{ mime = "**/application/{pdf,doc,rtf}", fg = "#f4c7a1" },
|
||||
{ mime = "vfs/{absent,stale}", fg = "#6e4a31" },
|
||||
{ url = "*", fg = "#fff1e6" },
|
||||
{ url = "*/", fg = "#ffb05c" },
|
||||
]
|
||||
|
||||
[icon]
|
||||
dirs = [
|
||||
{ name = ".config", text = "", fg = "#ffb05c" },
|
||||
{ name = ".git", text = "", fg = "#ff8800" },
|
||||
{ name = ".github", text = "", fg = "#ffb05c" },
|
||||
{ name = "Desktop", text = "", fg = "#ffb05c" },
|
||||
{ name = "Documents", text = "", fg = "#ffb05c" },
|
||||
{ name = "Downloads", text = "", fg = "#ffb05c" },
|
||||
{ name = "Pictures", text = "", fg = "#ffcc99" },
|
||||
{ name = "Videos", text = "", fg = "#c98a45" },
|
||||
]
|
||||
conds = [
|
||||
{ if = "orphan", text = "", fg = "#ff6b4a" },
|
||||
{ if = "link", text = "", fg = "#6e4a31" },
|
||||
{ if = "dir & hovered", text = "", fg = "#ffcc99" },
|
||||
{ if = "dir", text = "", fg = "#ffb05c" },
|
||||
{ if = "exec", text = "", fg = "#c98a45" },
|
||||
{ if = "!dir", text = "", fg = "#fff1e6" },
|
||||
]
|
||||
|
||||
[git]
|
||||
modified = { fg = "#ffb05c" }
|
||||
added = { fg = "#c98a45" }
|
||||
untracked = { fg = "#f4c7a1" }
|
||||
deleted = { fg = "#ff6b4a", bold = true }
|
||||
updated = { fg = "#ff8800" }
|
||||
ignored = { fg = "#6e4a31" }
|
||||
modified_sign = "M "
|
||||
added_sign = "A "
|
||||
untracked_sign = "? "
|
||||
deleted_sign = "D "
|
||||
updated_sign = "U "
|
||||
ignored_sign = "I "
|
||||
@@ -0,0 +1,9 @@
|
||||
[[plugin.prepend_fetchers]]
|
||||
url = "*"
|
||||
run = "git"
|
||||
group = "git"
|
||||
|
||||
[[plugin.prepend_fetchers]]
|
||||
url = "*/"
|
||||
run = "git"
|
||||
group = "git"
|
||||
Reference in New Issue
Block a user