many things changed

This commit is contained in:
parent 628dd7eca1
commit 8318a1e5a4
73 changed files with 2753 additions and 165 deletions

View File

@ -10,13 +10,17 @@ alias nt="n test"
alias ntd="n test:dev" alias ntd="n test:dev"
# ─────────────────────────────── vim/nvim ─────────────────────────────── # ─────────────────────────────── vim/nvim ───────────────────────────────
if command -v zoxide > /dev/null && command -v nvim-zoxide > /dev/null; then
alias nvim="nvim-zoxide"
fi
alias nv="nvim" alias nv="nvim"
alias lv="lvim" alias lv="lvim"
alias vim="nvim" alias vim="nvim"
alias v="vim" alias v="vim"
if command -v zoxide > /dev/null && command -v nvim-zoxide > /dev/null; then
alias nv="nvim-zoxide"
fi
# ───────────────────────────── drag n drop ───────────────────────────
alias dnd="dragon-drop"
alias cpdnd='cp $(dragon-drop -p -x -t .) .'
# ───────────────────────────────── eza ─────────────────────────────── # ───────────────────────────────── eza ───────────────────────────────
if command -v eza > /dev/null; then if command -v eza > /dev/null; then

View File

@ -0,0 +1,15 @@
{
// Place your snippets for typescript here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
// "Print to console": {
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}

View File

@ -2,7 +2,7 @@
animations { animations {
enabled = true enabled = true
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more # see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = myBezier, 0.05, 0.9, 0.1, 1.05 bezier = myBezier, 0.05, 0.9, 0.1, 1.05
bezier = easeOutQuint, 0.22, 1, 0.36, 1 bezier = easeOutQuint, 0.22, 1, 0.36, 1

View File

@ -15,6 +15,7 @@ bind = $mainMod SHIFT, T, exec, ~/.config/hypr/scripts/show-crow.sh
bind = $mainMod CTRL SHIFT, T, exec, ~/.config/hypr/scripts/translate-selection.sh bind = $mainMod CTRL SHIFT, T, exec, ~/.config/hypr/scripts/translate-selection.sh
bind = $mainMod, E, exec, $fileManager # file manager bind = $mainMod, E, exec, $fileManager # file manager
bind = $mainMod, A, exec, $toggle_menu_cmd # wofi bind = $mainMod, A, exec, $toggle_menu_cmd # wofi
bind = $mainMod CTRL ALT, V, exec, ~/.config/hypr/scripts/dnd-clipboard.sh
# ──────────────────────────────── copyq ────────────────────────────── # ──────────────────────────────── copyq ──────────────────────────────
bind = CTRL_ALT, V, exec, copyq toggle bind = CTRL_ALT, V, exec, copyq toggle
@ -99,14 +100,20 @@ bindle=, XF86AudioLowerVolume, exec, pactl set-sink-volume @DEFAULT_SINK@ -5% &
bindle=, XF86MonBrightnessUp, exec, ~/.config/scripts/set_brightness.sh +10% bindle=, XF86MonBrightnessUp, exec, ~/.config/scripts/set_brightness.sh +10%
bindle=, XF86MonBrightnessDown, exec, ~/.config/scripts/set_brightness.sh 10%- bindle=, XF86MonBrightnessDown, exec, ~/.config/scripts/set_brightness.sh 10%-
bindl=, XF86AudioMute, exec, amixer set Master toggle bindl=, XF86AudioMute, exec, amixer set Master toggle
bindl=, XF86AudioPlay, exec, playerctl play-pause bindl=, XF86AudioPlay, exec, playerctl --player=$(cat ~/.config/chosen_player) play-pause
bindl=, XF86AudioPause, exec, playerctl play-pause bindl=, XF86AudioPause, exec, playerctl --player=$(cat ~/.config/chosen_player) play-pause
bindl=, XF86AudioStop, exec, playerctl play-pause bindl=, XF86AudioStop, exec, playerctl --player=$(cat ~/.config/chosen_player) play-pause
bindl=, XF86AudioNext, exec, playerctl next bindl=, XF86AudioNext, exec, playerctl --player=$(cat ~/.config/chosen_player) next
bindl=, XF86AudioPrev, exec, playerctl previous bindl=, XF86AudioPrev, exec, playerctl --player=$(cat ~/.config/chosen_player) previous
bindl= CTRL ALT SHIFT, H, exec, playerctl previous bindl= CTRL ALT SHIFT, H, exec, playerctl --player=$(cat ~/.config/chosen_player) previous
bindl= CTRL ALT SHIFT, L, exec, playerctl next bindl= CTRL ALT SHIFT, L, exec, playerctl --player=$(cat ~/.config/chosen_player) next
bindl= CTRL ALT SHIFT, SPACE, exec, playerctl play-pause bindl= CTRL ALT SHIFT, SPACE, exec, playerctl --player=$(cat ~/.config/chosen_player) play-pause
# ─────────────────────── select pulseaudio output ───────────────────────
bind= CTRL ALT SHIFT, O, exec, ~/.config/hypr/scripts/wofi-pulse-output.sh
# ─────────────────────── select playerctl player ─────────────────────
bind= CTRL ALT SHIFT, P, exec, ~/.config/hypr/scripts/wofi-player.sh
# Move/resize windows with mainMod + LMB/RMB and dragging # Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow bindm = $mainMod, mouse:272, movewindow

View File

@ -17,8 +17,8 @@ source = ./workspaces.conf
# See https://wiki.hyprland.org/Configuring/Keywords/ # See https://wiki.hyprland.org/Configuring/Keywords/
# Set programs that you use # Set programs that you use
$terminal = alacritty $terminal = kitty
$fileManager = dolphin $fileManager = $terminal tmux new-session -s tmp-file-manager 'yazi'
$toggle_menu_cmd = pgrep wofi >/dev/null 2>&1 && killall wofi || wofi --show drun $toggle_menu_cmd = pgrep wofi >/dev/null 2>&1 && killall wofi || wofi --show drun
# ╭──────────────────────────────────────────────────────────╮ # ╭──────────────────────────────────────────────────────────╮

View File

@ -1,6 +1,7 @@
# Generated by nwg-displays on 2024-08-14 at 13:35:50. Do not edit manually. # Generated by nwg-displays on 2024-10-09 at 13:19:03. Do not edit manually.
monitor=eDP-1,1920x1080@60.01,0x0,1.0 monitor=eDP-1,1920x1080@60.01,0x0,1.0
monitor=DP-2,1920x1080@60.0,1920x-953,1.0 monitor=DP-2,1920x1080@60.0,1920x-1440,1.0
monitor=DP-2,transform,3
monitor=HDMI-A-1,2560x1440@59.95,-640x-1440,1.0 monitor=HDMI-A-1,2560x1440@59.95,-640x-1440,1.0
monitor=desc:BNQ BenQ G925HDA 29A01966019,prefered,auto,1.0 monitor=desc:BNQ BenQ G925HDA 29A01966019,prefered,auto,1.0

View File

@ -0,0 +1,6 @@
# Generated by nwg-displays on 2024-08-14 at 13:35:50. Do not edit manually.
monitor=eDP-1,1920x1080@60.01,0x0,1.0
monitor=DP-2,1920x1080@60.0,1920x-953,1.0
monitor=HDMI-A-1,2560x1440@59.95,-640x-1440,1.0
monitor=desc:BNQ BenQ G925HDA 29A01966019,prefered,auto,1.0

View File

@ -0,0 +1 @@
wl-paste > /tmp/clipboard_image.jpg && dragon-drop /tmp/clipboard_image.jpg

View File

@ -0,0 +1,37 @@
#!/bin/bash
# Function to get info for a player
get_player_info() {
playerctl -p "$1" metadata --format "{{ artist }} - {{ title }}" 2>/dev/null
}
# Get the currently selected player from the file, if it exists
current_player=$(cat ~/.config/chosen_player 2>/dev/null)
# Get list of players
players=$(playerctl -l)
# Prepare the list for rofi by appending info about each player
menu=""
for player in $players; do
info=$(get_player_info "$player")
if [ -z "$info" ]; then
info="(No track info)"
fi
# Highlight the current player with ✅
if [ "$player" = "$current_player" ]; then
menu+="$player: $info\n"
else
menu+="$player: $info\n"
fi
done
# Use rofi to choose the player
chosen=$(echo -e "$menu" | wofi -dmenu -p "Choose player" | awk -F: '{print $1}')
# If a player was chosen, save it to a file
if [ -n "$chosen" ]; then
echo "$chosen" > ~/.config/chosen_player
notify-send "Audio output switched" "Switched to $(echo "$chosen")"
fi

View File

@ -0,0 +1,28 @@
#!/bin/bash
# Get the current default sink
default_sink=$(pactl info | grep "Default Sink" | awk '{print $3}')
default_sink_number=$(pactl list sinks short | grep "$default_sink" | awk '{print $1}')
# Get a list of available sinks with their descriptions
sinks=$(pactl list sinks | grep -E 'Sink|Description' | sed -E 's/Sink #([0-9]+)/\1/' | sed -E 's/Description: (.+)/\1/')
# Format the sink list to show the index and description
formatted_sinks=$(echo "$sinks" | awk 'NR%2{printf "%s ", $0; next;}1')
# Add ✅ to the current default sink
formatted_sinks=$(echo "$formatted_sinks" | awk -v default_sink_number="$default_sink_number" '{if ($1 == default_sink_number) {print "✅ " $0} else {print $0}}')
# Use wofi to select a sink based on the description
selected_sink=$(echo "$formatted_sinks" | wofi --dmenu --prompt "Select audio output:")
# Extract the sink index
sink_index=$(echo "$selected_sink" | awk '{print $1}')
# Set the selected sink as the default
if [ -n "$sink_index" ]; then
pactl set-default-sink "$sink_index"
notify-send "Audio output switched" "Switched to $(echo "$selected_sink" | cut -d' ' -f2-)"
else
notify-send "No sink selected"
fi

View File

@ -66,7 +66,7 @@ inactive_border_color #6272a4
# BEGIN_KITTY_FONTS # BEGIN_KITTY_FONTS
font_family family="JetBrains Mono" font_family family="VictorMono Nerd Font Mono"
bold_font auto bold_font auto
italic_font auto italic_font auto
bold_italic_font auto bold_italic_font auto

View File

@ -0,0 +1,4 @@
git:
paging:
colorArg: always
pager: delta --dark --paging=never

View File

@ -1,10 +1,16 @@
lastupdatecheck: 0 lastupdatecheck: 0
recentrepos: recentrepos:
- /home/goodhumored/lazygit/lazygit - /home/goodhumored/side-hustle/lambo/er_lamborgini
- /home/goodhumored/side-hustle/alexflora/frontend
- /home/goodhumored/lazygit/lazygit
startuppopupversion: 5 startuppopupversion: 5
lastversion: 0.43.1
customcommandshistory: [] customcommandshistory: []
hidecommandlog: false hidecommandlog: false
ignorewhitespaceindiffview: false ignorewhitespaceindiffview: false
diffcontextsize: 3 diffcontextsize: 3
renamesimilaritythreshold: 50
localbranchsortorder: recency localbranchsortorder: recency
remotebranchsortorder: alphabetical remotebranchsortorder: alphabetical
gitlogorder: topo-order
gitlogshowgraph: always

View File

@ -0,0 +1,6 @@
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.ts",
callback = function()
vim.cmd("OrganizeImports")
end,
})

View File

@ -1,9 +1,21 @@
-- ───────────────────── disable highlight on search ─────────────────────
vim.keymap.set({ "n", "i" }, "<C-H>", "<C-W>", { noremap = true, desc = "Delete word" })
-- ───────────────────── disable highlight on search ───────────────────── -- ───────────────────── disable highlight on search ─────────────────────
vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>") vim.keymap.set("n", "<Esc>", "<cmd>nohlsearch<CR>")
-- ────────────────────────── insert timestamp ───────────────────────
vim.api.nvim_set_keymap("i", "<F3>", '<C-R>=strftime("%Y-%m-%dT%H:%M:%S.000Z")<CR>', { noremap = true, silent = true })
-- ─────────────────────────── ctrl+left/right ───────────────────────────
vim.api.nvim_set_keymap("i", "<C-Left>", "<C-o>b", { noremap = true, silent = true })
vim.api.nvim_set_keymap("i", "<C-Right>", "<C-o>w", { noremap = true, silent = true })
-- ───────────────────────── Diagnostic keymaps ────────────────────── -- ───────────────────────── Diagnostic keymaps ──────────────────────
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" }) vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, { desc = "Open diagnostic [Q]uickfix list" })
-- ─────────────────────── pasting in insert mode ────────────────────
vim.keymap.set("i", "<C-V>", "<C-r>+", { desc = "" })
-- ╭─────────────────────────────────────────────────────────╮ -- ╭─────────────────────────────────────────────────────────╮
-- │ terminal │ -- │ terminal │
-- ╰─────────────────────────────────────────────────────────╯ -- ╰─────────────────────────────────────────────────────────╯

