Initial commit

This commit is contained in:
Minty Cube 2024-04-23 07:34:15 +05:00 committed by mintycube
commit 06de15ce6d
362 changed files with 42206 additions and 0 deletions

36
.bashrc Executable file
View File

@ -0,0 +1,36 @@
# ~/.bashrc
bind "set completion-ignore-case on" # Perform file completion in a case insensitive fashion
bind "set completion-map-case on" # Treat hyphens and underscores as equivalent
bind "set show-all-if-ambiguous on" # Display matches for ambiguous patterns at first tab press
bind "set mark-symlinked-directories on" # Immediately add a trailing slash when autocompleting symlinks to directories
HISTSIZE=500000
HISTFILESIZE=100000
shopt -s histappend # Append to the history file, don't overwrite it
shopt -s cmdhist # Save multi-line commands as one command
PROMPT_COMMAND='history -a' # Record each line as it gets issued
HISTCONTROL="erasedups:ignoreboth" # Avoid duplicate entries
export HISTIGNORE="&:[ ]*:exit:ls:lf:bg:fg:history:clear" # Don't record some commands
HISTTIMEFORMAT='%F %T ' # Use standard ISO 8601 timestamp
export MANPAGER="nvim +Man!"
bind Space:magic-space # Typing !!<space> will replace the !! with your last command
bind '"\e[A": history-search-backward' # Enable incremental history search with up/down arrows (also Readline goodness)
bind '"\e[B": history-search-forward'
bind '"\e[C": forward-char'
bind '"\e[D": backward-char'
shopt -s autocd 2>/dev/null # Prepend cd to directory names automatically
shopt -s dirspell 2>/dev/null # Correct spelling errors during tab-completion
shopt -s cdspell 2>/dev/null # Correct spelling errors in arguments supplied to cd
shopt -s expand_aliases # expand aliases
shopt -s checkwinsize # checks term size when bash regains control
[ -f "$HOME/.config/shell/shortcutrc" ] && source "$HOME/.config/shell/shortcutrc" # shortcuts
[ -f "$HOME/.config/shell/aliasrc" ] && source "$HOME/.config/shell/aliasrc" # aliases
PS1='\[\e[34;3m\]\w \[\e[0;32m\] \[\e[0m\]' # prompt with dir in italic
source "$HOME/.local/src/fzf-tab-completion/bash/fzf-bash-completion.sh" # https://github.com/lincheney/fzf-tab-completion.git
bind -x '"\t": fzf_bash_completion'

27
.config/bat/config Normal file
View File

@ -0,0 +1,27 @@
# This is `bat`s configuration file. Each line either contains a comment or
# a command-line option that you want to pass to `bat` by default. You can
# run `bat --help` to get a list of all possible configuration options.
# Specify desired highlighting theme (e.g. "TwoDark"). Run `bat --list-themes`
# for a list of all available themes
--theme="base16"
--tabs=2
# Enable this to use italic text on the terminal. This is not supported on all
# terminal emulators (like tmux, by default):
#--italic-text=always
# Uncomment the following line to disable automatic paging:
#--paging=never
# Uncomment the following line if you are using less version >= 551 and want to
# enable mouse scrolling support in `bat` when running inside tmux. This might
# disable text selection, unless you press shift.
#--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse"
# Syntax mappings: map a certain filename pattern to a language.
# Example 1: use the C++ syntax for Arduino .ino files
# Example 2: Use ".gitignore"-style highlighting for ".ignore" files
#--map-syntax "*.ino:C++"
#--map-syntax ".ignore:Git Ignore"

22
.config/ctpv/config Normal file
View File

