Compare commits

...

23 Commits

Author SHA1 Message Date
dbcf65f6f5 vis: format go files on write 2025-09-25 23:12:21 +02:00
3ec6f839a5 vis: improve close prev/next window 2025-09-25 22:49:51 +02:00
fc02a390ae vis: add go_ext grammar with embedded sql with go templating 2025-09-25 22:24:04 +02:00
28595bbd31 vis: fix shell escape and update lazyjj key 2025-09-24 23:55:50 +02:00
b1f3a79744 tmux/nvim: remove switch pane/window integration 2025-09-24 23:54:58 +02:00
1e7c5902ea vis: templ: add (implement) templ lexer 2025-09-24 23:46:47 +02:00
fddce86eca vis: implement fast jump 2025-09-22 21:38:26 +02:00
f5a0ee0dc9 lupan-set-theme: toggle st theme (note: needs st patched to handle USR1) 2025-09-21 19:35:11 +02:00
8fded47ae8 shell: improve tmux and edit aliases 2025-09-20 12:23:46 +02:00
b11ccf5b82 lazygit: new, vis as editor and use nerd fonts 2025-09-20 12:23:46 +02:00
b72f3935d5 xsession: move awesome to top 2025-09-20 12:23:46 +02:00
d0bc15f7a7 vis: change status bar in dark theme and background in light one 2025-09-20 12:23:46 +02:00
e213b465b3 tmux: change terminal for vis compat, pane name on title, more vi like keys in copy mode 2025-09-20 10:59:38 +02:00
c613624f39 awesome: better toggle maximize, add keys to focus nth window on active tag 2025-09-20 10:59:38 +02:00
d4f4c1ad1a awesome: new themes, use st and clock without date 2025-09-20 10:59:38 +02:00
94fc8c036c vis: fzf.sh: add key to select alternative directory, fix switching between search and find 2025-09-19 00:14:10 +02:00
84d26c68a5 vis: add script fzf.sh and use it with just two keys
fzf.sh is a wrapper around fzf with mode for fd, rg, git and jj which
allow to switch between them with keys
2025-09-18 09:14:44 +02:00
d03dda4979 vis: set dark or light theme and start and also add key for this action 2025-09-15 23:04:19 +02:00
5464d111d0 vis: add keys for shell and themes, change current dir keys 2025-09-14 10:13:43 +02:00
bd15a7b443 vis: add lupan-dark and lupan-light themes, based on default with my selection of colors 2025-09-14 10:13:43 +02:00
2024651e33 xsession: add st-abduco-tabbed; dk: change term to st and add key for st-abduco-tabbed 2025-09-12 21:32:36 +02:00
ff66a92104 dk: add key for theme toggle 2025-09-10 10:38:08 +02:00
7fef9a8760 vis: global marks, do not reopen already opened file, fzf search current file 2025-09-10 10:36:54 +02:00
19 changed files with 1098 additions and 199 deletions

View File