View File

@ -1,5 +1,6 @@
require("goodhumored.common-vim-settings") require("goodhumored.common-vim-settings")
require("goodhumored.common-bindings") require("goodhumored.common-bindings")
require("goodhumored.autocommands")
require("goodhumored.lazy") require("goodhumored.lazy")
-- The line beneath this is called `modeline`. See `:help modeline` -- The line beneath this is called `modeline`. See `:help modeline`
-- vim: ts=2 sts=2 sw=2 et -- vim: ts=2 sts=2 sw=2 et

View File

@ -0,0 +1,13 @@
return {
"3rd/diagram.nvim",
dependencies = {
"3rd/image.nvim",
},
opts = { -- you can just pass {}, defaults below
renderer_options = {
plantuml = {
charset = "utf-8",
},
},
},
}

View File

@ -0,0 +1,32 @@
return {
"ellisonleao/gruvbox.nvim",
priority = 1000,
init = function()
require("gruvbox").setup({
terminal_colors = true, -- add neovim terminal colors
undercurl = true,
underline = true,
bold = true,
italic = {
strings = true,
emphasis = true,
comments = true,
operators = false,
folds = true,
},
strikethrough = true,
invert_selection = false,
invert_signs = false,
invert_tabline = false,
invert_intend_guides = false,
inverse = true, -- invert background for search, diffs, statuslines and errors
contrast = "soft", -- can be "hard", "soft" or empty string
palette_overrides = {},
overrides = {},
dim_inactive = false,
transparent_mode = false,
})
vim.o.background = "dark"
vim.cmd("colorscheme gruvbox")
end,
}

View File

@ -9,6 +9,7 @@ return {
-- default config -- default config
image.setup({ image.setup({
backend = "kitty", backend = "kitty",
kitty_method = "normal",
integrations = { integrations = {
markdown = { markdown = {
enabled = true, enabled = true,

View File

@ -4,33 +4,5 @@ return {
dependencies = { "neovim/nvim-lspconfig" }, dependencies = { "neovim/nvim-lspconfig" },
config = function() config = function()
require("inlay-hints").setup() require("inlay-hints").setup()
require("lspconfig").tsserver.setup({
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = true,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayVariableTypeHintsWhenTypeMatchesName = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = true,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayVariableTypeHintsWhenTypeMatchesName = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
})
end, end,
} }

View File

@ -0,0 +1,107 @@
local leet_arg = "leetcode.nvim"
return {
"kawre/leetcode.nvim",
build = ":TSUpdate html",
dependencies = {
"nvim-telescope/telescope.nvim",
"nvim-lua/plenary.nvim", -- required by telescope
"MunifTanjim/nui.nvim",
-- optional
"nvim-treesitter/nvim-treesitter",
"rcarriga/nvim-notify",
"nvim-tree/nvim-web-devicons",
},
cmd = "Leet",
lazy = leet_arg ~= vim.fn.argv()[1],
opts = {
---@type string
arg = leet_arg,
---@type lc.lang
lang = "golang",
cn = { -- leetcode.cn
enabled = false, ---@type boolean
translator = true, ---@type boolean
translate_problems = true, ---@type boolean
},
---@type lc.storage
storage = {
home = vim.fn.stdpath("data") .. "/leetcode",
cache = vim.fn.stdpath("cache") .. "/leetcode",
},
---@type table<string, boolean>
plugins = {
non_standalone = false,
},
---@type boolean
logging = true,
injector = {}, ---@type table<lc.lang, lc.inject>
cache = {
update_interval = 60 * 60 * 24 * 7, ---@type integer 7 days
},
console = {
open_on_runcode = true, ---@type boolean
dir = "row", ---@type lc.direction
size = { ---@type lc.size
width = "90%",
height = "75%",
},
result = {
size = "60%", ---@type lc.size
},
testcase = {
virt_text = true, ---@type boolean
size = "40%", ---@type lc.size
},
},
description = {
position = "left", ---@type lc.position
width = "40%", ---@type lc.size
show_stats = true, ---@type boolean
},
hooks = {
---@type fun()[]
["enter"] = {},
---@type fun(question: lc.ui.Question)[]
["question_enter"] = {},
---@type fun()[]
["leave"] = {},
},
keys = {
toggle = { "q" }, ---@type string|string[]
confirm = { "<CR>" }, ---@type string|string[]
reset_testcases = "r", ---@type string
use_testcase = "U", ---@type string
focus_testcases = "H", ---@type string
focus_result = "L", ---@type string
},
---@type lc.highlights
theme = {},
---@type boolean
image_support = false,
},
}

View File

@ -142,7 +142,36 @@ return { -- LSP Configuration & Plugins
-- https://github.com/pmizio/typescript-tools.nvim -- https://github.com/pmizio/typescript-tools.nvim
-- --
-- But for many setups, the LSP (`tsserver`) will work just fine -- But for many setups, the LSP (`tsserver`) will work just fine
tsserver = { ts_ls = {
init_options = {
preferences = {
importModuleSpecifierPreference = "relative",
},
},
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = true,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayVariableTypeHintsWhenTypeMatchesName = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
javascript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = true,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayVariableTypeHintsWhenTypeMatchesName = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
commands = { commands = {
OrganizeImports = { OrganizeImports = {
function() function()
@ -209,7 +238,6 @@ return { -- LSP Configuration & Plugins
settings = { settings = {
gopls = { gopls = {
gofumpt = true, gofumpt = true,
golines = true,
}, },
}, },
}) })

View File

@ -0,0 +1,35 @@
return {
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
config = function()
require("lualine").setup({
options = {
theme = "iceberg_dark",
component_separators = "",
section_separators = { left = "", right = "" },
},
sections = {
lualine_a = { { "mode", separator = { left = "" }, right_padding = 2 } },
lualine_b = { "filename", "branch" },
lualine_c = {
"%=", --[[ add your center compoentnts here in place of this comment ]]
},
lualine_x = {},
lualine_y = { "filetype", "progress" },
lualine_z = {
{ "location", separator = { right = "" }, left_padding = 2 },
},
},
inactive_sections = {
lualine_a = { "filename" },
lualine_b = {},
lualine_c = {},
lualine_x = {},
lualine_y = {},
lualine_z = { "location" },
},
tabline = {},
extensions = {},
})
end,
}

View File

@ -0,0 +1,12 @@
return { -- Collection of various small independent plugins/modules
"echasnovski/mini.nvim",
config = function()
-- Better Around/Inside textobjects
--
-- Examples:
-- - va) - [V]isually select [A]round [)]paren
-- - yinq - [Y]ank [I]nside [N]ext [Q]uote
-- - ci' - [C]hange [I]nside [']quote
require("mini.ai").setup({ n_lines = 500 })
end,
}

View File

@ -3,37 +3,47 @@ return {
lazy = false, lazy = false,
version = "*", version = "*",
config = function() config = function()
require("neorg").setup({ local neorg = require("neorg")
neorg.setup({
load = { load = {
["core.defaults"] = {}, ["core.defaults"] = {},
["core.concealer"] = {}, ["core.concealer"] = {},
["core.integrations.image"] = {},
["core.latex.renderer"] = {},
["core.export"] = {
config = { -- Note that this table is optional and doesn't need to be provided
-- Configuration here
},
},
["core.dirman"] = { ["core.dirman"] = {
config = { config = {
workspaces = { workspaces = {
notes = "~/notes", notes = "~/notes",
uni = "~/Uni", uni = "~/Uni",
job = "~/job", dipal = "~/Job/dipal/notes",
side = "~/side-hustle", side = "~/side-hustle/notes",
}, },
default_workspace = "notes", default_workspace = "notes",
open_last_workspace = true,
},
},
["core.qol.toc"] = {
config = {
close_split_on_jump = true,
}, },
}, },
}, },
}) })
neorg.modules.get_module("core.dirman").set_closest_workspace_match()
vim.wo.foldlevel = 99 vim.wo.foldlevel = 99
vim.wo.conceallevel = 2 vim.wo.conceallevel = 2
end, end,
keys = { keys = {
{
"<leader>n",
":Neorg<CR>",
desc = "[N]eorg",
},
{ {
"<leader>nw", "<leader>nw",
":Neorg workspace<CR>", ":Neorg workspace ",
desc = "[N]eorg [W]orkspaces", desc = "[N]eorg [W]orkspaces",
}, },
{ {
@ -46,5 +56,20 @@ return {
":Neorg index<CR>", ":Neorg index<CR>",
desc = "[N]eorg [I]ndex", desc = "[N]eorg [I]ndex",
}, },
{
"<leader>nT",
":Neorg toc qflist<CR>",
desc = "[N]eorg [T]able of contents",
},
{
"<leader>nr",
":Neorg return<CR>",
desc = "[N]eorg [R]eturn",
},
{
"<leader>tl",
":Neorg render-latex<CR>",
desc = "[N]eorg [L]atex",
},
}, },
} }

View File

@ -85,9 +85,9 @@ return {
filter_dir = function(name, rel_path, root) filter_dir = function(name, rel_path, root)
return name ~= "node_modules" or name ~= "dist" return name ~= "node_modules" or name ~= "dist"
end, end,
-- is_test_file = function(file_path) is_test_file = function(file_path)
-- return file_path:match(".*%.spec%.ts") ~= nil return file_path:match(".*%.spec%.ts") ~= nil
-- end, end,
}), }),
}, },
}) })

View File

@ -0,0 +1,49 @@
return {
"nyngwang/NeoZoom.lua",
config = function()
require("neo-zoom").setup({
popup = { enabled = true }, -- this is the default.
-- NOTE: Add popup-effect (replace the window on-zoom with a `[No Name]`).
-- EXPLAIN: This improves the performance, and you won't see two
-- identical buffers got updated at the same time.
-- popup = {
-- enabled = true,
-- exclude_filetypes = {},
-- exclude_buftypes = {},
-- },
exclude_buftypes = { "terminal" },
-- exclude_filetypes = { 'lspinfo', 'mason', 'lazy', 'fzf', 'qf' },
winopts = {
offset = {
-- NOTE: omit `top`/`left` to center the floating window vertically/horizontally.
-- top = 0,
-- left = 0.17,
width = 150,
height = 0.85,
},
-- NOTE: check :help nvim_open_win() for possible border values.
border = "thicc", -- this is a preset, try it :)
},
presets = {
{
-- NOTE: regex pattern can be used here!
filetypes = { "dapui_.*", "dap-repl" },
winopts = {
offset = { top = 0.02, left = 0.26, width = 0.74, height = 0.25 },
},
},
{
filetypes = { "markdown" },
callbacks = {
function()
vim.wo.wrap = true
end,
},
},
},
})
vim.keymap.set("n", "<CR>", function()
vim.cmd("NeoZoomToggle")
end, { silent = true, nowait = true })
end,
}

View File

@ -0,0 +1,15 @@
return {
"folke/noice.nvim",
event = "VeryLazy",
opts = {
-- add any options here
},
dependencies = {
-- if you lazy-load any plugin below, make sure to add proper `module="..."` entries
"MunifTanjim/nui.nvim",
-- OPTIONAL:
-- `nvim-notify` is only needed, if you want to use the notification view.
-- If not available, we use `mini` as the fallback
"rcarriga/nvim-notify",
},
}

View File

@ -0,0 +1,18 @@
return {
"kylechui/nvim-surround",
version = "*", -- Use for stability; omit to use `main` branch for the latest features
event = "VeryLazy",
config = function()
local surround = require("nvim-surround")
surround.setup({
aliases = {
["a"] = ">",
["b"] = ")",
["B"] = "}",
["r"] = "]",
["q"] = { '"', "'", "`" },
["s"] = { "}", "]", ")", ">", '"', "'", "`" },
},
})
end,
}

View File

@ -0,0 +1,7 @@
return {
"https://gitlab.com/itaranto/plantuml.nvim",
version = "*",
config = function()
require("plantuml").setup()
end,
}

View File