@ -0,0 +1,22 @@
set forcekittyanim
preview audio audio/* {{
/usr/bin/vendor_perl/exiftool -- "$f"
}}
preview lua application/javascript {{
if exists bat; then
batcmd=bat
elif exists batcat; then
batcmd=batcat
else
exit 127
fi
"$batcmd" \
--color always \
--style plain \
--paging never \
--terminal-width "$w" \
--wrap character \
-- "$f"
}}

69
.config/dunst/dunstrc Normal file
View File

@ -0,0 +1,69 @@
[global]
monitor = 0
follow = mouse
width = 200
height = 500
origin = top-right
offset = 15x15
corner_radius = 10
scale = 0
notification_limit = 0
progress_bar = true
progress_bar_height = 80
progress_bar_frame_width = 1
progress_bar_min_width = 300
progress_bar_max_width = 300
indicate_hidden = yes
transparency = 0
separator_height = 1
padding = 10
horizontal_padding = 10
text_icon_padding = 0
frame_width = 2
gap_size = 0
separator_color = frame
sort = yes
idle_threshold = 120
font = JetBrainsMono Nerd Font Semibold 9
line_height = 1
markup = full
format = %s\n%b
alignment = left
vertical_alignment = center
show_age_threshold = 60
ellipsize = middle
ignore_newline = no
stack_duplicates = true
hide_duplicate_count = false
show_indicators = yes
enable_recursive_icon_lookup = true
icon_position = left
min_icon_size = 24
max_icon_size = 48
sticky_history = yes
history_length = 20
browser = /usr/bin/xdg-open
always_run_script = true
mouse_left_click = close_current
mouse_middle_click = do_action, close_current
mouse_right_click = close_all
title = Dunst
class = Dunst
[urgency_low]
timeout = 2
background = "#1a1b26"
foreground = "#a0caf5"
frame_color = "#7aa2f7"
[urgency_normal]
timeout = 5
background = "#1a1b26"
foreground = "#a0caf5"
frame_color = "#7aa2f7"
[urgency_critical]
timeout = 0
background = "#1a1b26"
foreground = "#a0caf5"
frame_color = "#f7768e"

View File

@ -0,0 +1,40 @@
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<alias>
<family>serif</family>
<prefer>
<family>Apple Garamond</family>
<family>Joy Pixels</family>
<family>Noto Color Emoji</family>
<family>Symbols Nerd Font</family>
</prefer>
</alias>
<alias>
<family>sans-serif</family>
<prefer>
<family>Lucida Grande</family>
<family>Joy Pixels</family>
<family>Noto Color Emoji</family>
<family>Symbols Nerd Font</family>
</prefer>
</alias>
<alias>
<family>sans</family>
<prefer>
<family>Lucida Grande</family>
<family>Joy Pixels</family>
<family>Noto Color Emoji</family>
<family>Symbols Nerd Font</family>
</prefer>
</alias>
<alias>
<family>monospace</family>
<prefer>
<family>JetBrainsMono Nerd Font</family>
<family>Liberation Mono</family>
<family>Symbols Nerd Font</family>
<family>Braille</family>
</prefer>
</alias>
</fontconfig>

View File

@ -0,0 +1,11 @@
[Filechooser Settings]
LocationMode=path-bar
ShowHidden=false
ShowSizeColumn=true
GeometryX=209
GeometryY=51
GeometryWidth=948
GeometryHeight=647
SortColumn=modified
SortOrder=descending
StartupMode=recent

18
.config/gtk-2.0/gtkrc-2.0 Normal file
View File

@ -0,0 +1,18 @@
# DO NOT EDIT! This file will be overwritten by LXAppearance.
# Any customization should be done in ~/.gtkrc-2.0.mine instead.
gtk-theme-name="siduck-onedark"
gtk-icon-theme-name="Reversal-red-dark"
gtk-font-name="Noto Sans 10"
gtk-cursor-theme-name="Bibata-Modern-Ice"
gtk-cursor-theme-size=24
gtk-toolbar-style=GTK_TOOLBAR_TEXT
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=0
gtk-menu-images=1
gtk-enable-event-sounds=1
gtk-enable-input-feedback-sounds=1
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle="hintfull"
gtk-xft-rgba="rgb"

View File

@ -0,0 +1,16 @@
[Settings]
gtk-theme-name=siduck-onedark
gtk-icon-theme-name=Reversal-red-dark
gtk-font-name=Noto Sans 10
gtk-toolbar-style=GTK_TOOLBAR_TEXT
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=0
gtk-menu-images=1
gtk-enable-event-sounds=1
gtk-enable-input-feedback-sounds=1
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle=hintfull
gtk-xft-rgba=rgb
gtk-cursor-theme-name=Bibata-Modern-Ice
gtk-cursor-theme-size=24

19
.config/kitty/colors.conf Normal file
View File

@ -0,0 +1,19 @@
background #16161e
foreground #c0caf5
cursor #c0caf5
color0 #15161e
color1 #f7768e
color2 #9ece6a
color3 #e0af68
color4 #7aa2f7
color5 #bb9af7
color6 #7dcfff
color7 #a9b1d6
color8 #414868
color9 #f7768e
color10 #9ece6a
color11 #e0af68
color12 #7aa2f7
color13 #bb9af7
color14 #7dcfff
color15 #c0caf5

58
.config/kitty/kitty.conf Normal file
View File

@ -0,0 +1,58 @@
shell_integration no-cursor
cursor_shape underline
cursor_underline_thickness 2
cursor_stop_blinking_after 15.0
allow_remote_control socket-only
listen_on unix:/tmp/kitty
font_size 10
font_family JetBrainsMono NF Regular
bold_font JetBrainsMono NF Bold
italic_font JetBrainsMono NF Italic
bold_italic_font Jameel Noori Nastaleeq
enabled_layouts *
window_border_width 1
window_margin_width 0
window_padding_width 10
active_border_color #282c34
inactive_border_color #22262d
inactive_text_alpha 1.0
tab_bar_margin_width 4
tab_bar_style fade
tab_fade 1 1 1
symbol_map U+2800-U+28FF Symbola
background_opacity 1
enable_audio_bell no
confirm_os_window_close 0
update_check_interval 0
map ctrl+tab next_tab
map ctrl+shift+tab previous_tab
#map ctrl+t new_tab zsh
map ctrl+shift+t new_tab zsh
map ctrl+shift+r new_tab zsh -c 'lfub ~'
map ctrl+shift+w close_tab
map ctrl+shift+l next_layout
map ctrl+shift+f move_tab_forward
map ctrl+shift+b move_tab_backward
map alt+shift+j increase_font_size
map alt+shift+k decrease_font_size
map ctrl+shift+backspace restore_font_size
map ctrl+shift+f11 toggle_fullscreen
map alt+y copy_to_clipboard
#map alt+c copy_to_clipboard
#map alt+v paste_from_clipboard
#map ctrl+p paste_from_clipboard
map alt+p paste_from_clipboard
repaint_delay 6
input_delay 1
copy_on_select yes
strip_trailing_spaces always
include colors.conf

177
.config/lf/colors Normal file
View File

@ -0,0 +1,177 @@
# vim:ft=dircolors
# (This is not a dircolors file but it helps to highlight colors and comments)
# default values from dircolors
# (entries with a leading # are not implemented in lf)
# #no 00 # NORMAL
# fi 00 # FILE
# #rs 0 # RESET
# di 01;34 # DIR
# ln 01;36 # LINK
# #mh 00 # MULTIHARDLINK
# pi 40;33 # FIFO
# so 01;35 # SOCK
# #do 01;35 # DOOR
# bd 40;33;01 # BLK
# cd 40;33;01 # CHR
# or 40;31;01 # ORPHAN
# #mi 00 # MISSING
# su 37;41 # SETUID
# sg 30;43 # SETGID
# #ca 30;41 # CAPABILITY
# tw 30;42 # STICKY_OTHER_WRITABLE
# ow 34;42 # OTHER_WRITABLE
# st 37;44 # STICKY
# ex 01;32 # EXEC
# default values from lf (with matching order)
# ln 01;36 # LINK
# or 31;01 # ORPHAN
# tw 01;34 # STICKY_OTHER_WRITABLE
# ow 01;34 # OTHER_WRITABLE
# st 01;34 # STICKY
# di 01;34 # DIR
# pi 33 # FIFO
# so 01;35 # SOCK
# bd 33;01 # BLK
# cd 33;01 # CHR
# su 01;32 # SETUID
# sg 01;32 # SETGID
# ex 01;32 # EXEC
# fi 00 # FILE
# file types (with matching order)
ln 01;36 # LINK
or 31;01 # ORPHAN
tw 34 # STICKY_OTHER_WRITABLE
ow 34 # OTHER_WRITABLE
st 01;34 # STICKY
di 01;33 # DIR
pi 33 # FIFO
so 01;35 # SOCK
bd 33;01 # BLK
cd 33;01 # CHR
su 01;32 # SETUID
sg 01;32 # SETGID
ex 01;32 # EXEC
fi 49;68 # FILE
# archives or compressed (dircolors defaults)
*.tar 01;31
*.tgz 01;31
*.arc 01;31
*.arj 01;31
*.taz 01;31
*.lha 01;31
*.lz4 01;31
*.lzh 01;31
*.lzma 01;31
*.tlz 01;31
*.txz 01;31
*.tzo 01;31
*.t7z 01;31
*.zip 01;31
*.z 01;31
*.dz 01;31
*.gz 01;31
*.lrz 01;31
*.lz 01;31
*.lzo 01;31
*.xz 01;31
*.zst 01;31
*.tzst 01;31
*.bz2 01;31
*.bz 01;31
*.tbz 01;31
*.tbz2 01;31
*.tz 01;31
*.deb 01;31
*.rpm 01;31
*.jar 01;31
*.war 01;31
*.ear 01;31
*.sar 01;31
*.rar 01;31
*.alz 01;31
*.ace 01;31
*.zoo 01;31
*.cpio 01;31
*.7z 01;31
*.rz 01;31
*.cab 01;31
*.wim 01;31
*.swm 01;31
*.dwm 01;31
*.esd 01;31
# image formats (dircolors defaults)
*.jpg 01;35
*.jpeg 01;35
*.mjpg 01;35
*.mjpeg 01;35
*.gif 01;35
*.bmp 01;35
*.pbm 01;35
*.pgm 01;35
*.ppm 01;35
*.tga 01;35
*.xbm 01;35
*.xpm 01;35
*.tif 01;35
*.tiff 01;35
*.png 01;35
*.svg 01;35
*.svgz 01;35
*.mng 01;35
*.pcx 01;35
*.mov 01;35
*.mpg 01;35
*.mpeg 01;35
*.m2v 01;35
*.mkv 01;35
*.webm 01;35
*.ogm 01;35
*.mp4 01;35
*.m4v 01;35
*.mp4v 01;35
*.vob 01;35
*.qt 01;35
*.nuv 01;35
*.wmv 01;35
*.asf 01;35
*.rm 01;35
*.rmvb 01;35
*.flc 01;35
*.avi 01;35
*.fli 01;35
*.flv 01;35
*.gl 01;35
*.dl 01;35
*.xcf 01;35
*.xwd 01;35
*.yuv 01;35
*.cgm 01;35
*.emf 01;35
*.ogv 01;35
*.ogx 01;35
# audio formats (dircolors defaults)
*.aac 00;36
*.au 00;36
*.flac 00;36
*.m4a 00;36
*.mid 00;36
*.midi 00;36
*.mka 00;36
*.mp3 00;36
*.mpc 00;36
*.ogg 00;36
*.ra 00;36
*.wav 00;36
*.oga 00;36
*.opus 00;36
*.spx 00;36
*.xspf 00;36
# image formats (dircolors defaults)
~/Projects 01;32

340
.config/lf/icons Normal file
View File

@ -0,0 +1,340 @@
# file types
ln  # LINK
or  # ORPHAN
tw t # STICKY_OTHER_WRITABLE
# ow  # OTHER_WRITABLE
ow  # OTHER_WRITABLE
st t # STICKY
# di  # OTHER_WRITABLE
di  # DIR
pi p # FIFO
so s # SOCK
bd b # BLK
cd c # CHR
su u # SETUID
sg g # SETGID
ex  # EXEC
# fi  # FILE
# fi  # FILE
fi 󰈔 # FILE
# file extensions (vim-devicons)
*.styl 
*.sass 
*.scss 
*.htm 
*.html 
*.slim 
*.haml 
*.ejs 
*.css 
*.less 
*.md 
*.mdx 
*.markdown 
*.rmd 
*.json 
*.webmanifest 
*.js 
*.mjs 
*.jsx 
*.rb 
*.gemspec 
*.rake 
*.php 
*.py 
*.pyc 
*.pyo 
*.pyd 
*.coffee 
*.mustache 
*.hbs 
*.conf 
*.ini 
*.yml 
*.yaml 
*.toml 
*.bat 
*.mk 
*.jpg 
*.jpeg 
*.bmp 
*.png 
*.webp 
*.gif 
*.ico 
*.twig 
*.cpp 
*.c++ 
*.cxx 
*.cc 
*.cp 
*.c 
*.cs 
*.h 
*.hh 
*.hpp 
*.hxx 
*.hs 
*.lhs 
*.nix 
*.lua 
*.java 
*.sh 
*.fish 
*.bash 
*.zsh 
*.ksh 
*.csh 
*.awk 
*.ps1 
*.ml λ
*.mli λ
*.diff 
*.db 
*.sql 
*.dump 
*.clj 
*.cljc 
*.cljs 
*.edn 
*.scala 
*.go 
*.dart 
*.xul 
*.sln 
*.suo 
*.pl 
*.pm 
*.t 
*.rss 
'*.f#' 
*.fsscript 
*.fsx 
*.fs 
*.fsi 
*.rs 
*.rlib 
*.d 
*.erl 
*.hrl 
*.ex 
*.exs 
*.eex 
*.leex 
*.heex 
*.vim 
*.ai 
*.psd 
*.psb 
*.ts 
*.tsx 
*.jl 
*.pp 
*.vue 󰡄
*.elm 
*.swift 
*.xcplayground 
*.tex 󰿈
*.r 󰟔
*.rproj 鉶
*.sol ﲹ
*.pem 
# file names (vim-devicons) (case-insensitive not supported in lf)
*gruntfile.coffee 
*gruntfile.js 
*gruntfile.ls 
*gulpfile.coffee 
*gulpfile.js 
*gulpfile.ls 
*mix.lock 
*dropbox 
*.ds_store 
*.gitconfig 
*.gitignore 
*.gitattributes 
*.gitlab-ci.yml 
*.bashrc 
*.zshrc 
*.zshenv 
*.zprofile 
*.vimrc 
*.gvimrc 
*_vimrc 
*_gvimrc 
*.bashprofile 
*favicon.ico 
*license 
*node_modules 
*react.jsx 
*procfile 
*dockerfile 
*docker-compose.yml 
*rakefile 
*config.ru 
*gemfile 
*makefile 
*cmakelists.txt 
*robots.txt 󱙺
# file names (case-sensitive adaptations)
*Gruntfile.coffee 
*Gruntfile.js 
*Gruntfile.ls 
*Gulpfile.coffee 
*Gulpfile.js 
*Gulpfile.ls 
*Dropbox 
*.DS_Store 
*LICENSE 
*React.jsx 
*Procfile 
*Dockerfile 
*Docker-compose.yml 
*Rakefile 
*Gemfile 
*Makefile 
*CMakeLists.txt 
# file patterns (vim-devicons) (patterns not supported in lf)
# .*jquery.*\.js$ 
# .*angular.*\.js$ 
# .*backbone.*\.js$ 
# .*require.*\.js$ 
# .*materialize.*\.js$ 
# .*materialize.*\.css$ 
# .*mootools.*\.js$ 
# .*vimrc.* 
# Vagrantfile$ 
# file patterns (file name adaptations)
*jquery.min.js 
*angular.min.js 
*backbone.min.js 
*require.min.js 
*materialize.min.js 
*materialize.min.css 
*mootools.min.js 
*vimrc 
Vagrantfile 
# archives or compressed (extensions from dircolors defaults)
*.tar 
*.tgz 
*.arc 
*.arj 
*.taz 
*.lha 
*.lz4 
*.lzh 
*.lzma 
*.tlz 
*.txz 
*.tzo 
*.t7z 
*.zip 
*.z 
*.dz 
*.gz 
*.lrz 
*.lz 
*.lzo 
*.xz 
*.zst 
*.tzst 
*.bz2 
*.bz 
*.tbz 
*.tbz2 
*.tz 
*.deb 
*.rpm 
*.jar 
*.war 
*.ear 
*.sar 
*.rar 
*.alz 
*.ace 
*.zoo 
*.cpio 
*.7z 
*.rz 
*.cab 
*.wim 
*.swm 
*.dwm 
*.esd 
# image formats (extensions from dircolors defaults)
*.jpg 
*.jpeg 
*.mjpg 
*.mjpeg 
*.gif 
*.bmp 
*.pbm 
*.pgm 
*.ppm 
*.tga 
*.xbm 
*.xpm 
*.tif 
*.tiff 
*.png 
*.svg 
*.svgz 
*.mng 
*.pcx 
*.mov 
*.mpg 
*.mpeg 
*.m2v 
*.mkv 󰕧
*.webm 󰕧
*.ogm 
*.mp4 󰕧
*.m4v 
*.mp4v 
*.vob 
*.qt 
*.nuv 
*.wmv 
*.asf 
*.rm 
*.rmvb 
*.flc 
*.avi 
*.fli 
*.flv 
*.gl 
*.dl 
*.xcf 
*.xwd 
*.yuv 
*.cgm 
*.emf 
*.ogv 
*.ogx 
# audio formats (extensions from dircolors defaults)
*.aac 󰝚
*.au 󰝚
*.flac 󰝚
*.m4a 󰝚
*.mid 󰝚
*.midi 󰝚
*.mka 󰝚
*.mp3 󰝚
*.mpc 󰝚
*.ogg 󰝚
*.ra 󰝚
*.wav 󰝚
*.oga 󰝚
*.opus 󰝚
*.spx 󰝚
*.xspf 󰝚
# other formats
*.pdf 

210
.config/lf/lfrc Normal file
View File

@ -0,0 +1,210 @@
# Basic vars
set shellopts '-eu'
set ifs "\n"
set scrolloff 8
set icons
set hidden!
set period 1
set sortby ext
set hiddenfiles ".*:*.aux:*.log:*.bbl:*.bcf:*.blg:*.run.xml"
set promptfmt "\033[32m \033[35;1m%d\033[0m\033[1m%f\033[0m"
# set cleaner '~/.config/lf/cleaner'
# set previewer '~/.config/lf/scope'
set autoquit true
set cursorpreviewfmt "\033[7m"
set previewer ctpv
set cleaner ctpvclear
&ctpv -s $id
&ctpvquit $id
# cmds/functions
cmd open ${{
case $(file --mime-type "$(readlink -f $f)" -b) in
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) localc $fx ;;
image/vnd.djvu|application/pdf|application/octet-stream|application/postscript) setsid -f zathura $fx >/dev/null 2>&1 ;;
text/html) $EDITOR $fx;;
text/*|application/json|inode/x-empty|application/x-subrip|application/javascript) $EDITOR $fx;;
image/x-xcf) setsid -f gimp $f >/dev/null 2>&1 ;;
image/svg+xml) display -- $f ;;
image/*) rotdir $f | grep -i "\.\(png\|jpg\|jpeg\|gif\|webp\|avif\|tif\|ico\)\(_large\)*$" |
setsid -f nsxiv -aio 2>/dev/null | while read -r file; do
[ -z "$file" ] && continue
lf -remote "send select \"$file\""
lf -remote "send toggle"
done &
;;
audio/*|video/x-ms-asf) setsid -f mpv --loop-file --audio-display=no $f ;;
video/*) setsid -f mpv --loop-file $f -quiet >/dev/null 2>&1 ;;
application/pdf|application/vnd.djvu|application/epub*) setsid -f zathura $fx >/dev/null 2>&1 ;;
application/pgp-encrypted) $EDITOR $fx ;;
application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.oasis.opendocument.text|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet|application/octet-stream|application/vnd.oasis.opendocument.spreadsheet|application/vnd.oasis.opendocument.spreadsheet-template|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/vnd.oasis.opendocument.presentation-template|application/vnd.oasis.opendocument.presentation|application/vnd.ms-powerpoint|application/vnd.oasis.opendocument.graphics|application/vnd.oasis.opendocument.graphics-template|application/vnd.oasis.opendocument.formula|application/vnd.oasis.opendocument.database) setsid -f libreoffice $fx >/dev/null 2>&1 ;;
*) for f in $fx; do setsid -f $OPENER $f >/dev/null 2>&1; done;;
esac
}}
cmd on-cd &{{
# display repository status in your prompt
if [ -d .git ] || [ -f .git ]; then
branch=$(git branch --show-current 2>/dev/null) || true
remote=$(git config --get branch.$branch.remote 2>/dev/null) || true
url=$(git remote get-url $remote 2>/dev/null) || true
# "\033[32m \033[35;1m%d\033[0m\033[1m%f\033[0m"
fmt="\033[32m \033[35;1m%d\033[0m\033[1m%f\033[32m  $branch 󰄾 $url\033[0m"
elif [ -d .hg ]; then
hg=$(hg branch 2>/dev/null) || true
fmt="\033[32;1m%u@%h\033[0m:\033[34;1m%w\033[0m\033[33;1m [HG BRANCH:> $hg]\033[0m"
elif [ -d .svn ]; then
svn=$(svn info 2>/dev/null | awk '/^URL: /{print $2}') || true
fmt="\033[32;1m%u@%h\033[0m:\033[34;1m%w\033[0m\033[33;1m [SVN URL:> $svn]\033[0m"
else
fmt="\033[32m \033[35;1m%d\033[0m\033[1m%f\033[0m"
fi
lf -remote "send $id set promptfmt \"$fmt\""
}}
cmd fzf_search ${{
selected=$(fzf-fd)
if [ -n "$selected" ]; then
lf "$selected"
fi
}}
cmd fzf_grep ${{
fzf-grep "$f"
}}
cmd live_sever ${{
killall live-server; setsid -f live-server "$f"
}}
cmd ff $ff "$(echo $*)"
cmd extract ${{
clear; tput cup $(($(tput lines)/3)); tput bold
set -f
printf "%s\n\t" "$fx"
printf "extract?[y/N]"
read ans
[ $ans = "y" ] && {
case $fx in
*.tar.bz2) tar xjf $fx ;;
*.tar.gz) tar xzf $fx ;;
*.bz2) bunzip2 $fx ;;
*.rar) unrar e $fx ;;
*.gz) gunzip $fx ;;
*.tar) tar xf $fx ;;
*.tbz2) tar xjf $fx ;;
*.tgz) tar xzf $fx ;;
*.zip) unzip $fx ;;
*.Z) uncompress $fx ;;
*.7z) 7z x $fx ;;
*.tar.xz) tar xf $fx ;;
esac
}
}}
cmd delete ${{
clear; tput cup $(($(tput lines)/3)); tput bold
set -f
printf "%s\n\t" "$fx"
printf "delete?[y/N]"
read ans
[ $ans = "y" ] && rm -rf -- $fx
}}
cmd moveto ${{
clear; tput cup $(($(tput lines)/3)); tput bold
set -f
clear; echo "Move to where?"
dest="$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf | sed 's|~|$HOME|')" &&
for x in $fx; do
eval mv -iv \"$x\" \"$dest\"
done &&
notify-send "🚚 File(s) moved." "File(s) moved to $dest."
}}
cmd copyto ${{
clear; tput cup $(($(tput lines)/3)); tput bold
set -f
clear; echo "Copy to where?"
dest="$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf | sed 's|~|$HOME|')" &&
for x in $fx; do
eval cp -ivr \"$x\" \"$dest\"
done &&
notify-send "📋 File(s) copied." "File(s) copies to $dest."
}}
cmd setbg "$1"
cmd bulkrename ${{
tmpfile_old="$(mktemp)"
tmpfile_new="$(mktemp)"
[ -n "$fs" ] && fs=$(basename -a $fs) || fs=$(ls)
echo "$fs" > "$tmpfile_old"
echo "$fs" > "$tmpfile_new"
$EDITOR "$tmpfile_new"
[ "$(wc -l < "$tmpfile_old")" -eq "$(wc -l < "$tmpfile_new")" ] || { rm -f "$tmpfile_old" "$tmpfile_new"; exit 1; }
paste "$tmpfile_old" "$tmpfile_new" | while IFS="$(printf '\t')" read -r src dst
do
[ "$src" = "$dst" ] || [ -e "$dst" ] || mv -- "$src" "$dst"
done
rm -f "$tmpfile_old" "$tmpfile_new"
lf -remote "send $id unselect"
}}
cmd git_branch ${{
git branch | fzf | xargs git checkout
pwd_shell=$(pwd | sed 's/\\/\\\\/g;s/"/\\"/g')
lf -remote "send $id updir"
lf -remote "send $id cd \"$pwd_shell\""
}}
map gb :git_branch
map gp ${{clear; git pull --rebase || true; echo "press ENTER"; read ENTER}}
map gs ${{clear; git status; echo "press ENTER"; read ENTER}}
map gl ${{clear; git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit}}
# Bindings
map / :fzf_search
map ? :fzf_grep
map S live_server
map J $lf -remote "send $id cd $(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf)"
map gh
map gg top
map D delete
map E extract
map C copyto
map M moveto
map <c-n> push :ff<space>
map <c-r> reload
map <c-s> set hidden!
map <enter> shell
map x $$f
map X !$f
map o &mimeopen "$f"
map O $mimeopen --ask "$f"
map A :rename; cmd-end # at the very end
map c push A<c-u> # new rename
map I :rename; cmd-home # at the very beginning
map i :rename # before extension
map a :rename; cmd-right # after extension
map B bulkrename
map b $setbg $f
map <c-e> down
map <c-y> up
map V push :!nvim<space>
map W $setsid -f $TERMINAL >/dev/null 2>&1
map Y $printf "%s" "$fx" | xclip -selection clipboard
# Source Bookmarks
source "~/.config/lf/shortcutrc"

134
.config/lsd/config.yaml Normal file
View File

@ -0,0 +1,134 @@
# == Classic ==
# This is a shorthand to override some of the options to be backwards compatible
# with `ls`. It affects the "color"->"when", "sorting"->"dir-grouping", "date"
# and "icons"->"when" options.
# Possible values: false, true
classic: false
# == Blocks ==
# This specifies the columns and their order when using the long and the tree
# layout.
# Possible values: permission, user, group, context, size, date, name, inode, links
blocks:
- permission
- date
- name
- size
# == Color ==
# This has various color options. (Will be expanded in the future.)
color:
# When to colorize the output.
# When "classic" is set, this is set to "never".
# Possible values: never, auto, always
when: auto
# How to colorize the output.
# When "classic" is set, this is set to "no-color".
# Possible values: default, <theme-file-name>
# when specifying <theme-file-name>, lsd will look up theme file
# XDG Base Directory if relative, e.g. ~/.config/lsd/themes/<theme-file-name>.yaml,
# The file path if absolute
theme: default
# == Date ==
# This specifies the date format for the date column. The freeform format
# accepts a strftime like string.
# When "classic" is set, this is set to "date".
# Possible values: date, relative, '+<date_format>'
# `date_format` will be a `strftime` formatted value. e.g. `date: '+%d %b %y %X'` will give you a date like this: 17 Jun 21 20:14:55
date: '+%b-%d %I:%M %P'
# == Dereference ==
# Whether to dereference symbolic links.
# Possible values: false, true
dereference: false
# == Display ==
# What items to display. Do not specify this for the default behavior.
# Possible values: all, almost-all, directory-only
# display: all
# == Icons ==
icons:
# When to use icons.
# When "classic" is set, this is set to "never".
# Possible values: always, auto, never
when: auto
# Which icon theme to use.
# Possible values: fancy, unicode
theme: fancy
# Separator between icon and the name
# Default to 1 space
separator: " "
# == Ignore Globs ==
# A list of globs to ignore when listing.
# ignore-globs:
# - .git
# == Indicators ==
# Whether to add indicator characters to certain listed files.
# Possible values: false, true
indicators: false
# == Layout ==
# Which layout to use. "oneline" might be a bit confusing here and should be
# called "one-per-line". It might be changed in the future.
# Possible values: grid, tree, oneline
layout: grid
# == Recursion ==
recursion:
# Whether to enable recursion.
# Possible values: false, true
enabled: false
# How deep the recursion should go. This has to be a positive integer. Leave
# it unspecified for (virtually) infinite.
# depth: 3
# == Size ==
# Specifies the format of the size column.
# Possible values: default, short, bytes
size: default
# == Permission ==
# Specify the format of the permission column
# Possible value: rwx, octal
permission: rwx
# == Sorting ==
sorting:
# Specify what to sort by.
# Possible values: extension, name, time, size, version
column: name
# Whether to reverse the sorting.
# Possible values: false, true
reverse: false
# Whether to group directories together and where.
# When "classic" is set, this is set to "none".
# Possible values: first, last, none
dir-grouping: none
# == No Symlink ==
# Whether to omit showing symlink targets
# Possible values: false, true
no-symlink: false
# == Total size ==
# Whether to display the total size oZf directories.
# Possible values: false, true
total-size: false
# == Hyperlink ==
# Attach hyperlink to filenames
# Possible values: always, auto, never
hyperlink: never
# == Symlink arrow ==
# Specifies how the symlink arrow display, chars in both ascii and utf8
symlink-arrow:
# == Header ==
# Whether to display block headers.
# Possible values: false, true
header: false

21
.config/mpd/mpd.conf Normal file
View File

@ -0,0 +1,21 @@
music_directory "~/Music"
playlist_directory "~/.config/mpd/playlists"
auto_update "yes"
bind_to_address "127.0.0.1"
restore_paused "yes"
max_output_buffer_size "16384"
audio_output {
type "pulse"
name "pulse"
#type "alsa"
#name "ALSA"
}
audio_output {
type "fifo"
name "Visualizer feed"
path "/tmp/mpd.fifo"
format "44100:16:2"
}

5
.config/mpv/input.conf Normal file
View File

@ -0,0 +1,5 @@
l seek 5
h seek -5
j seek -60
k seek 60
S cycle sub

22
.config/mpv/mpv.conf Normal file
View File

@ -0,0 +1,22 @@
# profile=gpu-hq
profile=fast
profile=pseudo-gui
# scale=ewa_lanczossharp
save-position-on-quit=yes
force-seekable=yes
autofit-smaller=858x480 # min window size.
osd-font='Lucida Grande'
osd-font-size=18
# Using uosc and thumbfast
osc=no
osd-bar=no
border=no
volume=75 # 75% on startup.
volume-max=100 # max vol to 100%.
#Youtube videos in 360p or less.
ytdl-format=bestvideo[height<=?360]+bestaudio/best

475
.config/ncmpcpp/bindings Normal file
View File

@ -0,0 +1,475 @@
##############################################################
## This is the example bindings file. Copy it to ##
## ~/.ncmpcpp/bindings or $XDG_CONFIG_HOME/ncmpcpp/bindings ##
## and set up your preferences ##
##############################################################
#
#def_key "mouse"
# mouse_event
#
#def_key "up"
# scroll_up
#
#def_key "shift-up"
# select_item
# scroll_up
#
#def_key "down"
# scroll_down
#
#def_key "shift-down"
# select_item
# scroll_down
#
#def_key "["
# scroll_up_album
#
#def_key "]"
# scroll_down_album
#
#def_key "{"
# scroll_up_artist
#
#def_key "}"
# scroll_down_artist
#
#def_key "page_up"
# page_up
#
#def_key "page_down"
# page_down
#
#def_key "home"
# move_home
#
#def_key "end"
# move_end
#
#def_key "insert"
# select_item
#
#def_key "enter"
# enter_directory
#
#def_key "enter"
# toggle_output
#
#def_key "enter"
# run_action
#
#def_key "enter"
# play_item
#
#def_key "space"
# add_item_to_playlist
#
#def_key "space"
# toggle_lyrics_update_on_song_change
#
#def_key "space"
# toggle_visualization_type
#
#def_key "delete"
# delete_playlist_items
#
#def_key "delete"
# delete_browser_items
#
#def_key "delete"
# delete_stored_playlist
#
#def_key "right"
# next_column
#
#def_key "right"
# slave_screen
#
#def_key "right"
# volume_up
#
#def_key "+"
# volume_up
#
#def_key "left"
# previous_column
#
#def_key "left"
# master_screen
#
#def_key "left"
# volume_down
#
#def_key "-"
# volume_down
#
#def_key ":"
# execute_command
#
#def_key "tab"
# next_screen
#
#def_key "shift-tab"
# previous_screen
#
#def_key "f1"
# show_help
#
#def_key "1"
# show_playlist
#
#def_key "2"
# show_browser
#
#def_key "2"
# change_browse_mode
#
#def_key "3"
# show_search_engine
#
#def_key "3"
# reset_search_engine
#
#def_key "4"
# show_media_library
#
#def_key "4"
# toggle_media_library_columns_mode
#
#def_key "5"
# show_playlist_editor
#
#def_key "6"
# show_tag_editor
#
#def_key "7"
# show_outputs
#
#def_key "8"
# show_visualizer
#
#def_key "="
# show_clock
#
#def_key "@"
# show_server_info
#
#def_key "s"
# stop
#
#def_key "p"
# pause
#
#def_key ">"
# next
#
#def_key "<"
# previous
#
#def_key "ctrl-h"
# jump_to_parent_directory
#
#def_key "ctrl-h"
# replay_song
#
#def_key "backspace"
# jump_to_parent_directory
#
#def_key "backspace"
# replay_song
#
def_key "right"
seek_forward
def_key "left"
seek_backward
#def_key "r"
# toggle_repeat
#
#def_key "z"
# toggle_random
#
#def_key "y"
# save_tag_changes
#
#def_key "y"
# start_searching
#
#def_key "y"
# toggle_single
#
#def_key "R"
# toggle_consume
#
#def_key "Y"
# toggle_replay_gain_mode
#
#def_key "T"
# toggle_add_mode
#
#def_key "|"
# toggle_mouse
#
#def_key "#"
# toggle_bitrate_visibility
#
#def_key "Z"
# shuffle
#
#def_key "x"
# toggle_crossfade
#
#def_key "X"
# set_crossfade
#
#def_key "u"
# update_database
#
#def_key "ctrl-s"
# sort_playlist
#
#def_key "ctrl-s"
# toggle_browser_sort_mode
#
#def_key "ctrl-s"
# toggle_media_library_sort_mode
#
#def_key "ctrl-r"
# reverse_playlist
#
#def_key "ctrl-f"
# apply_filter
#
#def_key "ctrl-_"
# select_found_items
#
#def_key "/"
# find
#
#def_key "/"
# find_item_forward
#
#def_key "?"
# find
#
#def_key "?"
# find_item_backward
#
#def_key "."
# next_found_item
#
#def_key ","
# previous_found_item
#
#def_key "w"
# toggle_find_mode
#
#def_key "e"
# edit_song
#
#def_key "e"
# edit_library_tag
#
#def_key "e"
# edit_library_album
#
#def_key "e"
# edit_directory_name
#
#def_key "e"
# edit_playlist_name
#
#def_key "e"
# edit_lyrics
#
#def_key "i"
# show_song_info
#
#def_key "I"
# show_artist_info
#
#def_key "g"
# jump_to_position_in_song
#
#def_key "l"
# show_lyrics
#
#def_key "ctrl-v"
# select_range
#
#def_key "v"
# reverse_selection
#
#def_key "V"
# remove_selection
#
#def_key "B"
# select_album
#
#def_key "a"
# add_selected_items
#
#def_key "c"
# clear_playlist
#
#def_key "c"
# clear_main_playlist
#
#def_key "C"
# crop_playlist
#
#def_key "C"
# crop_main_playlist
#
#def_key "m"
# move_sort_order_up
#
#def_key "m"
# move_selected_items_up
#
#def_key "n"
# move_sort_order_down
#
#def_key "n"
# move_selected_items_down
#
#def_key "M"
# move_selected_items_to
#
#def_key "A"
# add
#
#def_key "S"
# save_playlist
#
#def_key "o"
# jump_to_playing_song
#
#def_key "G"
# jump_to_browser
#
#def_key "G"
# jump_to_playlist_editor
#
#def_key "~"
# jump_to_media_library
#
#def_key "E"
# jump_to_tag_editor
#
#def_key "U"
# toggle_playing_song_centering
#
#def_key "P"
# toggle_display_mode
#
#def_key "\\"
# toggle_interface
#
#def_key "!"
# toggle_separators_between_albums
#
#def_key "L"
# toggle_lyrics_fetcher
#
#def_key "F"
# fetch_lyrics_in_background
#
#def_key "alt-l"
# toggle_fetching_lyrics_in_background
#
#def_key "ctrl-l"
# toggle_screen_lock
#
#def_key "`"
# toggle_library_tag_type
#
#def_key "`"
# refetch_lyrics
#
#def_key "`"
# add_random_items
#
#def_key "ctrl-p"
# set_selected_items_priority
#
#def_key "q"
# quit
#
#
#def_key "f"
# find
#def_key "f"
# find_item_forward
def_key "+"
show_clock
def_key "="
volume_up
def_key "j"
scroll_down
def_key "k"
scroll_up
def_key "ctrl-u"
page_up
#push_characters "kkkkkkkkkkkkkkk"
def_key "ctrl-d"
page_down
#push_characters "jjjjjjjjjjjjjjj"
def_key "u"
page_up
#push_characters "kkkkkkkkkkkkkkk"
def_key "d"
page_down
#push_characters "jjjjjjjjjjjjjjj"
def_key "h"
previous_column
def_key "l"
next_column
def_key "."
show_lyrics
def_key "n"
next_found_item
def_key "N"
previous_found_item
# not used but bound
def_key "J"
move_sort_order_down
def_key "K"
move_sort_order_up
def_key "h"
jump_to_parent_directory
def_key "l"
enter_directory
def_key "l"
run_action
def_key "l"
play_item
def_key "m"
show_media_library
def_key "m"
toggle_media_library_columns_mode
def_key "t"
show_tag_editor
def_key "v"
show_visualizer
def_key "G"
move_end
def_key "g"
move_home
#jump_to_position_in_song
def_key "U"
update_database
def_key "s"
reset_search_engine
def_key "s"
show_search_engine
def_key "x"
delete_playlist_items
def_key "P"
show_playlist

46
.config/ncmpcpp/config Normal file
View File

@ -0,0 +1,46 @@
# vim: filetype=conf
ncmpcpp_directory = "~/.config/ncmpcpp"
lyrics_directory = "~/.local/share/lyrics"
mpd_music_dir = "~/Music"
message_delay_time = "1"
visualizer_type = "spectrum"
visualizer_spectrum_dft_size = 4
user_interface = "alternative"
startup_screen = "browser"
ignore_leading_the = yes
external_editor = nvim
use_console_editor = yes
execute_on_song_change="pkill -RTMIN+11 dwmblocks"
cyclic_scrolling = "yes"
mouse_support = "yes"
mouse_list_scroll_whole_page = "yes"
lines_scrolled = "1"
playlist_shorten_total_times = "yes"
playlist_display_mode = "classic"
browser_display_mode = "classic"
browser_sort_mode = "mtime"
search_engine_display_mode = "classic"
playlist_editor_display_mode = "classic"
autocenter_mode = "yes"
centered_cursor = "yes"
follow_now_playing_lyrics = "yes"
locked_screen_width_part = "50"
ask_for_locked_screen_width_part = "no"
display_bitrate = "no"
main_window_color = "default"
progressbar_look = "━━ "
progressbar_elapsed_color = "magenta"
header_visibility = "no"
statusbar_visibility = "yes"
titles_visibility = "yes"
enable_window_title = "yes"
clock_display_seconds = no
color1 = "white"
color2 = "blue"
now_playing_prefix = "$b$6 "
now_playing_suffix = "$/b$9"
current_item_prefix = "$b$3 "
song_list_format = "{{%a - %t}|{%f}}{$R%l}"
song_status_format = {%a - %t}|{%f}
song_library_format = {{%a - %t} (%b)}|{%f}

View File

@ -0,0 +1,28 @@
[dmenu]
dmenu_command = dmenu -i -bw 2 -W 250 -X 1101 -Y 15 -l 15
# # Note that dmenu_command can contain arguments as well like:
# # `dmenu_command = rofi -dmenu -i -theme nmdm`
# # `dmenu_command = rofi -dmenu -width 30 -i`
# # `dmenu_command = dmenu -i -l 25 -b -nb #909090 -nf #303030`
# rofi_highlight = <True or False> # (Default: False) use rofi highlighting instead of '=='
rofi_highlight = True
# compact = <True or False> # (Default: False). Remove extra spacing from display
compact = True
# pinentry = <Pinentry command> # (Default: None) e.g. `pinentry-gtk`
# wifi_chars = <string of 4 unicode characters representing 1-4 bars strength>
# wifi_chars = ▂▄▆█
# list_saved = <True or False> # (Default: False) list saved connections
[dmenu_passphrase]
# # Uses the -password flag for Rofi, -x for bemenu. For dmenu, sets -nb and
# # -nf to the same color or uses -P if the dmenu password patch is applied
# # https://tools.suckless.org/dmenu/patches/password/
obscure = True
# obscure_color = #222222
[editor]
# terminal = <name of terminal program>
# gui_if_available = <True or False> (Default: True)
[nmdm]
# rescan_delay = <seconds> # (seconds to wait after a wifi rescan before redisplaying the results)

13
.config/nvim/.luarc.json Normal file
View File

@ -0,0 +1,13 @@
{
"runtime.version": "LuaJIT",
"runtime.path": [
"lua/?.lua",
"lua/?/init.lua"
],
"diagnostics.globals": ["vim"],
"workspace.checkThirdParty": false,
"workspace.library": [
"$VIMRUNTIME",
"./lua"
]
}

3
.config/nvim/README.md Normal file
View File

@ -0,0 +1,3 @@
# Neovim
#Features:

7
.config/nvim/init.lua Normal file
View File

@ -0,0 +1,7 @@
vim.g.mapleader = " "
vim.g.maplocalleader = " "
require("options")
require("manager")
require("autocommands")
require("mappings")

View File

@ -0,0 +1,67 @@
{
"Comment.nvim": { "branch": "master", "commit": "0236521ea582747b58869cb72f70ccfa967d2e89" },
"LuaSnip": { "branch": "master", "commit": "72eea98b1900013e0cb214f29b898c8d91564930" },
"alpha-nvim": { "branch": "main", "commit": "41283fb402713fc8b327e60907f74e46166f4cfd" },
"cmp-async-path": { "branch": "main", "commit": "7df7f3721c45aac26b6e0474087538f4681c9c7a" },
"cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" },
"cmp-calc": { "branch": "main", "commit": "ce91d14d2e7a8b3f6ad86d85e34d41c1ae6268d9" },
"cmp-nvim-lsp": { "branch": "main", "commit": "5af77f54de1b16c34b23cba810150689a3a90312" },
"cmp-spell": { "branch": "master", "commit": "32a0867efa59b43edbb2db67b0871cfad90c9b66" },
"cmp-vimtex": { "branch": "master", "commit": "613fbfc54d9488252b0b0289d6d1d60242513558" },
"cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" },
"flit.nvim": { "branch": "main", "commit": "56490317983218b09698f8c960c3669958b12b32" },
"friendly-snippets": { "branch": "main", "commit": "ea068f1becd91bcd4591fceb6420d4335e2e14d3" },
"fzf-lua": { "branch": "main", "commit": "6860237cbcc6e95d26ffdb22e4fe7a65b2b3e60d" },
"gitsigns.nvim": { "branch": "main", "commit": "035da036e68e509ed158414416c827d022d914bd" },
"harpoon": { "branch": "harpoon2", "commit": "0378a6c428a0bed6a2781d459d7943843f374bce" },
"indent-blankline.nvim": { "branch": "master", "commit": "3d08501caef2329aba5121b753e903904088f7e6" },
"lazy.nvim": { "branch": "main", "commit": "31ddbea7c10b6920c9077b66c97951ca8682d5c8" },
"leap.nvim": { "branch": "main", "commit": "626be4c4ec040aeaf6466c9aae17ee0ab09f1a5b" },
"lf.nvim": { "branch": "master", "commit": "69ab1efcffee6928bf68ac9bd0c016464d9b2c8b" },
"lsp-zero.nvim": { "branch": "v3.x", "commit": "b93f040edd57888cd6a1e7d9dee47dddc4463f8f" },
"lspkind.nvim": { "branch": "master", "commit": "1735dd5a5054c1fb7feaf8e8658dbab925f4f0cf" },
"lualine.nvim": { "branch": "master", "commit": "0a5a66803c7407767b799067986b4dc3036e1983" },
"luasnip-latex-snippets.nvim": { "branch": "main", "commit": "6b5e24bd30735713b290c8523590197340da3e51" },
"markdown-preview.nvim": { "branch": "main", "commit": "462ce41af003f5cdadab856f3a42dc27e39b89c8" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "f3658bfc667df6a0340194a015ac2f31c1e675e0" },
"mason-nvim-dap.nvim": { "branch": "main", "commit": "67210c0e775adec55de9826b038e8b62de554afc" },
"mason.nvim": { "branch": "main", "commit": "751b1fcbf3d3b783fcf8d48865264a9bcd8f9b10" },
"mini.ai": { "branch": "main", "commit": "ee9446a17c160aba6a04ff22097389c41872c878" },
"mini.surround": { "branch": "main", "commit": "d035934958e2605048ee1378ce47cf799f7071d4" },
"none-ls.nvim": { "branch": "main", "commit": "88821b67e6007041f43b802f58e3d9fa9bfce684" },
"nvim-autopairs": { "branch": "master", "commit": "4f41e5940bc0443fdbe5f995e2a596847215cd2a" },
"nvim-cmp": { "branch": "main", "commit": "ce16de5665c766f39c271705b17fff06f7bcb84f" },
"nvim-colorizer.lua": { "branch": "master", "commit": "85855b38011114929f4058efc97af1059ab3e41d" },
"nvim-dap": { "branch": "master", "commit": "6ae8a14828b0f3bff1721a35a1dfd604b6a933bb" },
"nvim-dap-ui": { "branch": "master", "commit": "edfa93f60b189e5952c016eee262d0685d838450" },
"nvim-dap-virtual-text": { "branch": "master", "commit": "3e8e207513e6ef520894950acd76b79902714103" },
"nvim-html-css": { "branch": "main", "commit": "c514bd27ad560636ed39dea3e370b3103754e244" },
"nvim-lspconfig": { "branch": "master", "commit": "ed8b8a15acc441aec669f97d75f2c1f2ac8c8aa5" },
"nvim-markdown": { "branch": "master", "commit": "75639723c1a3a44366f80cff11383baf0799bcb5" },
"nvim-nio": { "branch": "master", "commit": "5800f585def265d52f1d8848133217c800bcb25d" },
"nvim-spectre": { "branch": "master", "commit": "9653847cf2f225648967f6e9363643e327387579" },
"nvim-treesitter": { "branch": "master", "commit": "1e20226231add3f8fad4e28fd66a68e3ae370b93" },
"nvim-treesitter-textobjects": { "branch": "master", "commit": "23b820146956b3b681c19e10d3a8bc0cbd9a1d4c" },
"nvim-ts-autotag": { "branch": "main", "commit": "531f48334c422222aebc888fd36e7d109cb354cd" },
"nvim-ts-context-commentstring": { "branch": "main", "commit": "a6382f744f584bbf71d0a563af789af7190aabda" },
"nvim-ufo": { "branch": "main", "commit": "a5390706f510d39951dd581f6d2a972741b3fa26" },
"nvim-web-devicons": { "branch": "master", "commit": "beb6367ab8496c9e43f22e0252735fdadae1872d" },
"outline.nvim": { "branch": "main", "commit": "bdfd2da90e9a7686d00e55afa9f772c4b6809413" },
"persistence.nvim": { "branch": "main", "commit": "4982499c1636eac254b72923ab826ee7827b3084" },
"plenary.nvim": { "branch": "master", "commit": "8aad4396840be7fc42896e3011751b7609ca4119" },
"project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" },
"promise-async": { "branch": "main", "commit": "93540c168c5ed2b030ec3e6c40ab8bbb85e36355" },
"qalc.nvim": { "branch": "main", "commit": "d3072e5ac8dc1caa4b60f673c53f70c7e06f1367" },
"refactoring.nvim": { "branch": "master", "commit": "d2786877c91aa409c824f27b4ce8a9f560dda60a" },
"todo-comments.nvim": { "branch": "main", "commit": "a7e39ae9e74f2c8c6dc4eea6d40c3971ae84752d" },
"toggleterm.nvim": { "branch": "main", "commit": "dca1c80fb8ec41c97e7c3ef308719d8143fbbb05" },
"tokyonight.nvim": { "branch": "main", "commit": "9bf9ec53d5e87b025e2404069b71e7ebdc3a13e5" },
"trouble.nvim": { "branch": "main", "commit": "b9cf677f20bb2faa2dacfa870b084e568dca9572" },
"undotree": { "branch": "main", "commit": "eab459ab87dd249617b5f7187bb69e614a083047" },
"vim-be-good": { "branch": "master", "commit": "4fa57b7957715c91326fcead58c1fa898b9b3625" },
"vim-illuminate": { "branch": "master", "commit": "e522e0dd742a83506db0a72e1ced68c9c130f185" },
"vim-repeat": { "branch": "master", "commit": "24afe922e6a05891756ecf331f39a1f6743d3d5a" },
"vimtex": { "branch": "master", "commit": "a1ea8ea08d7b5c1a2adbaed693dd2d1ad0d788ce" },
"which-key.nvim": { "branch": "main", "commit": "4433e5ec9a507e5097571ed55c02ea9658fb268a" },
"zen-mode.nvim": { "branch": "main", "commit": "78557d972b4bfbb7488e17b5703d25164ae64e6a" }
}

297
.config/nvim/lua/ascii.lua Normal file
View File

@ -0,0 +1,297 @@
return {
-- great_slash = {
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⡀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠠⣀⣠⣶⣶⣶⣿⣿⣿⣟⠟⠉⠁ ⠉⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣵⣶⣿⣿⣿⡿⣟⢿⡝⠙⠀⠤⠤⣤⣤⡶⠂⠀]],
-- [[⠀⠀⠀⠀⢀⠴⣪⣾⣿⣿⣿⣿⣿⢿⡿⠃⢿⢸⣧⡍⠭⣭⣿⡿⠋⠀⠀⠀]],
-- [[⠀⠀⠀⢀⣵⣿⣿⣿⣿⣿⢯⠟⡵⠋ ⢠⢾⣿⣿⣿⡤⣼⢏⣠⣀⠀⠀⠀]],
-- [[⠀⢠⣰⣻⣿⣿⣿⣾⣿⣧⢡⣘⠁⠀⠀⠘⣄⣻⣿⣿⣷⣿⣿⡿⠍⠁⠀⠀]],
-- [[⠀⡇⡿⣿⣿⣿⡿⣿⡻⣿⣜⢄⣶⣤⣀⠀⠀⠀⠈⠛⢻⣟⠫⠉⠀⠀⠀⠀]],
-- [[⠀⠣⡻⣌⡻⠿⣿⣮⣽⣿⣶⣾⣿⣳⠶⠖⠬⠍⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠈⠀⠉⠉⠙⠛⠛⠒⠓⠒⠀⠀⠀⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- mothwing = {
-- [[⠀⠀⠀⠀⢠⣶⡦⠀⣠⣤⣤⣤⣀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⢸⣿⣧⣾⣿⣣⠄⣹⣿⠟⢆⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠙⣿⣿⣿⣷⣿⣾⣿⣧⣸⡆⠀]],
-- [[⠀⠀⠀⠀⠀⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀]],
-- [[⠀⠀⠀⠀⠀⠻⣮⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀]],
-- [[⠀⠀⠀⠀⡠⢞⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀]],
-- [[⠀⠀⡰⣓⣼⡿⡿⢻⣭⣾⣿⢿⢻⡰⠀⠀⠀]],
-- [[⠀⡮⡺⠕⡫⠋⣬⣴⣿⣿⣿⣸⠸⡱⡄⠀⠀]],
-- [[⠸⡰⡝⣨⠕⠊⠀⣿⣿⣿⠏⠏⣶⡕⡇⠀⠀]],
-- [[⠘⠀⡢⠁⠀⠀⠀⠋⠋⠀⠀⢰⡘⠰⠇⠀⠀]],
-- [[ ⠸⠁⠀⠀⠀⠀]],
-- },
-- radiance = {
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⡇⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢇⠀⠃⢀⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠷⣷⢷⣴⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣧⣅⣂⣧⣾⣷⣇⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⢀⠀⠀⠀⢀⢠⢐⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡷⠑⢆⣠⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠢⢦⣀⣴⣾⣿⣭⣶⠵⠩⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡛⣘⠿⣿⣷⠶⠿⠦⠴⠠⡀⠀]],
-- [[⠀⠀⢀⣀⣘⣩⣙⣫⣭⣶⡿⣫⣪⣭⢛⠿⣿⣿⡿⠋⣩⣝⢶⣝⡿⣶⣭⣓⡦⢍⠂⠄⠀⠀]],
-- [[⠀⠀⠀⠐⠋⠩⢭⣉⣩⣵⢞⣵⡿⠁⠊⢀⣻⣿⡁⠉⡪⡻⣷⣝⢿⣶⡝⠭⡙⠓⠤⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠈⠉⠉⢉⢉⠠⠟⠉⠂⠀⠀⠠⣭⢩⡤⠀⠁⠰⠈⠙⠷⡈⠙⢆⠀⠆⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠟⠸⢓⠀⠀⠀⠀⠀⠀⠑⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⢠⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣾⠸⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠀⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- suckless = {
-- [[ ]],
-- [[ ]],
-- [[ ]],
-- [[ ]],
-- [[ ▀ ]],
-- [[█▀█▄█▀█▀█▀█]],
-- [[ ]],
-- [[ ]],
-- },
-- venom = {
-- [[⠀⠀⢰⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀]],
-- [[⠀⠀⣾⣧⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣼⡇⠀]],
-- [[⠀⠀⡏⢿⣿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣾⣿⣿⡗⠀⠀]],
-- [[⠀⠀⠁⠘⣿⣿⣿⣿⣿⣷⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣿⣿⣿⣿⣿⠁⠀⠀]],
-- [[⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣷⣍⠡⠀⠀⠀⠀⠀⠀⢋⣽⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠹⣻⣿⣿⣿⣿⣿⣧⣀⠀⠀⠀⠠⣀⣾⣿⣿⣿⡿⣟⣿⠏⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠈⠹⠜⠋⠟⠿⠉⠀⠀⠀⠀⠀⠑⠻⢿⠙⠩⠫⠛⠁⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⢠⠠⡆⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⡀⢀⠀⠄⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠂⠇⠰⠄⡞⠀⣼⠀⣿⡄⢰⡷⠸⣧⢰⡆⠨⡂⡾⡐⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠈⠈⢧⢹⡇⢿⠀⢿⠇⠈⡇⠨⡟⢸⡇⡿⠡⠁⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠸⡀⢸⠀⠀⠇⢸⠃⡿⠘⠁⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠈⠀⠀⠀⠊⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⢳⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡎⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠘⠧⢢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡆⠏⠁⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠺⣆⢡⢠⠀⡀⢠⢀⡄⡆⣸⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠸⠘⢂⡆⢸⣸⢃⠇⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠋⠎⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- symbol = {
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⢂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠋⠀⠀]],
-- [[⠀⠀⢦⣀⠀⠈⢣⡀⠀⠀⣀⣀⣀⣀⣴⠁⣠⡶⠀⠀⢀⣴⠋⠁⠀⠀⠀]],
-- [[⠀⠀⠀⠙⢷⣄⠈⢿⡞⠛⠉⠉⠉⢹⠃⣠⡞⠀⣠⣴⠟⠀⢀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠙⢣⣀⢡⡶⠞⠛⠛⠣⢦⠝⣠⣾⠟⢁⣤⠔⠃⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠙⠣⠀⢀⣀⣀⣀⣴⣾⠿⠡⠚⠻⣧⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠰⣾⠟⢉⡉⠙⣿⡅⢀⡀⡀⠀⢹⡄⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠈⢀⡀⠻⠟⢀⣿⠃⠘⠶⠃⠀⢸⡇⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⢀⠠⡶⣡⠄⣠⡿⠿⠶⠶⠟⠉⠀⠀⠀⠀⢀⣿⠁⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠘⠂⢡⡾⠋⠀⠀⠀⠀⠀⠀⠀⠱⣤⣠⡾⠃⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠐⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠋⢴⡀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢦⡀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀]],
-- },
-- scorpion = {
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢤⢠⠠⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣔⡀⠚⠀⠀⠠⠒⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡟⠁⠀⠀⠀⢀⡋⢙⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠛⠀⠀⢀⠀⠀⢐⣣⠤⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠒⠁⠢⡄⠀⡈⠀⢐⠧⢀⠇⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢂⠀⠀⠀⣘⢀⠇⣀⡱⢈⡁⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠀⢀⣠⢤⡍⢛⡆⣻⡴⣾⡸⣎⣳⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⣀⣠⣤⣤⣀⡀⣀⣀⡀⠀⢇⣤⣷⣿⣴⣌⣰⡤⡁⢀⡤⠄⠠⡄⠀⠀]],
-- [[⠀⠀⠀⢈⣽⣿⣿⣿⣿⠟⠑⠉⠑⠷⠱⣮⢹⣿⣿⣿⠟⠸⡭⠬⢥⣄⠀⠀⢀⠀⠀]],
-- [[⠀⠀⠔⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⢛⣑⣓⢬⣕⠋⠙⢦⠀⢀⠍⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⢦⡃⠀⠀⡃⠀⢸⠀⠈⠂⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣄⠀⢀⣤⢾⠃⠁⠀⠀⠃⠁⠀⠉⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠐⢄⣀⣀⣠⣴⣿⣿⣿⢣⠞⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⢀⠀⠀⠈⠉⣹⣿⣿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠈⠉⠛⠛⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- raven = {
-- [[ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⠀ ]],
-- [[ ⠀⠀⢤⠘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠠⣢⢃⡶ ]],
-- [[ ⠀⠀⣼⡶⠘⠀⠀⠀⠀⠀⠀⠀⠀⢠⢀⠄⠀⠢⢼⣿⣿⣷⡅ ]],
-- [[ ⠠⠀⣿⣿⢇⡀⠀⠀⠀⠀⠀⠀⡤⠀⢈⢄⡇⣪⣿⣿⣿⢟⡠ ]],
-- [[ ⠀⢸⣿⣿⣟⡐⠁⣀⠀⠀⠀⣠⡤⡨⣳⣿⣿⣿⣿⣿⣿⡿⠃ ]],
-- [[ ⠀⠀⢻⣿⣿⣇⠸⠠⠀⠀⣠⣿⣷⣿⣿⣿⣿⣿⣿⣿⠿⠁⠁ ]],
-- [[ ⠀⠀⠀⠙⠿⣿⣮⣄⣄⣈⣾⣿⣿⣿⣿⣿⣿⣿⣿⢏⠹⠄⠃ ]],
-- [[ ⠀⠀⠀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠻⠀⠙⠠⠀⠀ ]],
-- [[ ⠀⠀⠀⠈⢤⡟⠻⣿⣿⣿⣿⣿⣿⡿⠿⡻⠳⠁⠀⠁⠀⠀⠀ ]],
-- [[ ⠀⠀⠀⠀⠀⠀⠁⠙⢿⣿⣿⣿⣿⣶⣾⣷⣶⣦⣤⠀⠀⠀⠀ ]],
-- [[ ⠀⠀⠀⠀⠀⢀⣤⡶⡖⠿⣿⣿⣿⣿⡿⠏⠝⠁⠀⠀⠀⠀⠀ ]],
-- [[ ⠀⠀⠀⠀⠀⠈⠀⠡⠔⠀⠈⠙⠙⠑⠂⠀⠀⠀⠀⠀⠀⠀⠀ ]],
-- },
yggdrasil = {
[[ ⠀⠀⠀⠀⠀⠀⢀⢀⠀⣄⢂⣀⣂⣤⣀⢀⢀⠀⠀⠀⠀⠀⠀ ]],
[[ ⠀⠀⠀⠀⣄⣰⣝⣉⣙⢱⣞⠜⡖⣌⣌⣁⣻⣠⣀⠀⠀⠀⠀ ]],
[[ ⠀⠀⢔⢽⣊⣂⣇⡒⠮⢻⣇⠲⢍⣿⢟⣒⣰⣠⣑⡔⣀⠀⠀ ]],
[[ ⠀⠹⡸⢙⣕⡐⢂⠍⣩⡻⣿⣆⣾⠟⣉⢣⠪⠲⡰⡋⣢⢆⠀ ]],
[[ ⠀⣪⡹⣵⢦⠽⡓⠶⠶⣧⣹⣿⣏⣴⠶⠛⠟⠽⢛⣒⢮⡙⠀ ]],
[[ ⠸⢋⢪⠑⢩⠈⠀⠀⠀⠈⣿⣿⣿⠁⠀⠀⠘⢠⠈⠆⢎⢱⠁ ]],
[[ ⠀⠻⡕⡲⡈⠀⠀⠀⠀⠀⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠆⠄⠁ ]],
[[ ⠀⠀⠀⠇⠀⠀⠀⠀⠀⣰⣿⣿⣿⣤⡀⠀⠀⠀⠀⠌⠘⠀⠀ ]],
[[ ⠀⠀⠀⢱⠒⡶⡶⢖⣫⡿⢻⠿⡟⢿⣍⡱⢖⠶⠒⡆⠀⠀⠀ ]],
[[ ⠀⠀⠀⠀⠁⠬⡃⠴⣇⣴⠏⠖⠙⣦⣸⠦⡼⠣⠉⠀⠀⠀⠀ ]],
[[ ⠀⠀⠀⠀⠀⠀⠈⠁⠑⠢⠧⠭⠼⠵⠋⠊⠁⠀⠀⠀⠀⠀⠀ ]],
},
-- void_stranger = {
-- [[]],
-- [[⠀⠀⠀⠀⠀⠀⣀⣴⣶⣄⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⣴⠋⠁⠈⣿⡟⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⣾⣏⣀⠠⠞⠉⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⣸⣿⠏⠀⠀⠀⠀ ⠀⣀⡀⠀⠀]],
-- [[⠀⢰⣿⣿⠀⠀⠀⠀⡠⠒⠿⣿⣿⣧⠀]],
-- [[⠀⠀⣿⣿⣷⣤⡠⠊⠀⠀⠀⢸⣿⣿⠀]],
-- [[⠀⠀⠈⠛⠋⠁⠀⠀⠀⠀⠀⣼⣿⡇⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⢀⡤⠖⠈⣿⡿⠀⠀]],
-- [[⠀⠀⠀⠀⠀⢀⣾⣿⠀⠀⣰⠗⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠘⠯⢻⠶⠊⠁⠀⠀⠀⠀]],
-- [[]],
-- },
-- aot = {
-- [[⠀⠀⠀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⡄⠀⠀]],
-- [[⢰⠒⠒⢻⣿⣶⡒⠒⠒⠒⠒⠒⠒⠒⠒⠒⡲⠊⣰⣓⡒⡆]],
-- [[⢸⢸⢻⣭⡙⢿⣿⣍⡉⠉⡇⡏⠉⠉⣩⠋⢀⣔⠕⢫⡇⡇]],
-- [[⢸⢸⣈⡻⣿⣶⣽⡸⣿⣦⡇⡇⡠⠊⣸⢶⠋⢁⡤⠧⡇⡇]],
-- [[⢸⢸⠻⣿⣶⣝⠛⣿⣮⢻⠟⣏⣠⠞⠁⣼⡶⠋⢀⣴⡇⡇]],
-- [[⢸⢸⣿⣶⣍⠻⠼⣮⡕⢁⡤⢿⢁⡴⠊⣸⣵⠞⠋⢠⡇⡇]],
-- [[⢸⢘⣛⡻⣿⣧⢳⣿⣧⠎⢀⣾⠋⡠⠞⢱⢇⣠⡴⠟⡇⡇]],
-- [[⢸⢸⠹⣿⣷⣎⣉⣻⢁⡔⢁⢿⡏⢀⣤⢾⡟⠁⣀⣎⡇⡇]],
-- [[⢸⢸⠲⣶⣭⡛⠚⢿⢋⡔⢁⣼⠟⢋⣠⣼⠖⠋⢁⠎⡇⡇]],
-- [[⢸⢸⢤⣬⣛⠿⠞⣿⢋⠔⣉⣾⠖⠋⢁⣯⡴⠞⢃⠂⡇⡇]],
-- [[⢸⢸⠀⢙⣻⢿⣧⣾⡵⠚⣉⣯⠶⠛⣹⣧⠤⢮⠁⠀⡇⡇]],
-- [[⠸⣘⠢⣄⠙⠿⢷⡡⠖⣋⣽⠥⠒⣩⣟⣤⣔⣁⡤⠖⣃⠇]],
-- [[⠀⠀⠙⠢⢍⣻⡿⠒⢉⣴⣗⣚⣽⣋⣀⣤⣊⠥⠒⠉⠀⠀]],
-- [[⠀⠀⠀⢀⣔⠥⠒⢮⣙⠾⠀⠷⣚⡭⠞⠉⠛⠦⣀⠀⠀⠀]],
-- [[⠀⠀⠀⠉⠀⠀⠀⠀⠈⠑⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- meatboy = {
-- [[⠀⠀⣀⣀⣤⣤⣦⣶⢶⣶⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⡄⠀⠀⠀⠀⠀]],
-- [[⠀⠀⣿⣿⣿⠿⣿⣿⣾⣿⣿⣿⣿⣿⣿⠟⠛⠛⢿⣿⡇⠀⠀⠀⠀⠀]],
-- [[⠀⠀⣿⡟⠡⠂⠀⢹⣿⣿⣿⣿⣿⣿⡇⠘⠁⠀⠀⣿⡇⠀⢠⣄⠀⠀]],
-- [[⠀⠀⢸⣗⢴⣶⣷⣷⣿⣿⣿⣿⣿⣿⣷⣤⣤⣤⣴⣿⣗⣄⣼⣷⣶⡄]],
-- [[⠀⢀⣾⣿⡅⠐⣶⣦⣶⠀⢰⣶⣴⣦⣦⣶⠴⠀⢠⣿⣿⣿⣿⣼⣿⡇]],
-- [[⢀⣾⣿⣿⣷⣬⡛⠷⣿⣿⣿⣿⣿⣿⣿⠿⠿⣠⣿⣿⣿⣿⣿⠿⠛⠃]],
-- [[⢸⣿⣿⣿⣿⣿⣿⣿⣶⣦⣭⣭⣥⣭⣵⣶⣿⣿⣿⣿⣟⠉⠀⠀⠀⠀]],
-- [[⠀⠙⠇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⣿⣿⣿⣿⣿⣛⠛⠛⠛⠛⠛⢛⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠿⣿⣿⣿⠿⠿⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⠿⠇⠀⠀⠀⠀⠀]],
-- },
-- isaac = {
-- [[ ⣀⣤⣴⣶⣶⣶⣶⣶⣶⣤⣄⣀ ]],
-- [[ ⢀⣠⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄ ]],
-- [[ ⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣆ ]],
-- [[ ⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ ]],
-- [[ ⣾⣿⡿⠟⡋⠉⠛⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠉⠉⠙⠻⣿⣿⣇]],
-- [[⢠⣿⡏⢰⣿⣿⡇ ⢸⣿⣿⣿⠿⠿⣿⣿⣿⠁⣾⣿⣷ ⠘⣿⣿]],
-- [[⠸⣿⣇⠈⠉⠉ ⢀⣼⡿⠋ ⠙⢿⣄⠙⠛⠁ ⢠⣿⣿]],
-- [[ ⢿⣿⡇ ⣶⣿⣿⢁⣤⣤⣤⣤⣤⣤ ⣿⣷ ⠈⢹⣿⡟]],
-- [[ ⠈⢿⡗ ⢸⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿ ⢸⡟ ]],
-- [[ ⠳⡀ ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ⠌ ]],
-- [[ ⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤ ]],
-- [[ ⠉⠙⠻⠿⠿⣿⣿⣿⣿⠿⠿⠛⠉ ]],
-- },
-- gta = {
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣤⡀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⠟⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠻⣿⣷⣄⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣶⣿⡆⠀⠀⠉⠉⠀⠈⣶⡆⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⢻⣷⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⡿⠟⠀⠀⠀⠀⠀⠀⠀⣸⣿⡄]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣷]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠛⠃⠀⠀⠀⠀⠀⠀⠀⠀⢰⣾⣿⠏]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣧⡔⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠟⠁⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[Ah shit, here we go again.]],
-- },
-- hydra = {
-- [[ ⣴⣶⣤⡤⠦⣤⣀⣤⠆ ⣈⣭⣭⣿⣶⣿⣦⣼⣆ ]],
-- [[ ⠉⠻⢿⣿⠿⣿⣿⣶⣦⠤⠄⡠⢾⣿⣿⡿⠋⠉⠉⠻⣿⣿⡛⣦ ]],
-- [[ ⠈⢿⣿⣟⠦⠄⣾⣿⣿⣷ ⠻⠿⢿⣿⣧⣄ ]],
-- [[ ⣸⣿⣿⢧⠄⢻⠻⣿⣿⣷⣄⣀ ⣀⡀⠈⠙⠿ ]],
-- [[ ⢀ ⢠⣿⣿⣿⠈ ⣻⣿⣿⣿⣿⣿⣿⣿⣛⣳⣤⣀⣀ ]],
-- [[ ⢠⣧⣶⣥⡤ ⣸⣿⣿⠘ ⢀⣴⣿⣿⡿⠛⣿⣿⣧⠈⢿⠿⠟⠛⠻⠿⠄ ]],
-- [[ ⣰⣿⣿⠛⠻⣿⣿⡦⢹⣿⣷ ⢊⣿⣿⡏ ⢸⣿⣿⡇ ⢀⣠⣄⣾ ]],
-- [[⣠⣿⠿⠛ ⢀⣿⣿⣷⠘⢿⣿⣦⡀ ⢸⢿⣿⣿⣄ ⣸⣿⣿⡇⣪⣿⡿⠿⣿⣷⡄ ]],
-- [[⠙⠃ ⣼⣿⡟ ⠈⠻⣿⣿⣦⣌⡇⠻⣿⣿⣷⣿⣿⣿ ⣿⣿⡇ ⠛⠻⢷⣄]],
-- [[ ⢻⣿⣿⣄ ⠈⠻⣿⣿⣿⣷⣿⣿⣿⣿⣿⡟ ⠫⢿⣿⡆ ⠁]],
-- [[ ⠻⣿⣿⣿⣿⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⡟⢀⣀⣤⣾⡿⠃ ]],
-- },
-- spider = {
-- [[ ▐ ▌ ▐ ▌ ]],
-- [[ ▐▌ █ █ ▐▌ ]],
-- [[ ▄█ ▀▀▄▌▄▐▄▀▀ █▄ ]],
-- [[ ▐█ ▄█▀▄█████▄▀█▄ █ ]],
-- [[ ▀▀ ▄▄▄█████▄▄▄ ▀▀ ]],
-- [[ ▄█▀ ▄▀███▀▄ ▀█▄ ]],
-- [[ ▄█ ▄▀ ███ ▀▄ █▄ ]],
-- [[▐█ █ ▐█▌ █ █▌]],
-- [[ █ █ ▀ █ █ ]],
-- [[ ▀█ █ █ █▀ ]],
-- [[ █ █ █ █ ]],
-- [[ █ █ █ █ ]],
-- [[ ▌ ▌ ▐ ▐ ]],
-- },
-- moth = {
-- [[⠀⠀⠀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⣀⣀⠀⠀]],
-- [[⢀⡖⢭⡿⡁⣶⠒⢍⣩⡿⢽⣷⣦⣤⣀⠀⢾⣏⡋⡽⠇⠀⣀⣤⢴⣚⠟⣉⣉⡽⠖⠪⡟⣹⡿⠆]],
-- [[⠈⠙⠵⣫⠵⣐⣏⢒⣲⠿⢷⣛⣹⡽⣿⢻⣾⠿⡛⡧⣷⣛⣷⣯⣿⣲⢶⣾⣚⢇⢁⡼⣿⠟⠋⠀]],
-- [[⠀⠀⠀⠘⠿⣵⣫⠾⣛⣫⢫⠕⠂⠈⠀⢩⣷⠾⢲⢯⣍⠓⠉⠚⠹⣿⣯⣿⣹⣾⣿⠟⠁⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠉⢠⡾⣫⡶⡂⠀⠀⠀⠐⡟⠖⡙⡧⠆⠀⠀⠀⠀⣿⢋⣻⡧⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠘⢾⣕⢕⠰⡀⠀⠀⠀⣯⠩⠏⠇⠐⡀⠀⠀⢠⣇⣰⡿⠃⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠃⠉⠉⠃⠀⠀⢻⣨⡈⠀⠃⠑⠀⠘⠋⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- skull = {
-- [[ ⠀⠀⠀⠀⠀⠀⣀⣤⣴⣶⣾⣿⣿⣿⣶⣶⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠿⢿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ ]],
-- [[⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⣿⣿⡟⠁⠀⠀⠀⠈⢻⣿⣿⣿⠀⠀⠀⠀⠀⠀ ]],
-- [[⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⠛⠛⠛⠛⠛⠛⢛⣿⣮⣿⣿⣿⠀⠀⠀⠀⠀⠀⢈⣿⣿⡟⠀⠀⠀⠀⠀⠀ ]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⣧⡀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⢀⣼⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣶⣿⣿⣿⣿⠟⠉⠻⣿⣿⣿⣿⣶⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⣠⣷⡀⢹⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠋⠛⠋⠛⠙⠛⠙⠛⠙⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
-- morse = {
-- [[ ]],
-- [[ ]],
-- [[ ]],
-- [[ ]],
-- [[ ]],
-- [[ ▄▄ ▄▄ ▄▄ ▄▄ ▄▄ ▄▄ ▄▄ ]],
-- [[ ▄ ▄ ▄ ▄ ▄ ▄ ▄ ]],
-- [[ ]],
-- [[ ]],
-- [[ ]],
-- },
-- sharp = {
-- [[ ]],
-- [[  ]],
-- [[ ████ ██████ █████ ██ ]],
-- [[ ███████████ █████  ]],
-- [[ █████████ ███████████████████ ███ ███████████ ]],
-- [[ █████████ ███ █████████████ █████ ██████████████ ]],
-- [[ █████████ ██████████ █████████ █████ █████ ████ █████ ]],
-- [[ ███████████ ███ ███ █████████ █████ █████ ████ █████ ]],
-- [[ ██████ █████████████████████ ████ █████ █████ ████ ██████ ]],
-- [[ ]],
-- },
-- galaxy = {
-- [[ ⠀⠀⢀⣀⣀⡀⠒⠒⠦⣄⡀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⢀⣤⣶⡾⠿⠿⠿⠿⣿⣿⣶⣦⣄⠙⠷⣤⡀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⣠⡾⠛⠉⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⣿⣷⣄⠘⢿⡄⠀⠀⠀]],
-- [[⠀⢀⡾⠋⠀⠀⠀⠀⠀⠀⠀⠀⠐⠂⠠⢄⡀⠈⢿⣿⣧⠈⢿⡄⠀⠀]],
-- [[⢀⠏⠀⠀⠀⢀⠄⣀⣴⣾⠿⠛⠛⠛⠷⣦⡙⢦⠀⢻⣿⡆⠘⡇⠀⠀]],
-- [[⠀⠀⠀⠀⡐⢁⣴⡿⠋⢀⠠⣠⠤⠒⠲⡜⣧⢸⠄⢸⣿⡇⠀⡇⠀⠀]],
-- [[⠀⠀⠀⡼⠀⣾⡿⠁⣠⢃⡞⢁⢔⣆⠔⣰⠏⡼⠀⣸⣿⠃⢸⠃⠀⠀]],
-- [[⠀⠀⢰⡇⢸⣿⡇⠀⡇⢸⡇⣇⣀⣠⠔⠫⠊⠀⣰⣿⠏⡠⠃⠀⠀⢀]],
-- [[⠀⠀⢸⡇⠸⣿⣷⠀⢳⡈⢿⣦⣀⣀⣀⣠⣴⣾⠟⠁⠀⠀⠀⠀⢀⡎]],
-- [[⠀⠀⠘⣷⠀⢻⣿⣧⠀⠙⠢⠌⢉⣛⠛⠋⠉⠀⠀⠀⠀⠀⠀⣠⠎⠀]],
-- [[⠀⠀⠀⠹⣧⡀⠻⣿⣷⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡾⠃⠀⠀]],
-- [[⠀⠀⠀⠀⠈⠻⣤⡈⠻⢿⣿⣷⣦⣤⣤⣤⣤⣤⣴⡾⠛⠉⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠈⠙⠶⢤⣈⣉⠛⠛⠛⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀]],
-- [[⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀]],
-- },
}

View File

@ -0,0 +1,115 @@
-- local vim.api.nvim_create_augroup = vim.api.nvim_create_augroup
-- [[ Highlight on yank ]]
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
vim.highlight.on_yank({ timeout = 100 })
end,
group = vim.api.nvim_create_augroup("YankHighlight", { clear = true }),
pattern = "*",
})
-- [[ Disable Autocommenting on new lines ]]
vim.api.nvim_create_autocmd("BufEnter", {
callback = function()
vim.opt.formatoptions:remove({ "c", "r", "o" })
end,
group = vim.api.nvim_create_augroup("DisableAutocommenting", { clear = true }),
})
-- [[ Update file on Focus ]]
vim.api.nvim_create_autocmd("FocusGained", {
callback = function()
vim.cmd("checktime")
end,
group = vim.api.nvim_create_augroup("UpdateOnFocus", { clear = true }),
})
-- [[ Open lf when it's a Directory ]]
vim.api.nvim_create_autocmd("VimEnter", {
callback = function(data)
local directory = vim.fn.isdirectory(data.file) == 1
if directory then
require("lf").start()
end
end,
group = vim.api.nvim_create_augroup("lf_ifDirectory", { clear = true }),
})
-- [[ Remove trailing whitespaces ]]
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
pattern = { "*" },
callback = function()
local save_cursor = vim.fn.getpos(".")
vim.cmd([[%s/\s\+$//e]])
vim.cmd([[%s/\n\+\%$//e]])
vim.fn.setpos(".", save_cursor)
end,
group = vim.api.nvim_create_augroup("RemoveTrailingWhitespaces", { clear = true }),
})
-- [[ Restore last cursor position ]]
vim.api.nvim_create_autocmd("BufReadPost", {
pattern = "*",
callback = function()
local line = vim.fn.line "'\""
if
line > 1
and line <= vim.fn.line "$"
and vim.bo.filetype ~= "commit"
and vim.fn.index({ "xxd", "gitrebase" }, vim.bo.filetype) == -1
then
vim.cmd 'normal! g`"zz'
end
end,
})
-- [[ Reload xresources on write ]]
vim.api.nvim_create_autocmd({ "BufWritePost" }, {
pattern = vim.fn.resolve(vim.fn.expand("~/.config/x11/xresources")),
callback = function()
-- cmd([[!xrdb % ; killall -USR1 st ; renew-dwm ; notify-send " - xresources reloaded"]])
vim.cmd([[!xrdb % ; killall -USR1 st ; renew-dwm]])
end,
group = vim.api.nvim_create_augroup("ReloadXresources", { clear = true }),
})
-- [[ Recompile suckless software on write and show notification ]]
local function recompile(path)
vim.api.nvim_create_augroup("RecompileGroup_" .. path, { clear = true })
vim.api.nvim_create_autocmd({ "BufWritePost" }, {
pattern = vim.fn.resolve(vim.fn.expand(path)),
callback = function()
vim.cmd("!sudo make install; renew-dwm")
end,
})
end
recompile("~/.config/suckless/dwm/config.h")
recompile("~/.config/suckless/dmenu/config.h")
recompile("~/.config/suckless/st/config.h")
recompile("~/.config/suckless/dwmblocks/config.h")
--[[ Close nvim if toggleterm or Outline is the last buffer ]]
vim.api.nvim_create_autocmd({ "BufEnter" }, {
pattern = "*",
callback = function()
if
vim.fn.tabpagenr("$") == 1
and vim.fn.winnr("$") == 1
and (vim.bo.ft == "toggleterm" or vim.bo.ft == "Outline")
then
vim.cmd("bd! | q")
end
end,
group = vim.api.nvim_create_augroup("CloseLast", { clear = true }),
})
-- [[ Autosave ]]
-- vim.api.nvim_create_autocmd({ "FocusLost", "BufLeave", "BufWinLeave", "InsertLeave" }, {
-- callback = function()
-- if vim.bo.filetype ~= "" and vim.bo.buftype == "" then
-- vim.cmd("silent! w")
-- end
-- end,
-- group = vim.api.nvim_create_augroup("AutoSave", { clear = true }),
-- })

View File

@ -0,0 +1,70 @@
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable",
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup(
{
import = "plugins",
},
{
defaults = {
lazy = true,
},
install = {
colorscheme = { "tokyonight", "habamax" },
},
change_detection = {
notify = false,
},
ui = {
border = "rounded",
},
performance = {
cache = {
enabled = true,
},
reset_packpath = true,
rtp = {
disabled_plugins = {
"2html_plugin",
"tohtml",
"getscript",
"getscriptPlugin",
"gzip",
"logipat",
"netrw",
"netrwPlugin",
"netrwSettings",
"netrwFileHandlers",
"matchit",
"matchparen",
"tar",
"tarPlugin",
"rrhelper",
"spellfile_plugin",
"vimball",
"vimballPlugin",
"zip",
"zipPlugin",
"tutor",
"rplugin",
"syntax",
"synmenu",
"optwin",
"compiler",
"bugreport",
"ftplugin",
},
},
},
}
)

View File

@ -0,0 +1,56 @@
-- Does not contain plugin specific keybinds
vim.keymap.set("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
vim.keymap.set("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
vim.keymap.set("n", "<leader>s", ":%s/<C-r><C-w>//gI<Left><Left><Left>")
vim.keymap.set("n", "<C-h>", "<C-w>h")
vim.keymap.set("n", "<C-j>", "<C-w>j")
vim.keymap.set("n", "<C-k>", "<C-w>k")
vim.keymap.set("n", "<C-l>", "<C-w>l")
vim.keymap.set("n", "<C-Left>", ":vertical resize -2<CR>", { silent = true })
vim.keymap.set("n", "<C-Right>", ":vertical resize +2<CR>", { silent = true })
vim.keymap.set("n", "<C-Up>", ":resize +2<CR>", { silent = true })
vim.keymap.set("n", "<C-Down>", ":resize -2<CR>", { silent = true })
vim.keymap.set("n", "J", "mzJ`z")
vim.keymap.set("n", "<C-d>", "<C-d>zz")
vim.keymap.set("n", "<C-u>", "<C-u>zz")
vim.keymap.set("n", "n", "nzzzv")
vim.keymap.set("n", "N", "Nzzzv")
vim.keymap.set("n", "<leader>cx", "<cmd>!chmod +x %<CR>", { desc = "chmod +x" })
vim.keymap.set("n", "<leader>cp", ':!compiler "%:p"<CR>', { desc = "run (C)om[P]iler script" })
vim.keymap.set("n", "<leader>sa", [[:%s/\<<C-r><C-w>\>/<C-r><C-w>/gI<Left><Left><Left>]], { desc = "Replace All" })
vim.keymap.set("n", "<leader>y", "<cmd>%yank<CR>", { desc = "Yank buffer" })
vim.keymap.set("n", "<A-;>", "<Esc>miA;<Esc>`i")
vim.keymap.set("n", "<leader>q", ":lua vim.diagnostic.open_float()<CR>", { noremap = true, silent = true })
vim.keymap.set("n", "<A-w>", ":bd<CR>", { silent = true })
vim.keymap.set("n", "<A-v>", ":vsplit<CR>", { silent = true })
vim.keymap.set("n", "<A-h>", ":split<CR>", { silent = true })
vim.keymap.set("n", "<C-s>", ":w<CR>")
vim.keymap.set('n', "gl", ':lua vim.diagnostic.open_float()<cr>')
vim.keymap.set("n", "<leader>cs", ":setlocal spell! spelllang=en_us<CR>", { desc = "Spellcheck", silent = true })
vim.keymap.set("x", "p", 'p:let @+=@0<CR>:let @"=@0<CR>', { silent = true })
vim.keymap.set("x", "K", ":m '<-2<cr>gv=gv")
vim.keymap.set("x", "J", ":m '>+1<cr>gv=gv")
vim.keymap.set("x", "<leader>h", [["ay:!dmenuhandler '<C-r>a'<cr>]])
vim.keymap.set("v", "<", "<gv^")
vim.keymap.set("v", ">", ">gv^")
vim.keymap.set("i", "<C-u>", "<Esc>viwUea")
vim.keymap.set("i", "<C-t>", "<Esc>b~lea")
vim.keymap.set("i", "<C-;>", "<Esc>miA;<Esc>`ii")
vim.keymap.set("i", "<A-j>", "<Esc>:m .+1<CR>==gi")
vim.keymap.set("i", "<A-k>", "<Esc>:m .-2<CR>==gi")
vim.keymap.set("i", "<A-Up>", "<C-\\><C-N><C-w>k")
vim.keymap.set("i", "<A-Down>", "<C-\\><C-N><C-w>j")
vim.keymap.set("i", "<A-Left>", "<C-\\><C-N><C-w>h")
vim.keymap.set("i", "<A-Right>", "<C-\\><C-N><C-w>l")
vim.keymap.set("t", "<C-h>", "<C-\\><C-N><C-w>h")
vim.keymap.set("t", "<C-j>", "<C-\\><C-N><C-w>j")
vim.keymap.set("t", "<C-k>", "<C-\\><C-N><C-w>k")
vim.keymap.set("t", "<C-l>", "<C-\\><C-N><C-w>l")
vim.keymap.set({ "x", "v", "n" }, ";", ":", { nowait = true })
vim.keymap.set({ "x", "v", "n" }, "<A-j>", ":m .+1<cr>==")
vim.keymap.set({ "x", "v", "n" }, "<A-k>", ":m .-2<cr>==")

View File

@ -0,0 +1,75 @@
-- indentation
vim.opt.tabstop = 2
vim.opt.softtabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true
vim.opt.smartindent = true
vim.opt.breakindent = true
vim.opt.autoindent = true
vim.opt.smarttab = true
-- search and replace
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.hlsearch = false
vim.opt.incsearch = true
vim.opt.gdefault = true
vim.opt.showmatch = true
vim.opt.grepformat = "%f:%l:%c:%m"
vim.opt.grepprg = "rg --vimgrep"
vim.opt.inccommand = "nosplit"
-- user interface
vim.opt.fillchars = { eob = " " }
vim.opt.laststatus = 3
vim.opt.number = true
vim.opt.numberwidth = 2
vim.opt.relativenumber = true
vim.opt.ruler = false
vim.opt.wrap = true
vim.opt.termguicolors = true
vim.opt.scrolloff = 4
vim.opt.sidescrolloff = 4
vim.opt.signcolumn = "yes"
vim.opt.cursorline = true
vim.opt.cursorlineopt = "both"
vim.opt.conceallevel = 2
vim.opt.list = false
-- vim.opt.listchars = {eol = "󰌑" }
vim.opt.showmode = false
-- vim.opt.colorcolumn = "80"
vim.opt.winminwidth = 5
-- editing
vim.opt.completeopt = { "menu", "menuone", "noselect" }
vim.opt.timeoutlen = 300
vim.opt.undofile = true
vim.opt.autowrite = true
vim.opt.mouse = "a"
vim.opt.whichwrap:append("<>,[,],h,l")
vim.opt.iskeyword:append("-")
-- window management
vim.opt.splitbelow = true
vim.opt.splitright = true
-- clipboard
vim.opt.clipboard = "unnamedplus"
-- auto change dir
vim.opt.autochdir = true
-- fold options
vim.opt.foldlevel = 99
vim.opt.foldlevelstart = 99
vim.opt.foldenable = true
vim.opt.shortmess = "aoOFCWstTAIcCqFS"
-- gui options
vim.opt.guifont = "JetBrainsMono NF:h9"
-- neovide ui
vim.g.neovide_padding_top = 5
vim.g.neovide_padding_bottom = 0
vim.g.neovide_padding_right = 10
vim.g.neovide_padding_left = 10

View File

@ -0,0 +1,69 @@
return {
-- dap + dependencies
{
"mfussenegger/nvim-dap",
dependencies = {
{
"rcarriga/nvim-dap-ui",
dependencies = { "nvim-neotest/nvim-nio" },
--stylua: ignore
keys = {
{ "<leader>du", function() require("dapui").toggle({}) end, desc = "Dap UI" },
{ "<leader>de", function() require("dapui").eval() end, desc = "Eval", mode = { "n", "v" } },
},
opts = {},
config = function(_, opts)
require("dapui").setup(opts)
require("dap").listeners.after.event_initialized["dapui_config"] = function()
require("dapui").open({})
end
require("dap").listeners.before.event_terminated["dapui_config"] = function()
require("dapui").close({})
end
require("dap").listeners.before.event_exited["dapui_config"] = function()
require("dapui").close({})
end
end,
},
{
"theHamsta/nvim-dap-virtual-text",
opts = {},
},
{
"jay-babu/mason-nvim-dap.nvim",
dependencies = "mason.nvim",
cmd = { "DapInstall", "DapUninstall" },
opts = {
automatic_installation = true,
handlers = {},
ensure_installed = {
"bash-debug-adapter",
"codelldb",
"debugpy",
"go-debug-adapter",
},
},
},
},
--stylua: ignore
keys = {
{ "<leader>dB", function() require("dap").set_breakpoint(vim.fn.input('Breakpoint condition: ')) end, desc = "Breakpoint Condition" },
{ "<leader>db", function() require("dap").toggle_breakpoint() end, desc = "Toggle Breakpoint" },
{ "<leader>dc", function() require("dap").continue() end, desc = "Continue" },
{ "<leader>da", function() require("dap").continue({ before = get_args }) end, desc = "Run with Args" },
{ "<leader>dC", function() require("dap").run_to_cursor() end, desc = "Run to Cursor" },
{ "<leader>dg", function() require("dap").goto_() end, desc = "Go to Line (No Execute)" },
{ "<leader>di", function() require("dap").step_into() end, desc = "Step Into" },
{ "<leader>dj", function() require("dap").down() end, desc = "Down" },
{ "<leader>dk", function() require("dap").up() end, desc = "Up" },
{ "<leader>dl", function() require("dap").run_last() end, desc = "Run Last" },
{ "<leader>do", function() require("dap").step_out() end, desc = "Step Out" },
{ "<leader>dO", function() require("dap").step_over() end, desc = "Step Over" },
{ "<leader>dp", function() require("dap").pause() end, desc = "Pause" },
{ "<leader>dr", function() require("dap").repl.toggle() end, desc = "Toggle REPL" },
{ "<leader>ds", function() require("dap").session() end, desc = "Session" },
{ "<leader>dt", function() require("dap").terminate() end, desc = "Terminate" },
{ "<leader>dw", function() require("dap.ui.widgets").hover() end, desc = "Widgets" },
},
}
}

View File

@ -0,0 +1,77 @@
return {
-- markdown
{
"ixru/nvim-markdown",
ft = { "markdown" },
},
-- glow preview
{
"0x00-ketsu/markdown-preview.nvim",
keys = {
{ "<leader>cm", "<cmd>lua require('markdown-preview')<cr><cmd>MPToggle<cr>", desc = "[M]arkdown preview" },
},
opts = {},
},
-- qalc
{
"Apeiros-46B/qalc.nvim",
event = "BufEnter *.qalc",
cmd = { "QalcAttach", "QalcYank" },
keys = {
{ "<leader>cqa", "<cmd>QalcAttach<CR>", desc = "Attach Calculator" },
{ "<leader>cqy", "<cmd>QalcYank<CR>", desc = "Yank Result" },
},
opts = {
cmd_args = {}, -- table
bufname = '', -- string
set_ft = 'config', -- string
attach_extension = '*.qalc', -- string
sign = ' ==> ', -- string
show_sign = true, -- boolean
right_align = true, -- boolean
highlights = {
sign = '@comment', -- sign before result
result = '@string', -- result in virtual text
},
diagnostics = { -- table
underline = false,
virtual_text = false,
signs = true,
update_in_insert = true,
severity_sort = true,
}
}
},
-- vimtex + snippets
{
"lervag/vimtex",
ft = "tex",
dependencies = {
{
"iurimateus/luasnip-latex-snippets.nvim",
dependencies = "L3MON4D3/LuaSnip",
config = function()
require("luasnip-latex-snippets").setup()
-- or setup({ use_treesitter = true })
require("luasnip").config.setup({ enable_autosnippets = true })
end,
},
},
keys = {
{ "<leader>cc", "<cmd>VimtexCompile<cr>", desc = "[C]ompile latex" },
{ "<leader>co", "<cmd>VimtexCompileOutput<cr>", desc = "Show latex compiler output" },
},
config = function()
vim.g.vimtex_view_general_viewer = "zathura"
-- vim.g.vimtex_view_general_options = [[--unique file:@pdf\#src:@line@tex]]
-- vim.g.vimtex_quickfix_enabled = 1
vim.g.vimtex_syntax_enabled = 1
vim.g.vimtex_quickfix_mode = 0
vim.g.vimtex_compiler_method = "tectonic"
-- vim.cmd("call vimtex#init()")
end,
},
}

View File

@ -0,0 +1,539 @@
return {
-- project management
{
"ahmedkhalf/project.nvim",
event = "VeryLazy",
keys = {
{
"\\p",
function()
local contents = require("project_nvim").get_recent_projects()
local reverse = {}
for i = #contents, 1, -1 do
reverse[#reverse + 1] = contents[i]
end
require("fzf-lua").fzf_exec(reverse, {
actions = {
["default"] = function(e)
-- vim.cmd.cd(e[1])
require("fzf-lua").files({ cwd = e[1] })
end,
["ctrl-d"] = function(x)
local choice = vim.fn.confirm("Delete '" .. #x .. "' projects? ", "&Yes\n&No", 2)
if choice == 1 then
local history = require("project_nvim.utils.history")
for _, v in ipairs(x) do
history.delete_project(v)
end
end
end,
},
winopts = {
height = 0.3,
width = 0.5,
},
})
end,
desc = "Projects"
},
},
config = function()
require("project_nvim").setup {
patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "tex" },
}
end,
},
-- harpoon
{
"ThePrimeagen/harpoon",
branch = "harpoon2",
dependencies = { "nvim-lua/plenary.nvim" },
keys = {
{ "<leader>a", function() require("harpoon"):list():add() end, desc = "Add to list" },
{ "<leader>h", function() require("harpoon").ui:toggle_quick_menu(require("harpoon"):list()) end, desc = "harpoon ui" },
{ "<leader>1", function() require("harpoon"):list():select(1) end, desc = "Harpoon Select 1" },
{ "<leader>2", function() require("harpoon"):list():select(2) end, desc = "Harpoon Select 2" },
{ "<leader>3", function() require("harpoon"):list():select(3) end, desc = "Harpoon Select 3" },
{ "<leader>4", function() require("harpoon"):list():select(4) end, desc = "Harpoon Select 4" },
{ "<leader>5", function() require("harpoon"):list():select(5) end, desc = "Harpoon Select 5" },
{ "<leader>6", function() require("harpoon"):list():select(6) end, desc = "Harpoon Select 6" },
{ "<leader>7", function() require("harpoon"):list():select(7) end, desc = "Harpoon Select 7" },
{ "<leader>8", function() require("harpoon"):list():select(8) end, desc = "Harpoon Select 8" },
{ "<leader>9", function() require("harpoon"):list():select(9) end, desc = "Harpoon Select 9" },
},
config = function()
require("harpoon"):setup()
end
},
-- vim-be-good game
{
"theprimeagen/vim-be-good",
dependencies = {
"nvim-lua/plenary.nvim"
},
config = function()
end
},
-- todo-comments
{
"folke/todo-comments.nvim",
dependencies = "nvim-lua/plenary.nvim",
cmd = { "TodoTrouble" },
event = "VeryLazy",
config = true,
-- stylua: ignore
keys = {
{ "]t", function() require("todo-comments").jump_next() end, desc = "Next Todo Comment" },
{ "[t", function() require("todo-comments").jump_prev() end, desc = "Previous Todo Comment" },
{ "<leader>xt", "<cmd>TodoTrouble<cr>", desc = "Todo (Trouble)" },
{ "<leader>xT", "<cmd>TodoTrouble keywords=TODO,FIX,FIXME<cr>", desc = "Todo/Fix/Fixme (Trouble)" },
-- { "<leader>st", "<cmd>TodoTelescope<cr>", desc = "Todo" },
-- { "<leader>sT", "<cmd>TodoTelescope keywords=TODO,FIX,FIXME<cr>", desc = "Todo/Fix/Fixme" },
},
},
-- trouble
{
"folke/trouble.nvim",
cmd = { "TroubleToggle", "Trouble" },
opts = { use_diagnostic_signs = true },
keys = {
{ "<leader>xx", "<cmd>TroubleToggle document_diagnostics<cr>", desc = "Document Diagnostics (Trouble)" },
{ "<leader>xX", "<cmd>TroubleToggle workspace_diagnostics<cr>", desc = "Workspace Diagnostics (Trouble)" },
{ "<leader>xL", "<cmd>TroubleToggle loclist<cr>", desc = "Location List (Trouble)" },
{ "<leader>xQ", "<cmd>TroubleToggle quickfix<cr>", desc = "Quickfix List (Trouble)" },
{
"[q",
function()
if require("trouble").is_open() then
require("trouble").previous({ skip_groups = true, jump = true })
else
local ok, err = pcall(vim.cmd.cprev)
if not ok then
vim.notify(err, vim.log.levels.ERROR)
end
end
end,
desc = "Previous Trouble/Quickfix Item",
},
{
"]q",
function()
if require("trouble").is_open() then
require("trouble").next({ skip_groups = true, jump = true })
else
local ok, err = pcall(vim.cmd.cnext)
if not ok then
vim.notify(err, vim.log.levels.ERROR)
end
end
end,
desc = "Next Trouble/Quickfix Item",
},
},
},
-- spectre
{
"nvim-pack/nvim-spectre",
build = false,
cmd = "Spectre",
opts = { open_cmd = "noswapfile vnew" },
-- stylua: ignore
keys = {
{ "<leader>sr", function() require("spectre").open() end, desc = "Replace in Files (Spectre)" },
},
},
-- sessions
{
"folke/persistence.nvim",
event = "BufReadPre",
opts = { options = vim.opt.sessionoptions:get() },
-- stylua: ignore
keys = {
{ "<leader>qs", function() require("persistence").load() end, desc = "Restore Session" },
{ "<leader>ql", function() require("persistence").load({ last = true }) end, desc = "Restore Last Session" },
{ "<leader>qd", function() require("persistence").stop() end, desc = "Don't Save Current Session" },
},
},
-- illuminate
{
"RRethy/vim-illuminate",
event = "VeryLazy",
opts = {
delay = 200,
large_file_cutoff = 2000,
large_file_overrides = {
providers = { "lsp" },
},
filetypes_denylist = {
"alpha",
"help",
"lazy",
"mason",
"outline",
"toggleterm",
"fzf",
"lspinfo",
"null-ls-info",
},
},
config = function(_, opts)
require("illuminate").configure(opts)
local function map(key, dir, buffer)
vim.keymap.set("n", key, function()
require("illuminate")["goto_" .. dir .. "_reference"](false)
end, { desc = dir:sub(1, 1):upper() .. dir:sub(2) .. " Reference", buffer = buffer })
end
map("]]", "next")
map("[[", "prev")
-- also set it after loading ftplugins, since a lot overwrite [[ and ]]
vim.api.nvim_create_autocmd("FileType", {
callback = function()
local buffer = vim.api.nvim_get_current_buf()
map("]]", "next", buffer)
map("[[", "prev", buffer)
end,
})
end,
keys = {
{ "]]", desc = "Next Reference" },
{ "[[", desc = "Prev Reference" },
},
},
-- symbols sidebar
{
"hedyhli/outline.nvim",
lazy = true,
cmd = { "Outline", "OutlineOpen" },
keys = {
{ "<leader>cn", "<cmd>Outline<CR>", desc = "Toggle outline" },
},
opts = {
outline_window = {
focus_on_open = false,
},
},
},
-- folds
{
"kevinhwang91/nvim-ufo",
dependencies = "kevinhwang91/promise-async",
event = "VeryLazy",
opts = {},
},
-- comments
{
"numToStr/Comment.nvim",
dependencies = {
{ "nvim-treesitter/nvim-treesitter" },
{
"JoosepAlviste/nvim-ts-context-commentstring",
config = function()
require("ts_context_commentstring").setup({
enable_autocmd = false,
})
vim.g.skip_ts_context_commentstring_module = true
end,
},
},
config = function()
require("Comment").setup({
pre_hook = require("ts_context_commentstring.integrations.comment_nvim").create_pre_hook(),
})
end,
keys = {
{ "gcc", mode = "n", desc = "Comment toggle current line" },
{ "gc", mode = { "n", "o" }, desc = "Comment toggle linewise" },
{ "gc", mode = "x", desc = "Comment toggle linewise (visual)" },
{ "gbc", mode = "n", desc = "Comment toggle current block" },
{ "gb", mode = { "n", "o" }, desc = "Comment toggle blockwise" },
{ "gb", mode = "x", desc = "Comment toggle blockwise (visual)" },
},
},
-- surround
{
"echasnovski/mini.surround",
event = "VeryLazy",
opts = {
mappings = {
add = "gza", -- Add surrounding in Normal and Visual modes
delete = "gzd", -- Delete surrounding
find = "gzf", -- Find surrounding (to the right)
find_left = "gzF", -- Find surrounding (to the left)
highlight = "gzh", -- Highlight surrounding
replace = "gzr", -- Replace surrounding
update_n_lines = "gzn", -- Update `n_lines`
},
},
},
-- whichkey
{
"folke/which-key.nvim",
event = "VeryLazy",
keys = { "<leader>", "<space>", " ", "'", "`", "g", "c", "v", "z", "[", "]", "<M>" },
cmd = "WhichKey",
opts = {},
},
-- autopairs
{
"windwp/nvim-autopairs",
event = "InsertEnter",
opts = {
ignored_next_char = "[%w%.]",
},
},
-- leap
{
"ggandor/leap.nvim",
enabled = true,
dependencies = {
{
"ggandor/flit.nvim",
enabled = true,
keys = function()
local ret = {}
for _, key in ipairs({ "f", "F", "t", "T" }) do
ret[#ret + 1] = { key, mode = { "n", "x", "o" }, desc = key }
end
return ret
end,
opts = { labeled_modes = "nx" },
},
{ "tpope/vim-repeat" },
},
keys = {
{ "s", mode = { "n", "x", "o" }, desc = "Leap Forward to" },
{ "S", mode = { "n", "x", "o" }, desc = "Leap Backward to" },
{ "gs", mode = { "n", "x", "o" }, desc = "Leap from Windows" },
},
config = function(_, opts)
local leap = require("leap")
for k, v in pairs(opts) do
leap.opts[k] = v
end
leap.add_default_mappings(true)
vim.keymap.del({ "x", "o" }, "x")
vim.keymap.del({ "x", "o" }, "X")
vim.api.nvim_set_hl(0, "LeapBackdrop", { link = "Comment" })
vim.api.nvim_set_hl(0, "LeapMatch", { fg = "white", bold = true, nocombine = true })
vim.api.nvim_set_hl(0, "LeapLabelPrimary", { fg = "#f02077", bold = true, nocombine = true })
vim.api.nvim_set_hl(0, "LeapLabelSecondary", { fg = "#99ddff", bold = true, nocombine = true })
end,
},
-- colorizer
{
"NvChad/nvim-colorizer.lua",
event = "VeryLazy",
opts = {
user_default_options = {
css = true,
RRGGBBAA = true,
AARRGGBB = true,
names = false,
RGB = false,
},
},
},
-- file manager
{
"lmburns/lf.nvim",
dependencies = { "nvim-lua/plenary.nvim", "akinsho/toggleterm.nvim" },
opts = {
winblend = 0,
highlights = { NormalFloat = { guibg = "NONE" } },
border = "rounded",
escape_quit = true,
},
keys = {
{ "<leader><space>", "<cmd>lua require('lf').start()<cr>", desc = "Lf file manager" },
},
},
{
"mikavilpas/yazi.nvim",
enabled = false,
dependencies = {
"nvim-lua/plenary.nvim",
},
event = "VeryLazy",
keys = {
{
"<leader><space>",
function()
require("yazi").yazi()
end,
{ desc = "Open the file manager" },
},
},
opts = {
open_for_directories = true,
},
},
-- gitsigns
{
"lewis6991/gitsigns.nvim",
init = function()
-- load gitsigns only when a git file is opened
vim.api.nvim_create_autocmd({ "BufRead" }, {
group = vim.api.nvim_create_augroup("GitSignsLazyLoad", { clear = true }),
callback = function()
vim.fn.system("git -C " .. '"' .. vim.fn.expand("%:p:h") .. '"' .. " rev-parse")
if vim.v.shell_error == 0 then
vim.api.nvim_del_augroup_by_name("GitSignsLazyLoad")
vim.schedule(function()
require("lazy").load({ plugins = { "gitsigns.nvim" } })
end)
end
end,
})
end,
opts = {
signs = {
add = { text = "" },
change = { text = "" },
delete = { text = "" },
topdelete = { text = "" },
changedelete = { text = "" },
untracked = { text = "" },
},
on_attach = function(buffer)
local gs = package.loaded.gitsigns
local function map(mode, l, r, desc)
vim.keymap.set(mode, l, r, { buffer = buffer, desc = desc })
end
-- stylua: ignore start
map("n", "]h", gs.next_hunk, "Next Hunk")
map("n", "[h", gs.prev_hunk, "Prev Hunk")
map({ "n", "v" }, "<leader>ghs", ":Gitsigns stage_hunk<CR>", "Stage Hunk")
map({ "n", "v" }, "<leader>ghr", ":Gitsigns reset_hunk<CR>", "Reset Hunk")
map("n", "<leader>ghS", gs.stage_buffer, "Stage Buffer")
map("n", "<leader>ghu", gs.undo_stage_hunk, "Undo Stage Hunk")
map("n", "<leader>ghR", gs.reset_buffer, "Reset Buffer")
map("n", "<leader>ghp", gs.preview_hunk_inline, "Preview Hunk Inline")
map("n", "<leader>ghb", function() gs.blame_line({ full = true }) end, "Blame Line")
map("n", "<leader>ghd", gs.diffthis, "Diff This")
map("n", "<leader>ghD", function() gs.diffthis("~") end, "Diff This ~")
map({ "o", "x" }, "ih", ":<C-U>Gitsigns select_hunk<CR>", "GitSigns Select Hunk")
end,
},
},
-- undotree sidebar
{
"jiaoshijie/undotree",
dependencies = "nvim-lua/plenary.nvim",
config = true,
keys = { -- load the plugin only when using it's keybinding:
{ "<leader>u", "<cmd>lua require('undotree').toggle()<cr>" },
},
},
-- terminal
{
"akinsho/toggleterm.nvim",
cmd = { "ToggleTerm" },
opts = {},
keys = {
{ "<leader>t", "<cmd>ToggleTerm direction=vertical<cr>", desc = "Open terminal" },
{
"<leader>gg",
"<cmd>lua _LAZYGIT_TOGGLE()<CR>",
desc = "Toggle Lazy[G]it",
silent = true,
noremap = true,
},
{
"<leader>p",
":lua RUN_CODE()<CR>",
desc = "Run [P]roject",
silent = true,
noremap = true,
},
},
config = function()
require("toggleterm").setup({
size = function(term)
if term.direction == "horizontal" then
return 15
elseif term.direction == "vertical" then
return vim.o.columns * 0.45
end
end,
})
local run_command_table = {
["cpp"] = "([[ -f Makefile ]] && make all run)",
["c"] = "gcc -g -Wall % -o %:r && ./%:r",
["python"] = "python %",
["lua"] = "lua %",
["zsh"] = "zsh %",
["sh"] = "sh %",
-- ["java"] = "cd %:h && javac *.java && java %:t:r",
-- ["asm"] = "nasm -f elf64 % -o %:r.o && ld %:r.o -o %:r && ./%:r && rm %:r.o",
-- ["cpp"] = "g++ -g -Wall -Weffc++ -Wextra -Wconversion -Wsign-conversion -Werror -std=c++20 -pedantic-errors % -o %:r && ./%:r",
-- ["rust"] = "rustc % && ./%:r",
-- ["go"] = "go run %",
-- ["javascript"] = "node %",
}
local extra = 'printf "\\\\n\\\\033[0;33mPress ENTER to continue \\\\033[0m"; read'
local Terminal = require("toggleterm.terminal").Terminal
function EXPAND_SYMBOL_RESOLVER(cmd)
local mod = string.byte("%")
local space = string.byte(" ")
local col = string.byte(":")
local i = 1
local expanded_cmd = ""
while i <= #cmd do
if cmd:byte(i) == mod then
local j = i + 1
while cmd:byte(j) == col and cmd:byte(j + 1) ~= space and j <= #cmd do
j = j + 2
end
expanded_cmd = expanded_cmd .. vim.fn.expand(string.sub(cmd, i, j - 1))
i = j
end
expanded_cmd = expanded_cmd .. string.sub(cmd, i, i)
i = i + 1
end
return expanded_cmd
end
function RUN_CODE()
if run_command_table[vim.bo.filetype] then
local expanded_cmd = EXPAND_SYMBOL_RESOLVER(run_command_table[vim.bo.filetype])
local runcmd = expanded_cmd .. "; " .. extra
local runterm = Terminal:new({ cmd = runcmd, direction = "vertical" })
runterm:toggle()
else
print("\nFileType not supported\n")
end
end
function _LAZYGIT_TOGGLE()
Terminal:new({ cmd = "lazygit", hidden = true, direction = "float" }):toggle()
end
end,
},
}

View File

@ -0,0 +1,31 @@
return {
-- fzf
{
"ibhagwan/fzf-lua",
keys = {
{ "<leader>/", function() require("fzf-lua").buffers() end, desc = "Switch buffers" },
{ "<leader>l", function() require("fzf-lua").live_grep_native() end, desc = "Live Grep" },
{ "<leader>o", function() require("fzf-lua").oldfiles() end, desc = "Open Recent file" },
{ "<leader>b", function() require("fzf-lua").builtin() end, desc = "FZF menu" },
{ "<leader>ca", function() require("fzf-lua").lsp_code_actions() end, mode = { "n", "v" }, desc = "LSP Code Actions" },
{ "<leader>cd", function() require("fzf-lua").lsp_definitions() end, mode = { "n", "v" }, desc = "LSP Definitions" },
{ "<leader>cD", function() require("fzf-lua").lsp_declarations() end, mode = { "n", "v" }, desc = "LSP Declarations" },
{ "<leader>cI", function() require("fzf-lua").lsp_implementations() end, mode = { "n", "v" }, desc = "LSP Implementations" },
{ "<leader>cr", function() require("fzf-lua").lsp_references() end, mode = { "n", "v" }, desc = "LSP References" },
{ "<leader>ce", function() require("fzf-lua").lsp_document_diagnostics() end, desc = "LSP Diagnostics" },
{ "<leader>cwe", function() require("fzf-lua").lsp_workspace_diagnostics() end, desc = "LSP Workspace Diagnostics" },
{ "<leader>cD", function() require("fzf-lua").lsp_declarations() end, mode = { "n", "v" }, desc = "LSP Declarations" },
},
opts = {
previewers = {
builtin = {
extensions = {
["png"] = { "ueberzug" },
["jpg"] = { "ueberzug" },
},
ueberzug_scaler = "cover",
}
}
}
}
}

View File

@ -0,0 +1,186 @@
return {
{
"VonHeikemen/lsp-zero.nvim",
branch = "v3.x",
lazy = true,
config = false,
init = function()
vim.g.lsp_zero_extend_cmp = 0
vim.g.lsp_zero_extend_lspconfig = 0
end,
},
-- autocompletion
{
"hrsh7th/nvim-cmp",
event = "InsertEnter",
dependencies = {
{ "L3MON4D3/LuaSnip" },
{ "hrsh7th/cmp-buffer" },
{ "https://codeberg.org/FelipeLema/cmp-async-path" },
{ "hrsh7th/cmp-nvim-lsp" },
{ "saadparwaiz1/cmp_luasnip" },
{ "rafamadriz/friendly-snippets" },
{ "onsails/lspkind.nvim" },
{ "hrsh7th/cmp-calc" },
{ "f3fora/cmp-spell" },
{ "micangl/cmp-vimtex" },
{ "Jezda1337/nvim-html-css" },
},
config = function()
local lsp_zero = require("lsp-zero")
lsp_zero.extend_cmp()
local cmp = require("cmp")
local cmp_action = lsp_zero.cmp_action()
-- Lazy load snippets from VSCode
require("luasnip.loaders.from_vscode").lazy_load()
require("luasnip.loaders.from_vscode").lazy_load({ paths = { "./lua/snippets" } })
cmp.setup({
sources = {
{ name = "luasnip" },
{ name = "nvim_lsp" },
{ name = "buffer" },
{ name = "async_path" },
{ name = "calc" },
{ name = "html-css" },
{ name = "vimtex" },
{
name = "spell",
option = {
keep_all_entries = false,
enable_in_context = function()
return true
end,
},
},
},
preselect = "item",
completion = {
completeopt = "menu,menuone,noinsert",
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
formatting = {
maxwidth = 30,
fields = { "abbr", "kind" },
format = require("lspkind").cmp_format({
mode = "symbol_text",
maxwidth = 30,
ellipsis_char = "",
}),
},
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(),
["<C-u>"] = cmp.mapping.scroll_docs(-4),
["<C-d>"] = cmp.mapping.scroll_docs(4),
["<C-f>"] = cmp_action.luasnip_jump_forward(),
["<C-b>"] = cmp_action.luasnip_jump_backward(),
["<CR>"] = cmp.mapping.confirm({ select = false }),
["<Tab>"] = cmp_action.luasnip_supertab(),
["<S-Tab>"] = cmp_action.luasnip_shift_supertab(),
}),
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
})
end,
},
-- lsp
{
"neovim/nvim-lspconfig",
cmd = { "LspInfo", "LspInstall", "LspStart" },
event = { "BufReadPre", "BufNewFile" },
dependencies = {
{
"williamboman/mason.nvim",
config = true,
},
{ "hrsh7th/cmp-nvim-lsp" },
{ "williamboman/mason-lspconfig.nvim" },
},
config = function()
local lsp_zero = require("lsp-zero")
lsp_zero.extend_lspconfig()
lsp_zero.on_attach(function(client, bufnr)
lsp_zero.default_keymaps({
buffer = bufnr,
-- exclude = { 'gl', 'K' },
})
end)
lsp_zero.set_sign_icons({
error = "",
warn = "",
hint = "󰌵",
info = "",
})
require("mason-lspconfig").setup({
ensure_installed = {
"clangd",
"ruff_lsp",
"marksman",
"html",
"cssls",
"lua_ls",
"bashls",
"texlab",
"jsonls",
"eslint",
},
handlers = {
lsp_zero.default_setup,
lua_ls = function()
require("lspconfig").lua_ls.setup({
settings = {
Lua = {
workspace = { checkThirdParty = false },
telemetry = { enable = false },
},
},
})
end,
clangd = function()
require("lspconfig").clangd.setup({
capabilities = { offsetEncoding = "utf-16" },
-- cmd = {
-- "clangd",
-- "--background-index",
-- "--clang-tidy",
-- "--header-insertion=iwyu",
-- "--completion-style=detailed",
-- "--function-arg-placeholders",
-- "--fallback-style=llvm",
-- },
-- init_options = {
-- usePlaceholders = true,
-- completeUnimported = true,
-- clangdFileStatus = true,
-- },
})
end,
-- ltex = function()
-- require("lspconfig").ltex.setup({
-- settings = {
-- ltex = {
-- language = {"en-US"},
-- -- dictionary = {":~/.config/nvim/spell/en.utf-8.add"},
-- disabledRules = { ['en-US'] = { 'MORFOLOGIK_RULE_EN_US' } },
-- },
-- },
-- })
-- end,
},
})
end,
},
}

View File

@ -0,0 +1,45 @@
return {
-- formatting and linting
{
"nvimtools/none-ls.nvim",
event = "LspAttach",
opts = function()
local formatting = require("null-ls").builtins.formatting
local lint = require("null-ls").builtins.diagnostics
local code_actions = require("null-ls").builtins.code_actions
-- local actions = require("null-ls").builtins.code_actions
return {
sources = {
-- Linting
lint.cppcheck, -- for c,cpp ( Install manually using pacman )
lint.proselint, -- for md
lint.stylelint, -- for css
lint.codespell, -- general code spellings
-- Formatting
formatting.shfmt, -- for sh
formatting.prettier, -- for js, md, html, css``
-- Code Actions
code_actions.proselint,
code_actions.gitsigns,
code_actions.refactoring.with({
filetypes = {
"go",
"javascript",
"lua",
"python",
"typescript",
"c",
"cpp"
}
}),
},
}
end,
keys = {
{ "<leader>f", ":lua vim.lsp.buf.format({ timeout_ms = 2000 })<CR>", desc = "Format", silent = true },
},
}
}

View File

@ -0,0 +1,46 @@
return {
-- refactoring
{
"ThePrimeagen/refactoring.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-treesitter/nvim-treesitter",
},
event = "LspAttach",
cmd = { "Refactor" },
config = function()
require("refactoring").setup({
prompt_func_return_type = {
go = false,
java = false,
cpp = false,
c = false,
h = false,
hpp = false,
cxx = false,
},
prompt_func_param_type = {
go = false,
java = false,
cpp = false,
c = false,
h = false,
hpp = false,
cxx = false,
},
printf_statements = {},
print_var_statements = {},
show_success_message = false,
})
vim.keymap.set("x", "<leader>re", ":Refactor extract ")
vim.keymap.set("x", "<leader>rf", ":Refactor extract_to_file ")
vim.keymap.set("x", "<leader>rv", ":Refactor extract_var ")
vim.keymap.set({ "n", "x" }, "<leader>ri", ":Refactor inline_var")
vim.keymap.set("n", "<leader>rI", ":Refactor inline_func")
vim.keymap.set("n", "<leader>rb", ":Refactor extract_block")
vim.keymap.set("n", "<leader>rbf", ":Refactor extract_block_to_file")
end,
},
}

View File

@ -0,0 +1,105 @@
return {
-- treesitter
{
"nvim-treesitter/nvim-treesitter",
version = false,
event = { "BufReadPre", "BufNewFile" },
build = ":TSUpdate",
dependencies = {
"nvim-treesitter/nvim-treesitter-textobjects",
{
"windwp/nvim-ts-autotag",
opts = {},
},
},
config = function()
local treesitter = require("nvim-treesitter.configs")
treesitter.setup({
highlight = { enable = true, disable = { "latex" } },
indent = { enable = true },
ensure_installed = {
"bash",
"html",
"css",
"javascript",
"lua",
"python",
"vim",
"vimdoc",
"yaml",
"json",
"c",
"cpp",
"go",
"rust",
"regex",
"latex",
"bibtex"
},
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<C-space>",
node_incremental = "<C-space>",
scope_incremental = "<c-s>",
node_decremental = "<M-space>",
},
},
textobjects = {
move = {
enable = true,
goto_next_start = { ["]f"] = "@function.outer", ["]c"] = "@class.outer" },
goto_next_end = { ["]F"] = "@function.outer", ["]C"] = "@class.outer" },
goto_previous_start = { ["[f"] = "@function.outer", ["[c"] = "@class.outer" },
goto_previous_end = { ["[F"] = "@function.outer", ["[C"] = "@class.outer" },
},
},
})
end,
},
-- mini.ai
{
"echasnovski/mini.ai",
-- keys = {
-- { "a", mode = { "x", "o" } },
-- { "i", mode = { "x", "o" } },
-- },
event = "VeryLazy",
opts = function()
local ai = require("mini.ai")
return {
n_lines = 500,
custom_textobjects = {
o = ai.gen_spec.treesitter({
a = { "@block.outer", "@conditional.outer", "@loop.outer" },
i = { "@block.inner", "@conditional.inner", "@loop.inner" },
}, {}),
f = ai.gen_spec.treesitter({ a = "@function.outer", i = "@function.inner" }, {}),
c = ai.gen_spec.treesitter({ a = "@class.outer", i = "@class.inner" }, {}),
t = { "<([%p%w]-)%f[^<%w][^<>]->.-</%1>", "^<.->().*()</[^/]->$" },
d = { "%f[%d]%d+" }, -- digits
e = { -- Word with case
{
"%u[%l%d]+%f[^%l%d]",
"%f[%S][%l%d]+%f[^%l%d]",
"%f[%P][%l%d]+%f[^%l%d]",
"^[%l%d]+%f[^%l%d]",
},
"^().*()$",
},
g = function() -- Whole buffer, similar to `gg` and 'G' motion
local from = { line = 1, col = 1 }
local to = {
line = vim.fn.line("$"),
col = math.max(vim.fn.getline("$"):len(), 1),
}
return { from = from, to = to }
end,
u = ai.gen_spec.function_call(), -- u for "Usage"
U = ai.gen_spec.function_call({ name_pattern = "[%w_]" }), -- without dot in function name
},
}
end,
}
}

View File

@ -0,0 +1,422 @@
return {
-- colorscheme
{
"folke/tokyonight.nvim",
lazy = false,
priority = 1000,
config = function()
require("tokyonight").setup({
style = "night",
styles = {
sidebars = "dark",
floats = "dark",
},
sidebars = { "qf", "help", "Outline" },
on_colors = function(colors)
colors.bg = "#16161E"
colors.bg_dark = "#0d0d12"
end,
on_highlights = function(hl, colors)
hl.DiagnosticVirtualTextError = {
fg = colors.comment
}
hl.DiagnosticVirtualTextHint = {
fg = colors.comment
}
hl.DiagnosticVirtualTextInfo = {
fg = colors.comment
}
hl.DiagnosticVirtualTextWarn = {
fg = colors.comment
}
end,
})
vim.cmd.colorscheme("tokyonight")
end,
},
-- icons
{
"nvim-tree/nvim-web-devicons",
},
-- statusline
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
config = function()
local lualine = require("lualine")
local themecolor = require("tokyonight.colors").setup()
local colors = {
bg = "#0d0d12",
fg = themecolor.fg_dark,
yellow = themecolor.yellow,
cyan = themecolor.cyan,
green = themecolor.green,
magenta = themecolor.magenta,
blue = themecolor.blue,
red = themecolor.red,
low = themecolor.terminal_black,
mode = themecolor.terminal_black,
bg2 = "#292e42",
bg3 = "#16161e"
}
local mode_color = {
n = colors.blue,
i = colors.green,
v = colors.magenta,
["^V"] = colors.magenta,
V = colors.magenta,
c = colors.blue,
no = colors.red,
ic = colors.yellow,
R = colors.red,
Rv = colors.red,
cv = colors.red,
ce = colors.red,
r = colors.blue,
rm = colors.blue,
["r?"] = colors.blue,
["!"] = colors.blue,
t = colors.blue,
}
local conditions = {
buffer_not_empty = function()
return vim.fn.empty(vim.fn.expand("%:t")) ~= 1
end,
hide_in_width = function()
return vim.fn.winwidth(0) > 80
end,
check_git_workspace = function()
local filepath = vim.fn.expand("%:p:h")
local gitdir = vim.fn.finddir(".git", filepath .. ";")
return gitdir and #gitdir > 0 and #gitdir < #filepath
end,
}
local config = {
options = {
component_separators = "",
section_separators = "",
disabled_filetypes = { "help", "lazy", "mason", "fzf", "lspinfo", "alpha" },
theme = {
normal = { c = { fg = colors.fg, bg = colors.bg3 } },
inactive = { c = { fg = colors.fg, bg = colors.bg3 } },
},
},
sections = {
lualine_a = {},
lualine_b = {},
lualine_y = {},
lualine_z = {},
lualine_c = {},
lualine_x = {},
},
inactive_sections = {
lualine_a = {},
lualine_b = {},
lualine_y = {},
lualine_z = {},
lualine_c = {},
lualine_x = {},
},
}
local function ins_left(component)
table.insert(config.sections.lualine_c, component)
end
local function ins_right(component)
table.insert(config.sections.lualine_x, component)
end
ins_left({
function()
return ""
end,
color = { fg = colors.bg2, bg = colors.bg3 },
padding = { left = 0, right = 0 },
})
ins_left({
function()
return ""
-- return " "
-- return " "
end,
color = function()
return { fg = mode_color[vim.fn.mode()], bg = colors.bg2 }
end,
padding = { left = 0, right = 0 },
})
ins_left({
function()
return ""
end,
color = { fg = colors.bg2 },
padding = { left = 0, right = 1 },
})
ins_left({
"buffers",
buffers_color = {
active = { fg = colors.magenta, bg = colors.bg3 },
inactive = { fg = colors.low, bg = colors.bg3 },
},
symbols = {
modified = "",
alternate_file = "",
},
cond = conditions.buffer_not_empty,
color = { fg = colors.magenta, gui = "bold" },
})
ins_right({
function()
if vim.bo.filetype == "txt" or vim.bo.filetype == "markdown" or vim.bo.filetype == "tex" then
if vim.fn.wordcount().visual_words == 1 then
return tostring(vim.fn.wordcount().visual_words) .. " word"
elseif not (vim.fn.wordcount().visual_words == nil) then
return tostring(vim.fn.wordcount().visual_words) .. " words"
else
return tostring(vim.fn.wordcount().words) .. " words"
end
else
return ""
end
end,
color = { fg = colors.low },
})
ins_right({
-- Lsp server name
function()
local msg = "Inactive"
local buf_ft = vim.api.nvim_buf_get_option(0, "filetype")
local clients = vim.lsp.get_active_clients()
if next(clients) == nil then
return msg
end
for _, client in ipairs(clients) do
local filetypes = client.config.filetypes
if filetypes and vim.fn.index(filetypes, buf_ft) ~= -1 then
return client.name
end
end
return msg
end,
icon = "",
color = { fg = colors.low },
})
ins_right({
"branch",
icon = "",
color = { fg = colors.low, gui = "bold" },
})
ins_right({
"diff",
symbols = { added = "", modified = "", removed = "" },
diff_color = {
added = { fg = colors.low },
modified = { fg = colors.low },
removed = { fg = colors.low },
},
cond = conditions.hide_in_width,
})
ins_right({
"location",
color = function()
return { fg = mode_color[vim.fn.mode()] }
end,
padding = { left = 0, right = 1 },
})
ins_right({
function()
return ""
end,
color = { fg = colors.bg2 },
padding = { left = 0, right = 0 },
})
ins_right({
"progress",
color = function()
return { fg = mode_color[vim.fn.mode()], bg = colors.bg2, gui = "bold" }
end,
padding = { left = 0, right = 0 },
})
ins_right({
function()
return ""
end,
color = { fg = colors.bg2, bg = colors.bg3 },
padding = { left = 0, right = 0 },
})
lualine.setup(config)
end,
},
-- indentation lines
{
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
event = "VeryLazy",
opts = {
-- scope = { enabled = false },
scope = { enabled = true },
exclude = {
filetypes = { "help", "lazy", "mason", "outline", "toggleterm", "fzf", "lspinfo" },
},
},
},
-- dashboard
{
"goolord/alpha-nvim",
event = "VimEnter",
config = function()
local dashboard = require("alpha.themes.dashboard")
local create_gradient = function(start, finish, steps)
local r1, g1, b1 =
tonumber("0x" .. start:sub(2, 3)),
tonumber("0x" .. start:sub(4, 5)),
tonumber("0x" .. start:sub(6, 7))
local r2, g2, b2 =
tonumber("0x" .. finish:sub(2, 3)),
tonumber("0x" .. finish:sub(4, 5)),
tonumber("0x" .. finish:sub(6, 7))
local r_step = (r2 - r1) / steps
local g_step = (g2 - g1) / steps
local b_step = (b2 - b1) / steps
local gradient = {}
for i = 1, steps do
local r = math.floor(r1 + r_step * i)
local g = math.floor(g1 + g_step * i)
local b = math.floor(b1 + b_step * i)
table.insert(gradient, string.format("#%02x%02x%02x", r, g, b))
end
return gradient
end
local function apply_gradient_hl(text)
local gradient = create_gradient("#7aa2f7", "#414868", #text)
local lines = {}
for i, line in ipairs(text) do
local tbl = {
type = "text",
val = line,
opts = {
hl = "HeaderGradient" .. i,
shrink_margin = false,
position = "center",
},
}
table.insert(lines, tbl)
-- create hl group
vim.api.nvim_set_hl(0, "HeaderGradient" .. i, { fg = gradient[i] })
end
return {
type = "group",
val = lines,
opts = { position = "center" },
}
end
local headers = require("ascii")
dashboard.section.buttons.val = {
dashboard.button("r", " Recent files", ":lua require('fzf-lua').oldfiles()<CR>"),
dashboard.button("e", " New file", ":ene <BAR> startinsert <CR>"),
dashboard.button("p", " Projects",
function()
local contents = require("project_nvim").get_recent_projects()
local reverse = {}
for i = #contents, 1, -1 do
reverse[#reverse + 1] = contents[i]
end
require("fzf-lua").fzf_exec(reverse, {
actions = {
["default"] = function(e)
-- vim.cmd.cd(e[1])
require("fzf-lua").files({ cwd = e[1] })
end,
["ctrl-d"] = function(x)
local choice = vim.fn.confirm("Delete '" .. #x .. "' projects? ", "&Yes\n&No", 2)
if choice == 1 then
local history = require("project_nvim.utils.history")
for _, v in ipairs(x) do
history.delete_project(v)
end
end
end,
},
winopts = {
height = 0.3,
width = 0.5,
},
})
end),
dashboard.button("f", " Find file", ":lua require('fzf-lua').files()<CR>"),
dashboard.button("t", "󱎸 Find text", ":lua require('fzf-lua').live_grep_native()<CR>"),
dashboard.button("s", " Restore Session", ":lua require('persistence').load()<CR>"),
dashboard.button("n", "󰠮 Notes", ":lua require('fzf-lua').files({cwd =[[~/notes]]})<CR>"),
dashboard.button("c", " Configuration", ":e $MYVIMRC <CR>"),
dashboard.button("z", "󰒲 Lazy", ":Lazy<CR>"),
dashboard.button("q", " Quit Neovim", ":qa<CR>"),
}
dashboard.section.buttons.opts.spacing = 0
vim.api.nvim_create_autocmd("User", {
pattern = "LazyVimStarted",
callback = function()
local stats = require("lazy").stats()
local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100)
dashboard.section.footer.val = "󱎫 " .. ms .. " ms"
pcall(vim.cmd.AlphaRedraw)
end,
})
local headerKeys = {}
for key, _ in pairs(headers) do
table.insert(headerKeys, key)
end
local randomHeader = headerKeys[math.random(#headerKeys)]
dashboard.config.layout = {
{ type = "padding", val = 3 },
-- options = randomHeader, raven, yggdrasil,
-- void_stranger, aot, meatboy, isaac, gta,
-- hydra, spider, morse, sharp, galaxy,
apply_gradient_hl(headers[randomHeader]),
{ type = "padding", val = 4 },
dashboard.section.buttons,
{ type = "padding", val = 4 },
dashboard.section.footer,
}
dashboard.opts.opts.noautocmd = true
require("alpha").setup(dashboard.opts)
end,
},
-- zen-mode
{
"folke/zen-mode.nvim",
opts = {
window = {
backdrop = 0,
width = 100,
height = 0.85,
},
plugins = {
gitsigns = { enabled = false },
kitty = {
enabled = true,
font = "+2",
},
},
},
keys = {
{ "<leader>z", ":lua require('zen-mode').toggle()<CR>", desc = "[Z]en Mode", silent = true },
},
},
}

View File

@ -0,0 +1,34 @@
{
"Print Name and Date": {
"prefix": "signature",
"body": ["${0:Author}", "${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}"],
"description": "Signature"
},
"MIT": {
"prefix": "mitl",
"description": "MIT License",
"body": [
"The MIT License (MIT)",
"",
"Copyright (c) ${CURRENT_YEAR} ${0:Author}",
"",
"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,21 @@
{
"name": "user snippets",
"engines": {
"vscode": "^1.11.0"
},
"contributes": {
"snippets": [
{
"language": [
"plaintext",
"markdown",
"tex",
"html",
"global",
"all"
],
"path": "./global.json"
}
]
}
}

50
.config/shell/aliasrc Normal file
View File

@ -0,0 +1,50 @@
#!/bin/sh
# Use neovim for vim if present.
[ -x "$(command -v nvim)" ] && alias vim="nvim" vimdiff="nvim -d"
# Use $XINITRC variable if file exists.
[ -f "$XINITRC" ] && alias startx="startx \$XINITRC"
alias svn="svn --config-dir \"$XDG_CONFIG_HOME\"/subversion"
# sudo not required for some system commands
for command in mount umount pacman updatedb su shutdown poweroff reboot; do
alias $command="sudo $command"
done
unset command
alias \
be="fzf-fd \$HOME/.local/bin | xargs nvim" \
yy="yazi" \
ce="fzf-fd \$HOME/.config | xargs nvim" \
cg="fzf-grep \$HOME/.config" \
fe="fzf-fd \$(pwd) | xargs nvim" \
fg="fzf-grep \$(pwd)" \
cp="cp -iv" \
mv="mv -iv" \
rm="rm -vI" \
ka="killall" \
g="git" \
sdn="shutdown -h now" \
v="\$EDITOR" \
p="pacman" \
z="zathura" \
x="exit" \
mkd="mkdir -pv" \
ls="eza --icons --group-directories-first" \
lss="lsd -lt --total-size --group-directories-first" \
lsa="eza -a --icons --group-directories-first" \
lsas="lsd -lAt --total-size --group-directories-first" \
lst="eza -T --icons" \
grep="grep --color=auto" \
diff="diff --color=auto" \
ccat="highlight --out-format=ansi" \
ip="ip -color=auto" \
cat="bat -pp" \
yt="yt-dlp --embed-metadata -i" \
yta="yt -x -f bestaudio/best" \
ffmpeg="ffmpeg -hide_banner" \
ref="shortcuts >/dev/null; source \${XDG_CONFIG_HOME:-\$HOME/.config}/shell/shortcutrc ; source \${XDG_CONFIG_HOME:-\$HOME/.config}/shell/zshnameddirrc" \
weath="curl wttr.in | head -n -1 | cat" \
weath2="curl v2.wttr.in | head -n -1 | cat"

9
.config/shell/vi.zsh Normal file
View File

@ -0,0 +1,9 @@
echo -ne '\e[3 q' # Use underline shape cursor on startup.
preexec() { echo -ne '\e[3 q' ;} # Use underline shape cursor for each new prompt.
# Edit line in vim with ctrl-e:
autoload edit-command-line; zle -N edit-command-line
bindkey '^e' edit-command-line
bindkey -M vicmd '^[[P' vi-delete-char
bindkey -M vicmd '^e' edit-command-line
bindkey -M visual '^[[P' vi-delete

13
.config/starship.toml Normal file
View File

@ -0,0 +1,13 @@
[git_branch]
symbol = ' '
[git_metrics]
disabled = false
added_style = 'bold blue'
format = '[+$added]($added_style)/[-$deleted]($deleted_style) '
[gcloud]
disabled = true
[battery]
disabled = true

View File

@ -0,0 +1,30 @@
MIT/X Consortium License
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
© 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com>
© 2006-2007 Michał Janeczek <janeczek@gmail.com>
© 2007 Kris Maglione <jg@suckless.org>
© 2009 Gottox <gottox@s01.de>
© 2009 Markus Schnalke <meillo@marmaro.de>
© 2009 Evan Gates <evan.gates@gmail.com>
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
© 2014-2022 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2015-2019 Quentin Rameau <quinq@fifth.space>
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,58 @@
# dmenu - dynamic menu
# See LICENSE file for copyright and license details.
include config.mk
SRC = drw.c dmenu.c stest.c util.c
OBJ = $(SRC:.c=.o)
all: dmenu stest
.c.o:
$(CC) -c $(CFLAGS) $<
config.h:
cp config.def.h $@
$(OBJ): arg.h config.h config.mk drw.h
dmenu: dmenu.o drw.o util.o
$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
stest: stest.o
$(CC) -o $@ stest.o $(LDFLAGS)
clean:
rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
dist: clean
mkdir -p dmenu-$(VERSION)
cp LICENSE Makefile README arg.h config.mk dmenu.1\
drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
dmenu-$(VERSION)
tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
gzip dmenu-$(VERSION).tar
rm -rf dmenu-$(VERSION)
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
$(DESTDIR)$(PREFIX)/bin/dmenu_path\
$(DESTDIR)$(PREFIX)/bin/dmenu_run\
$(DESTDIR)$(PREFIX)/bin/stest\
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
$(DESTDIR)$(MANPREFIX)/man1/stest.1
.PHONY: all clean dist install uninstall

View File

@ -0,0 +1,49 @@
/*
* Copy me if you can.
* by 20h
*/
#ifndef ARG_H__
#define ARG_H__
extern char *argv0;
/* use main(int argc, char *argv[]) */
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
argv[0] && argv[0][0] == '-'\
&& argv[0][1];\
argc--, argv++) {\
char argc_;\
char **argv_;\
int brk_;\
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
argv++;\
argc--;\
break;\
}\
for (brk_ = 0, argv[0]++, argv_ = argv;\
argv[0][0] && !brk_;\
argv[0]++) {\
if (argv_ != argv)\
break;\
argc_ = argv[0][0];\
switch (argc_)
#define ARGEND }\
}
#define ARGC() argc_
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
((x), abort(), (char *)0) :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
(char *)0 :\
(brk_ = 1, (argv[0][1] != '\0')?\
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
#endif

View File

@ -0,0 +1,39 @@
/* See LICENSE file for copyright and license details. */
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
static int fuzzy = 1; /* -F option; if 0, dmenu doesn't use fuzzy matching */
static int instant = 0; /* -n option; if 1, selects matching item without the need to press enter */
static int center = 0; /* -c option; if 0, dmenu won't be centered on the screen */
static int min_width = 680; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */
static char *fonts[] =
{
"JetBrainsMono Nerd Font Semiblod:size=12"
};
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static
char *colors[][2] = {
/* fg bg */
[SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#00ffff" },
[SchemeBorder] = { "#000000", "#005577" },
};
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
static unsigned int lines = 0;
/* -g option; if nonzero, dmenu uses a grid comprised of columns and lines */
static unsigned int columns = 0;
static unsigned int lineheight = 0; /* -h option; minimum height of a menu line */
static unsigned int min_lineheight = 8;
/*
* Characters not considered part of a word while deleting words
* for example: " /?\"&[]"
*/
static const char worddelimiters[] = " ";
/* Size of the window border */
static unsigned int border_width = 0;

View File

@ -0,0 +1,42 @@
# dmenu version
VERSION = 5.2
# paths
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = $(X11INC)/freetype2
#MANPREFIX = ${PREFIX}/man
# uncomment on RHEL for strcasecmp
#EXTRAFLAGS=-D_GNU_SOURCE
# Uncomment this for the alpha patch / ALPHA_PATCH
XRENDER = -lXrender
# Uncomment for the pango patch / PANGO_PATCH
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
# includes and libs
INCS = -I$(X11INC) -I$(FREETYPEINC) ${PANGOINC}
LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) -lm $(XRENDER) ${PANGOLIB}
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) $(EXTRAFLAGS)
CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
LDFLAGS = $(LIBS)
# compiler and linker
CC = cc