@@ -88,7 +88,7 @@ local function switch_theme()
end
-- This is used later as the default terminal and editor to run.
local terminal = "alacritty"
local terminal = "st"
-- Default modkey.
local modkey = "Mod4"
@@ -123,7 +123,7 @@ local mykeyboardlayout = awful.widget.keyboardlayout()
-- {{{ Wibar
-- Create a textclock widget
local mytextclock = wibox.widget.textclock()
local mytextclock = wibox.widget.textclock('%H:%M ')
-- Create a wibox for each screen and add it
local taglist_buttons = gears.table.join(
@@ -236,6 +236,15 @@ local function layout_menu()
awful.menu(layouts):show()
end
local function focus_nth_window (n)
local cc = {}
for _, c in ipairs(client.get()) do
if awful.widget.tasklist.filter.currenttags(c, mouse.screen) then cc[#cc + 1] = c end
end
local new_focused = cc[n]
if new_focused then client.focus = new_focused; new_focused:raise() end
end
-- {{{ Key bindings
local globalkeys = gears.table.join(
awful.key({ modkey, }, "s", hotkeys_popup.show_help,
@@ -368,8 +377,11 @@ local clientkeys = gears.table.join(
{ description = "minimize", group = "client" }),
awful.key({ modkey, }, "m",
function(c)
c.maximized = not c.maximized
c:raise()
if awful.layout.getname() == "max" then
awful.layout.set(awful.layout.suit.tile)
else
awful.layout.set(awful.layout.suit.max)
end
end,
{ description = "(un)maximize", group = "client" }),
awful.key({ modkey, }, "v",
@@ -432,7 +444,11 @@ for i = 1, 9 do
end
end
end,
{ description = "toggle focused client on tag #" .. i, group = "tag" })
{ description = "toggle focused client on tag #" .. i, group = "tag" }),
--- Focus nth window
awful.key({ "Control" }, "#" .. i + 9,
function() focus_nth_window(i) end,
{ description = "focus window index #" .. i, group = "client" })
)
end

View File

@@ -9,26 +9,26 @@ theme.font = "Fira Code Nerd Font 10"
theme.tasklist_disable_icon = true
theme.wibar_height = 30
theme.bg_normal = "#293d38" -- hsl(165deg 20% 20%)
theme.bg_focus = "#478575" -- hsl(165deg 30% 40%)
theme.bg_urgent = "#5c3d45" -- hsl(345deg 20% 30%)
theme.bg_minimize = "#363e49" -- hsl(215deg 15% 25%)
theme.bg_normal = "#111c22" -- hsl(200 35% 10%)
theme.bg_focus = "#316781" -- hsl(200 45% 35%)
theme.bg_urgent = "#814c31" -- hsl(20 45% 35%)
theme.bg_minimize = "#454f54" -- hsl(200 10% 30%)
theme.bg_systray = theme.bg_normal
theme.tasklist_bg_focus = "#3d5c54" -- hsl(165deg 20% 30%)
theme.tasklist_bg_focus = "#1c3b4a" -- hsl(200 45% 20%)
theme.fg_normal = "#a9d6ca" -- hsl(165deg 35% 75%)"
theme.fg_focus = "#b1babd"
theme.fg_normal = "#73848c" -- hsl(200 10% 50%)
theme.fg_focus = "#abb5ba" -- hsl(200 10% 70%)
theme.fg_urgent = theme.bg_focus
theme.fg_minimize = "#8a9294"
theme.taglist_fg_empty = "#62847b" -- hsl(165deg 15% 45%)"
theme.fg_minimize = theme.fg_normal
theme.taglist_fg_empty = "#454f54" -- hsl(200 10% 30%)
theme.useless_gap = dpi(1)
theme.border_width = dpi(2)
theme.border_normal = "#708090"
theme.border_focus = "#a0522d"
theme.border_marked = "#91231c"
theme.border_normal = "#73848c" -- hsl(200 10% 50%)
theme.border_focus = "#b25e34" -- hsl(20 55% 45%)
theme.border_marked = "#3488b2" -- hsl(200 55% 45%)
theme.bg_wallpaper = "#424a4c"
theme.bg_wallpaper = "#454f54" -- hsl(200 10% 30%)
theme.hotkeys_font = theme.font
theme.hotkeys_description_font = theme.font

View File

@@ -9,26 +9,26 @@ theme.font = "Fira Code Nerd Font 10"
theme.tasklist_disable_icon = true
theme.wibar_height = 30
theme.bg_normal = "#293d38" -- hsl(165deg 20% 20%)
theme.bg_focus = "#a9d6ca" -- hsl(165deg 35% 75%)
theme.bg_urgent = "#bc8f9b" -- hsl(345deg 25% 65%)
theme.bg_minimize = "#62847b" -- hsl(165deg 15% 45%)
theme.bg_normal = "#111c22" -- hsl(200 35% 10%)
theme.bg_focus = "#d0e3fb" -- hsl(214 85% 90%)
theme.bg_urgent = "#f2d1a6" -- hsl(34 75% 80%)
theme.bg_minimize = "#8596ad" -- hsl(214 20% 60%)
theme.bg_systray = theme.bg_normal
theme.tasklist_bg_focus = "#8fbcb1" -- hsl(165deg 25% 65%)
theme.tasklist_bg_focus = "#a6c7f2" -- hsl(214 75% 80%)
theme.fg_normal = "#a9d6ca" -- hsl(165deg 35% 75%)"
theme.fg_focus = "#363d3e"
theme.fg_urgent = "#e9f2f5"
theme.fg_minimize = "#4b5456"
theme.taglist_fg_empty = "#62847b" -- hsl(165deg 15% 45%)"
theme.fg_normal = "#a9bcd6" -- hsl(214 35% 75%)
theme.fg_focus = "#454b54" -- hsl(214 10% 30%)
theme.fg_urgent = "#70675c" -- hsl(34 10% 40%)
theme.fg_minimize = "#70675c" -- hsl(34 10% 40%)
theme.taglist_fg_empty = theme.fg_minimize
theme.useless_gap = dpi(1)
theme.border_width = dpi(2)
theme.border_normal = "#bebebe"
theme.border_focus = "#ff7f50"
theme.border_marked = "#91231c"
theme.border_normal = theme.bg_minimize
theme.border_focus = "#df8c20" -- hsl(34 75% 50%)
theme.border_marked = "#2073df" -- hsl(214 75% 50%)
theme.bg_wallpaper = "#b0bec2"
theme.bg_wallpaper = theme.fg_normal
theme.hotkeys_font = theme.font
theme.hotkeys_description_font = theme.font

View File

@@ -7,7 +7,10 @@ mod4 + p
# terminal
mod4 + shift + Return
alacritty
st
mod4 + ctrl + shift + Return
st-abduco-tabbed
# screenshot and selection capture
{_,mod4 + }@Print
@@ -107,4 +110,8 @@ mod4 + ctrl + shift + l
mod4 + ctrl + shift + s
systemctl suspend
# toggle light/dark theme
mod4 + F6
lupan-set-theme toggle
# vim:ft=sxhkdrc

View File

@@ -0,0 +1,9 @@
os:
edit: 'vis {{filename}}'
editAtLine: 'vis +:{{line}} {{filename}}'
editAtLineAndWait: 'vis +:{{line}} {{filename}}'
editInTerminal: true
openDirInEditor: 'vis {{dir}}'
gui:
nerdFontsVersion: "3"

View File

@@ -1,9 +1,6 @@
alias v=nvim
alias v=vis
alias ll='ls -l'
alias ta='tmux attach -t'
alias tl='tmux list-sessions'
alias tn='tmux new -s'
alias fv='fzf --preview="bat --color=always --theme=Nord {}" --bind="enter:become(nvim {})"'
alias rgh='rg -.'
alias fdh='fd -H'
@@ -15,10 +12,22 @@ fi
alias nocaps='setxkbmap pl -option ctrl:nocaps'
alias fixdp='xrandr --output DP-0 --right-of DP-2'
vf() {
if [ -z "$1" ]; then
vis $(fzf)
tn() {
if [ $# -eq 0 ]; then
tmux new
else
vis $(fzf -q $1)
tmux new -s "$@"
fi
}
ta() {
if [ $# -eq 0 ]; then
tmux attach
else
tmux attach -t "$@"
fi
}
vf() {
fzf --bind 'enter:become:vis {}' -q "$1"
}

View File

@@ -33,55 +33,23 @@ bind-key Left resize-pane -L 8
bind-key Up resize-pane -U 4
bind-key Down resize-pane -D 4
set -g default-terminal "screen-256color"
set -g default-terminal "xterm-256color"
set -as terminal-features ",*:RGB"
set -g base-index 1
setw -g base-index 1
set -g set-titles on
set -g set-titles-string "#H [#S]"
set -g set-titles-string "#H [#S] #W"
set -g status-justify centre
set -g status-left " #[fg=green]#[bg=green]#[fg=black] #H #[bg=default]#[fg=green]#[fg=default] #S"
set -g status-left " #[fg=#316781]#[bg=#316781]#[fg=#abb5ba] #H #[bg=default]#[fg=#316781]#[fg=default] #S"
set -g status-left-length 50
set -g status-right "#[fg=green]#[bg=green]#[fg=black] %H:%M #[bg=default]#[fg=green] "
set-window-option -g window-status-current-format '#[fg=green]#[bg=green]#[fg=black] #I:#W#F #[fg=green]#[bg=black]'
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?\.?(view|n?vim?x?)(-wrapped)?(diff)?$'"
bind-key -n 'M-h' if-shell "$is_vim" 'send-keys M-h' 'select-pane -L'
bind-key -n 'M-j' if-shell "$is_vim" 'send-keys M-j' 'select-pane -D'
bind-key -n 'M-k' if-shell "$is_vim" 'send-keys M-k' 'select-pane -U'
bind-key -n 'M-l' if-shell "$is_vim" 'send-keys M-l' 'select-pane -R'
bind-key -n 'M-n' if-shell "$is_vim" 'send-keys M-n' 'select-window -n'
bind-key -n 'M-p' if-shell "$is_vim" 'send-keys M-p' 'select-window -p'
bind-key -T copy-mode-vi 'M-h' select-pane -L
bind-key -T copy-mode-vi 'M-j' select-pane -D
bind-key -T copy-mode-vi 'M-k' select-pane -U
bind-key -T copy-mode-vi 'M-l' select-pane -R
bind-key -T copy-mode-vi 'M-n' select-window -n
bind-key -T copy-mode-vi 'M-p' select-window -p
bind -n 'M-H' if-shell "$is_vim" 'send-keys M-H' 'resize-pane -L 1'
bind -n 'M-J' if-shell "$is_vim" 'send-keys M-J' 'resize-pane -D 1'
bind -n 'M-K' if-shell "$is_vim" 'send-keys M-K' 'resize-pane -U 1'
bind -n 'M-L' if-shell "$is_vim" 'send-keys M-L' 'resize-pane -R 1'
bind-key -T copy-mode-vi M-H resize-pane -L 1
bind-key -T copy-mode-vi M-J resize-pane -D 1
bind-key -T copy-mode-vi M-K resize-pane -U 1
bind-key -T copy-mode-vi M-L resize-pane -R 1
bind -n 'C-M-h' if-shell "$is_vim" 'send-keys C-M-h' 'swap-pane -s "{left-of}"'
bind -n 'C-M-j' if-shell "$is_vim" 'send-keys C-M-j' 'swap-pane -s "{down-of}"'
bind -n 'C-M-k' if-shell "$is_vim" 'send-keys C-M-k' 'swap-pane -s "{up-of}"'
bind -n 'C-M-l' if-shell "$is_vim" 'send-keys C-M-l' 'swap-pane -s "{right-of}"'
bind-key -T copy-mode-vi C-M-h swap-pane -s "{left-of}"
bind-key -T copy-mode-vi C-M-j swap-pane -s "{down-of}"
bind-key -T copy-mode-vi C-M-k swap-pane -s "{up-of}"
bind-key -T copy-mode-vi C-M-l swap-pane -s "{right-of}"
set -g status-right "#[fg=#316781]#[bg=#316781]#[fg=#abb5ba] %H:%M #[bg=default]#[fg=#316781] "
set-window-option -g window-status-current-format '#[fg=#316781]#[bg=#316781]#[fg=#abb5ba] #I:#W#F #[fg=#316781]#[bg=black]'
bind-key -n M-0 run-shell tmux-session-menu
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel
bind P paste-buffer

View File

@@ -0,0 +1,110 @@
local lpeg = vis.lpeg
P = lpeg.P
R = lpeg.R
S = lpeg.S
Cp = lpeg.Cp
Ct = lpeg.Ct
space = S(' \t\n\r')
alnum = R('az', 'AZ', '09')
local function search(p)
return Ct(((1 - p)^0 * Cp() * p * Cp())^0)
end
vis:map(vis.modes.NORMAL, '\\', function(keys)
if #keys > 1 then
vis.win:draw()
end
local _, esc = keys:find('<Escape>')
if esc then
return esc
end
local _, enter = keys:find('<Enter>')
if enter then
keys = keys:gsub('<Enter>', '')
end
keys = keys:gsub('<Tab>', 'J')
keys = keys:gsub('<S[-]Tab>', 'K')
vis:info(keys)
local n = 0
keys = keys:gsub('[KJ]', function(s)
if s == 'K' then
n = n - 1
elseif s == 'J' then
n = n + 1
end
return ''
end)
keys = keys:gsub('.<Backspace>', '')
if #keys < 1 then
return -1
end
local up = n < 0
local v = vis.win.viewport.bytes
local data = vis.win.file:content(v)
local p = P(false)
local prefix = nil
for i = 1, #keys do
local x = keys:sub(i, i)
if x == 'A' then
prefix = alnum
elseif x == 'F' then
prefix = P(1) - space
else
local y = S(x:lower() .. x:upper())
if i == 1 then
p = y
elseif prefix then
p = p * (prefix - y)^0 * y
elseif x == ' ' then
p = p * space^1
else
p = p * y
end
prefix = false
end
end
p = search(p)
local lst = p:match(data)
if not lst then
vis:info('not found')
return
end
local pos = vis.win.selection.pos
local prev = 0
local next = 0
for i = 2, #lst, 2 do
local a = lst[i-1] + v.start - 1
if a < pos then
prev = i
end
if a > pos then
next = i
break
end
end
local j = 0
if up then
j = prev + 1 + 2 * n
else
j = next - 1 + 2 * n
end
if j > 0 and j < #lst then
pos = lst[j] + v.start - 1
end
if enter then
vis.win.selection.pos = pos
return enter
end
for i = 2, #lst, 2 do
local a = lst[i-1] + v.start - 1
local b = lst[i] + v.start - 2
if a == pos then
vis.win:style(vis.win.STYLE_COLOR_COLUMN, a, b)
else
vis.win:style(vis.win.STYLE_SELECTION, a, b)
end
end
return -1
end, 'colorize token')

281
vis/.config/vis/fzf.sh Executable file
View File

@@ -0,0 +1,281 @@
#!/bin/sh
prompt=${FZF_PROMPT%> }
cmd=${prompt%+*}
hidden=${prompt#$cmd}
ripgrep='rg --column --line-number --color=always --smart-case'
if [ "$1" = list ]; then
case "$FZF_HEADER_LABEL" in
:?*)
dir=${FZF_HEADER_LABEL#?}
;;
*)
dir=
;;
esac
case "$prompt" in
dir:*)
dir=${FZF_HEADER_LABEL#?}
zoxide query -l
echo $dir
exit
;;
files)
exec fd --type f '' $dir
;;
files+hidden)
exec fd --type f -H '' $dir
;;
search)
exec $ripgrep "$FZF_QUERY" $dir
;;
search+hidden)
exec $ripgrep -. "$FZF_QUERY" $dir
;;
git-files*)
if [ -z "$dir" ]; then
exec git ls-files
else
exec git -C $dir ls-files --format "$dir/%(path)"
fi
;;
git-search*)
if [ -z "$dir" ]; then
exec git grep --column --line-number --color=always "$FZF_QUERY"
else
exec git -C $dir grep --column --line-number --color=always "$FZF_QUERY" | sed "s:^:$dir/:"
fi
;;
jj-files*)
if [ -z "$dir" ]; then
exec jj file list --ignore-working-copy
else
jj=$(cd $dir && jj root --ignore-working-copy 2> /dev/null)
exec jj -R $jj file list --ignore-working-copy $dir
fi
;;
jj-search*)
if [ -z "$dir" ]; then
exec $ripgrep "$FZF_QUERY" $(jj file list --ignore-working-copy)
else
jj=$(cd $dir && jj root --ignore-working-copy 2> /dev/null)
exec $ripgrep "$FZF_QUERY" $(jj -R $jj file list --ignore-working-copy $dir)
fi
;;
esac
exit
fi
if [ "$1" = preview ]; then
if [ -n "$3" ]; then
start=$(( $3 - $FZF_PREVIEW_LINES / 2 ))
if [ $start -lt 1 ]; then
start=1
fi
end=$(( $start + $FZF_PREVIEW_LINES ))
exec bat --style=numbers --color=always --highlight-line $3 --line-range $start:$end $2
else
exec bat --style=numbers --color=always $2
fi
fi
reload="reload(sh $0 list || true)"
no_search="rebind(change)+disable-search"
search="unbind(change)+enable-search"
if [ "$1" = key ]; then
case "$FZF_KEY" in
alt-a)
prompt=${FZF_PROMPT#dir:}
if [ $prompt = $FZF_PROMPT ]; then
echo "change-prompt(dir:$FZF_PROMPT)+$search+$reload"
else
case "$cmd" in
*files)
infix="$search"
;;
*)
infix="$no_search"
;;
esac
echo "change-prompt($prompt)+$infix+$reload"
fi
;;
alt-d)
dir=${FZF_HEADER_LABEL#?}
case "$FZF_HEADER_LABEL" in
.?*)
echo "change-header(path: $dir)+change-header-label(:$dir)+$reload"
;;
*)
echo "change-header()+change-header-label(.$dir)+$reload"
;;
esac
;;
alt-f)
case "$cmd" in
*files|search)
prompt="files$hidden"
;;
*search)
prompt="${cmd%-*}-files$hidden"
;;
esac
echo "change-prompt($prompt> )+$search+$reload"
;;
alt-g)
case "$cmd" in
*files)
prompt="git-files$hidden"
echo "change-prompt($prompt> )+$search+$reload"
;;
*search)
prompt="git-search$hidden"
echo "change-prompt($prompt> )+$no_search+$reload"
;;
esac
;;
alt-h)
if [ -z "$hidden" ]; then
prompt="$cmd+hidden"
else
prompt="$cmd"
fi
echo "change-prompt($prompt> )+$reload"
;;
alt-j)
case "$cmd" in
*files)
prompt="jj-files$hidden"
echo "change-prompt($prompt> )+$search+$reload"
;;
*search)
prompt="jj-search$hidden"
echo "change-prompt($prompt> )+$no_search+$reload"
;;
esac
;;
alt-s)
case "$cmd" in
*search|files)
prompt="search$hidden"
;;
*files)
prompt="${cmd%-*}-search$hidden"
;;
esac
echo "change-prompt($prompt> )+$no_search+$reload"
;;
esac
exit
fi
if [ "$1" = chdir ]; then
dir="$2"
prompt=${FZF_PROMPT#dir:}
case "$cmd" in
*files)
infix="$search"
;;
*)
infix="$no_search"
;;
esac
echo "change-header(path: $dir)+change-header-label(:$dir)+change-prompt($prompt)+$infix+$reload"
exit
fi
if [ -n "$2" ]; then
label=".$2"
else
label=".."
fi
case ${1%+hidden} in
auto-files)
git=$(git rev-parse --show-toplevel 2> /dev/null)
jj=$(jj root --ignore-working-copy 2> /dev/null)
if [ -n "$jj" ] && [ "${git#$jj}" = "$git" -o "$git" = "$jj" ]; then
cmd="jj-files$hidden"
elif [ -n "$git" ] && [ "${jj#$git}" = "$jj" ]; then
cmd="git-files$hidden"
else
cmd="files"
fi
action="$search"
prompt="$cmd> "
;;
auto-search)
git=$(git rev-parse --show-toplevel 2> /dev/null)
jj=$(jj root --ignore-working-copy 2> /dev/null)
if [ -n "$jj" ] && [ "${git#$jj}" = "$git" -o "$git" = "$jj" ]; then
cmd="jj-search$hidden"
elif [ -n "$git" ] && [ "${jj#$git}" = "$jj" ]; then
cmd="git-search$hidden"
else
cmd="search"
fi
action="$no_search"
prompt="$cmd> "
;;
files|git-files|jj-files)
cmd="$1"
action="$search"
prompt="$1> "
;;
search|git-search|jj-search)
cmd="$1"
action="$no_search"
prompt="$1> "
;;
*)
cmd="files"
action="$search"
prompt="files> "
;;
esac
key="transform(sh $0 key)"
HELP='Keys:
alt-? help
alt-a select alternative directory
alt-d toggle alternative directory
alt-f switch to files (twice for plain files)
alt-g switch to git
alt-j switch to jj
alt-h toggle hidden
alt-p toggle preview (also to turn off help)
alt-s switch to search (twice for plain search)
alt-u toggle preview window position (right or up)
'
accept="
if [ \${FZF_PROMPT#dir:} = \$FZF_PROMPT ]; then
echo accept
else
sh $0 chdir {1}
fi
"
exec fzf --query "$3" \
--prompt "$prompt" \
--header-label "$label" \
--ansi \
--delimiter : \
--ghost ' (Use alt-? for help)' \
--bind "enter:transform($accept)" \
--bind "change:$reload" \
--bind "start:$reload+$action" \
--bind "alt-a:$key" \
--bind "alt-d:$key" \
--bind "alt-f:$key" \
--bind "alt-g:$key" \
--bind "alt-j:$key" \
--bind "alt-h:$key" \
--bind "alt-s:$key" \
--bind "alt-p:change-preview(sh $0 preview {1} {2})+toggle-preview" \
--bind "alt-u:change-preview-window(up|right)" \
--bind "alt-?:change-preview(echo '$HELP')+show-preview"

View File

@@ -0,0 +1,2 @@
/home/lupan/dotfiles/Makefile:23:22: (PREFIX): make -C dwm install PREFIX="${HOME}/.local"
/home/lupan/dotfiles/Makefile:41:15: (clock): install-lupan-clock:

View File

@@ -0,0 +1,31 @@
-- Copyright 2006-2025 Mitchell. See LICENSE.
-- go with SQL LPeg lexer.
local lexer = lexer
local starts_line = lexer.starts_line
local B, P, S = lpeg.B, lpeg.P, lpeg.S
local lex = lexer.new(..., {inherit = lexer.load('go')})
local open_brace = lex:tag(lexer.OPERATOR, P('{'))
local close_brace = lex:tag(lexer.OPERATOR, P('}'))
local backtick = lex:tag(lexer.STRING, P('`'))
local ws = lex:get_rule('whitespace')
local tpl = lexer.new("template")
tpl:add_rule('keyword', lex:tag(lexer.KEYWORD, lexer.word_match('if else end with range break define continue template block')))
tpl:add_rule('constant', lex:get_rule('constant'))
tpl:add_rule('operator', lex:get_rule('operator') + lex:tag(lexer.OPERATOR, S('$')))
local func = lexer.after_set(' \t\n{|', lexer.word)
tpl:add_rule('function', lex:tag(lexer.FUNCTION, func))
tpl:add_rule('identifier', lex:get_rule('identifier'))
tpl:add_rule('string', lex:get_rule('string'))
tpl:add_rule('number', lex:get_rule('number'))
local sql = lexer.load('sql')
local sql_kwd = lexer.word_match('ALTER CREATE DELETE DROP GRANT INSERT SELECT UPDATE WITH')
sql:embed(tpl, open_brace * open_brace, close_brace * close_brace)
lex:embed(sql, backtick * #(ws^0 * sql_kwd), backtick)
return lex

View File

@@ -1,71 +1,65 @@
-- Copyright 2006-2025 Mitchell. See LICENSE.
-- Go LPeg lexer.
-- templ LPeg lexer.
local lexer = lexer
local starts_line = lexer.starts_line
local P, S = lpeg.P, lpeg.S
local lex = lexer.new(...)
local lex = lexer.new(..., {inherit = lexer.load('go')})
-- Keywords.
lex:add_rule('keyword', lex:tag(lexer.KEYWORD, lex:word_match(lexer.KEYWORD)))
local close_paren = lex:tag(lexer.OPERATOR, P(')'))
local open_brace = lex:tag(lexer.OPERATOR, P('{'))
local close_brace = lex:tag(lexer.OPERATOR, P('}'))
local colon = lex:tag(lexer.OPERATOR, P(':'))
local at = lex:tag(lexer.OPERATOR, P('@'))
local ws = lex:get_rule('whitespace')
local ident = lex:get_rule('identifier')
-- Constants.
lex:add_rule('constant', lex:tag(lexer.CONSTANT_BUILTIN, lex:word_match(lexer.CONSTANT_BUILTIN)))
local html = lexer.load('html')
local go_expr = lexer.load('go', 'go.expr')
local go_stmt1 = lexer.load('go', 'go.stmt1')
local go_stmt2 = lexer.load('go', 'go.stmt2')
local go_stmt3 = lexer.load('go', 'go.stmt3')
local for_ = lex:tag(lexer.KEYWORD, lexer.word_match('for if switch'))
local else_ = close_brace * ws^0 * lex:tag(lexer.KEYWORD, P('else'))
local case_ = lex:tag(lexer.KEYWORD, lexer.word_match('case default'))
html:embed(go_expr, open_brace, close_brace * close_brace^-1)
html:embed(go_stmt1, starts_line(for_ + else_, true), open_brace * #lexer.newline)
html:embed(go_stmt2, starts_line(case_, true), colon * #lexer.newline)
html:embed(go_stmt3, starts_line(at, true), (ident + open_brace + close_paren) * #lexer.newline)
-- Types.
lex:add_rule('type', lex:tag(lexer.TYPE, lex:word_match(lexer.TYPE)))
local func_block_start = close_paren * ws^0 * open_brace
-- Functions.
local builtin_func = -lpeg.B('.') *
lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN))
local func = lex:tag(lexer.FUNCTION, lexer.word)
local method = lpeg.B('.') * lex:tag(lexer.FUNCTION_METHOD, lexer.word)
lex:add_rule('function', (builtin_func + method + func) * #(lexer.space^0 * '('))
lex:set_word_list(lexer.KEYWORD, 'templ css script', true)
-- Identifiers.
lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, lexer.word))
local function starts_with(keyword)
local prefix = '\n' .. keyword .. '%s'
return function(input, index)
local i = index - 1024
if i < 1 then
i = 1
end
local s = input:sub(i, index)
local k = 0
repeat
i = s:find('\n%w', i)
if i then
k = i
i = i + 2
end
until not i
return k > 0 and s:find(prefix, k) and true
end
end
-- Strings.
local sq_str = lexer.range("'", true)
local dq_str = lexer.range('"', true)
local raw_str = lexer.range('`', false, false)
lex:add_rule('string', lex:tag(lexer.STRING, sq_str + dq_str + raw_str))
lex:embed(html, func_block_start * P(starts_with("templ")), starts_line(close_brace))
-- Comments.
local line_comment = lexer.to_eol('//')
local block_comment = lexer.range('/*', '*/')
lex:add_rule('comment', lex:tag(lexer.COMMENT, line_comment + block_comment))
local css = lexer.load('css')
local css_go_expr = lexer.load('go', 'go.expr2')
css:embed(css_go_expr, open_brace, close_brace)
lex:embed(css, func_block_start * P(starts_with("css")), starts_line(close_brace))
-- Numbers.
lex:add_rule('number', lex:tag(lexer.NUMBER, lexer.number * P('i')^-1))
-- Operators.
lex:add_rule('operator', lex:tag(lexer.OPERATOR, S('+-*/%&|^<>=!~:;.,()[]{}@')))
-- Fold points.
lex:add_fold_point(lexer.OPERATOR, '{', '}')
lex:add_fold_point(lexer.COMMENT, '/*', '*/')
-- Word lists.
lex:set_word_list(lexer.KEYWORD, {
'break', 'case', 'chan', 'const', 'continue', 'default', 'defer', 'else', 'fallthrough', 'for',
'func', 'go', 'goto', 'if', 'import', 'interface', 'map', 'package', 'range', 'return', 'select',
'struct', 'switch', 'type', 'var', 'templ'
})
lex:set_word_list(lexer.CONSTANT_BUILTIN, 'true false iota nil')
lex:set_word_list(lexer.TYPE, {
'any', 'bool', 'byte', 'comparable', 'complex64', 'complex128', 'error', 'float32', 'float64',
'int', 'int8', 'int16', 'int32', 'int64', 'rune', 'string', 'uint', 'uint8', 'uint16', 'uint32',
'uint64', 'uintptr'
})
lex:set_word_list(lexer.FUNCTION_BUILTIN, {
'append', 'cap', 'close', 'complex', 'copy', 'delete', 'imag', 'len', 'make', 'new', 'panic',
'print', 'println', 'real', 'recover'
})
lexer.property['scintillua.comment'] = '//'
local js = lexer.load('javascript')
lex:embed(js, func_block_start * P(starts_with("script")), starts_line(close_brace))
return lex

View File

@@ -0,0 +1,158 @@
-- Eight-color scheme
local lexers = vis.lexers
lexers.STYLE_DEFAULT ='back:#1f212e,fore:#9da0af'
lexers.STYLE_NOTHING = ''
lexers.STYLE_ATTRIBUTE = 'fore:#a1a3aa,bold'
lexers.STYLE_CLASS = 'fore:yellow,bold'
lexers.STYLE_COMMENT = 'fore:#334d40,bold'
lexers.STYLE_CONSTANT = 'fore:cyan,bold'
lexers.STYLE_DEFINITION = 'fore:blue,bold'
lexers.STYLE_ERROR = 'fore:red,italics'
lexers.STYLE_FUNCTION = 'fore:#6b8ac7,bold'
lexers.STYLE_HEADING = 'fore:#d1d147'
lexers.STYLE_KEYWORD = 'fore:#bf8040,bold'
lexers.STYLE_LABEL = 'fore:green,bold'
lexers.STYLE_NUMBER = 'fore:#acac53,bold'
lexers.STYLE_OPERATOR = 'fore:#93806c,bold'
lexers.STYLE_REGEX = 'fore:#59862d,bold'
lexers.STYLE_STRING = 'fore:#3d8f66,bold'
lexers.STYLE_PREPROCESSOR = 'fore:#cc66cc,bold'
lexers.STYLE_TAG = 'fore:#705943,bold'
lexers.STYLE_TYPE = 'fore:#7461d1,bold'
lexers.STYLE_VARIABLE = 'fore:#8c5eba,bold'
lexers.STYLE_WHITESPACE = ''
lexers.STYLE_EMBEDDED = 'back:#2d3353,bold'
lexers.STYLE_IDENTIFIER = ''
lexers.STYLE_LINENUMBER = ''
lexers.STYLE_LINENUMBER_CURSOR = 'fore:#bf8040'
lexers.STYLE_CURSOR = 'back:#bf8040,fore:#1f212e'
lexers.STYLE_CURSOR_PRIMARY = lexers.STYLE_CURSOR..',fore:#e6fefe'
lexers.STYLE_CURSOR_LINE = 'underlined'
lexers.STYLE_COLOR_COLUMN = 'back:red'
lexers.STYLE_SELECTION = 'back:#4d5580,bold'
lexers.STYLE_STATUS = 'back:#1c3b4a,fore:#73848c'
lexers.STYLE_STATUS_FOCUSED = 'back:#1c3b4a,fore:#abb5ba,bold'
lexers.STYLE_SEPARATOR = lexers.STYLE_DEFAULT
lexers.STYLE_INFO = 'bold'
lexers.STYLE_EOF = ''
-- lexer specific styles
-- Diff
lexers.STYLE_ADDITION = 'fore:#3a783a'
lexers.STYLE_DELETION = 'fore:#862d2d'
lexers.STYLE_CHANGE = 'fore:#2d3353'
-- CSS
lexers.STYLE_PROPERTY = lexers.STYLE_ATTRIBUTE
lexers.STYLE_PSEUDOCLASS = ''
lexers.STYLE_PSEUDOELEMENT = ''
-- HTML
lexers.STYLE_TAG_UNKNOWN = lexers.STYLE_TAG .. ',italics'
lexers.STYLE_TAG_SINGLE = lexers.STYLE_TAG
lexers.STYLE_TAG_DOCTYPE = lexers.STYLE_TAG .. ',bold'
lexers.STYLE_ATTRIBUTE_UNKNOWN = lexers.STYLE_ATTRIBUTE .. ',italics'
-- Latex, TeX, and Texinfo
lexers.STYLE_COMMAND = lexers.STYLE_KEYWORD
lexers.STYLE_COMMAND_SECTION = lexers.STYLE_CLASS
lexers.STYLE_ENVIRONMENT = lexers.STYLE_TYPE
lexers.STYLE_ENVIRONMENT_MATH = lexers.STYLE_NUMBER
-- Makefile
lexers.STYLE_TARGET = ''
-- Markdown
lexers.STYLE_HR = ''
for i = 1,6 do lexers['STYLE_HEADING_H'..i] = lexers.STYLE_HEADING end
lexers.STYLE_BOLD = 'bold'
lexers.STYLE_ITALIC = 'italics'
lexers.STYLE_LIST = lexers.STYLE_KEYWORD
lexers.STYLE_LINK = lexers.STYLE_KEYWORD
lexers.STYLE_REFERENCE = lexers.STYLE_KEYWORD
lexers.STYLE_CODE = lexers.STYLE_EMBEDDED
-- Output
lexers.STYE_FILENAME = ''
lexers.STYLE_LINE = ''
lexers.STYLE_COLUMN = ''
lexers.STYLE_MESSAGE = ''
-- Python
lexers.STYLE_KEYWORD_SOFT = ''
-- Taskpaper
lexers.STYLE_NOTE = ''
lexers.STYLE_TAG_EXTENDED = ''
lexers.STYLE_TAG_DAY = 'fore:yellow'
lexers.STYLE_TAG_OVERDUE = 'fore:red'
lexers.STYLE_TAG_PLAIN = ''
-- XML
lexers.STYLE_CDATA = ''
-- YAML
lexers.STYLE_ERROR_INDENT = 'back:red'
-- The following are temporary styles until their legacy lexers are migrated.
-- Antlr
lexers.STYLE_ACTION = ''
-- Clojure
lexers.STYLE_CLOJURE_KEYWORD = lexers.STYLE_TYPE
lexers.STYLE_CLOJURE_SYMBOL = lexers.STYLE_TYPE .. ',bold'
-- Crystal
--lexers.STYLE_SYMBOL = lexers.STYLE_STRING
-- Gleam
lexers.STYLE_MODULE = lexers.STYLE_CONSTANT
lexers.STYLE_DISCARD = lexers.STYLE_COMMENT
-- Icon
lexers.STYLE_SPECIAL_KEYWORD = lexers.STYLE_TYPE
-- jq
lexers.STYLE_FORMAT = lexers.STYLE_CONSTANT
lexers.STYLE_SYSVAR = lexers.STYLE_CONSTANT .. ',bold'
-- Julia
-- lexers.STYLE_SYMBOL = lexers.STYLE_STRING
lexers.STYLE_CHARACTER = lexers.STYLE_CONSTANT
-- Mediawiki
lexers.STYLE_BEHAVIOR_SWITCH = lexers.STYLE_KEYWORD
-- Moonscript
lexers.STYLE_TBL_KEY = lexers.STYLE_REGEX
lexers.STYLE_SELF_REF = lexers.STYLE_LABEL
lexers.STYLE_PROPER_IDENT = lexers.STYLE_CLASS
lexers.STYLE_FNDEF = lexers.STYLE_PREPROCESSOR
-- lexers.STYLE_SYMBOL = lexers.STYLE_EMBEDDED
-- reST
lexers.STYLE_LITERAL_BLOCK = lexers.STYLE_EMBEDDED
lexers.STYLE_FOOTNOTE_BLOCK = lexers.STYLE_LABEL
lexers.STYLE_CITATION_BLOCK = lexers.STYLE_LABEL
lexers.STYLE_LINK_BLOCK = lexers.STYLE_LABEL
lexers.STYLE_CODE_BLOCK = lexers.STYLE_CODE
lexers.STYLE_DIRECTIVE = lexers.STYLE_KEYWORD
lexers.STYLE_SPHINX_DIRECTIVE = lexers.STYLE_KEYWORD
lexers.STYLE_UNKNOWN_DIRECTIVE = lexers.STYLE_KEYWORD
lexers.STYLE_SUBSTITUTION = lexers.STYLE_VARIABLE
lexers.STYLE_INLINE_LITERAL = lexers.STYLE_EMBEDDED
lexers.STYLE_ROLE = lexers.STYLE_CLASS
lexers.STYLE_INTERPRETED = lexers.STYLE_STRING
-- txt2tags
lexers.STYLE_LINE = 'bold'
for i = 1,5 do lexers['STYLE_H'..i] = lexers.STYLE_HEADING end
lexers.STYLE_IMAGE = 'fore:green'
lexers.STYLE_STRIKE = 'italics'
lexers.STYLE_TAGGED = lexers.STYLE_EMBEDDED
lexers.STYLE_TAGGED_AREA = lexers.STYLE_EMBEDDED
lexers.STYLE_TABLE_SEP = 'fore:green'
lexers.STYLE_HEADER_CELL_CONTENT = 'fore:green'

View File

@@ -0,0 +1,158 @@
-- Eight-color scheme
local lexers = vis.lexers
lexers.STYLE_DEFAULT ='back:#dae4f1,fore:#1f212e'
lexers.STYLE_NOTHING = ''
lexers.STYLE_ATTRIBUTE = 'fore:#a1a3aa,bold'
lexers.STYLE_CLASS = 'fore:yellow,bold'
lexers.STYLE_COMMENT = 'fore:#334d40,bold'
lexers.STYLE_CONSTANT = 'fore:cyan,bold'
lexers.STYLE_DEFINITION = 'fore:blue,bold'
lexers.STYLE_ERROR = 'fore:red,italics'
lexers.STYLE_FUNCTION = 'fore:#6b8ac7,bold'
lexers.STYLE_HEADING = 'fore:#d1d147'
lexers.STYLE_KEYWORD = 'fore:#bf8040,bold'
lexers.STYLE_LABEL = 'fore:green,bold'
lexers.STYLE_NUMBER = 'fore:#acac53,bold'
lexers.STYLE_OPERATOR = 'fore:#93806c,bold'
lexers.STYLE_REGEX = 'fore:#59862d,bold'
lexers.STYLE_STRING = 'fore:#3d8f66,bold'
lexers.STYLE_PREPROCESSOR = 'fore:#cc66cc,bold'
lexers.STYLE_TAG = 'fore:#705943,bold'
lexers.STYLE_TYPE = 'fore:#7461d1,bold'
lexers.STYLE_VARIABLE = 'fore:#8c5eba,bold'
lexers.STYLE_WHITESPACE = ''
lexers.STYLE_EMBEDDED = 'back:#2d3353,bold'
lexers.STYLE_IDENTIFIER = ''
lexers.STYLE_LINENUMBER = ''
lexers.STYLE_LINENUMBER_CURSOR = 'fore:#bf8040'
lexers.STYLE_CURSOR = 'back:#bf8040,fore:#1f212e'
lexers.STYLE_CURSOR_PRIMARY = lexers.STYLE_CURSOR..',fore:#e6fefe'
lexers.STYLE_CURSOR_LINE = 'underlined'
lexers.STYLE_COLOR_COLUMN = 'back:red'
lexers.STYLE_SELECTION = 'back:#a6c7f2,bold'
lexers.STYLE_STATUS = 'reverse'
lexers.STYLE_STATUS_FOCUSED = 'reverse,bold'
lexers.STYLE_SEPARATOR = lexers.STYLE_DEFAULT
lexers.STYLE_INFO = 'bold'
lexers.STYLE_EOF = ''
-- lexer specific styles
-- Diff
lexers.STYLE_ADDITION = 'fore:#3a783a'
lexers.STYLE_DELETION = 'fore:#862d2d'
lexers.STYLE_CHANGE = 'fore:#2d3353'
-- CSS
lexers.STYLE_PROPERTY = lexers.STYLE_ATTRIBUTE
lexers.STYLE_PSEUDOCLASS = ''
lexers.STYLE_PSEUDOELEMENT = ''
-- HTML
lexers.STYLE_TAG_UNKNOWN = lexers.STYLE_TAG .. ',italics'
lexers.STYLE_TAG_SINGLE = lexers.STYLE_TAG
lexers.STYLE_TAG_DOCTYPE = lexers.STYLE_TAG .. ',bold'
lexers.STYLE_ATTRIBUTE_UNKNOWN = lexers.STYLE_ATTRIBUTE .. ',italics'
-- Latex, TeX, and Texinfo
lexers.STYLE_COMMAND = lexers.STYLE_KEYWORD
lexers.STYLE_COMMAND_SECTION = lexers.STYLE_CLASS
lexers.STYLE_ENVIRONMENT = lexers.STYLE_TYPE
lexers.STYLE_ENVIRONMENT_MATH = lexers.STYLE_NUMBER
-- Makefile
lexers.STYLE_TARGET = ''
-- Markdown
lexers.STYLE_HR = ''
for i = 1,6 do lexers['STYLE_HEADING_H'..i] = lexers.STYLE_HEADING end
lexers.STYLE_BOLD = 'bold'
lexers.STYLE_ITALIC = 'italics'
lexers.STYLE_LIST = lexers.STYLE_KEYWORD
lexers.STYLE_LINK = lexers.STYLE_KEYWORD
lexers.STYLE_REFERENCE = lexers.STYLE_KEYWORD
lexers.STYLE_CODE = lexers.STYLE_EMBEDDED
-- Output
lexers.STYE_FILENAME = ''
lexers.STYLE_LINE = ''
lexers.STYLE_COLUMN = ''
lexers.STYLE_MESSAGE = ''
-- Python
lexers.STYLE_KEYWORD_SOFT = ''
-- Taskpaper
lexers.STYLE_NOTE = ''
lexers.STYLE_TAG_EXTENDED = ''
lexers.STYLE_TAG_DAY = 'fore:yellow'
lexers.STYLE_TAG_OVERDUE = 'fore:red'
lexers.STYLE_TAG_PLAIN = ''
-- XML
lexers.STYLE_CDATA = ''
-- YAML
lexers.STYLE_ERROR_INDENT = 'back:red'
-- The following are temporary styles until their legacy lexers are migrated.
-- Antlr
lexers.STYLE_ACTION = ''
-- Clojure
lexers.STYLE_CLOJURE_KEYWORD = lexers.STYLE_TYPE
lexers.STYLE_CLOJURE_SYMBOL = lexers.STYLE_TYPE .. ',bold'
-- Crystal
--lexers.STYLE_SYMBOL = lexers.STYLE_STRING
-- Gleam
lexers.STYLE_MODULE = lexers.STYLE_CONSTANT
lexers.STYLE_DISCARD = lexers.STYLE_COMMENT
-- Icon
lexers.STYLE_SPECIAL_KEYWORD = lexers.STYLE_TYPE
-- jq
lexers.STYLE_FORMAT = lexers.STYLE_CONSTANT
lexers.STYLE_SYSVAR = lexers.STYLE_CONSTANT .. ',bold'
-- Julia
-- lexers.STYLE_SYMBOL = lexers.STYLE_STRING
lexers.STYLE_CHARACTER = lexers.STYLE_CONSTANT
-- Mediawiki
lexers.STYLE_BEHAVIOR_SWITCH = lexers.STYLE_KEYWORD
-- Moonscript
lexers.STYLE_TBL_KEY = lexers.STYLE_REGEX
lexers.STYLE_SELF_REF = lexers.STYLE_LABEL
lexers.STYLE_PROPER_IDENT = lexers.STYLE_CLASS
lexers.STYLE_FNDEF = lexers.STYLE_PREPROCESSOR
-- lexers.STYLE_SYMBOL = lexers.STYLE_EMBEDDED
-- reST
lexers.STYLE_LITERAL_BLOCK = lexers.STYLE_EMBEDDED
lexers.STYLE_FOOTNOTE_BLOCK = lexers.STYLE_LABEL
lexers.STYLE_CITATION_BLOCK = lexers.STYLE_LABEL
lexers.STYLE_LINK_BLOCK = lexers.STYLE_LABEL
lexers.STYLE_CODE_BLOCK = lexers.STYLE_CODE
lexers.STYLE_DIRECTIVE = lexers.STYLE_KEYWORD
lexers.STYLE_SPHINX_DIRECTIVE = lexers.STYLE_KEYWORD
lexers.STYLE_UNKNOWN_DIRECTIVE = lexers.STYLE_KEYWORD
lexers.STYLE_SUBSTITUTION = lexers.STYLE_VARIABLE
lexers.STYLE_INLINE_LITERAL = lexers.STYLE_EMBEDDED
lexers.STYLE_ROLE = lexers.STYLE_CLASS
lexers.STYLE_INTERPRETED = lexers.STYLE_STRING
-- txt2tags
lexers.STYLE_LINE = 'bold'
for i = 1,5 do lexers['STYLE_H'..i] = lexers.STYLE_HEADING end
lexers.STYLE_IMAGE = 'fore:green'
lexers.STYLE_STRIKE = 'italics'
lexers.STYLE_TAGGED = lexers.STYLE_EMBEDDED
lexers.STYLE_TAGGED_AREA = lexers.STYLE_EMBEDDED
lexers.STYLE_TABLE_SEP = 'fore:green'
lexers.STYLE_HEADER_CELL_CONTENT = 'fore:green'

View File

@@ -1,4 +1,5 @@
require('vis')
require('fast-jump')
local plug = (function()
if not pcall(require, 'plugins/vis-plug') then
@@ -22,6 +23,10 @@ local plugins = {
plug.init(plugins, true)
vis.ftdetect.filetypes.go_ext = vis.ftdetect.filetypes.go
vis.ftdetect.filetypes.go = nil
plug.plugins.lspc.ls_map.go_ext = plug.plugins.lspc.ls_map.go
vis.ftdetect.filetypes.templ = {
ext = { "%.templ$" },
}
@@ -48,7 +53,9 @@ local function open_file_pos(line, open_cmd)
local file = iter()
local line_num = nil_or_tonumber(iter())
local col = nil_or_tonumber(iter()) or 1
open_file(file, open_cmd)
if open_cmd ~= 'e' or vis.win.file ~= file then
open_file(file, open_cmd)
end
if line_num ~= nil then
vis.win.selection:to(line_num, col)
end
@@ -61,7 +68,33 @@ local function open_file_current_line(open_cmd)
end
local function escape_and_quoted(s)
return "'" .. s:gsub("'", "\\'") .. "'"
return "'" .. s:gsub("'", [['"'"']]) .. "'"
end
local function cmd_action(cmd, action)
local code, out, err = vis:pipe(cmd, true)
if code == 0 then
action(out)
elseif err ~= nil then
vis:info(err)
elseif code ~= 0 then
vis:info('Program exit code ' .. code)
end
end
local function fzf_sh(arg)
action = function(out)
open_file_pos(out, vis.win.file.modified and 'o' or 'e')
end
local home = os.getenv('HOME')
local path = vis.win.file.path or ''
local dir = path:match('^.*/') or ''
local reg = ''
if reg ~= '"' then
reg = string.gsub(vis.registers[vis.register][1], '%z', '')
end
local cmd = home .. '/.config/vis/fzf.sh ' .. escape_and_quoted(arg) .. ' ' .. escape_and_quoted(dir) .. ' ' .. escape_and_quoted(reg)
cmd_action(cmd, action)
end
local function search(cmd, action)
@@ -76,14 +109,7 @@ local function search(cmd, action)
cmd = cmd .. ' --query=' .. escape_and_quoted(reg)
end
end
local code, out, err = vis:pipe(cmd, true)
if code == 0 then
action(out)
elseif err ~= nil then
vis:info(err)
elseif code ~= 0 then
vis:info('Program exit code ' .. code)
end
cmd_action(cmd, action)
end
local file_slots = {}
@@ -120,8 +146,61 @@ local function fzf_reload(cmd)
' --bind "alt-enter:unbind(change,alt-enter)+change-prompt(2. fzf> )+enable-search+clear-query"'
end
local function add_global_mark()
local file = vis.win.file.path
if file ~= nil then
local code, out, err = vis:pipe('vis-menu -p "global mark comment:"', true)
if code == 0 then
local prefix = file .. ':' .. vis.win.selection.line .. ':' .. vis.win.selection.col .. ': '
local line = vis.win.file.lines[vis.win.selection.line]
out = out:gsub('\n$', '')
if out ~= '' then
prefix = prefix .. '(' .. out .. '): '
end
out = io.open(os.getenv('HOME') .. '/.config/vis/global-marks.txt', 'a')
out:write(prefix .. line .. '\n')
out:close()
elseif err ~= nil then
vis:info(err)
elseif code ~= 0 then
vis:info('Program exit code ' .. code)
end
else
vis:info('Save file first')
end
end
function set_current_theme()
local f = io.open(os.getenv('HOME') .. '/.config/xsettingsd/xsettingsd.conf')
if f then
local s = f:read('*all')
f:close()
if s:match('light') then
vis:command('set theme lupan-light')
else
vis:command('set theme lupan-dark')
end
end
end
local ripgrep = 'rg --column --line-number --color=always --smart-case'
local function close_prev_win()
vis:feedkeys('<vis-window-prev>')
if not vis.win:close() then
vis:feedkeys('<vis-window-next>')
vis:info('No write since last change')
end
end
local function close_next_win()
vis:feedkeys('<vis-window-next>')
if not vis.win:close() then
vis:feedkeys('<vis-window-prev>')
vis:info('No write since last change')
end
end
vis.events.subscribe(vis.events.INIT, function()
vis:command('set autoindent')
@@ -131,82 +210,57 @@ vis.events.subscribe(vis.events.INIT, function()
vis:map(vis.modes.NORMAL, '<M-k>', '<vis-window-prev>')
vis:map(vis.modes.NORMAL, '<M-j>', '<vis-window-next>')
vis:map(vis.modes.NORMAL, ' K', '<vis-window-prev>:q<Enter>', 'close previous window')
vis:map(vis.modes.NORMAL, ' J', '<vis-window-next>:q<Enter><vis-window-prev>', 'close next window')
vis:map(vis.modes.NORMAL, ' K', close_prev_win)
vis:map(vis.modes.NORMAL, ' J', close_next_win)
vis:map(vis.modes.NORMAL, ' l[', ':lspc-prev-diagnostic<Enter>')
vis:map(vis.modes.NORMAL, ' l]', ':lspc-next-diagnostic<Enter>')
vis:map(vis.modes.NORMAL, ' l=', ':lspc-format<Enter>')
for num = 1, 9 do
vis:map(vis.modes.NORMAL, ' s' .. num, function() set_file_slot(num) end, 'set file slot ' .. num)
vis:map(vis.modes.NORMAL, ' r' .. num, function() set_file_slot(num) end, 'set file slot ' .. num)
vis:map(vis.modes.NORMAL, ' ' .. num, function() open_file_slot(num, 'e') end, 'open file slot ' .. num)
vis:map(vis.modes.NORMAL, ' h' .. num, function() open_file_slot(num, 'o') end, 'open file slot ' .. num)
vis:map(vis.modes.NORMAL, ' v' .. num, function() open_file_slot(num, 'vsplit') end,
'open file slot ' .. num)
end
vis:map(vis.modes.NORMAL, ' fg', function()
search(fzf_reload(ripgrep))
end, 'fzf: rg')
vis:map(vis.modes.NORMAL, ' s', function()
fzf_sh('auto-search')
end, 'fzf: search')
vis:map(vis.modes.NORMAL, ' hg', function()
search(fzf_reload(ripgrep .. ' -.'))
end, 'fzf: rg with hidden files')
vis:map(vis.modes.NORMAL, ' ff', function()
search('fd --type f | fzf')
vis:map(vis.modes.NORMAL, ' f', function()
fzf_sh('auto-files')
end, 'fzf: files')
vis:map(vis.modes.NORMAL, ' fh', function()
search('fd -H --type f | fzf')
end, 'fzf: files with hidden files')
vis:map(vis.modes.NORMAL, ' /', function()
search(fzf_reload(ripgrep .. ' --with-filename {q} ' .. escape_and_quoted(vis.win.file.path)))
end, 'fzf: rg current file')
vis:map(vis.modes.NORMAL, ' .', function()
local shell = os.getenv('SHELL')
vis:command('!' .. shell)
end, 'run shell')
vis:map(vis.modes.NORMAL, ' ds', function()
local shell = os.getenv('SHELL')
local path = vis.win.file.path
if path then
local dir = path:match('^.*/')
local arg = escape_and_quoted(dir)
search('fd --type f "" ' .. arg .. ' | fzf')
vis:command('!cd ' .. arg .. ' && ' .. shell)
else
search('fd --type f | fzf')
vis:command('!' .. shell)
end
end, 'fzf in file directory')
vis:map(vis.modes.NORMAL, ' h.', function()
local path = vis.win.file.path
if path then
local dir = path:match('^.*/')
local arg = escape_and_quoted(dir)
search('fd -H --type f "" ' .. arg .. ' | fzf')
else
search('fd -H --type f | fzf')
end
end, 'fzf in file directory with hidden files')
vis:map(vis.modes.NORMAL, ' gf', function()
search('git ls-files | fzf')
end, 'fzf: git files')
vis:map(vis.modes.NORMAL, ' gg', function()
search(fzf_reload('git grep --column --line-number --color=always'))
end, 'fzf: jj grep')
end, 'run shell in file directory')
vis:map(vis.modes.NORMAL, ' gl', function()
vis:command('!lazygit')
end, 'lazygit')
vis:map(vis.modes.NORMAL, ' jf', function()
search('jj file list | fzf')
end, 'fzf: jj files')
vis:map(vis.modes.NORMAL, ' jg', function()
search(fzf_reload(ripgrep .. ' {q} $(jj file list | xargs)'))
end, 'fzf: jj grep')
vis:map(vis.modes.NORMAL, ' jl', function()
vis:map(vis.modes.NORMAL, ' gj', function()
vis:command('!lazyjj')
end, 'fzf open')
end, 'lazyjj')
vis:map(vis.modes.NORMAL, ' ', function()
vis:command('fzfmru')
@@ -236,8 +290,37 @@ vis.events.subscribe(vis.events.INIT, function()
vis:command('!yazi')
end
end, 'yazi in file directory')
vis:map(vis.modes.NORMAL, ' ma', add_global_mark, 'global marks: add')
vis:map(vis.modes.NORMAL, ' mj', function()
search('cat ~/.config/vis/global-marks.txt | fzf --tac')
end, 'global marks: jump')
vis:map(vis.modes.NORMAL, ' me', function()
vis:command('o ~/.config/vis/global-marks.txt')
end, 'global marks: edit')
vis:map(vis.modes.NORMAL, ' td', function()
vis:command('set theme lupan-dark')
end, 'change to dark theme')
vis:map(vis.modes.NORMAL, ' tl', function()
vis:command('set theme lupan-light')
end, 'change to light theme')
vis:map(vis.modes.NORMAL, ' tt', set_current_theme)
set_current_theme()
end)
vis.events.subscribe(vis.events.WIN_OPEN, function(win)
vis:command('set relativenumber')
end)
vis.events.subscribe(vis.events.FILE_SAVE_PRE, function(file, path)
if path:find('[.]go$') then
-- formatting is async, so when reformated you should write file again
vis:command('lspc-format')
end
return true
end)

View File

@@ -1,3 +1,5 @@
#define THEME_DARK
#if HEIGHT >= 2160
Xft.dpi: 160
Xcursor.size: 48
@@ -53,3 +55,49 @@ XTerm.vt100.color14: #8FBCBB
! white
XTerm.vt100.color7: #E5E9F0
XTerm.vt100.color15: #ECEFF4
st.font: FiraCode Nerd Font:size=10
#ifdef THEME_DARK
st.background: #1f212e
st.foreground: #9da0af
st.cursorColor: #bf8040
st.reverse-cursor: #1f212e
st.color0: #1f212e
st.color1: #862d2d
st.color2: #3a783a
st.color3: #707010
st.color4: #345eb2
st.color5: #cc66cc
st.color6: #3a7878
st.color7: #a1a3aa
st.color8: #4d4d4d
st.color9: #c27070
st.color10: #40bf40
st.color11: #acac53
st.color12: #6b8ac7
st.color13: #8f248f
st.color14: #509595
st.color15: #dbdff0
#else
st.background: #dae4f1
st.foreground: #1f212e
st.cursorColor: #bf8040
st.reverse-cursor: #1f212e
st.color0: #1f212e
st.color1: #862d2d
st.color2: #3a783a
st.color3: #707010
st.color4: #345eb2
st.color5: #cc66cc
st.color6: #3a7878
st.color7: #a1a3aa
st.color8: #73778c
st.color9: #c27070
st.color10: #40bf40
st.color11: #acac53
st.color12: #6b8ac7
st.color13: #8f248f
st.color14: #509595
st.color15: #dae4f1
#endif

View File

@@ -30,6 +30,10 @@ xsetroot -cursor_name left_ptr
picom -b -I 1 -O 1 -i 1 -e 1 --no-fading-openclose || compton -b --no-fading-openclose
if which awesome > /dev/null; then
exec awesome
fi
if which dk > /dev/null; then
for m in $(polybar --list-monitors | cut -d: -f1); do
MONITOR=$m polybar --reload bar &
@@ -43,10 +47,6 @@ if which dwm > /dev/null; then
exec dwm
fi
if which awesome > /dev/null; then
exec awesome
fi
if which xmonad > /dev/null && test -f ~/.config/xmonad/xmonad.hs; then
exec xmonad
fi

View File

@@ -19,6 +19,16 @@ else
exit 1
fi
if [ -f ~/.Xresources ]; then
if [ "$THEME" = dark ]; then
sed -i 's/^#undef THEME_DARK/#define THEME_DARK/' ~/.Xresources
elif [ "$THEME" = light ]; then
sed -i 's/^#define THEME_DARK/#undef THEME_DARK/' ~/.Xresources
fi
xrdb -merge ~/.Xresources
killall -USR1 st
fi
# Alacritty
if [ -f ~/.config/alacritty/alacritty.yml ]; then
sed -i "s/^colors: [*].*/colors: *$THEME/" ~/.config/alacritty/alacritty.yml

15
xsession/bin/st-abduco-tabbed Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
if [ $# -eq 0 ]; then
exec tabbed "$0" -w
fi
if [ "$1" = "-w" ] && [ -n "$2" ]; then
name=$(abduco | tail +2 | awk -F'\t' '{ print $NF }' | dmenu -p session: -l 10)
if [ -n "$name" ]; then
exec st -w "$2" -t "$name" -e abduco -A "$name" "$SHELL"
fi
else
echo error: requires either no arguments or single option -w with and argument >&2
exit 1
fi