@ -0,0 +1,53 @@
{
"private readonly ...": {
"scope": "typescript",
"prefix": "prr",
"body": [
"private readonly _${1:name}: ${2:Type}"
]
},
"props": {
"scope": "typescriptreact",
"prefix": "props",
"body": [
"{ className }: { className?: string }"
]
},
"prop": {
"scope": "typescript",
"prefix": "prop",
"body": [
"private _${1:name}: ${3:Type}",
"get${2:Name}(): ${3:Type} {",
" return this._${1:name}",
"}",
"set${2:Name}(${1:name}: ${3:Type}) {",
" this._${1:name} = ${1:name}",
"}"
]
},
"roprop": {
"scope": "typescript",
"prefix": "ro",
"body": [
"private readonly _${1:name}: ${3:Type};",
"get${2:Name}(): ${3:Type} {",
" return this._${1:name}",
"}"
]
},
"vs": {
"scope": "typescript",
"prefix": "vs",
"body": [
"vi.spyOn(${1:class}, \"${2:method}\")${3:.mock$4};"
]
},
"faker lorem word": {
"scope": "typescript",
"prefix": "flw",
"body": [
"faker.lorem.word();"
]
}
}

View File

@ -7,7 +7,354 @@ return {
config = function() config = function()
-- load snippets from path/of/your/nvim/config/my-cool-snippets -- load snippets from path/of/your/nvim/config/my-cool-snippets
require("luasnip.loaders.from_vscode").lazy_load({ require("luasnip.loaders.from_vscode").lazy_load({
paths = { "~/.config/Code/User/snippets/typescript.code-snippets" }, paths = {
-- "~/.config/Code/User/snippets/typescript.code-snippets",
-- "~/.config/nvim/lua/goodhumored/plugins/snippets/code-snippets",
"./code-snippets",
},
})
require("luasnip.loaders.from_snipmate").lazy_load()
local ls = require("luasnip")
local s = ls.snippet
local sn = ls.snippet_node
local t = ls.text_node
local i = ls.insert_node
local f = ls.function_node
local c = ls.choice_node
local d = ls.dynamic_node
local r = ls.restore_node
local l = require("luasnip.extras").lambda
local rep = require("luasnip.extras").rep
local p = require("luasnip.extras").partial
local m = require("luasnip.extras").match
local n = require("luasnip.extras").nonempty
local dl = require("luasnip.extras").dynamic_lambda
local fmt = require("luasnip.extras.fmt").fmt
local fmta = require("luasnip.extras.fmt").fmta
local types = require("luasnip.util.types")
local conds = require("luasnip.extras.conditions")
local conds_expand = require("luasnip.extras.conditions.expand")
local function copy(args)
return args[1]
end
-- Make sure to not pass an invalid command, as io.popen() may write over nvim-text.
local function bash(_, _, command)
local file = io.popen(command, "r")
local res = {}
for line in file:lines() do
table.insert(res, line)
end
return res
end
-- Returns a snippet_node wrapped around an insertNode whose initial
-- text value is set to the current date in the desired format.
local date_input = function(args, snip, old_state, fmt)
local fmt = fmt or "%Y-%m-%d"
return sn(nil, i(1, os.date(fmt)))
end
local ts_snippets = {
s("prr", {
t("private readonly _"),
i(1, "field"),
t(";"),
}),
s("prr", {
t("private readonly _"),
i(1, "field"),
t(";"),
}),
}
local react_snippets = {
s("comp", {
t({
'import React from "react";',
"",
"export default function ",
}),
i(1),
t({ "({className}: {className?: string}) {", "\treturn (", "\t\t<" }),
i(2, "div"),
t({ " className={`${className}`}>", "\t\t\t" }),
i(3),
t({ "", "\t\t</" }),
f(copy, 2),
t({ ">", "\t)", "}" }),
}),
}
ls.add_snippets("typescript", ts_snippets)
ls.add_snippets("typescriptreact", react_snippets)
ls.add_snippets("all", {
-- trigger is `fn`, second argument to snippet-constructor are the nodes to insert into the buffer on expansion.
s("fn", {
-- Simple static text.
t("//Parameters: "),
-- function, first parameter is the function, second the Placeholders
-- whose text it gets as input.
f(copy, 2),
t({ "", "function " }),
-- Placeholder/Insert.
i(1),
t("("),
-- Placeholder with initial text.
i(2, "int foo"),
-- Linebreak
t({ ") {", "\t" }),
-- Last Placeholder, exit Point of the snippet.
i(0),
t({ "", "}" }),
}),
s("class", {
-- Choice: Switch between two different Nodes, first parameter is its position, second a list of nodes.
c(1, {
t("public "),
t("private "),
}),
t("class "),
i(2),
t(" "),
c(3, {
t("{"),
-- sn: Nested Snippet. Instead of a trigger, it has a position, just like insertNodes. !!! These don't expect a 0-node!!!!
-- Inside Choices, Nodes don't need a position as the choice node is the one being jumped to.
sn(nil, {
t("extends "),
-- restoreNode: stores and restores nodes.
-- pass position, store-key and nodes.
r(1, "other_class", i(1)),
t(" {"),
}),
sn(nil, {
t("implements "),
-- no need to define the nodes for a given key a second time.
r(1, "other_class"),
t(" {"),
}),
}),
t({ "", "\t" }),
i(0),
t({ "", "}" }),
}),
-- Alternative printf-like notation for defining snippets. It uses format
-- string with placeholders similar to the ones used with Python's .format().
s(
"fmt1",
fmt("To {title} {} {}.", {
i(2, "Name"),
i(3, "Surname"),
title = c(1, { t("Mr."), t("Ms.") }),
})
),
-- To escape delimiters use double them, e.g. `{}` -> `{{}}`.
-- Multi-line format strings by default have empty first/last line removed.
-- Indent common to all lines is also removed. Use the third `opts` argument
-- to control this behaviour.
s(
"fmt2",
fmt(
[[
foo({1}, {3}) {{
return {2} * {4}
}}
]],
{
i(1, "x"),
rep(1),
i(2, "y"),
rep(2),
}
)
),
-- Empty placeholders are numbered automatically starting from 1 or the last
-- value of a numbered placeholder. Named placeholders do not affect numbering.
s(
"fmt3",
fmt("{} {a} {} {1} {}", {
t("1"),
t("2"),
a = t("A"),
})
),
-- The delimiters can be changed from the default `{}` to something else.
s("fmt4", fmt("foo() { return []; }", i(1, "x"), { delimiters = "[]" })),
-- `fmta` is a convenient wrapper that uses `<>` instead of `{}`.
s("fmt5", fmta("foo() { return <>; }", i(1, "x"))),
-- By default all args must be used. Use strict=false to disable the check
s("fmt6", fmt("use {} only", { t("this"), t("not this") }, { strict = false })),
-- Use a dynamicNode to interpolate the output of a
-- function (see date_input above) into the initial
-- value of an insertNode.
s("novel", {
t("It was a dark and stormy night on "),
d(1, date_input, {}, { user_args = { "%A, %B %d of %Y" } }),
t(" and the clocks were striking thirteen."),
}),
-- Parsing snippets: First parameter: Snippet-Trigger, Second: Snippet body.
-- Placeholders are parsed into choices with 1. the placeholder text(as a snippet) and 2. an empty string.
-- This means they are not SELECTed like in other editors/Snippet engines.
ls.parser.parse_snippet("lspsyn", "Wow! This ${1:Stuff} really ${2:works. ${3:Well, a bit.}}"),
-- When wordTrig is set to false, snippets may also expand inside other words.
ls.parser.parse_snippet({ trig = "te", wordTrig = false }, "${1:cond} ? ${2:true} : ${3:false}"),
-- When regTrig is set, trig is treated like a pattern, this snippet will expand after any number.
ls.parser.parse_snippet({ trig = "%d", regTrig = true }, "A Number!!"),
-- Using the condition, it's possible to allow expansion only in specific cases.
s("cond", {
t("will only expand in c-style comments"),
}, {
condition = function(line_to_cursor, matched_trigger, captures)
-- optional whitespace followed by //
return line_to_cursor:match("%s*//")
end,
}),
-- there's some built-in conditions in "luasnip.extras.conditions.expand" and "luasnip.extras.conditions.show".
s("cond2", {
t("will only expand at the beginning of the line"),
}, {
condition = conds_expand.line_begin,
}),
s("cond3", {
t("will only expand at the end of the line"),
}, {
condition = conds_expand.line_end,
}),
-- on conditions some logic operators are defined
s("cond4", {
t("will only expand at the end and the start of the line"),
}, {
-- last function is just an example how to make own function objects and apply operators on them
condition = conds_expand.line_end + conds_expand.line_begin * conds.make_condition(function()
return true
end),
}),
-- The last entry of args passed to the user-function is the surrounding snippet.
s(
{ trig = "a%d", regTrig = true },
f(function(_, snip)
return "Triggered with " .. snip.trigger .. "."
end, {})
),
-- It's possible to use capture-groups inside regex-triggers.
s(
{ trig = "b(%d)", regTrig = true },
f(function(_, snip)
return "Captured Text: " .. snip.captures[1] .. "."
end, {})
),
s({ trig = "c(%d+)", regTrig = true }, {
t("will only expand for even numbers"),
}, {
condition = function(line_to_cursor, matched_trigger, captures)
return tonumber(captures[1]) % 2 == 0
end,
}),
-- Use a function to execute any shell command and print its text.
s("bash", f(bash, {}, { user_args = { "ls" } })),
-- Short version for applying String transformations using function nodes.
s("transform", {
i(1, "initial text"),
t({ "", "" }),
-- lambda nodes accept an l._1,2,3,4,5, which in turn accept any string transformations.
-- This list will be applied in order to the first node given in the second argument.
l(l._1:match("[^i]*$"):gsub("i", "o"):gsub(" ", "_"):upper(), 1),
}),
s("transform2", {
i(1, "initial text"),
t("::"),
i(2, "replacement for e"),
t({ "", "" }),
-- Lambdas can also apply transforms USING the text of other nodes:
l(l._1:gsub("e", l._2), { 1, 2 }),
}),
s({ trig = "trafo(%d+)", regTrig = true }, {
-- env-variables and captures can also be used:
l(l.CAPTURE1:gsub("1", l.TM_FILENAME), {}),
}),
-- Set store_selection_keys = "<Tab>" (for example) in your
-- luasnip.config.setup() call to populate
-- TM_SELECTED_TEXT/SELECT_RAW/SELECT_DEDENT.
-- In this case: select a URL, hit Tab, then expand this snippet.
s("link_url", {
t('<a href="'),
f(function(_, snip)
-- TM_SELECTED_TEXT is a table to account for multiline-selections.
-- In this case only the first line is inserted.
return snip.env.TM_SELECTED_TEXT[1] or {}
end, {}),
t('">'),
i(1),
t("</a>"),
i(0),
}),
-- Shorthand for repeating the text in a given node.
s("repeat", { i(1, "text"), t({ "", "" }), rep(1) }),
-- Directly insert the ouput from a function evaluated at runtime.
s("part", p(os.date, "%Y")),
-- use matchNodes (`m(argnode, condition, then, else)`) to insert text
-- based on a pattern/function/lambda-evaluation.
-- It's basically a shortcut for simple functionNodes:
s("mat", {
i(1, { "sample_text" }),
t(": "),
m(1, "%d", "contains a number", "no number :("),
}),
-- The `then`-text defaults to the first capture group/the entire
-- match if there are none.
s("mat2", {
i(1, { "sample_text" }),
t(": "),
m(1, "[abc][abc][abc]"),
}),
-- It is even possible to apply gsubs' or other transformations
-- before matching.
s("mat3", {
i(1, { "sample_text" }),
t(": "),
m(1, l._1:gsub("[123]", ""):match("%d"), "contains a number that isn't 1, 2 or 3!"),
}),
-- `match` also accepts a function in place of the condition, which in
-- turn accepts the usual functionNode-args.
-- The condition is considered true if the function returns any
-- non-nil/false-value.
-- If that value is a string, it is used as the `if`-text if no if is explicitly given.
s("mat4", {
i(1, { "sample_text" }),
t(": "),
m(1, function(args)
-- args is a table of multiline-strings (as usual).
return (#args[1][1] % 2 == 0 and args[1]) or nil
end),
}),
-- The nonempty-node inserts text depending on whether the arg-node is
-- empty.
s("nempty", {
i(1, "sample_text"),
n(1, "i(1) is not empty!"),
}),
-- dynamic lambdas work exactly like regular lambdas, except that they
-- don't return a textNode, but a dynamicNode containing one insertNode.
-- This makes it easier to dynamically set preset-text for insertNodes.
s("dl1", {
i(1, "sample_text"),
t({ ":", "" }),
dl(2, l._1, 1),
}),
-- Obviously, it's also possible to apply transformations, just like lambdas.
s("dl2", {
i(1, "sample_text"),
i(2, "sample_text_2"),
t({ "", "" }),
dl(3, l._1:gsub("\n", " linebreak ") .. l._2, { 1, 2 }),
}),
}, {
key = "all",
}) })
end, end,
} }