View File

@ -0,0 +1,194 @@
.TH DMENU 1 dmenu\-VERSION
.SH NAME
dmenu \- dynamic menu
.SH SYNOPSIS
.B dmenu
.RB [ \-bfiv ]
.RB [ \-l
.IR lines ]
.RB [ \-m
.IR monitor ]
.RB [ \-p
.IR prompt ]
.RB [ \-fn
.IR font ]
.RB [ \-nb
.IR color ]
.RB [ \-nf
.IR color ]
.RB [ \-sb
.IR color ]
.RB [ \-sf
.IR color ]
.RB [ \-w
.IR windowid ]
.P
.BR dmenu_run " ..."
.SH DESCRIPTION
.B dmenu
is a dynamic menu for X, which reads a list of newline\-separated items from
stdin. When the user selects an item and presses Return, their choice is printed
to stdout and dmenu terminates. Entering text will narrow the items to those
matching the tokens in the input.
.P
.B dmenu_run
is a script used by
.IR dwm (1)
which lists programs in the user's $PATH and runs the result in their $SHELL.
.SH OPTIONS
.TP
.B \-b
dmenu appears at the bottom of the screen.
.TP
.B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This
is faster, but will lock up X until stdin reaches end\-of\-file.
.TP
.B \-i
dmenu matches menu items case insensitively.
.TP
.BI \-l " lines"
dmenu lists items vertically, with the given number of lines.
.TP
.BI \-m " monitor"
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
from 0.
.TP
.BI \-p " prompt"
defines the prompt to be displayed to the left of the input field.
.TP
.BI \-fn " font"
defines the font or font set used.
.TP
.BI \-nb " color"
defines the normal background color.
.IR #RGB ,
.IR #RRGGBB ,
and X color names are supported.
.TP
.BI \-nf " color"
defines the normal foreground color.
.TP
.BI \-sb " color"
defines the selected background color.
.TP
.BI \-sf " color"
defines the selected foreground color.
.TP
.B \-v
prints version information to stdout, then exits.
.TP
.BI \-w " windowid"
embed into windowid.
.SH USAGE
dmenu is completely controlled by the keyboard. Items are selected using the
arrow keys, page up, page down, home, and end.
.TP
.B Tab
Copy the selected item to the input field.
.TP
.B Return
Confirm selection. Prints the selected item to stdout and exits, returning
success.
.TP
.B Ctrl-Return
Confirm selection. Prints the selected item to stdout and continues.
.TP
.B Shift\-Return
Confirm input. Prints the input text to stdout and exits, returning success.
.TP
.B Escape
Exit without selecting an item, returning failure.
.TP
.B Ctrl-Left
Move cursor to the start of the current word
.TP
.B Ctrl-Right
Move cursor to the end of the current word
.TP
.B C\-a
Home
.TP
.B C\-b
Left
.TP
.B C\-c
Escape
.TP
.B C\-d
Delete
.TP
.B C\-e
End
.TP
.B C\-f
Right
.TP
.B C\-g
Escape
.TP
.B C\-h
Backspace
.TP
.B C\-i
Tab
.TP
.B C\-j
Return
.TP
.B C\-J
Shift-Return
.TP
.B C\-k
Delete line right
.TP
.B C\-m
Return
.TP
.B C\-M
Shift-Return
.TP
.B C\-n
Down
.TP
.B C\-p
Up
.TP
.B C\-u
Delete line left
.TP
.B C\-w
Delete word left
.TP
.B C\-y
Paste from primary X selection
.TP
.B C\-Y
Paste from X clipboard
.TP
.B M\-b
Move cursor to the start of the current word
.TP
.B M\-f
Move cursor to the end of the current word
.TP
.B M\-g
Home
.TP
.B M\-G
End
.TP
.B M\-h
Up
.TP
.B M\-j
Page down
.TP
.B M\-k
Page up
.TP
.B M\-l
Down
.SH SEE ALSO
.IR dwm (1),
.IR stest (1)

View File

@ -0,0 +1,1041 @@
/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#ifdef XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include <X11/Xft/Xft.h>
/* Patch incompatibility overrides */
#include "drw.h"
#include "util.h"
#include <stdbool.h>
/* macros */
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
/* enums */
enum {
SchemeNorm,
SchemeSel,
SchemeOut,
SchemeBorder,
SchemeLast,
}; /* color schemes */
struct item {
char *text;
char *stext;
struct item *left, *right;
int out;
double distance;
};
static char text[BUFSIZ] = "";
static char *embed;
static int bh, mw, mh;
static int dmx = 0, dmy = 0; /* put dmenu at these x and y offsets */
static unsigned int dmw = 0; /* make dmenu this wide */
static int inputw = 0, promptw;
static int passwd = 0;
static int lrpad; /* sum of left and right padding */
static size_t cursor;
static struct item *items = NULL;
static struct item *matches, *matchend;
static struct item *prev, *curr, *next, *sel;
static int mon = -1, screen;
static Atom clip, utf8;
static Display *dpy;
static Window root, parentwin, win;
static XIC xic;
static Drw *drw;
static Clr *scheme[SchemeLast];
#include "patch/include.h"
#include "config.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr;
static unsigned int
textw_clamp(const char *str, unsigned int n)
{
unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad;
return MIN(w, n);
}
static void appenditem(struct item *item, struct item **list, struct item **last);
static void calcoffsets(void);
static void cleanup(void);
static char * cistrstr(const char *s, const char *sub);
static int drawitem(struct item *item, int x, int y, int w);
static void drawmenu(void);
static void grabfocus(void);
static void grabkeyboard(void);
static void match(void);
static void insert(const char *str, ssize_t n);
static size_t nextrune(int inc);
static void movewordedge(int dir);
static void keypress(XKeyEvent *ev);
static void paste(void);
static void readstdin(void);
static void run(void);
static void setup(void);
static void usage(void);
#include "patch/include.c"
static void
appenditem(struct item *item, struct item **list, struct item **last)
{
if (*last)
(*last)->right = item;
else
*list = item;
item->left = *last;
item->right = NULL;
*last = item;
}
static void
calcoffsets(void)
{
int i, n, rpad = 0;
if (lines > 0) {
if (columns)
n = lines * columns * bh;
else
n = lines * bh;
} else {
n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">") + rpad);
}
/* calculate which items will begin the next page and previous page */
for (i = 0, next = curr; next; next = next->right)
if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n)
break;
for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n)
break;
}
static void
cleanup(void)
{
size_t i;
XUngrabKey(dpy, AnyKey, AnyModifier, root);
for (i = 0; i < SchemeLast; i++)
free(scheme[i]);
for (i = 0; items && items[i].text; ++i)
free(items[i].text);
free(items);
drw_free(drw);
XSync(dpy, False);
XCloseDisplay(dpy);
}
static char *
cistrstr(const char *s, const char *sub)
{
size_t len;
for (len = strlen(sub); *s; s++)
if (!strncasecmp(s, sub, len))
return (char *)s;
return NULL;
}
static int
drawitem(struct item *item, int x, int y, int w)
{
int r;
char *text = item->stext;
if (item == sel)
drw_setscheme(drw, scheme[SchemeSel]);
else if (item->out)
drw_setscheme(drw, scheme[SchemeOut]);
else
drw_setscheme(drw, scheme[SchemeNorm]);
r = drw_text(drw
, x
, y
, w
, bh
, lrpad / 2
, text
, 0
);
return r;
}
static void
drawmenu(void)
{
static int curpos, oldcurlen;
int curlen, rcurlen;
struct item *item;
int x = 0, y = 0, w, rpad = 0, itw = 0, stw = 0;
int fh = drw->fonts->h;
char *censort;
drw_setscheme(drw, scheme[SchemeNorm]);
drw_rect(drw, 0, 0, mw, mh, 1, 1);
if (prompt && *prompt) {
drw_setscheme(drw, scheme[SchemeSel]);
x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0
);
}
/* draw input field */
w = (lines > 0 || !matches) ? mw - x : inputw;
w -= lrpad / 2;
x += lrpad / 2;
rcurlen = TEXTW(text + cursor) - lrpad;
curlen = TEXTW(text) - lrpad - rcurlen;
curpos += curlen - oldcurlen;
curpos = MIN(w, MAX(0, curpos));
curpos = MAX(curpos, w - rcurlen);
curpos = MIN(curpos, curlen);
oldcurlen = curlen;
drw_setscheme(drw, scheme[SchemeNorm]);
if (passwd) {
censort = ecalloc(1, sizeof(text));
memset(censort, '.', strlen(text));
drw_text_align(drw, x, 0, curpos, bh, censort, cursor, AlignR);
drw_text_align(drw, x + curpos, 0, w - curpos, bh, censort + cursor, strlen(censort) - cursor, AlignL);
free(censort);
} else {
drw_text_align(drw, x, 0, curpos, bh, text, cursor, AlignR);
drw_text_align(drw, x + curpos, 0, w - curpos, bh, text + cursor, strlen(text) - cursor, AlignL);
}
drw_rect(drw, x + curpos - 1, 2 + (bh-fh)/2, 2, fh - 4, 1, 0);
if (lines > 0) {
/* draw grid */
int i = 0;
for (item = curr; item != next; item = item->right, i++)
if (columns)
drawitem(
item,
0 + ((i / lines) * (mw / columns)),
y + (((i % lines) + 1) * bh),
mw / columns
);
else
drawitem(item, 0, y += bh, mw);
} else if (matches) {
/* draw horizontal list */
x += inputw;
w = TEXTW("<");
if (curr->left) {
drw_setscheme(drw, scheme[SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0
);
}
x += w;
for (item = curr; item != next; item = item->right) {
stw = TEXTW(">");
itw = textw_clamp(item->stext, mw - x - stw - rpad);
x = drawitem(item, x, 0, itw);
}
if (next) {
w = TEXTW(">");
drw_setscheme(drw, scheme[SchemeNorm]);
drw_text(drw, mw - w - rpad, 0, w, bh, lrpad / 2
, ">"
, 0
);
}
}
drw_map(drw, win, 0, 0, mw, mh);
}
static void
grabfocus(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
Window focuswin;
int i, revertwin;
for (i = 0; i < 100; ++i) {
XGetInputFocus(dpy, &focuswin, &revertwin);
if (focuswin == win)
return;
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
nanosleep(&ts, NULL);
}
die("cannot grab focus");
}
static void
grabkeyboard(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
int i;
if (embed)
return;
/* try to grab keyboard, we may have to wait for another process to ungrab */
for (i = 0; i < 1000; i++) {
if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
GrabModeAsync, CurrentTime) == GrabSuccess)
return;
nanosleep(&ts, NULL);
}
die("cannot grab keyboard");
}
static void
match(void)
{
if (fuzzy) {
fuzzymatch();
return;
}
static char **tokv = NULL;
static int tokn = 0;
char buf[sizeof text], *s;
int i, tokc = 0;
size_t len, textsize;
struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
strcpy(buf, text);
/* separate input text into tokens to be matched individually */
for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
die("cannot realloc %zu bytes:", tokn * sizeof *tokv);
len = tokc ? strlen(tokv[0]) : 0;
matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
textsize = strlen(text) + 1;
for (item = items; item && item->text; item++)
{
for (i = 0; i < tokc; i++)
if (!fstrstr(item->text, tokv[i]))
break;
if (i != tokc) /* not all tokens match */
continue;
/* exact matches go first, then prefixes, then substrings */
if (!tokc || !fstrncmp(text, item->text, textsize))
appenditem(item, &matches, &matchend);
else if (!fstrncmp(tokv[0], item->text, len))
appenditem(item, &lprefix, &prefixend);
else
appenditem(item, &lsubstr, &substrend);
}
if (lprefix) {
if (matches) {
matchend->right = lprefix;
lprefix->left = matchend;
} else
matches = lprefix;
matchend = prefixend;
}
if (lsubstr)
{
if (matches) {
matchend->right = lsubstr;
lsubstr->left = matchend;
} else
matches = lsubstr;
matchend = substrend;
}
curr = sel = matches;
if (instant && matches && matches==matchend && !lsubstr) {
puts(matches->text);
cleanup();
exit(0);
}
calcoffsets();
}
static void
insert(const char *str, ssize_t n)
{
if (strlen(text) + n > sizeof text - 1)
return;
/* move existing text out of the way, insert new text, and update cursor */
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
if (n > 0)
memcpy(&text[cursor], str, n);
cursor += n;
match();
}
static size_t
nextrune(int inc)
{
ssize_t n;
/* return location of next utf8 rune in the given direction (+1 or -1) */
for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc)
;
return n;
}
static void
movewordedge(int dir)
{
if (dir < 0) { /* move cursor to the start of the word*/
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
cursor = nextrune(-1);
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
cursor = nextrune(-1);
} else { /* move cursor to the end of the word */
while (text[cursor] && strchr(worddelimiters, text[cursor]))
cursor = nextrune(+1);
while (text[cursor] && !strchr(worddelimiters, text[cursor]))
cursor = nextrune(+1);
}
}
static void
keypress(XKeyEvent *ev)
{
char buf[64];
int len;
KeySym ksym = NoSymbol;
Status status;
int i;
struct item *tmpsel;
bool offscreen = false;
len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
switch (status) {
default: /* XLookupNone, XBufferOverflow */
return;
case XLookupChars: /* composed string from input method */
goto insert;
case XLookupKeySym:
case XLookupBoth: /* a KeySym and a string are returned: use keysym */
break;
}
if (ev->state & ControlMask) {
switch(ksym) {
case XK_a: expect("ctrl-a", ev); ksym = XK_Home; break;
case XK_b: expect("ctrl-b", ev); ksym = XK_Left; break;
case XK_c: expect("ctrl-c", ev); ksym = XK_Escape; break;
case XK_d: expect("ctrl-d", ev); ksym = XK_Delete; break;
case XK_e: expect("ctrl-e", ev); ksym = XK_End; break;
case XK_f: expect("ctrl-f", ev); ksym = XK_Right; break;
case XK_g: expect("ctrl-g", ev); ksym = XK_Escape; break;
case XK_h: expect("ctrl-h", ev); ksym = XK_BackSpace; break;
case XK_i: expect("ctrl-i", ev); ksym = XK_Tab; break;
case XK_j: expect("ctrl-j", ev); ksym = XK_Down; break;
case XK_J:/* fallthrough */
case XK_l: expect("ctrl-l", ev); break;
case XK_m: expect("ctrl-m", ev); /* fallthrough */
case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
case XK_n: expect("ctrl-n", ev); ksym = XK_Down; break;
case XK_p: expect("ctrl-p", ev); ksym = XK_Up; break;
case XK_o: expect("ctrl-o", ev); break;
case XK_q: expect("ctrl-q", ev); break;
case XK_r: expect("ctrl-r", ev); break;
case XK_s: expect("ctrl-s", ev); break;
case XK_t: expect("ctrl-t", ev); break;
case XK_k: expect("ctrl-k", ev); ksym = XK_Up; break;
case XK_u: expect("ctrl-u", ev); /* delete left */
insert(NULL, 0 - cursor);
break;
case XK_w: expect("ctrl-w", ev); /* delete word */
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
insert(NULL, nextrune(-1) - cursor);
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
insert(NULL, nextrune(-1) - cursor);
break;
case XK_v:
expect("ctrl-v", ev);
case XK_V:
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
utf8, utf8, win, CurrentTime);
return;
case XK_y: expect("ctrl-y", ev); /* paste selection */
case XK_Y:
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
utf8, utf8, win, CurrentTime);
return;
case XK_x: expect("ctrl-x", ev); break;
case XK_z: expect("ctrl-z", ev); break;
case XK_Left:
case XK_KP_Left:
movewordedge(-1);
goto draw;
case XK_Right:
case XK_KP_Right:
movewordedge(+1);
goto draw;
case XK_Return:
case XK_KP_Enter:
break;
case XK_bracketleft:
cleanup();
exit(1);
default:
return;
}
} else if (ev->state & Mod1Mask) {
switch(ksym) {
case XK_b:
movewordedge(-1);
goto draw;
case XK_f:
movewordedge(+1);
goto draw;
case XK_g: ksym = XK_Home; break;
case XK_G: ksym = XK_End; break;
case XK_h: ksym = XK_Up; break;
case XK_j: ksym = XK_Next; break;
case XK_k: ksym = XK_Prior; break;
case XK_l: ksym = XK_Down; break;
default:
return;
}
}
switch(ksym) {
default:
insert:
if (!iscntrl((unsigned char)*buf))
insert(buf, len);
break;
case XK_Delete:
case XK_KP_Delete:
if (text[cursor] == '\0')
return;
cursor = nextrune(+1);
/* fallthrough */
case XK_BackSpace:
if (cursor == 0)
return;
insert(NULL, nextrune(-1) - cursor);
break;
case XK_End:
case XK_KP_End:
if (text[cursor] != '\0') {
cursor = strlen(text);
break;
}
if (next) {
/* jump to end of list and position items in reverse */
curr = matchend;
calcoffsets();
curr = prev;
calcoffsets();
while (next && (curr = curr->right))
calcoffsets();
}
sel = matchend;
break;
case XK_Escape:
cleanup();
exit(1);
case XK_Home:
case XK_KP_Home:
if (sel == matches) {
cursor = 0;
break;
}
sel = curr = matches;
calcoffsets();
break;
case XK_Left:
case XK_KP_Left:
if (columns > 1) {
if (!sel)
return;
tmpsel = sel;
for (i = 0; i < lines; i++) {
if (!tmpsel->left || tmpsel->left->right != tmpsel)
return;
if (tmpsel == curr)
offscreen = true;
tmpsel = tmpsel->left;
}
sel = tmpsel;
if (offscreen) {
curr = prev;
calcoffsets();
}
break;
}
if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
cursor = nextrune(-1);
break;
}
if (lines > 0)
return;
/* fallthrough */
case XK_Up:
case XK_KP_Up:
if (sel && sel->left && (sel = sel->left)->right == curr) {
curr = prev;
calcoffsets();
}
break;
case XK_Next:
case XK_KP_Next:
if (!next)
return;
sel = curr = next;
calcoffsets();
break;
case XK_Prior:
case XK_KP_Prior:
if (!prev)
return;
sel = curr = prev;
calcoffsets();
break;
case XK_Return:
case XK_KP_Enter:
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
if (!(ev->state & ControlMask)) {
cleanup();
exit(0);
}
if (sel)
sel->out = 1;
break;
case XK_Right:
case XK_KP_Right:
if (columns > 1) {
if (!sel)
return;
tmpsel = sel;
for (i = 0; i < lines; i++) {
if (!tmpsel->right || tmpsel->right->left != tmpsel)
return;
tmpsel = tmpsel->right;
if (tmpsel == next)
offscreen = true;
}
sel = tmpsel;
if (offscreen) {
curr = next;
calcoffsets();
}
break;
}
if (text[cursor] != '\0') {
cursor = nextrune(+1);
break;
}
if (lines > 0)
return;
/* fallthrough */
case XK_Down:
case XK_KP_Down:
if (sel && sel->right && (sel = sel->right) == next) {
curr = next;
calcoffsets();
}
break;
case XK_Tab:
if (!sel)
return;
cursor = strnlen(sel->text, sizeof text - 1);
memcpy(text, sel->text, cursor);
text[cursor] = '\0';
match();
break;
}
draw:
drawmenu();
}
static void
paste(void)
{
char *p, *q;
int di;
unsigned long dl;
Atom da;
/* we have been given the current selection, now insert it into input */
if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
== Success && p) {
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
XFree(p);
}
drawmenu();
}
static void
readstdin(void)
{
char *line = NULL;
char *buf, *p;
size_t i, linesiz, itemsiz = 0;
ssize_t len;
if (passwd) {
inputw = lines = 0;
return;
}
/* read each line from stdin and add it to the item list */
for (i = 0; (len = getline(&line, &linesiz, stdin)) != -1; i++) {
if (i + 1 >= itemsiz) {
itemsiz += 256;
if (!(items = realloc(items, itemsiz * sizeof(*items))))
die("cannot realloc %zu bytes:", itemsiz * sizeof(*items));
}
if (line[len - 1] == '\n')
line[len - 1] = '\0';
if (!(items[i].text = strdup(line)))
die("strdup:");
if (!(buf = strdup(line)))
die("cannot strdup %u bytes:", strlen(line) + 1);
if ((p = strchr(buf, '\t')))
*p = '\0';
items[i].stext = buf;
items[i].out = 0;
}
free(line);
if (items)
items[i].text = NULL;
lines = MIN(lines, i);
}
static void
run(void)
{
XEvent ev;
while (!XNextEvent(dpy, &ev)) {
if (XFilterEvent(&ev, win))
continue;
switch(ev.type) {
case ButtonPress:
buttonpress(&ev);
break;
case DestroyNotify:
if (ev.xdestroywindow.window != win)
break;
cleanup();
exit(1);
case Expose:
if (ev.xexpose.count == 0)
drw_map(drw, win, 0, 0, mw, mh);
break;
case FocusIn:
/* regrab focus from parent window */
if (ev.xfocus.window != win)
grabfocus();
break;
case KeyPress:
keypress(&ev.xkey);
break;
case SelectionNotify:
if (ev.xselection.property == utf8)
paste();
break;
case VisibilityNotify:
if (ev.xvisibility.state != VisibilityUnobscured)
XRaiseWindow(dpy, win);
break;
}
}
}
static void
setup(void)
{
int x, y, i, j;
unsigned int du;
XSetWindowAttributes swa;
XIM xim;
Window w, dw, *dws;
XWindowAttributes wa;
XClassHint ch = {"dmenu", "dmenu"};
#ifdef XINERAMA
XineramaScreenInfo *info;
Window pw;
int a, di, n, area = 0;
#endif
/* init appearance */
for (j = 0; j < SchemeLast; j++)
scheme[j] = drw_scm_create(drw, (const char**)colors[j], 2);
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
/* calculate menu geometry */
bh = drw->fonts->h + 2;
bh = MAX(bh,lineheight); /* make a menu line AT LEAST 'lineheight' tall */
lines = MAX(lines, 0);
mh = (lines + 1) * bh;
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
#ifdef XINERAMA
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
else if (w != root && w != PointerRoot && w != None) {
/* find top-level window containing current input focus */
do {
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
XFree(dws);
} while (w != root && w != pw);
/* find xinerama screen with which the window intersects most */
if (XGetWindowAttributes(dpy, pw, &wa))
for (j = 0; j < n; j++)
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
area = a;
i = j;
}
}
/* no focused window is on screen, so use pointer location instead */
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
for (i = 0; i < n; i++)
if (INTERSECT(x, y, 1, 1, info[i]) != 0)
break;
if (center) {
mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2);
} else {
x = info[i].x_org + dmx;
y = info[i].y_org + (topbar ? dmy : info[i].height - mh - dmy);
mw = (dmw>0 ? dmw : info[i].width);
}
XFree(info);
} else
#endif
{
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
if (center) {
mw = MIN(MAX(max_textw() + promptw, min_width), wa.width);
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
} else {
x = dmx;
y = topbar ? dmy : wa.height - mh - dmy;
mw = (dmw>0 ? dmw : wa.width);
}
}
inputw = mw / 3; /* input width: ~33.33% of monitor width */
match();
/* create menu window */
swa.override_redirect = True;
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask
| ButtonPressMask
;
win = XCreateWindow(
dpy, root,
x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width,
CopyFromParent, CopyFromParent, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa
);
if (border_width)
XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColBg].pixel);
XSetClassHint(dpy, win, &ch);
/* input methods */
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
die("XOpenIM failed: could not open input device");
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, win, XNFocusWindow, win, NULL);
XMapRaised(dpy, win);
if (embed) {
XReparentWindow(dpy, win, parentwin, x, y);
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
for (i = 0; i < du && dws[i] != win; ++i)
XSelectInput(dpy, dws[i], FocusChangeMask);
XFree(dws);
}
grabfocus();
}
drw_resize(drw, mw, mh);
drawmenu();
}
static void
usage(void)
{
die("usage: dmenu [-bv"
"c"
"f"
"i"
"n"
"F"
"P"
"] "
"[-g columns] "
"[-l lines] [-p prompt] [-fn font] [-m monitor]"
"\n [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"
"\n "
" [-ex expectkey]"
" [-bw width]"
"\n "
" [-h height]"
" [-X xoffset] [-Y yoffset] [-W width]" // (arguments made upper case due to conflicts)
"\n");
}
int
main(int argc, char *argv[])
{
XWindowAttributes wa;
int i;
int fast = 0;
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fputs("warning: no locale support\n", stderr);
if (!(dpy = XOpenDisplay(NULL)))
die("cannot open display");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if (!embed || !(parentwin = strtol(embed, NULL, 0)))
parentwin = root;
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
drw = drw_create(dpy, screen, root, wa.width, wa.height);
readxresources();
for (i = 1; i < argc; i++) {
if (argv[i][0] == '\0')
continue;
/* these options take no arguments */
if (!strcmp(argv[i], "-v")) { /* prints version information */
puts("dmenu-"VERSION);
exit(0);
} else if (!strcmp(argv[i], "-b")) { /* appears at the bottom of the screen */
topbar = 0;
} else if (!strcmp(argv[i], "-c")) { /* toggles centering of dmenu window on screen */
center = !center;
} else if (!strcmp(argv[i], "-f")) { /* grabs keyboard before reading stdin */
fast = 1;
} else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;
} else if (!strcmp(argv[i], "-n")) { /* instant select only match */
instant = !instant;
} else if (!strcmp(argv[i], "-F")) { /* disable/enable fuzzy matching, depends on default */
fuzzy = !fuzzy;
} else if (!strcmp(argv[i], "-P")) { /* is the input a password */
passwd = 1;
} else if (!strcmp(argv[i], "-ex")) { /* expect key */
expected = argv[++i];
} else if (i + 1 == argc)
usage();
/* these options take one argument */
else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */
columns = atoi(argv[++i]);
if (columns && lines == 0)
lines = 1;
}
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
lines = atoi(argv[++i]);
else if (!strcmp(argv[i], "-X")) /* window x offset */
dmx = atoi(argv[++i]);
else if (!strcmp(argv[i], "-Y")) /* window y offset (from bottom up if -b) */
dmy = atoi(argv[++i]);
else if (!strcmp(argv[i], "-W")) /* make dmenu this wide */
dmw = atoi(argv[++i]);
else if (!strcmp(argv[i], "-m"))
mon = atoi(argv[++i]);
else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
prompt = argv[++i];
else if (!strcmp(argv[i], "-fn")) /* font or font set */
fonts[0] = argv[++i];
else if(!strcmp(argv[i], "-h")) { /* minimum height of one menu line */
lineheight = atoi(argv[++i]);
lineheight = MAX(lineheight, min_lineheight); /* reasonable default in case of value too small/negative */
}
else if (!strcmp(argv[i], "-nb")) /* normal background color */
colors[SchemeNorm][ColBg] = argv[++i];
else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
colors[SchemeNorm][ColFg] = argv[++i];
else if (!strcmp(argv[i], "-sb")) /* selected background color */
colors[SchemeSel][ColBg] = argv[++i];
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
colors[SchemeSel][ColFg] = argv[++i];
else if (!strcmp(argv[i], "-w")) /* embedding window id */
embed = argv[++i];
else if (!strcmp(argv[i], "-bw")) /* border width around dmenu */
border_width = atoi(argv[++i]);
else {
usage();
}
}
if (!drw_fontset_create(drw, (const char**)fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
if (lineheight == -1)
lineheight = drw->fonts->h * 2.5;
#ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1)
die("pledge");
#endif
if (fast && !isatty(0)) {
grabkeyboard();
readstdin();
} else {
readstdin();
grabkeyboard();
}
setup();
run();
return 1; /* unreachable */
}

View File

@ -0,0 +1,13 @@
#!/bin/sh
cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
cache="$cachedir/dmenu_run"
[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
IFS=:
if stest -dqr -n "$cache" $PATH; then
stest -flx $PATH | sort -u | tee "$cache"
else
cat "$cache"
fi

View File

@ -0,0 +1,6 @@
#!/bin/sh
export _JAVA_AWT_WM_NONREPARENTING=1
dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
# Uncomment for the NAVHISTORY patch (and remove the exec above)
#dmenu_path | dmenu -H "${XDG_CACHE_HOME:-$HOME/.cache/}/dmenu_run.hist" "$@" | ${SHELL:-"/bin/sh"} &

View File

@ -0,0 +1,455 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
return (unsigned char)c & ~utfmask[*i];
return 0;
}
static size_t
utf8validate(long *u, size_t i)
{
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
;
return i;
}
static size_t
utf8decode(const char *c, long *u, size_t clen)
{
size_t i, j, len, type;
long udecoded;
*u = UTF_INVALID;
if (!clen)
return 0;
udecoded = utf8decodebyte(c[0], &len);
if (!BETWEEN(len, 1, UTF_SIZ))
return 1;
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
if (type)
return j;
}
if (j < len)
return 0;
*u = udecoded;
utf8validate(u, len);
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
if (!drw)
return;
drw->w = w;
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw);
}
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
* same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
} else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
} else {
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
font->h = xfont->ascent + xfont->descent;
font->dpy = drw->dpy;
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
XftFontClose(font->dpy, font->xfont);
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
if (drw)
drw->fonts = set;
}
void
drw_setscheme(Drw *drw, Clr *scm)
{
if (drw)
drw->scheme = scm;
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
}
int
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
{
int ty, ellipsis_x = 0;
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0, overflow = 0;
/* keep track of a couple codepoints for which we have no match. */
static unsigned int nomatches[128], ellipsis_width;
const char *ellipsis = "...";
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
return 0;
if (!render) {
w = invert ? invert : ~invert;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
x += lpad;
w -= lpad;
}
usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, ellipsis);
while (1) {
ew = ellipsis_len = utf8strlen = 0;
utf8str = text;
nextfont = NULL;
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
if (ew + ellipsis_width <= w) {
/* keep track where the ellipsis still fits */
ellipsis_x = x + ew;
ellipsis_w = w - ew;
ellipsis_len = utf8strlen;
}
if (ew + tmpw > w) {
overflow = 1;
/* called from drw_fontset_getwidth_clamp():
* it wants the width AFTER the overflow
*/
if (!render)
x += tmpw;
else
utf8strlen = ellipsis_len;
} else if (curfont == usedfont) {
utf8strlen += utf8charlen;
text += utf8charlen;
ew += tmpw;
} else {
nextfont = curfont;
}
break;
}
}
if (overflow || !charexists || nextfont)
break;
else
charexists = 0;
}
if (utf8strlen) {
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
}
x += ew;
w -= ew;
}
if (render && overflow && ellipsis_w)
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, ellipsis, invert);
if (!*text || overflow) {
break;
} else if (nextfont) {
charexists = 0;
usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is found, the
* character must be drawn. */
charexists = 1;
hash = (unsigned int)utf8codepoint;
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
h1 = (hash >> 17) % LENGTH(nomatches);
/* avoid expensive XftFontMatch call when we know we won't find a match */
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
goto no_match;
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
xfont_free(usedfont);
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
no_match:
usedfont = drw->fonts;
}
}
}
}
if (d)
XftDrawDestroy(d);
return x + (render ? w : 0);
}
void
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
{
if (!drw)
return;
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
XSync(drw->dpy, False);
}
unsigned int
drw_fontset_getwidth(Drw *drw, const char *text)
{
if (!drw || !drw->fonts || !text)
return 0;
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
}
unsigned int
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
{
unsigned int tmp = 0;
if (drw && drw->fonts && text && n)
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
return MIN(n, tmp);
}
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
XGlyphInfo ext;
if (!font || !text)
return;
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
if (w)
*w = ext.xOff;
if (h)
*h = font->h;
}
Cur *
drw_cur_create(Drw *drw, int shape)
{
Cur *cur;
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
return NULL;
cur->cursor = XCreateFontCursor(drw->dpy, shape);
return cur;
}
void
drw_cur_free(Drw *drw, Cur *cursor)
{
if (!cursor)
return;
XFreeCursor(drw->dpy, cursor->cursor);
free(cursor);
}
#include "patch/scroll.c"