View File

@ -1,37 +0,0 @@
return { -- Collection of various small independent plugins/modules
"echasnovski/mini.nvim",
config = function()
-- Better Around/Inside textobjects
--
-- Examples:
-- - va) - [V]isually select [A]round [)]paren
-- - yinq - [Y]ank [I]nside [N]ext [Q]uote
-- - ci' - [C]hange [I]nside [']quote
require("mini.ai").setup({ n_lines = 500 })
-- Add/delete/replace surroundings (brackets, quotes, etc.)
--
-- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren
-- - sd' - [S]urround [D]elete [']quotes
-- - sr)' - [S]urround [R]eplace [)] [']
require("mini.surround").setup()
-- Simple and easy statusline.
-- You could remove this setup call if you don't like it,
-- and try some other statusline plugin
local statusline = require("mini.statusline")
-- set use_icons to true if you have a Nerd Font
statusline.setup({ use_icons = vim.g.have_nerd_font })
-- You can configure sections in the statusline by overriding their
-- default behavior. For example, here we set the section for
-- cursor location to LINE:COLUMN
---@diagnostic disable-next-line: duplicate-set-field
statusline.section_location = function()
return "%2l:%-2v"
end
-- ... and there is more!
-- Check out: https://github.com/echasnovski/mini.nvim
end,
}

View File

@ -0,0 +1,32 @@
return {
"ellisonleao/gruvbox.nvim",
priority = 1000,
config = function()
require("gruvbox").setup({
terminal_colors = true, -- add neovim terminal colors
undercurl = true,
underline = true,
bold = true,
italic = {
strings = true,
emphasis = true,
comments = true,
operators = false,
folds = true,
},
strikethrough = true,
invert_selection = false,
invert_signs = false,
invert_tabline = false,
invert_intend_guides = false,
inverse = true, -- invert background for search, diffs, statuslines and errors
contrast = "", -- can be "hard", "soft" or empty string
palette_overrides = {},
overrides = {},
dim_inactive = false,
transparent_mode = false,
})
vim.o.background = "dark"
vim.cmd("colorscheme gruvbox")
end,
}

View File