View File

@ -0,0 +1,61 @@
/* See LICENSE file for copyright and license details. */
typedef struct {
Cursor cursor;
} Cur;
typedef struct Fnt {
Display *dpy;
unsigned int h;
XftFont *xfont;
FcPattern *pattern;
struct Fnt *next;
} Fnt;
enum { ColFg, ColBg }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
Fnt *fonts;
} Drw;
/* Drawable abstraction */
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
void drw_fontset_free(Fnt* set);
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
#include "patch/scroll.h"

View File

@ -0,0 +1,8 @@
static int
max_textw(void)
{
int len = 0;
for (struct item *item = items; item && item->text; item++)
len = MAX(TEXTW(item->text), len);
return len;
}

View File

@ -0,0 +1,89 @@
#include <math.h>
int
compare_distance(const void *a, const void *b)
{
struct item *da = *(struct item **) a;
struct item *db = *(struct item **) b;
if (!db)
return 1;
if (!da)
return -1;
return da->distance == db->distance ? 0 : da->distance < db->distance ? -1 : 1;
}
void
fuzzymatch(void)
{
/* bang - we have so much memory */
struct item *it;
struct item **fuzzymatches = NULL;
char c;
int number_of_matches = 0, i, pidx, sidx, eidx;
int text_len = strlen(text), itext_len;
matches = matchend = NULL;
/* walk through all items */
for (it = items; it && it->text; it++) {
if (text_len) {
itext_len = strlen(it->text);
pidx = 0; /* pointer */
sidx = eidx = -1; /* start of match, end of match */
/* walk through item text */
for (i = 0; i < itext_len && (c = it->text[i]); i++) {
/* fuzzy match pattern */
if (!fstrncmp(&text[pidx], &c, 1)) {
if (sidx == -1)
sidx = i;
pidx++;
if (pidx == text_len) {
eidx = i;
break;
}
}
}
/* build list of matches */
if (eidx != -1) {
/* compute distance */
/* add penalty if match starts late (log(sidx+2))
* add penalty for long a match without many matching characters */
it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len);
/* fprintf(stderr, "distance %s %f\n", it->text, it->distance); */
appenditem(it, &matches, &matchend);
number_of_matches++;
}
} else {
appenditem(it, &matches, &matchend);
}
}
if (number_of_matches) {
/* initialize array with matches */
if (!(fuzzymatches = realloc(fuzzymatches, number_of_matches * sizeof(struct item*))))
die("cannot realloc %u bytes:", number_of_matches * sizeof(struct item*));
for (i = 0, it = matches; it && i < number_of_matches; i++, it = it->right) {
fuzzymatches[i] = it;
}
/* sort matches according to distance */
qsort(fuzzymatches, number_of_matches, sizeof(struct item*), compare_distance);
/* rebuild list of matches */
matches = matchend = NULL;
for (i = 0, it = fuzzymatches[i]; i < number_of_matches && it && \
it->text; i++, it = fuzzymatches[i]) {
appenditem(it, &matches, &matchend);
}
free(fuzzymatches);
}
curr = sel = matches;
if (instant && matches && matches==matchend) {
puts(matches->text);
cleanup();
exit(0);
}
calcoffsets();
}