@ -6,7 +6,55 @@ return {
"nvim-tree/nvim-web-devicons", "nvim-tree/nvim-web-devicons",
}, },
config = function() config = function()
require("nvim-tree").setup({}) local api = require("nvim-tree.api")
local function edit_or_open()
local node = api.tree.get_node_under_cursor()
if node.nodes ~= nil then
-- expand or collapse folder
api.node.open.edit()
else
-- open file
api.node.open.edit()
-- Close the tree if file was opened
api.tree.close()
end
end
-- open as vsplit on current node
local function vsplit_preview()
local node = api.tree.get_node_under_cursor()
if node.nodes ~= nil then
-- expand or collapse folder
api.node.open.edit()
else
-- open file as vsplit
api.node.open.vertical()
end
-- Finally refocus on tree if it was lost
api.tree.focus()
end
local function collapse_folder()
local node = api.tree.get_node_under_cursor()
api.node.navigate.parent(node)
api.node.open.edit(node.parent)
end
require("nvim-tree").setup({
on_attach = function(bufnr)
local function opts(desc)
return { desc = "nvim-tree: " .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true }
end
-- default mappings
api.config.mappings.default_on_attach(bufnr)
vim.keymap.set("n", "l", edit_or_open, opts("Edit Or Open"))
vim.keymap.set("n", "L", vsplit_preview, opts("Vsplit Preview"))
vim.keymap.set("n", "h", collapse_folder, opts("Close"))
vim.keymap.set("n", "H", api.tree.collapse_all, opts("Collapse All"))
end,
})
local api = require("nvim-tree.api") local api = require("nvim-tree.api")
vim.keymap.set("n", "<leader>e", api.tree.toggle, { desc = "[E]xplorer" }) vim.keymap.set("n", "<leader>e", api.tree.toggle, { desc = "[E]xplorer" })
vim.keymap.set("n", "<leader>E", function() vim.keymap.set("n", "<leader>E", function()

View File

@ -0,0 +1,87 @@
return -- Lua
{
"folke/zen-mode.nvim",
opts = {
window = {
backdrop = 0.95, -- shade the backdrop of the Zen window. Set to 1 to keep the same as Normal
-- height and width can be:
-- * an absolute number of cells when > 1
-- * a percentage of the width / height of the editor when <= 1
-- * a function that returns the width or the height
width = 120, -- width of the Zen window
height = 1, -- height of the Zen window
-- by default, no options are changed for the Zen window
-- uncomment any of the options below, or add other vim.wo options you want to apply
options = {
-- signcolumn = "no", -- disable signcolumn
-- number = false, -- disable number column
-- relativenumber = false, -- disable relative numbers
-- cursorline = false, -- disable cursorline
-- cursorcolumn = false, -- disable cursor column
-- foldcolumn = "0", -- disable fold column
-- list = false, -- disable whitespace characters
},
},
plugins = {
-- disable some global vim options (vim.o...)
-- comment the lines to not apply the options
options = {
enabled = true,
ruler = false, -- disables the ruler text in the cmd line area
showcmd = false, -- disables the command in the last line of the screen
-- you may turn on/off statusline in zen mode by setting 'laststatus'
-- statusline will be shown only if 'laststatus' == 3
laststatus = 0, -- turn off the statusline in zen mode
},
twilight = { enabled = true }, -- enable to start Twilight when zen mode opens
gitsigns = { enabled = false }, -- disables git signs
tmux = { enabled = true }, -- disables the tmux statusline
todo = { enabled = false }, -- if set to "true", todo-comments.nvim highlights will be disabled
-- this will change the font size on kitty when in zen mode
-- to make this work, you need to set the following kitty options:
-- - allow_remote_control socket-only
-- - listen_on unix:/tmp/kitty
kitty = {
enabled = false,
font = "+8", -- font size increment
},
-- this will change the font size on alacritty when in zen mode
-- requires Alacritty Version 0.10.0 or higher
-- uses `alacritty msg` subcommand to change font size
alacritty = {
enabled = false,
font = "18", -- font size
},
-- this will change the font size on wezterm when in zen mode
-- See alse also the Plugins/Wezterm section in this projects README
wezterm = {
enabled = false,
-- can be either an absolute font size or the number of incremental steps
font = "+4", -- (10% increase per step)
},
-- this will change the scale factor in Neovide when in zen mode
-- See alse also the Plugins/Wezterm section in this projects README
neovide = {
enabled = false,
-- Will multiply the current scale factor by this number
scale = 1.2,
-- disable the Neovide animations while in Zen mode
disable_animations = {
neovide_animation_length = 0,
neovide_cursor_animate_command_line = false,
neovide_scroll_animation_length = 0,
neovide_position_animation_length = 0,
neovide_cursor_animation_length = 0,
neovide_cursor_vfx_mode = "",
},
},
},
-- callback where you can add custom code when the Zen window opens
on_open = function(win) end,
-- callback where you can add custom code when the Zen window closes
on_close = function() end,
},
keys = {
{ "<leader>tz", ":ZenMode<CR>", desc = "[T]oggle [Z]en" },
},
}

View File

@ -0,0 +1,6 @@
# comment
# snippet <trigger> <description>
# <snippet-body>
snippet if C-style if
if ($1)
$0

View File

@ -0,0 +1,6 @@
# comment
# snippet <trigger> <description>
# <snippet-body>
snippet if C-style if
if ($1)
$0

View File

@ -1,7 +1,7 @@
title=$(playerctl metadata --format '{{markup_escape(artist)}} - {{markup_escape(title)}}') title=$(playerctl --player=$(cat ~/.config/chosen_player) metadata --format '{{markup_escape(artist)}} - {{markup_escape(title)}}')
position=$(playerctl metadata --format '{{position}}') position=$(playerctl --player=$(cat ~/.config/chosen_player) metadata --format '{{position}}')
length=$(playerctl metadata --format '{{mpris:length}}') length=$(playerctl --player=$(cat ~/.config/chosen_player) metadata --format '{{mpris:length}}')
artUrl=$(playerctl metadata --format "{{mpris:artUrl}}") artUrl=$(playerctl --player=$(cat ~/.config/chosen_player) metadata --format "{{mpris:artUrl}}")
if [[ -n "$artUrl" ]]; then if [[ -n "$artUrl" ]]; then
cover=$(echo "$artUrl" | sed "s/file:\/\///g") cover=$(echo "$artUrl" | sed "s/file:\/\///g")

View File

@ -19,11 +19,24 @@
"*": 5 "*": 5
} }
}, },
// //
// pomodoro // pomodoro
// //
"custom/pomodoro": { "custom/pomodoro": {
"format-icons": ["🕛", "🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚"], "format-icons": [
"🕛",
"🕐",
"🕑",
"🕒",
"🕓",
"🕔",
"🕕",
"🕖",
"🕗",
"🕘",
"🕙",
"🕚"
],
"return-type": "json", "return-type": "json",
"tooltip": true, "tooltip": true,
"format": "{icon} {}", "format": "{icon} {}",
@ -33,9 +46,9 @@
"exec": "~/.config/waybar/custom/pomodoro.sh", "exec": "~/.config/waybar/custom/pomodoro.sh",
"interval": 1 "interval": 1
}, },
// //
// player // player
// //
"group/playerctl": { "group/playerctl": {
"orientation": "inherit", "orientation": "inherit",
"children-class": "playerctl", "children-class": "playerctl",
@ -46,29 +59,26 @@
"custom/playerctl-title" "custom/playerctl-title"
] ]
}, },
"custom/playerctl-title": { "custom/playerctl-title": {
"interval": 2, "interval": 2,
"format": "{}", "format": "{}",
"hide-empty-text": true, "hide-empty-text": true,
"return-type": "json", "return-type": "json",
"exec": "~/.config/waybar/custom/playerctl.sh", "exec": "~/.config/waybar/custom/playerctl.sh",
"on-click": "playerctl play-pause", "on-click": "playerctl --player=$(cat ~/.config/chosen_player) play-pause",
"on-scroll-up": "playerctl position 1+", "on-scroll-up": "playerctl --player=$(cat ~/.config/chosen_player) position 1+",
"on-scroll-down": "playerctl position 1-", "on-scroll-down": "playerctl --player=$(cat ~/.config/chosen_player) position 1-",
}, },
"custom/playerctl-prev": { "custom/playerctl-prev": {
"interval": 1, "interval": 1,
"format": "", "format": "",
"tooltip-format": "previous track", "tooltip-format": "previous track",
"return-type": "json", "return-type": "json",
"exec": "playerctl metadata --format '{\"alt\": \"{{status}}\", \"class\": \"{{status}}\"}}'", "exec": "playerctl --player=$(cat ~/.config/chosen_player) metadata --format '{\"alt\": \"{{status}}\", \"class\": \"{{status}}\"}}'",
"on-click": "playerctl previous", "on-click": "playerctl --player=$(cat ~/.config/chosen_player) previous",
"on-scroll-up": "playerctl position 1+", "on-scroll-up": "playerctl --player=$(cat ~/.config/chosen_player) position 1+",
"on-scroll-down": "playerctl position 1-", "on-scroll-down": "playerctl --player=$(cat ~/.config/chosen_player) position 1-",
}, },
"custom/playerctl-pause-play": { "custom/playerctl-pause-play": {
"interval": 1, "interval": 1,
"format": "{icon}", "format": "{icon}",
@ -78,23 +88,21 @@
"Paused": "" "Paused": ""
}, },
"return-type": "json", "return-type": "json",
"exec": "playerctl metadata --format '{\"alt\": \"{{status}}\", \"class\": \"{{status}}\"}}'", "exec": "playerctl --player=$(cat ~/.config/chosen_player) metadata --format '{\"alt\": \"{{status}}\", \"class\": \"{{status}}\"}}'",
"on-click": "playerctl play-pause", "on-click": "playerctl --player=$(cat ~/.config/chosen_player) play-pause",
"on-scroll-up": "playerctl position 1+", "on-scroll-up": "playerctl --player=$(cat ~/.config/chosen_player) position 1+",
"on-scroll-down": "playerctl position 1-", "on-scroll-down": "playerctl --player=$(cat ~/.config/chosen_player) position 1-",
}, },
"custom/playerctl-next": { "custom/playerctl-next": {
"interval": 1, "interval": 1,
"format": "", "format": "",
"tooltip-format": "next track", "tooltip-format": "next track",
"return-type": "json", "return-type": "json",
"exec": "playerctl metadata --format '{\"alt\": \"{{status}}\", \"class\": \"{{status}}\"}}'", "exec": "playerctl --player=$(cat ~/.config/chosen_player) metadata --format '{\"alt\": \"{{status}}\", \"class\": \"{{status}}\"}}'",
"on-click": "playerctl next", "on-click": "playerctl --player=$(cat ~/.config/chosen_player) next",
"on-scroll-up": "playerctl position 1+", "on-scroll-up": "playerctl --player=$(cat ~/.config/chosen_player) position 1+",
"on-scroll-down": "playerctl position 1-", "on-scroll-down": "playerctl --player=$(cat ~/.config/chosen_player) position 1-",
}, },
// //
// sunset (night light) // sunset (night light)
// //
@ -112,7 +120,6 @@
"exec-if": "/dotfiles/.config/scripts/sunset.sh check", "exec-if": "/dotfiles/.config/scripts/sunset.sh check",
"signal": 6 "signal": 6
}, },
// Taskbar // Taskbar
"wlr/taskbar": { "wlr/taskbar": {
"format": "{icon}", "format": "{icon}",
@ -120,7 +127,10 @@
"tooltip-format": "{title}", "tooltip-format": "{title}",
"on-click": "activate", "on-click": "activate",
"on-click-middle": "close", "on-click-middle": "close",
"ignore-list": ["Alacritty", "kitty"], "ignore-list": [
"Alacritty",
"kitty"
],
"app_ids-mapping": { "app_ids-mapping": {
"firefoxdeveloperedition": "firefox-developer-edition" "firefoxdeveloperedition": "firefox-developer-edition"
}, },
@ -146,7 +156,6 @@
"on-click-right": "hyprctl switchxkblayout at-translated-set-2-keyboard prev", "on-click-right": "hyprctl switchxkblayout at-translated-set-2-keyboard prev",
"interval": 1 "interval": 1
}, },
// Wofi Application Launcher // Wofi Application Launcher
"custom/appmenuicon": { "custom/appmenuicon": {
"format": "", "format": "",
@ -154,38 +163,32 @@
"on-click-right": "~/dotfiles/hypr/scripts/keybindings.sh", "on-click-right": "~/dotfiles/hypr/scripts/keybindings.sh",
"tooltip-format": "Left: Open the application launcher\nRight: Show all keybindings" "tooltip-format": "Left: Open the application launcher\nRight: Show all keybindings"
}, },
// Power Menu // Power Menu
"custom/exit": { "custom/exit": {
"format": "", "format": "",
"on-click": "wlogout", "on-click": "wlogout",
"tooltip-format": "Power Menu" "tooltip-format": "Power Menu"
}, },
// System tray // System tray
"tray": { "tray": {
"icon-size": 21, "icon-size": 21,
"spacing": 10 "spacing": 10
}, },
// Clock // Clock
"clock": { "clock": {
"format": "{:%H:%M:%S\r<small>%d.%m.%Y</small>}", "format": "{:%H:%M:%S\r<small>%d.%m.%Y</small>}",
"interval": 1, "interval": 1,
}, },
// CPU // CPU
"cpu": { "cpu": {
"format": "/ C {usage}% ", "format": "/ C {usage}% ",
"on-click": "~/dotfiles/.settings/systeminfo.sh" "on-click": "~/dotfiles/.settings/systeminfo.sh"
}, },
// Memory // Memory
"memory": { "memory": {
"format": "/ M {}% ", "format": "/ M {}% ",
"on-click": "~/dotfiles/.settings/systeminfo.sh" "on-click": "~/dotfiles/.settings/systeminfo.sh"
}, },
// Harddisc space used // Harddisc space used
"disk": { "disk": {
"interval": 30, "interval": 30,
@ -193,7 +196,6 @@
"path": "/", "path": "/",
"on-click": "~/dotfiles/.settings/systeminfo.sh" "on-click": "~/dotfiles/.settings/systeminfo.sh"
}, },
// Group Hardware // Group Hardware
"group/hardware": { "group/hardware": {
"orientation": "inherit", "orientation": "inherit",
@ -202,9 +204,14 @@
"children-class": "not-memory", "children-class": "not-memory",
"transition-left-to-right": false "transition-left-to-right": false
}, },
"modules": ["custom/system", "disk", "cpu", "memory", "hyprland/language"] "modules": [
"custom/system",
"disk",
"cpu",
"memory",
"hyprland/language"
]
}, },
// Group Tools // Group Tools
"group/tools": { "group/tools": {
"orientation": "inherit", "orientation": "inherit",
@ -220,7 +227,6 @@
"custom/hyprshade" "custom/hyprshade"
] ]
}, },
// Battery // Battery
"battery": { "battery": {
"states": { "states": {
@ -234,9 +240,14 @@
"format-alt": "{icon} {time}", "format-alt": "{icon} {time}",
// "format-good": "", // An empty format will hide the module // "format-good": "", // An empty format will hide the module
// "format-full": "", // "format-full": "",
"format-icons": [" ", " ", " ", " ", " "] "format-icons": [
" ",
" ",
" ",
" ",
" "
]
}, },
// Pulseaudio // Pulseaudio
"pulseaudio": { "pulseaudio": {
// "scroll-step": 1, // %, can be a float // "scroll-step": 1, // %, can be a float
@ -253,11 +264,14 @@
"phone": " ", "phone": " ",
"portable": " ", "portable": " ",
"car": " ", "car": " ",
"default": ["", "", ""] "default": [
"",
"",
""
]
}, },
"on-click": "pavucontrol" "on-click": "pavucontrol"
}, },
// Bluetooth // Bluetooth
"bluetooth": { "bluetooth": {
"format": " {status}", "format": " {status}",

8
.config/yazi/bookmark Normal file
View File

@ -0,0 +1,8 @@
Uni /home/goodhumored/Uni/ u
trash /run/user/1000/kio-fuse-LJbUkF/trash/ t
side-hustle /home/goodhumored/side-hustle/ s
Notes /home/goodhumored/notes/ n
Job /home/goodhumored/Job/ j
halloween /home/goodhumored/side-hustle/memecoins/halloween/ h
Downloads /home/goodhumored/Downloads/ d
dipal /home/goodhumored/Job/dipal/ D

59
.config/yazi/init.lua Normal file
View File

@ -0,0 +1,59 @@
-- You can configure your bookmarks by lua language
local bookmarks = {}
function path(...)
local args = { ... }
local path_sep = package.config:sub(1, 1)
-- Trim leading slashes from the first element
args[1] = args[1]:gsub("^/*", "")
-- Trim trailing slashes from the last element
args[#args] = args[#args]:gsub("/*$", "")
-- Join the arguments with the path separator
return path_sep .. table.concat(args, path_sep)
end
local home_path = os.getenv("HOME")
table.insert(bookmarks, {
tag = "Downloads",
path = path(home_path, "Downloads", ""),
key = "d",
})
table.insert(bookmarks, {
tag = "Notes",
path = path(home_path, "notes", ""),
key = "n",
})
table.insert(bookmarks, {
tag = "Job",
path = path(home_path, "Job", ""),
key = "j",
})
table.insert(bookmarks, {
tag = "Uni",
path = path(home_path, "Uni", ""),
key = "u",
})
table.insert(bookmarks, {
tag = "side-hustle",
path = path(home_path, "side-hustle", ""),
key = "s",
})
table.insert(bookmarks, {
tag = "trash",
path = "/run/user/1000/kio-fuse-LJbUkF/trash/",
key = "t",
})
require("yamb"):setup({
-- Optional, the path ending with path seperator represents folder.
bookmarks = bookmarks,
-- Optional, recieve notification everytime you jump.
jump_notify = true,
-- Optional, the cli of fzf.
cli = "fzf",
-- Optional, a string used for randomly generating keys, where the preceding characters have higher priority.
keys = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
-- Optional, the path of bookmarks
path = (ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark")
or (os.getenv("HOME") .. "/.config/yazi/bookmark"),
})

67
.config/yazi/keymap.toml Normal file
View File

@ -0,0 +1,67 @@
[[manager.prepend_keymap]]
on = [ "<Enter>" ]
run = "enter"
desc = "Enter the child directory"
[[manager.prepend_keymap]]
on = ["<C-o>"]
run = "back"
desc = "Jump back"
[[manager.prepend_keymap]]
on = [ "g", "c" ]
run = "cd ~/dotfiles/"
desc = "Go to the config directory"
# ───────────────────────────── jump to char ─────────────────────────────
[[manager.prepend_keymap]]
on = "f"
run = "plugin jump-to-char"
desc = "Jump to char"
# ─────────────────────────────── Compress ───────────────────────────────
[[manager.prepend_keymap]]
on = ["C"]
run = "plugin ouch --args=zip"
desc = "Compress with ouch"
# ────────────────────────────── bookmarks ────────────────────────────
[[manager.prepend_keymap]]
on = [ "m" ]
run = "plugin yamb --args=save"
desc = "Add bookmark"
[[manager.prepend_keymap]]
on = [ "'" ]
run = "plugin yamb --args=jump_by_key"
desc = "Jump bookmark by key"
[[manager.prepend_keymap]]
on = [ "\"" ]
run = "plugin yamb --args=jump_by_fzf"
desc = "Jump bookmark by fzf"
[[manager.prepend_keymap]]
on = [ "b", "d" ]
run = "plugin yamb --args=delete_by_key"
desc = "Delete bookmark by key"
[[manager.prepend_keymap]]
on = [ "b", "f" ]
run = "plugin yamb --args=delete_by_fzf"
desc = "Delete bookmark by fzf"
[[manager.prepend_keymap]]
on = [ "b", "D" ]
run = "plugin yamb --args=delete_all"
desc = "Delete all bookmarks"
[[manager.prepend_keymap]]
on = [ "b", "r" ]
run = "plugin yamb --args=rename_by_key"
desc = "Rename bookmark by key"
[[manager.prepend_keymap]]
on = [ "b", "R" ]
run = "plugin yamb --args=rename_by_fzf"
desc = "Rename bookmark by fzf"

View File

@ -0,0 +1,5 @@
[plugin]
deps = [{ use = "h-hg/yamb", rev = "0598b8d" }, { use = "dedukun/bookmarks", rev = "600f87c" }, { use = "Reledia/miller", rev = "40e0265" }, { use = "yazi-rs/plugins:jump-to-char", rev = "35100e7" }, { use = "ndtoan96/ouch", rev = "251da69" }]
[flavor]
deps = []

View File

@ -0,0 +1,19 @@
Copyright (c) 2024 dedukun
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.

View File

@ -0,0 +1,132 @@
# bookmarks.yazi
A [Yazi](https://github.com/sxyazi/yazi) plugin that adds the basic functionality of [vi-like marks](https://neovim.io/doc/user/motion.html#mark-motions).
https://github.com/dedukun/bookmarks.yazi/assets/25795432/9a9fe345-dd06-442e-99f1-8475ab22fad5
## Requirements
- [Yazi](https://github.com/sxyazi/yazi) v0.3.0+
## Features
- Create/delete bookmarks
- Custom Notifications
- `''` to go back to the previous folder
- Bookmarks persistence
## Installation
```sh
ya pack -a dedukun/bookmarks
```
## Configuration
Add this to your `keymap.toml`:
```toml
[[manager.prepend_keymap]]
on = [ "m" ]
run = "plugin bookmarks --args=save"
desc = "Save current position as a bookmark"
[[manager.prepend_keymap]]
on = [ "'" ]
run = "plugin bookmarks --args=jump"
desc = "Jump to a bookmark"
[[manager.prepend_keymap]]
on = [ "b", "d" ]
run = "plugin bookmarks --args=delete"
desc = "Delete a bookmark"
[[manager.prepend_keymap]]
on = [ "b", "D" ]
run = "plugin bookmarks --args=delete_all"
desc = "Delete all bookmarks"
```
---
Additionally there are configurations that can be done using the plugin's `setup` function in Yazi's `init.lua`, i.e. `~/.config/yazi/init.lua`.
The following are the default configurations:
```lua
-- ~/.config/yazi/init.lua
require("bookmarks"):setup({
save_last_directory = false, -- DEPRECATED - will be removed in the future. Use `last_directory`
last_directory = { enable = false, persist = false },
persist = "none",
desc_format = "full",
file_pick_mode = "hover",
notify = {
enable = false,
timeout = 1,
message = {
new = "New bookmark '<key>' -> '<folder>'",
delete = "Deleted bookmark in '<key>'",
delete_all = "Deleted all bookmarks",
},
},
})
```
### `save_last_directory`
When enabled, a new bookmark is automatically created in `'` which allows the user to jump back to
the last directory.
***NOTE:*** This option is **DEPRECATED** and will be removed in the future in favor of `last_directory`.
### `last_directory`
When enabled, a new bookmark is automatically created in `'` which allows the user to jump back to
the last directory.
There's also the option to enable persistence to this automatic bookmark.
### `persist`
When enabled the bookmarks will persist, i.e. if you close and reopen Yazi they will still be
present.
There are three possible values for this option:
| Value | Description |
| ------ | -------------------------------------------------------------------------------------------------------------------- |
| `none` | The default value, i.e., no persistance |
| `all` | All the bookmarks are saved in persistent memory |
| `vim` | This mode emulates the vim global marks, i.e., only the bookmarks in upper case (A-Z) are saved to persistent memory |
### `desc_format`
The format for the bookmark description.
There are two possible values for this option:
| Value | Description |
| -------- | ----------------------------------------------------------------------------------------------- |
| `full` | The default, it shows the full path of the bookmark, i.e., the parent folder + the hovered file |
| `parent` | Only shows the parent folder of the bookmark |
### `file_pick_mode`
The mode for choosing which directory to bookmark.
There are two possible values for this option:
| Value | Description |
| -------- | ----------------------------------------------------------------------------------------------- |
| `hover` | The default, it uses the path of the hovered file for new bookmarks |
| `parent` | Uses the path of the parent folder for new bookmarks |
### `notify`
When enabled, notifications will be shown when the user creates a new bookmark and deletes one or
all saved bookmarks.
By default the notification has a 1 second timeout that can be changed with `notify.timeout`.
Furthermore, you can customize the notification messages with `notify.message`.
For the `new` and `delete` messages, the `<key>` and `<folder>` keywords can be used, which will be replaced by the respective new/deleted bookmark's associated key and folder.

View File

@ -0,0 +1,291 @@
-- stylua: ignore
local SUPPORTED_KEYS = {
{ on = "0"}, { on = "1"}, { on = "2"}, { on = "3"}, { on = "4"},
{ on = "5"}, { on = "6"}, { on = "7"}, { on = "8"}, { on = "9"},
{ on = "A"}, { on = "B"}, { on = "C"}, { on = "D"}, { on = "E"},
{ on = "F"}, { on = "G"}, { on = "H"}, { on = "I"}, { on = "J"},
{ on = "K"}, { on = "L"}, { on = "M"}, { on = "N"}, { on = "O"},
{ on = "P"}, { on = "Q"}, { on = "R"}, { on = "S"}, { on = "T"},
{ on = "U"}, { on = "V"}, { on = "W"}, { on = "X"}, { on = "Y"}, { on = "Z"},
{ on = "a"}, { on = "b"}, { on = "c"}, { on = "d"}, { on = "e"},
{ on = "f"}, { on = "g"}, { on = "h"}, { on = "i"}, { on = "j"},
{ on = "k"}, { on = "l"}, { on = "m"}, { on = "n"}, { on = "o"},
{ on = "p"}, { on = "q"}, { on = "r"}, { on = "s"}, { on = "t"},
{ on = "u"}, { on = "v"}, { on = "w"}, { on = "x"}, { on = "y"}, { on = "z"},
}
local _send_notification = ya.sync(
function(state, message)
ya.notify {
title = "Bookmarks",
content = message,
timeout = state.notify.timeout,
}
end
)
local _get_real_index = ya.sync(function(state, idx)
for key, value in pairs(state.bookmarks) do
if value.on == SUPPORTED_KEYS[idx].on then
return key
end
end
return nil
end)
local _get_bookmark_file = ya.sync(function(state)
local folder = cx.active.current
if state.file_pick_mode == "parent" or not folder.hovered then
return { url = folder.cwd, is_parent = true }
end
return { url = folder.hovered.url, is_parent = false }
end)
local _generate_description = ya.sync(function(state, file)
-- if this is true, we don't have information about the folder, so just return the folder url
if file.is_parent then
return tostring(file.url)
end
if state.desc_format == "parent" then
return tostring(file.url:parent())
end
-- full description
return tostring(file.url)
end)
local _load_state = ya.sync(function(state)
ps.sub_remote("@bookmarks", function(body)
if not state.bookmarks and body then
state.bookmarks = {}
for _, value in pairs(body) do
table.insert(state.bookmarks, value)
end
end
end)
end)
local _save_state = ya.sync(function(state, bookmarks)
if not bookmarks then
ps.pub_to(0, "@bookmarks", nil)
return
end
local save_state = {}
if state.persist == "all" then
save_state = bookmarks
else -- VIM mode
local idx = 1
for _, value in pairs(bookmarks) do
-- Only save bookmarks in upper case keys
if string.match(value.on, "%u") then
save_state[idx] = value
idx = idx + 1
end
end
end
ps.pub_to(0, "@bookmarks", save_state)
end)
local _save_last_directory = ya.sync(function(state, persist)
if persist then
ps.sub_remote("@bookmarks-lastdir", function(body) state.curr_dir = body end)
end
ps.sub("cd", function()
local file = _get_bookmark_file()
state.last_dir = state.curr_dir
if persist and state.last_dir then
ps.pub_to(0, "@bookmarks-lastdir", state.last_dir)
end
state.curr_dir = {
on = "'",
desc = _generate_description(file),
path = tostring(file.url),
is_parent = file.is_parent,
}
end)
ps.sub("hover", function()
local file = _get_bookmark_file()
state.curr_dir.desc = _generate_description(file)
state.curr_dir.path = tostring(file.url)
end)
end)
-- ***********************************************
-- **============= C O M M A N D S =============**
-- ***********************************************
local save_bookmark = ya.sync(function(state, idx)
local file = _get_bookmark_file()
state.bookmarks = state.bookmarks or {}
local _idx = _get_real_index(idx)
if not _idx then
_idx = #state.bookmarks + 1
end
state.bookmarks[_idx] = {
on = SUPPORTED_KEYS[idx].on,
desc = _generate_description(file),
path = tostring(file.url),
is_parent = file.is_parent,
}
if state.persist then
_save_state(state.bookmarks)
end
if state.notify and state.notify.enable then
local message = state.notify.message.new
message, _ = message:gsub("<key>", state.bookmarks[_idx].on)
message, _ = message:gsub("<folder>", state.bookmarks[_idx].desc)
_send_notification(message)
end
end)
local all_bookmarks = ya.sync(function(state, append_last_dir)
local bookmarks = {}
if state.bookmarks then
for _, value in pairs(state.bookmarks) do
table.insert(bookmarks, value)
end
end
if append_last_dir and state.last_dir then
table.insert(bookmarks, state.last_dir)
end
return bookmarks
end)
local delete_bookmark = ya.sync(function(state, idx)
if state.notify and state.notify.enable then
local message = state.notify.message.delete
message, _ = message:gsub("<key>", state.bookmarks[idx].on)
message, _ = message:gsub("<folder>", state.bookmarks[idx].desc)
_send_notification(message)
end
table.remove(state.bookmarks, idx)
if state.persist then
_save_state(state.bookmarks)
end
end)
local delete_all_bookmarks = ya.sync(function(state)
state.bookmarks = nil
if state.persist then
_save_state(nil)
end
if state.notify and state.notify.enable then
_send_notification(state.notify.message.delete_all)
end
end)
return {
entry = function(_, args)
local action = args[1]
if not action then
return
end
if action == "save" then
local key = ya.which { cands = SUPPORTED_KEYS, silent = true }
if key then
save_bookmark(key)
end
return
end
if action == "delete_all" then
return delete_all_bookmarks()
end
local bookmarks = all_bookmarks(action == "jump")
local selected = #bookmarks > 0 and ya.which { cands = bookmarks }
if not selected then
return
end
if action == "jump" then
if bookmarks[selected].is_parent then
ya.manager_emit("cd", { bookmarks[selected].path })
else
ya.manager_emit("reveal", { bookmarks[selected].path })
end
elseif action == "delete" then
delete_bookmark(selected)
end
end,
setup = function(state, args)
if not args then
return
end
-- TODO: DEPRECATED
if args.save_last_directory then
_save_last_directory()
elseif type(args.last_directory) == "table" then
if args.last_directory.enable then
_save_last_directory(args.last_directory.persist)
end
end
if args.persist == "all" or args.persist == "vim" then
state.persist = args.persist
_load_state()
end
if args.desc_format == "parent" then
state.desc_format = "parent"
else
state.desc_format = "full"
end
if args.file_pick_mode == "parent" then
state.file_pick_mode = "parent"
else
state.file_pick_mode = "hover"
end
state.notify = {
enable = false,
timeout = 1,
message = {
new = "New bookmark '<key>' -> '<folder>'",
delete = "Deleted bookmark in '<key>'",
delete_all = "Deleted all bookmarks",
},
}
if type(args.notify) == "table" then
if type(args.notify.enable) == "boolean" then
state.notify.enable = args.notify.enable
end
if type(args.notify.timeout) == "number" then
state.notify.timeout = args.notify.timeout
end
if type(args.notify.message) == "table" then
if type(args.notify.message.new) == "string" then
state.notify.message.new = args.notify.message.new
end
if type(args.notify.message.delete) == "string" then
state.notify.message.delete = args.notify.message.delete
end
if type(args.notify.message.delete_all) == "string" then
state.notify.message.delete_all = args.notify.message.delete_all
end
end
end
end,
}

View File

@ -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.

View File

@ -0,0 +1,24 @@
# jump-to-char.yazi
Vim-like `f<char>`, jump to the next file whose name starts with `<char>`.
https://github.com/yazi-rs/plugins/assets/17523360/aac9341c-b416-4e0c-aaba-889d48389869
## Installation
```sh
ya pack -a yazi-rs/plugins:jump-to-char
```
## Usage
Add this to your `~/.config/yazi/keymap.toml`:
```toml
[[manager.prepend_keymap]]
on = "f"
run = "plugin jump-to-char"
desc = "Jump to char"
```
Make sure the <kbd>f</kbd> key is not used elsewhere.

View File

@ -0,0 +1,30 @@
local AVAILABLE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."
local changed = ya.sync(function(st, new)
local b = st.last ~= new
st.last = new
return b or not cx.active.finder
end)
local escape = function(s) return s == "." and "\\." or s end
return {
entry = function()
local cands = {}
for i = 1, #AVAILABLE_CHARS do
cands[#cands + 1] = { on = AVAILABLE_CHARS:sub(i, i) }
end
local idx = ya.which { cands = cands, silent = true }
if not idx then
return
end
local kw = escape(cands[idx].on)
if changed(kw) then
ya.manager_emit("find_do", { "^" .. kw })
else
ya.manager_emit("find_arrow", {})
end
end,
}

View File

@ -0,0 +1,7 @@
Copyright © 2024 Reledia <reledia@prontonmail.com>
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.

View File

@ -0,0 +1,27 @@
# miller.yazi
[Miller](https://github.com/johnkerl/miller) now in [yazi](https://github.com/sxyazi/yazi). To install, use the command `ya pack -a Reledia/miller` and add to your `yazi.toml`:
```toml
[plugin]
prepend_previewers = [
{ mime = "text/csv", run = "miller"},
]
```
## Preview
![preview](https://github.com/Reledia/miller.yazi/blob/main/preview.png?raw=true)
## Color
To change colors of keys and values, edit the `init.lua` file after the `--key-color` and `--value-color` flags. To view a list of possible colors, use `mlr --list-color-names`. Make sure to have miller installed and inside your PATH.
## Other types of file
To adapt this plugin to the other format supported from miller (like json):
- copy the plugin folder
- change the name of the copied folder into miller\_(fmt)
- change the `--icsv` flag inside `init.lua` to `--i(fmt)`
- add the correct mime/name rule into `prepend_previewers` and the exec as `miller_(fmt)`

View File

@ -0,0 +1,59 @@
local M = {}
function M:peek()
local child = Command("mlr")
:args({
"--icsv",
"--opprint",
"-C",
"--key-color",
"darkcyan",
"--value-color",
"grey70",
"cat",
tostring(self.file.url),
})
:stdout(Command.PIPED)
:stderr(Command.PIPED)
:spawn()
local limit = self.area.h
local i, lines = 0, ""
repeat
local next, event = child:read_line()
if event == 1 then
ya.err(tostring(event))
elseif event ~= 0 then
break
end
i = i + 1
if i > self.skip then
lines = lines .. next
end
until i >= self.skip + limit
child:start_kill()
if self.skip > 0 and i < self.skip + limit then
ya.manager_emit(
"peek",
{ tostring(math.max(0, i - limit)), only_if = tostring(self.file.url), upper_bound = "" }
)
else
lines = lines:gsub("\t", string.rep(" ", PREVIEW.tab_size))
ya.preview_widgets(self, { ui.Paragraph.parse(self.area, lines) })
end
end
function M:seek(units)
local h = cx.active.current.hovered
if h and h.url == self.file.url then
local step = math.floor(units * self.area.h / 10)
ya.manager_emit("peek", {
tostring(math.max(0, cx.active.preview.skip + step)),
only_if = tostring(self.file.url),
})
end
end
return M

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 ndtoan96
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.

View File

@ -0,0 +1,67 @@
# ouch.yazi
[ouch](https://github.com/ouch-org/ouch) plugin for [Yazi](https://github.com/sxyazi/yazi).
![ouch.yazi](https://github.com/ndtoan96/ouch.yazi/assets/33489972/946397ec-b37b-4bf4-93f1-c676fc8e59f2)
## Features
- Archive preview
- Compression
## Installation
```bash
# Linux/macOS
git clone https://github.com/ndtoan96/ouch.yazi.git ~/.config/yazi/plugins/ouch.yazi
# Windows
git clone https://github.com/ndtoan96/ouch.yazi.git %AppData%\yazi\config\plugins\ouch.yazi
```
Make sure you have [ouch](https://github.com/ouch-org/ouch) installed and in your `PATH`.
## Usage
### Preview
For archive preview, add this to your `yazi.toml`:
```toml
[plugin]
prepend_previewers = [
# Archive previewer
{ mime = "application/*zip", run = "ouch" },
{ mime = "application/x-tar", run = "ouch" },
{ mime = "application/x-bzip2", run = "ouch" },
{ mime = "application/x-7z-compressed", run = "ouch" },
{ mime = "application/x-rar", run = "ouch" },
{ mime = "application/x-xz", run = "ouch" },
]
```
Now go to an archive on Yazi, you should see the archive's content in the preview pane. You can use `Alt-j` and `Alt-k` to roll up and down the preview.
If you want to change the icon or the style of text, you can modify the `peek` function in `init.lua` file (all of them are stored in the `lines` variable).
### Compression
For compession, add this to your `keymap.toml`:
```toml
[[manager.prepend_keymap]]
on = ["C"]
run = "plugin ouch --args=zip"
desc = "Compress with ouch"
```
The `--args=zip` part tells the plugin that default format is `zip`. You can change that to whatever format you want.
### Decompression
This plugin does not provide a decompression feature because it already is supported by Yazi.
To decompress with `ouch`, configure the opener in `yazi.toml`.
```toml
[opener]
extract = [
{ run = 'ouch d -y "%*"', desc = "Extract here with ouch", for = "windows" },
{ run = 'ouch d -y "$@"', desc = "Extract here with ouch", for = "unix" },
]
```

View File

@ -0,0 +1,143 @@
local M = {}
function M:peek()
local child = Command("ouch")
:args({ "l", "-t", "-y", tostring(self.file.url) })
:stdout(Command.PIPED)
:stderr(Command.PIPED)
:spawn()
local limit = self.area.h
local file_name = string.match(tostring(self.file.url), ".*[/\\](.*)")
local lines = string.format("\x1b[2m📁 %s\x1b[0m\n", file_name)
local num_lines = 1
local num_skip = 0
repeat
local line, event = child:read_line()
if event == 1 then
ya.err(tostring(event))
elseif event ~= 0 then
break
end
if line:find('Archive', 1, true) ~= 1 and line:find('[INFO]', 1, true) ~= 1 then
if num_skip >= self.skip then
lines = lines .. line
num_lines = num_lines + 1
else
num_skip = num_skip + 1
end
end
until num_lines >= limit
child:start_kill()
if self.skip > 0 and num_lines < limit then
ya.manager_emit(
"peek",
{ tostring(math.max(0, self.skip - (limit - num_lines))), only_if = tostring(self.file.url), upper_bound = "" }
)
else
ya.preview_widgets(self, { ui.Paragraph.parse(self.area, lines) })
end
end
function M:seek(units)
local h = cx.active.current.hovered
if h and h.url == self.file.url then
local step = math.floor(units * self.area.h / 10)
ya.manager_emit("peek", {
math.max(0, cx.active.preview.skip + step),
only_if = tostring(self.file.url),
})
end
end
-- Check if file exists
local function file_exists(name)
local f = io.open(name, "r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
-- Get the files that need to be compressed and infer a default archive name
local get_compression_target = ya.sync(function()
local tab = cx.active
local default_name
local paths = {}
if #tab.selected == 0 then
if tab.current.hovered then
local name = tab.current.hovered.name
default_name = name
table.insert(paths, name)
else
return
end
else
default_name = tab.current.cwd:name()
for _, url in pairs(tab.selected) do
table.insert(paths, tostring(url))
end
-- The compression targets are aquired, now unselect them
ya.manager_emit("escape", {})
end
return paths, default_name
end)
local function invoke_compress_command(paths, name)
local cmd_output, err_code = Command("ouch")
:args({ "c", "-y" })
:args(paths)
:arg(name)
:stderr(Command.PIPED)
:output()
if err_code ~= nil then
ya.notify({
title = "Failed to run ouch command",
content = "Status: " .. err_code,
timeout = 5.0,
level = "error",
})
elseif not cmd_output.status.success then
ya.notify({
title = "Compression failed: status code " .. cmd_output.status.code,
content = cmd_output.stderr,
timeout = 5.0,
level = "error",
})
end
end
function M:entry(args)
local default_fmt = args[1]
-- Get the files that need to be compressed and infer a default archive name
local paths, default_name = get_compression_target()
-- Get archive name from user
local output_name, name_event = ya.input({
title = "Create archive:",
value = default_name .. "." .. default_fmt,
position = { "top-center", y = 3, w = 40 },
})
if name_event ~= 1 then
return
end
-- Get confirmation if file exists
if file_exists(output_name) then
local confirm, confirm_event = ya.input({
title = "Overwrite " .. output_name .. "? (y/N)",
position = { "top-center", y = 3, w = 40 },
})
if not (confirm_event == 1 and confirm:lower() == "y") then
return
end
end
invoke_compress_command(paths, output_name)
end
return M

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Hunter Hwang
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.

View File

@ -0,0 +1,112 @@
# Yet another bookmarks
A [Yazi](https://github.com/sxyazi/yazi) plugin for bookmark management, supporting the following features
- Persistent bookmarks. No bookmarks are lost after you close yazi.
- Quickly jump, delete, and rename a bookmark by keymap.
- Support fuzzy search through [fzf](https://github.com/junegunn/fzf).
- Configure your bookmarks using Lua language.
## Installation
> [!NOTE]
> Yazi >= 0.25.
```sh
# Linux/macOS
git clone https://github.com/h-hg/yamb.yazi.git ~/.config/yazi/plugins/yamb.yazi
# Windows
git clone https://github.com/h-hg/yamb.yazi.git $env:APPDATA\yazi\config\plugins\yamb.yazi
# if you are using Yazi version >= 3.0
ya pack -a h-hg/yamb
```
## Usage
Add this to your `init.lua`
```lua
-- You can configure your bookmarks by lua language
local bookmarks = {}
local path_sep = package.config:sub(1, 1)
local home_path = ya.target_family() == "windows" and os.getenv("USERPROFILE") or os.getenv("HOME")
if ya.target_family() == "windows" then
table.insert(bookmarks, {
tag = "Scoop Local",
path = (os.getenv("SCOOP") or home_path .. "\\scoop") .. "\\",
key = "p"
})
table.insert(bookmarks, {
tag = "Scoop Global",
path = (os.getenv("SCOOP_GLOBAL") or "C:\\ProgramData\\scoop") .. "\\",
key = "P"
})
end
table.insert(bookmarks, {
tag = "Desktop",
path = home_path .. path_sep .. "Desktop" .. path_sep,
key = "d"
})
require("yamb"):setup {
-- Optional, the path ending with path seperator represents folder.
bookmarks = bookmarks,
-- Optional, recieve notification everytime you jump.
jump_notify = true,
-- Optional, the cli of fzf.
cli = "fzf",
-- Optional, a string used for randomly generating keys, where the preceding characters have higher priority.
keys = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
-- Optional, the path of bookmarks
path = (ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark") or
(os.getenv("HOME") .. "/.config/yazi/bookmark"),
}
```
Add this to your `keymap.toml`:
```toml
[[manager.prepend_keymap]]
on = [ "u", "a" ]
run = "plugin yamb --args=save"
desc = "Add bookmark"
[[manager.prepend_keymap]]
on = [ "u", "g" ]
run = "plugin yamb --args=jump_by_key"
desc = "Jump bookmark by key"
[[manager.prepend_keymap]]
on = [ "u", "G" ]
run = "plugin yamb --args=jump_by_fzf"
desc = "Jump bookmark by fzf"
[[manager.prepend_keymap]]
on = [ "u", "d" ]
run = "plugin yamb --args=delete_by_key"
desc = "Delete bookmark by key"
[[manager.prepend_keymap]]
on = [ "u", "D" ]
run = "plugin yamb --args=delete_by_fzf"
desc = "Delete bookmark by fzf"
[[manager.prepend_keymap]]
on = [ "u", "A" ]
run = "plugin yamb --args=delete_all"
desc = "Delete all bookmarks"
[[manager.prepend_keymap]]
on = [ "u", "r" ]
run = "plugin yamb --args=rename_by_key"
desc = "Rename bookmark by key"
[[manager.prepend_keymap]]
on = [ "u", "R" ]
run = "plugin yamb --args=rename_by_fzf"
desc = "Rename bookmark by fzf"
```

View File

@ -0,0 +1,355 @@
local path_sep = package.config:sub(1, 1)
local get_hovered_path = ya.sync(function(state)
local h = cx.active.current.hovered
if h then
local path = tostring(h.url)
if h.cha.is_dir then
return path .. path_sep
end
return path
else
return ''
end
end)
local get_state_attr = ya.sync(function(state, attr)
return state[attr]
end)
local set_state_attr = ya.sync(function(state, attr, value)
state[attr] = value
end)
local set_bookmarks = ya.sync(function(state, path, value)
state.bookmarks[path] = value
end)
local sort_bookmarks = function(bookmarks, key1, key2, reverse)
reverse = reverse or false
table.sort(bookmarks, function(x, y)
if x[key1] == nil and y[key1] == nil then
return x[key2] < y[key2]
elseif x[key1] == nil then
return false
elseif y[key1] == nil then
return true
else
return x[key1] < y[key1]
end
end)
if reverse then
local n = #bookmarks
for i = 1, math.floor(n / 2) do
bookmarks[i], bookmarks[n - i + 1] = bookmarks[n - i + 1], bookmarks[i]
end
end
return bookmarks
end
local save_to_file = function(mb_path, bookmarks)
local file = io.open(mb_path, "w")
if file == nil then
return
end
local array = {}
for _, item in pairs(bookmarks) do
table.insert(array, item)
end
sort_bookmarks(array, "tag", "key", true)
for _, item in ipairs(array) do
file:write(string.format("%s\t%s\t%s\n", item.tag, item.path, item.key))
end
file:close()
end
local fzf_find = function(cli, mb_path)
local permit = ya.hide()
local cmd = string.format("%s < \"%s\"", cli, mb_path)
local handle = io.popen(cmd, "r")
local result = ""
if handle then
-- strip
result = string.gsub(handle:read("*all") or "", "^%s*(.-)%s*$", "%1")
handle:close()
end
permit:drop()
local tag, path, key = string.match(result or "", "(.-)\t(.-)\t(.*)")
return path
end
local which_find = function(bookmarks)
local cands = {}
for path, item in pairs(bookmarks) do
if #item.tag ~= 0 then
table.insert(cands, { desc = item.tag, on = item.key, path = item.path })
end
end
sort_bookmarks(cands, "on", "desc", false)
if #cands == 0 then
ya.notify {
title = "Bookmarks",
content = "Empty bookmarks",
timeout = 2,
level = "info",
}
return nil
end
local idx = ya.which { cands = cands }
if idx == nil then
return nil
end
return cands[idx].path
end
local action_jump = function(bookmarks, path, jump_notify)
if path == nil then
return
end
local tag = bookmarks[path].tag
if string.sub(path, -1) == path_sep then
ya.manager_emit("cd", { path })
else
ya.manager_emit("reveal", { path })
end
if jump_notify then
ya.notify {
title = "Bookmarks",
content = 'Jump to "' .. tag .. '"',
timeout = 2,
level = "info",
}
end
end
local generate_key = function(bookmarks)
local keys = get_state_attr("keys")
local key2rank = get_state_attr("key2rank")
local mb = {}
for _, item in pairs(bookmarks) do
if #item.key == 1 then
table.insert(mb, item.key)
end
end
if #mb == 0 then
return keys[1]
end
table.sort(mb, function(a, b)
return key2rank[a] < key2rank[b]
end)
local idx = 1
for _, key in ipairs(keys) do
if key2rank[key] < key2rank[mb[idx]] then
return key
end
idx = idx + 1
end
return nil
end
local action_save = function(mb_path, bookmarks, path)
if path == nil or #path == 0 then
return
end
local path_obj = bookmarks[path]
-- check tag
local tag = path_obj and path_obj.tag or path:match(".*[\\/]([^\\/]+)[\\/]?$")
while true do
local value, event = ya.input({
title = "Tag (alias name)",
value = tag,
position = { "top-center", y = 3, w = 40 },
})
if event ~= 1 then
return
end
tag = value or ''
if #tag == 0 then
ya.notify {
title = "Bookmarks",
content = "Empty tag",
timeout = 2,
level = "info",
}
else
-- check the tag
local tag_obj = nil
for _, item in pairs(bookmarks) do
if item.tag == tag then
tag_obj = item
break
end
end
if tag_obj == nil or tag_obj.path == path then
break
end
ya.notify {
title = "Bookmarks",
content = "Duplicated tag",
timeout = 2,
level = "info",
}
end
end
-- check key
local key = path_obj and path_obj.key or generate_key(bookmarks)
while true do
local value, event = ya.input({
title = "Key (1 character, optional)",
value = key,
position = { "top-center", y = 3, w = 40 },
})
if event ~= 1 then
return
end
key = value or ""
if key == "" then
key = ""
break
elseif #key == 1 then
-- check the key
local key_obj = nil
for _, item in pairs(bookmarks) do
if item.key == key then
key_obj = item
break
end
end
if key_obj == nil or key_obj.path == path then
break
else
ya.notify {
title = "Bookmarks",
content = "Duplicated key",
timeout = 2,
level = "info",
}
end
else
ya.notify {
title = "Bookmarks",
content = "The length of key shoule be 1",
timeout = 2,
level = "info",
}
end
end
-- save
set_bookmarks(path, { tag = tag, path = path, key = key })
bookmarks = get_state_attr("bookmarks")
save_to_file(mb_path, bookmarks)
ya.notify {
title = "Bookmarks",
content = '"' .. tag .. '" saved"',
timeout = 2,
level = "info",
}
end
local action_delete = function(mb_path, bookmarks, path)
if path == nil then
return
end
local tag = bookmarks[path].tag
set_bookmarks(path, nil)
bookmarks = get_state_attr("bookmarks")
save_to_file(mb_path, bookmarks)
ya.notify {
title = "Bookmarks",
content = '"' .. tag .. '" deleted',
timeout = 2,
level = "info",
}
end
local action_delete_all = function(mb_path)
local value, event = ya.input({
title = "Delete all bookmarks? (y/n)",
position = { "top-center", y = 3, w = 40 },
})
if event ~= 1 then
return
end
if string.lower(value) == "y" then
set_state_attr("bookmarks", {})
save_to_file(mb_path, {})
ya.notify {
title = "Bookmarks",
content = "All bookmarks deleted",
timeout = 2,
level = "info",
}
else
ya.notify {
title = "Bookmarks",
content = "Cancel delete",
timeout = 2,
level = "info",
}
end
end
return {
setup = function(state, options)
state.path = options.path or
(ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark") or
(os.getenv("HOME") .. "/.config/yazi/bookmark")
state.cli = options.cli or "fzf"
state.jump_notify = options.jump_notify and true
-- init the keys
local keys = options.keys or "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
state.keys = {}
state.key2rank = {}
for i = 1, #keys do
local char = keys:sub(i, i)
table.insert(state.keys, char)
state.key2rank[char] = i
end
-- init the bookmarks
local bookmarks = {}
for _, item in pairs(options.bookmarks or {}) do
bookmarks[item.path] = { tag = item.tag, path = item.path, key = item.key }
end
-- load the config
local file = io.open(state.path, "r")
if file ~= nil then
for line in file:lines() do
local tag, path, key = string.match(line, "(.-)\t(.-)\t(.*)")
if tag and path then
key = key or ""
bookmarks[path] = { tag = tag, path = path, key = key }
end
end
file:close()
end
-- create bookmarks file to enable fzf
save_to_file(state.path, bookmarks)
state.bookmarks = bookmarks
end,
entry = function(self, args)
local action = args[1]
if not action then
return
end
local mb_path, cli, bookmarks, jump_notify = get_state_attr("path"), get_state_attr("cli"), get_state_attr("bookmarks"), get_state_attr("jump_notify")
if action == "save" then
action_save(mb_path, bookmarks, get_hovered_path())
elseif action == "delete_by_key" then
action_delete(mb_path, bookmarks, which_find(bookmarks))
elseif action == "delete_by_fzf" then
action_delete(mb_path, bookmarks, fzf_find(cli, mb_path))
elseif action == "delete_all" then
action_delete_all(mb_path)
elseif action == "jump_by_key" then
action_jump(bookmarks, which_find(bookmarks), jump_notify)
elseif action == "jump_by_fzf" then
action_jump(bookmarks, fzf_find(cli, mb_path), jump_notify)
elseif action == "rename_by_key" then
action_save(mb_path, bookmarks, which_find(bookmarks))
elseif action == "rename_by_fzf" then
action_save(mb_path, bookmarks, fzf_find(cli, mb_path))
end
end,
}

25
.config/yazi/yazi.toml Normal file
View File

@ -0,0 +1,25 @@
[opener]
edit = [
{ run = 'nvim "$@"', block = true, for = "unix" },
]
play = [
{ run = 'mpv "$@"', orphan = true, for = "unix" },
]
open = [
{ run = 'xdg-open "$@"', desc = "Open" },
]
extract = [
{ run = 'ouch d -y "%*"', desc = "Extract here with ouch", for = "windows" },
{ run = 'ouch d -y "$@"', desc = "Extract here with ouch", for = "unix" },
]
[plugin]
prepend_previewers = [
# Archive previewer
{ mime = "application/*zip", run = "ouch" },
{ mime = "application/x-tar", run = "ouch" },
{ mime = "application/x-bzip2", run = "ouch" },
{ mime = "application/x-7z-compressed", run = "ouch" },
{ mime = "application/x-rar", run = "ouch" },
{ mime = "application/x-xz", run = "ouch" },
]

View File

@ -25,3 +25,5 @@
[diff] [diff]
colorMoved = default colorMoved = default
[alias]
zip = archive HEAD -o

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
.config/nvim/lazy-lock.json .config/nvim/lazy-lock.json
.oh-my-zsh/cache/.zsh-update .oh-my-zsh/cache
.config/Code/DawnGraphiteCache/ .config/Code/DawnGraphiteCache/
.config/Code/DawnWebGPUCache/ .config/Code/DawnWebGPUCache/

3
.gitmodules vendored
View File

@ -25,3 +25,6 @@
[submodule ".tmux/plugins/vim-tmux-navigator"] [submodule ".tmux/plugins/vim-tmux-navigator"]
path = .tmux/plugins/vim-tmux-navigator path = .tmux/plugins/vim-tmux-navigator
url = https://git::@github.com/christoomey/vim-tmux-navigator url = https://git::@github.com/christoomey/vim-tmux-navigator
[submodule ".tmux/plugins/tmux-gruvbox"]
path = .tmux/plugins/tmux-gruvbox
url = https://git::@github.com/egel/tmux-gruvbox

View File

@ -20,9 +20,15 @@ bind -n M-Right select-pane -R
bind -n M-Up select-pane -U bind -n M-Up select-pane -U
bind -n M-Down select-pane -D bind -n M-Down select-pane -D
# ────────────────────────────── move panes ──────────────────────────────
bind j command-prompt -p "join pane from:" "join-pane -s '%%'"
bind s command-prompt -p "send pane to:" "join-pane -t '%%'"
# ───────────────── Shift Alt vim keys to switch windows ───────────────── # ───────────────── Shift Alt vim keys to switch windows ─────────────────
bind -n M-H previous-window bind -n M-H previous-window
bind -n M-L next-window bind -n M-L next-window
bind -n M-K switch-client -p
bind -n M-J switch-client -n
# ─────────────────── trying to make home end working ───────────────── # ─────────────────── trying to make home end working ─────────────────
bind-key -n Home send Escape "OH" bind-key -n Home send Escape "OH"
@ -97,27 +103,33 @@ set -g @resurrect-strategy-nvim 'session' # resurrect nvim sessions
set -g @plugin 'tmux-plugins/tmux-continuum' set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @continuum-restore 'on' # enabling set -g @continuum-restore 'on' # enabling
# ╭──────────────────────────────────────────────────────────╮
# │ gruvbox theme │
# ╰──────────────────────────────────────────────────────────╯
set -g @plugin 'egel/tmux-gruvbox'
set -g @tmux-gruvbox 'dark'
# ╭──────────────────────────────────────────────────────────╮ # ╭──────────────────────────────────────────────────────────╮
# │ Dracula theme │ # │ Dracula theme │
# ╰──────────────────────────────────────────────────────────╯ # ╰──────────────────────────────────────────────────────────╯
# available plugins: battery, cpu-usage, git, gpu-usage, ram-usage, tmux-ram-usage, network, network-bandwidth, network-ping, ssh-session, attached-clients, network-vpn, weather, time, mpc, spotify-tui, playerctl, kubernetes-context, synchronize-panes # available plugins: battery, cpu-usage, git, gpu-usage, ram-usage, tmux-ram-usage, network, network-bandwidth, network-ping, ssh-session, attached-clients, network-vpn, weather, time, mpc, spotify-tui, playerctl, kubernetes-context, synchronize-panes
set -g @plugin 'dracula/tmux' # set -g @plugin 'dracula/tmux'
set -g @dracula-show-powerline true # set -g @dracula-show-powerline true
set -g @dracula-plugins "git network network-vpn platerctl time battery" # set -g @dracula-plugins "git network network-vpn platerctl time battery"
# it can accept `hostname` (full hostname), `session`, `shortname` (short name), `smiley`, `window`, or any character. # # it can accept `hostname` (full hostname), `session`, `shortname` (short name), `smiley`, `window`, or any character.
set -g @dracula-show-left-icon session # set -g @dracula-show-left-icon session
set -g @dracula-show-empty-plugins false # set -g @dracula-show-empty-plugins false
set -g @dracula-battery-label "🔋" # set -g @dracula-battery-label "🔋"
set -g @dracula-show-timezone false # set -g @dracula-show-timezone false
set -g @dracula-military-time true # set -g @dracula-military-time true
set -g @dracula-day-month true # set -g @dracula-day-month true
set -g @dracula-show-fahrenheit false # set -g @dracula-show-fahrenheit false
set -g @dracula-playerctl-format "► {{ artist }} - {{ title }}" # set -g @dracula-playerctl-format "► {{ artist }} - {{ title }}"
# for left # # for left
set -g @dracula-show-left-sep \uE0C0 # set -g @dracula-show-left-sep \uE0C0
#
# for right symbol (can set any symbol you like as separator) # # for right symbol (can set any symbol you like as separator)
set -g @dracula-show-right-sep \uE0B2 # set -g @dracula-show-right-sep \uE0B2
# ╭──────────────────────────────────────────────────────────╮ # ╭──────────────────────────────────────────────────────────╮
# │ run tmux plugin manager │ # │ run tmux plugin manager │

@ -0,0 +1 @@
Subproject commit 245e31430fb7298e02ef0d4030905b49d0385746

View File

@ -0,0 +1,79 @@
[
{
"include": "include",
"type": "wildcard",
"title": "All",
"pattern": "*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "localhost all ports",
"pattern": "*://localhost:*/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "127 all ports",
"pattern": "*://127.0.0.1:*/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "localhost default port",
"pattern": "*://localhost/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "127 default port",
"pattern": "*://127.0.0.1/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "vk",
"pattern": "*//*.vk.*/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "dipal vpn",
"pattern": "*://jenkins.ci-cd.svc.cluster.local/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "local with port",
"pattern": "*://192.168.1.*:*/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "local no port",
"pattern": "*://192.168.1.*/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "guap",
"pattern": "*://*.guap.ru/*",
"active": true
},
{
"include": "exclude",
"type": "wildcard",
"title": "dipal",
"pattern": "*://*.dipal.ru/*",
"active": true
}
]