View File

@ -0,0 +1,15 @@
static char *expected;
void
expect(char *expect, XKeyEvent *ignored)
{
if (sel && expected && strstr(expected, expect)) {
puts(expect);
puts(sel->text);
cleanup();
exit(1);
} else if (!sel && expected && strstr(expected, expect)){
puts(expect);
cleanup();
exit(1);
}
}

View File

@ -0,0 +1 @@
static void expect(char *expect, XKeyEvent *ev);

View File

@ -0,0 +1,5 @@
#include "center.c"
#include "fuzzymatch.c"
#include "fzfexpect.c"
#include "mousesupport.c"
#include "xresources.c"

View File

@ -0,0 +1 @@
#include "fzfexpect.h"

View File

@ -0,0 +1,114 @@
static void
buttonpress(XEvent *e)
{
struct item *item;
XButtonPressedEvent *ev = &e->xbutton;
int x = 0, y = 0, h = bh, w;
if (ev->window != win)
return;
/* right-click: exit */
if (ev->button == Button3)
exit(1);
if (prompt && *prompt)
x += promptw;
/* input field */
w = (lines > 0 || !matches) ? mw - x : inputw;
/* left-click on input: clear input,
* NOTE: if there is no left-arrow the space for < is reserved so
* add that to the input width */
if (ev->button == Button1 &&
((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
((!prev || !curr->left) ? TEXTW("<") : 0)) ||
(lines > 0 && ev->y >= y && ev->y <= y + h))) {
insert(NULL, -cursor);
drawmenu();
return;
}
/* middle-mouse click: paste selection */
if (ev->button == Button2) {
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
utf8, utf8, win, CurrentTime);
drawmenu();
return;
}
/* scroll up */
if (ev->button == Button4 && prev) {
sel = curr = prev;
calcoffsets();
drawmenu();
return;
}
/* scroll down */
if (ev->button == Button5 && next) {
sel = curr = next;
calcoffsets();
drawmenu();
return;
}
if (ev->button != Button1)
return;
if (ev->state & ~ControlMask)
return;
if (lines > 0) {
/* vertical list: (ctrl)left-click on item */
w = mw - x;
for (item = curr; item != next; item = item->right) {
y += h;
if (ev->y >= y && ev->y <= (y + h)) {
puts(item->text);
if (!(ev->state & ControlMask)) {
exit(0);
}
sel = item;
if (sel) {
sel->out = 1;
drawmenu();
}
return;
}
}
} else if (matches) {
/* left-click on left arrow */
x += inputw;
w = TEXTW("<");
if (prev && curr->left) {
if (ev->x >= x && ev->x <= x + w) {
sel = curr = prev;
calcoffsets();
drawmenu();
return;
}
}
/* horizontal list: (ctrl)left-click on item */
for (item = curr; item != next; item = item->right) {
x += w;
w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
if (ev->x >= x && ev->x <= x + w) {
puts(item->text);
if (!(ev->state & ControlMask)) {
exit(0);
}
sel = item;
if (sel) {
sel->out = 1;
drawmenu();
}
return;
}
}
/* left-click on right arrow */
w = TEXTW(">");
x = mw - w;
if (next && ev->x >= x && ev->x <= x + w) {
sel = curr = next;
calcoffsets();
drawmenu();
return;
}
}
}

View File

@ -0,0 +1,168 @@
int
utf8nextchar(const char *str, int len, int i, int inc)
{
int n;
for (n = i + inc; n + inc >= 0 && n + inc <= len
&& (str[n] & 0xc0) == 0x80; n += inc)
;
return n;
}
int
drw_text_align(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int textlen, int align)
{
int ty;
unsigned int ew;
XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
size_t len;
int utf8strlen, utf8charlen, render = x || y || w || h;
long utf8codepoint = 0;
const char *utf8str;
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
XftResult result;
int charexists = 0;
int i, n;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts || textlen <= 0
|| (align != AlignL && align != AlignR))
return 0;
if (!render) {
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
}
usedfont = drw->fonts;
i = align == AlignL ? 0 : textlen;
x = align == AlignL ? x : x + w;
while (1) {
utf8strlen = 0;
nextfont = NULL;
/* if (align == AlignL) */
utf8str = text + i;
while ((align == AlignL && i < textlen) || (align == AlignR && i > 0)) {
if (align == AlignL) {
utf8charlen = utf8decode(text + i, &utf8codepoint, MIN(textlen - i, UTF_SIZ));
if (!utf8charlen) {
textlen = i;
break;
}
} else {
n = utf8nextchar(text, textlen, i, -1);
utf8charlen = utf8decode(text + n, &utf8codepoint, MIN(textlen - n, UTF_SIZ));
if (!utf8charlen) {
textlen -= i;
text += i;
i = 0;
break;
}
}
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
if (charexists) {
if (curfont == usedfont) {
utf8strlen += utf8charlen;
i += align == AlignL ? utf8charlen : -utf8charlen;
} else {
nextfont = curfont;
}
break;
}
}
if (!charexists || nextfont)
break;
else
charexists = 0;
}
if (align == AlignR)
utf8str = text + i;
if (utf8strlen) {
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
/* shorten text if necessary */
if (align == AlignL) {
for (len = utf8strlen; len && ew > w; ) {
len = utf8nextchar(utf8str, len, len, -1);
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
}
} else {
for (len = utf8strlen; len && ew > w; ) {
n = utf8nextchar(utf8str, len, 0, +1);
utf8str += n;
len -= n;
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
}
}
if (len) {
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[ColFg],
usedfont->xfont, align == AlignL ? x : x - ew, ty, (XftChar8 *)utf8str, len);
}
x += align == AlignL ? ew : -ew;
w -= ew;
}
if (len < utf8strlen)
break;
}
if ((align == AlignR && i <= 0) || (align == AlignL && i >= textlen)) {
break;
} else if (nextfont) {
charexists = 0;
usedfont = nextfont;
} else {
/* Regardless of whether or not a fallback font is found, the
* character must be drawn. */
charexists = 1;
fccharset = FcCharSetCreate();
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
/* Refer to the comment in xfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
usedfont = xfont_create(drw, NULL, match);
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
xfont_free(usedfont);
usedfont = drw->fonts;
}
}
}
}
if (d)
XftDrawDestroy(d);
return x;
}

View File

@ -0,0 +1,3 @@
enum { AlignL, AlignR };
int drw_text_align(Drw *drw, int x, int y, unsigned int w, unsigned int h, const char *text, int textlen, int align);

View File

@ -0,0 +1,34 @@
#include <X11/Xresource.h>
void
readxresources(void)
{
XrmInitialize();
char* xrm;
if ((xrm = XResourceManagerString(drw->dpy))) {
char *type;
XrmDatabase xdb = XrmGetStringDatabase(xrm);
XrmValue xval;
if (XrmGetResource(xdb, "dmenu.font", "*", &type, &xval))
fonts[0] = strdup(xval.addr);
else
fonts[0] = strdup(fonts[0]);
if (XrmGetResource(xdb, "dmenu.background", "*", &type, &xval))
colors[SchemeNorm][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dmenu.foreground", "*", &type, &xval))
colors[SchemeNorm][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dmenu.selbackground", "*", &type, &xval))
colors[SchemeSel][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dmenu.selforeground", "*", &type, &xval))
colors[SchemeSel][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dmenu.outbackground", "*", &type, &xval))
colors[SchemeOut][ColBg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dmenu.outforeground", "*", &type, &xval))
colors[SchemeOut][ColFg] = strdup(xval.addr);
if (XrmGetResource(xdb, "dmenu.bordercolor", "*", &type, &xval))
colors[SchemeBorder][ColBg] = strdup(xval.addr);
XrmDestroyDatabase(xdb);
}
}

View File

@ -0,0 +1,90 @@
.TH STEST 1 dmenu\-VERSION
.SH NAME
stest \- filter a list of files by properties
.SH SYNOPSIS
.B stest
.RB [ -abcdefghlpqrsuwx ]
.RB [ -n
.IR file ]
.RB [ -o
.IR file ]
.RI [ file ...]
.SH DESCRIPTION
.B stest
takes a list of files and filters by the files' properties, analogous to
.IR test (1).
Files which pass all tests are printed to stdout. If no files are given, stest
reads files from stdin.
.SH OPTIONS
.TP
.B \-a
Test hidden files.
.TP
.B \-b
Test that files are block specials.
.TP
.B \-c
Test that files are character specials.
.TP
.B \-d
Test that files are directories.
.TP
.B \-e
Test that files exist.
.TP
.B \-f
Test that files are regular files.
.TP
.B \-g
Test that files have their set-group-ID flag set.
.TP
.B \-h
Test that files are symbolic links.
.TP
.B \-l
Test the contents of a directory given as an argument.
.TP
.BI \-n " file"
Test that files are newer than
.IR file .
.TP
.BI \-o " file"
Test that files are older than
.IR file .
.TP
.B \-p
Test that files are named pipes.
.TP
.B \-q
No files are printed, only the exit status is returned.
.TP
.B \-r
Test that files are readable.
.TP
.B \-s
Test that files are not empty.
.TP
.B \-u
Test that files have their set-user-ID flag set.
.TP
.B \-v
Invert the sense of tests, only failing files pass.
.TP
.B \-w
Test that files are writable.
.TP
.B \-x
Test that files are executable.
.SH EXIT STATUS
.TP
.B 0
At least one file passed all tests.
.TP
.B 1
No files passed all tests.
.TP
.B 2
An error occurred.
.SH SEE ALSO
.IR dmenu (1),
.IR test (1)

View File

@ -0,0 +1,109 @@
/* See LICENSE file for copyright and license details. */
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "arg.h"
char *argv0;
#define FLAG(x) (flag[(x)-'a'])
static void test(const char *, const char *);
static void usage(void);
static int match = 0;
static int flag[26];
static struct stat old, new;
static void
test(const char *path, const char *name)
{
struct stat st, ln;
if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */
&& (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
&& (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
&& (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
&& (!FLAG('e') || access(path, F_OK) == 0) /* exists */
&& (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
&& (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
&& (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
&& (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
&& (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
&& (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
&& (!FLAG('r') || access(path, R_OK) == 0) /* readable */
&& (!FLAG('s') || st.st_size > 0) /* not empty */
&& (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
&& (!FLAG('w') || access(path, W_OK) == 0) /* writable */
&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */
if (FLAG('q'))
exit(0);
match = 1;
puts(name);
}
}
static void
usage(void)
{
fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
"[-n file] [-o file] [file...]\n", argv0);
exit(2); /* like test(1) return > 1 on error */
}
int
main(int argc, char *argv[])
{
struct dirent *d;
char path[PATH_MAX], *line = NULL, *file;
size_t linesiz = 0;
ssize_t n;
DIR *dir;
int r;
ARGBEGIN {
case 'n': /* newer than file */
case 'o': /* older than file */
file = EARGF(usage());
if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
perror(file);
break;
default:
/* miscellaneous operators */
if (strchr("abcdefghlpqrsuvwx", ARGC()))
FLAG(ARGC()) = 1;
else
usage(); /* unknown flag */
} ARGEND;
if (!argc) {
/* read list from stdin */
while ((n = getline(&line, &linesiz, stdin)) > 0) {
if (line[n - 1] == '\n')
line[n - 1] = '\0';
test(line, line);
}
free(line);
} else {
for (; argc; argc--, argv++) {
if (FLAG('l') && (dir = opendir(*argv))) {
/* test directory contents */
while ((d = readdir(dir))) {
r = snprintf(path, sizeof path, "%s/%s",
*argv, d->d_name);
if (r >= 0 && (size_t)r < sizeof path)
test(path, d->d_name);
}
closedir(dir);
} else {
test(*argv, *argv);
}
}
}
return match ? 0 : 1;
}

View File

@ -0,0 +1,36 @@
/* See LICENSE file for copyright and license details. */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
void
die(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr);
perror(NULL);
} else {
fputc('\n', stderr);
}
exit(1);
}
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}

View File

@ -0,0 +1,13 @@
/* See LICENSE file for copyright and license details. */
#ifndef MAX
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#endif
#ifndef MIN
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#endif
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
void die(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);

View File

@ -0,0 +1,38 @@
MIT/X Consortium License
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
© 2007-2009 Christof Musik <christof at sendfax dot de>
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
© 2008 Neale Pickett <neale dot woozle dot org>
© 2009 Mate Nagy <mnagy at port70 dot net>
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
© 2011 Christoph Lohmann <20h@r-36.net>
© 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
© 2020-2022 Chris Down <chris@chrisdown.name>
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 @@
# dwm - dynamic window manager
# See LICENSE file for copyright and license details.
include config.mk
SRC = drw.c dwm.c util.c
OBJ = ${SRC:.c=.o}
# FreeBSD users, prefix all ifdef, else and endif statements with a . for this to work (e.g. .ifdef)
ifdef YAJLLIBS
all: dwm dwm-msg
else
all: dwm
endif
.c.o:
${CC} -c ${CFLAGS} $<
${OBJ}: config.h config.mk
config.h:
cp config.def.h $@
dwm: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
ifdef YAJLLIBS
dwm-msg:
${CC} -o $@ patch/ipc/dwm-msg.c ${LDFLAGS}
endif
clean:
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
rm -f dwm-msg
dist: clean
mkdir -p dwm-${VERSION}
cp -R LICENSE Makefile README config.def.h config.mk\
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
gzip dwm-${VERSION}.tar
rm -rf dwm-${VERSION}
install: all
mkdir -p ${DESTDIR}${PREFIX}/bin
cp -f dwm ${DESTDIR}${PREFIX}/bin
ifdef YAJLLIBS
cp -f dwm-msg ${DESTDIR}${PREFIX}/bin
endif
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
ifdef YAJLLIBS
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg
endif
mkdir -p ${DESTDIR}${MANPREFIX}/man1
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
test -f ${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop || cp -n dwm.desktop ${DESTDIR}${PREFIX}/share/xsessions
chmod 644 ${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop
uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
${DESTDIR}${MANPREFIX}/man1/dwm.1\
${DESTDIR}${PREFIX}/share/xsessions/dwm.desktop
.PHONY: all clean dist install uninstall

View File

@ -0,0 +1,7 @@
# dwm - dynamic window manager
This is my configuration for dwm generated by the awesome [dwm flexipatch](https://github.com/mintycube/dwm-flexipatch) and finalized by [flexipatch-finalizer]().
## Patches
The patches used and the accompanying documentation is listed below:

View File

@ -0,0 +1,275 @@
/* See LICENSE file for copyright and license details. */
#include <X11/XF86keysym.h>
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const int showbar = 1; /* 0 means no bar */
static const int topbar = 0; /* 0 means bottom bar */
static const int statusmon = 'A';
static const char buttonbar[] = "";
/* Indicators: see patch/bar_indicators.h for options */
static int tagindicatortype = INDICATOR_NONE;
static int tiledindicatortype = INDICATOR_NONE;
static int floatindicatortype = INDICATOR_TOP_LEFT_SQUARE;
static int fakefsindicatortype = INDICATOR_PLUS;
static int floatfakefsindicatortype = INDICATOR_PLUS_AND_LARGER_SQUARE;
// static const char *fonts[] = { "JetBrainsMono NF DWM:size=9" };
static const char *fonts[] = { "CaskaydiaCove NF :pixelsize=12" };
static char c000000[] = "#000000"; // placeholder value
static char normfgcolor[] = "#bbbbbb";
static char normbgcolor[] = "#222222";
static char normbordercolor[] = "#444444";
static char normfloatcolor[] = "#db8fd9";
static char selfgcolor[] = "#eeeeee";
static char selbgcolor[] = "#88c096";
static char selbordercolor[] = "#88c096";
static char selfloatcolor[] = "#88c096";
static char titlenormfgcolor[] = "#bbbbbb";
static char titlenormbgcolor[] = "#222222";
static char titlenormbordercolor[] = "#444444";
static char titlenormfloatcolor[] = "#db8fd9";
static char titleselfgcolor[] = "#eeeeee";
static char titleselbgcolor[] = "#88c096";
static char titleselbordercolor[] = "#88c096";
static char titleselfloatcolor[] = "#88c096";
static char tagsnormfgcolor[] = "#bbbbbb";
static char tagsnormbgcolor[] = "#222222";
static char tagsnormbordercolor[] = "#444444";
static char tagsnormfloatcolor[] = "#db8fd9";
static char tagsselfgcolor[] = "#eeeeee";
static char tagsselbgcolor[] = "#88c096";
static char tagsselbordercolor[] = "#88c096";
static char tagsselfloatcolor[] = "#88c096";
static char hidnormfgcolor[] = "#88c096";
static char hidselfgcolor[] = "#227799";
static char hidnormbgcolor[] = "#222222";
static char hidselbgcolor[] = "#222222";
static char urgfgcolor[] = "#bbbbbb";
static char urgbgcolor[] = "#222222";
static char urgbordercolor[] = "#ff0000";
static char urgfloatcolor[] = "#db8fd9";
static char *colors[][ColCount] = {
/* fg bg border float */
[SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor, normfloatcolor },
[SchemeSel] = { selfgcolor, selbgcolor, selbordercolor, selfloatcolor },
[SchemeTitleNorm] = { titlenormfgcolor, titlenormbgcolor, titlenormbordercolor, titlenormfloatcolor },
[SchemeTitleSel] = { titleselfgcolor, titleselbgcolor, titleselbordercolor, titleselfloatcolor },
[SchemeTagsNorm] = { tagsnormfgcolor, tagsnormbgcolor, tagsnormbordercolor, tagsnormfloatcolor },
[SchemeTagsSel] = { tagsselfgcolor, tagsselbgcolor, tagsselbordercolor, tagsselfloatcolor },
[SchemeHidNorm] = { hidnormfgcolor, hidnormbgcolor, c000000, c000000 },
[SchemeHidSel] = { hidselfgcolor, hidselbgcolor, c000000, c000000 },
[SchemeUrg] = { urgfgcolor, urgbgcolor, urgbordercolor, urgfloatcolor },
};
static const char *const autostart[] = {
// "st", NULL,
"dwmblocks", NULL,
NULL
};
const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x28", NULL };
const char *spcmd2[] = {"st", "-n", "spcalc", "-g", "120x28", "-e", "qalc", "--color", "--interactive", NULL };
const char *spcmd3[] = {"qalculate-gtk", NULL };
const char *spcmd4[] = {"st", "-n", "spmusic", "-g", "100x25", "-e", "ncmpcpp", NULL };
const char *spcmd5[] = {"st", "-n", "spnotes", "-g", "120x34", "-e", "nvim", NULL };
static Sp scratchpads[] = {
/* name cmd */
{"spterm", spcmd1},
{"spcalc", spcmd2},
{"spcalcgui", spcmd3},
{"spmusic", spcmd4},
{"spnotes", spcmd5},
};
static char *tagicons[][NUMTAGS] =
{
[DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
[ALTERNATIVE_TAGS] = { "A", "B", "C", "D", "E", "F", "G", "H", "I" },
[ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" },
};
static const Rule rules[] = {
RULE(.wintype = WTYPE "DIALOG", .isfloating = 1)
RULE(.wintype = WTYPE "UTILITY", .isfloating = 1)
RULE(.wintype = WTYPE "TOOLBAR", .isfloating = 1)
RULE(.wintype = WTYPE "SPLASH", .isfloating = 1)
// RULE(.class = "Gimp", .tags = 1 << 4)
// RULE(.class = "Firefox", .tags = 1 << 7)
RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1)
RULE(.instance = "spcalc", .tags = SPTAG(1), .isfloating = 1)
RULE(.class = "Qalculate-gtk", .tags = SPTAG(2), .isfloating = 1)
RULE(.instance = "spmusic", .tags = SPTAG(3), .isfloating = 1)
RULE(.instance = "spnotes", .tags = SPTAG(4), .isfloating = 1)
RULE(.class = "volume-ui", .isfloating = 1)
};
static const BarRule barrules[] = {
/* monitor bar alignment widthfunc drawfunc clickfunc hoverfunc name */
{ -1, 0, BAR_ALIGN_LEFT, width_stbutton, draw_stbutton, click_stbutton, NULL, "statusbutton" },
{ -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, hover_tags, "tags" },
{ -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, NULL, "layout" },
{ statusmon, 0, BAR_ALIGN_RIGHT, width_status2d, draw_status2d, click_statuscmd, NULL, "status2d" },
};
/* layout(s) */
static const float mfact = 0.50;
static const int nmaster = 1;
static const int resizehints = 0;
static const int lockfullscreen = 1;
/* mouse scroll resize */
static const int scrollsensetivity = 15;
static const int scrollargs[][2] = {
/* width change height change */
{ +scrollsensetivity, 0 },
{ -scrollsensetivity, 0 },
{ 0, +scrollsensetivity },
{ 0, -scrollsensetivity },
};
static const Layout layouts[] = {
{ "󰙀", tile }, /* first entry is default */
{ "󰖲", NULL },
{ "󰖯", monocle },
};
/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
#define STATUSBAR "dwmblocks"
static const char *termcmd[] = { "st", NULL };
static const char* dmenu_run_cmd[] = { "dmenu_run", "-bw", "2", "-i", "-W", "390", "-X", "961", "-Y", "15", "-l", "15", "-g", "3", NULL };
static const char* clipmenu_cmd[] = { "clipmenu", "-bw", "2", "-i", "-W", "290", "-X", "1061", "-Y", "15", "-l", "15", NULL };
static const Key on_empty_keys[] = {
/* modifier key function argument */
{ 0, XK_w, spawn, {.v = (const char*[]){ "firefox", NULL } } },
{ 0, XK_grave, spawn, {.v = (const char*[]){ "dmenunerdsymbols", NULL } } },
{ 0, XK_BackSpace, spawn, {.v = (const char*[]){ "sysact", NULL } } },
{ 0, XK_r, spawn, {.v = (const char*[]){ "st", "-e", "lf", NULL } } },
{ 0, XK_Return, spawn, {.v = (const char*[]){ "st", NULL } } },
{ 0, XK_d, spawn, {.v = dmenu_run_cmd } },
{ 0, XK_a, spawn, {.v = (const char*[]){ "dmenu_hub", NULL } } },
{ 0, XK_space, spawn, {.v = (const char*[]){ "dmenu_web", NULL } } },
{ 0, XK_n, spawn, {.v = (const char*[]){ "st", "-e", "nvim", NULL } } },
};
static const Key keys[] = {
/* modifier key function argument */
{ 0,XF86XK_AudioMute, spawn, SHCMD("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle; pkill -RTMIN+8 dwmblocks") },
{ 0,XF86XK_AudioRaiseVolume, spawn, SHCMD("wpctl set-volume @DEFAULT_AUDIO_SINK@ 0%- && wpctl set-volume @DEFAULT_AUDIO_SINK@ 3%+; pkill -RTMIN+8 dwmblocks") },
{ 0,XF86XK_AudioLowerVolume, spawn, SHCMD("wpctl set-volume @DEFAULT_AUDIO_SINK@ 0%+ && wpctl set-volume @DEFAULT_AUDIO_SINK@ 3%-; pkill -RTMIN+8 dwmblocks") },
{ 0,XF86XK_AudioPrev, spawn, {.v = (const char*[]){ "mpc", "prev", NULL } } },
{ 0,XF86XK_AudioNext, spawn, {.v = (const char*[]){ "mpc", "next", NULL } } },
{ 0,XF86XK_AudioPause, spawn, {.v = (const char*[]){ "mpc", "pause", NULL } } },
{ 0,XF86XK_AudioPlay, spawn, {.v = (const char*[]){ "mpc", "play", NULL } } },
{ 0,XK_F7, spawn, {.v = clipmenu_cmd } },
{ 0,XF86XK_MonBrightnessUp, spawn, {.v = (const char*[]){ "xbacklight", "-inc", "15", NULL } } },
{ 0,XF86XK_MonBrightnessDown, spawn, {.v = (const char*[]){ "xbacklight", "-dec", "15", NULL } } },
{ 0, XK_Print, spawn, {.v = (const char*[]){ "maimpick", NULL } } },
{ MODKEY, XK_Print, spawn, {.v = (const char*[]){ "dmenurecord", NULL } } },
{ MODKEY|ShiftMask, XK_Delete, quit, {0} },
{ MODKEY, XK_Delete, quit, {1} },
{ MODKEY|ControlMask, XK_grave, setscratch, {.ui = 0 } },
{ MODKEY|ShiftMask, XK_grave, removescratch, {.ui = 0 } },
{ MODKEY, XK_0, view, {.ui = ~SPTAGMASK } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~SPTAGMASK } },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY, XK_BackSpace, spawn, {.v = (const char*[]){ "sysact", NULL } } },
{ MODKEY|ShiftMask, XK_BackSpace, spawn, {.v = (const char*[]){ "sysact", NULL } } },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY, XK_w, spawn, {.v = (const char*[]){ "firefox", NULL } } },
{ MODKEY, XK_r, spawn, {.v = (const char*[]){ "st", "-e", "lf", NULL } } },
{ MODKEY|ShiftMask, XK_r, spawn, {.v = (const char*[]){ "thunar", NULL } } },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, // tiled
{ MODKEY, XK_y, setlayout, {.v = &layouts[1]} }, // monocle
{ MODKEY, XK_u, setlayout, {.v = &layouts[2]} }, // none
{ MODKEY, XK_o, incnmaster, {.i = +1 } },
{ MODKEY|ShiftMask, XK_o, incnmaster, {.i = -1 } },
{ MODKEY, XK_a, spawn, {.v = (const char*[]){ "dmenu_hub", NULL } } },
{ MODKEY, XK_d, spawn, {.v = dmenu_run_cmd } },
{ MODKEY, XK_f, togglefakefullscreen, {0} },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY|ShiftMask, XK_apostrophe, togglescratch, {.ui = 2 } },
{ MODKEY, XK_apostrophe, togglescratch, {.ui = 1 } },
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
{ MODKEY|ShiftMask, XK_Return, togglescratch, {.ui = 0 } },
{ MODKEY, XK_m, togglescratch, {.ui = 3 } },
{ MODKEY, XK_comma, togglescratch, {.ui = 4 } },
{ MODKEY, XK_x, transfer, {0} },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY|ShiftMask, XK_b, spawn, {.v = (const char*[]){ "dmenu_web", "--add" , NULL } } },
{ MODKEY, XK_n, spawn, {.v = (const char*[]){ "st", "-e", "nvim", NULL } } },
{ MODKEY|ShiftMask, XK_n, spawn, {.v = (const char*[]){ "st", "-e", "newsboat", NULL } } },
// { MODKEY, XK_m, spawn, {.v = (const char*[]){ "st", "-e", "ncmpcpp", NULL } } },
{ MODKEY, XK_space, spawn, {.v = (const char*[]){ "dmenu_web", NULL } } },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_Left, focusdir, {.i = 0 } },
{ MODKEY, XK_Right, focusdir, {.i = 1 } },
{ MODKEY, XK_Up, focusdir, {.i = 2 } },
{ MODKEY, XK_Down, focusdir, {.i = 3 } },
{ MODKEY|ControlMask, XK_Up, rotatestack, {.i = +1 } },
{ MODKEY|ControlMask, XK_Down, rotatestack, {.i = -1 } },
{ MODKEY|Mod1Mask, XK_Left, shiftboth, { .i = -1 } },
{ MODKEY|Mod1Mask, XK_Right, shiftboth, { .i = +1 } },
{ MODKEY|ControlMask, XK_Left, shiftviewclients, { .i = -1 } },
{ MODKEY|ControlMask, XK_Right, shiftviewclients, { .i = +1 } },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static const Button buttons[] = {
/* click event mask button function argument */
{ ClkRootWin, 0, Button1, spawn, SHCMD("dunstctl close-all; killall dmenu") },
{ ClkRootWin, 0, Button3, spawn, SHCMD("dunstctl close-all; pgrep -x 'dmenu' > /dev/null && killall dmenu || dmenu_hub") },
{ ClkButton, 0, Button1, spawn, {.v = dmenu_run_cmd } },
{ ClkButton, 0, Button3, spawn, {.v = (const char*[]){ "dmenu_hub", NULL } } },
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkStatusText, 0, Button1, sigstatusbar, {.i = 1 } },
{ ClkStatusText, 0, Button2, sigstatusbar, {.i = 2 } },
{ ClkStatusText, 0, Button3, sigstatusbar, {.i = 3 } },
{ ClkStatusText, 0, Button4, sigstatusbar, {.i = 4} },
{ ClkStatusText, 0, Button5, sigstatusbar, {.i = 5} },
{ ClkStatusText, ShiftMask, Button1, sigstatusbar, {.i = 6} },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkClientWin, MODKEY, Button4, resizemousescroll, {.v = &scrollargs[0]} },
{ ClkClientWin, MODKEY, Button5, resizemousescroll, {.v = &scrollargs[1]} },
{ ClkClientWin, MODKEY, Button6, resizemousescroll, {.v = &scrollargs[2]} },
{ ClkClientWin, MODKEY, Button7, resizemousescroll, {.v = &scrollargs[3]} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};

View File

@ -0,0 +1,73 @@
# dwm version
VERSION = 6.4
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
# FreeBSD (uncomment)
#X11INC = /usr/local/include
#X11LIB = /usr/local/lib
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# FreeBSD (uncomment)
#FREETYPEINC = /usr/local/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
# OpenBSD - Uncomment this for the swallow patch / SWALLOW_PATCH
#KVMLIB = -lkvm
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
XRENDER = -lXrender
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
#MPDCLIENT = -lmpdclient
# Uncomment for the pango patch / BAR_PANGO_PATCH
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
# Uncomment for the ipc patch / IPC_PATCH
#YAJLLIBS = -lyajl
#YAJLINC = -I/usr/include/yajl
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
#XEXTLIB = -lXext
# Uncomment this for the swallow patch / SWALLOW_PATCH
#XCBLIBS = -lX11-xcb -lxcb -lxcb-res
# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
#IMLIB2LIBS = -lImlib2
# Uncomment for the bidi patch
#BDINC = `pkg-config --cflags fribidi`
#BDLIBS = `pkg-config --libs fribidi`
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC} ${BDINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS} $(BDLIBS)
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
# compiler and linker
CC = cc

438
.config/suckless/dwm/drw.c Normal file
View File

@ -0,0 +1,438 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
static long
utf8decodebyte(const char c, size_t *i)
{
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
return (unsigned char)c & ~utfmask[*i];
return 0;
}
static size_t
utf8validate(long *u, size_t i)
{
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
*u = UTF_INVALID;
for (i = 1; *u > utfmax[i]; ++i)
;
return i;
}
static size_t
utf8decode(const char *c, long *u, size_t clen)
{
size_t i, j, len, type;
long udecoded;
*u = UTF_INVALID;
if (!clen)
return 0;
udecoded = utf8decodebyte(c[0], &len);
if (!BETWEEN(len, 1, UTF_SIZ))
return 1;
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
if (type)
return j;
}
if (j < len)
return 0;
*u = udecoded;
utf8validate(u, len);
return len;
}
Drw *
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
drw->screen = screen;
drw->root = root;
drw->w = w;
drw->h = h;
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
drw->gc = XCreateGC(dpy, root, 0, NULL);
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
return drw;
}
void
drw_resize(Drw *drw, unsigned int w, unsigned int h)
{
if (!drw)
return;
drw->w = w;
drw->h = h;
if (drw->drawable)
XFreePixmap(drw->dpy, drw->drawable);
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
}
void
drw_free(Drw *drw)
{
XFreePixmap(drw->dpy, drw->drawable);
XFreeGC(drw->dpy, drw->gc);
drw_fontset_free(drw->fonts);
free(drw);
}
/* This function is an implementation detail. Library users should use
* drw_fontset_create instead.
*/
static Fnt *
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
{
Fnt *font;
XftFont *xfont = NULL;
FcPattern *pattern = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
* same substitution results as using the pattern returned by
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
XftFontClose(drw->dpy, xfont);
return NULL;
}
} else if (fontpattern) {
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
} else {
die("no font specified.");
}
font = ecalloc(1, sizeof(Fnt));
font->xfont = xfont;
font->pattern = pattern;
font->h = xfont->ascent + xfont->descent;
font->dpy = drw->dpy;
return font;
}
static void
xfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
XftFontClose(font->dpy, font->xfont);
free(font);
}
Fnt*
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
{
Fnt *cur, *ret = NULL;
size_t i;
if (!drw || !fonts)
return NULL;
for (i = 1; i <= fontcount; i++) {
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
}
return (drw->fonts = ret);
}
void
drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
xfont_free(font);
}
}
void
drw_clr_create(
Drw *drw,
Clr *dest,
const char *clrname
) {
if (!drw || !dest || !clrname)
return;
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen),
clrname, dest))
die("error, cannot allocate color '%s'", clrname);
dest->pixel |= 0xff << 24;
}