diff options
67 files changed, 3930 insertions, 121 deletions
diff --git a/alacritty/dot-config/alacritty/alacritty-base.toml b/alacritty/dot-config/alacritty/alacritty-base.toml new file mode 100644 index 0000000..c05e61a --- /dev/null +++ b/alacritty/dot-config/alacritty/alacritty-base.toml @@ -0,0 +1,41 @@ +[general] +live_config_reload = true + +[window] +padding = { x = 3, y = 3 } +dynamic_title = true + +[scrolling] +history = 5000 +multiplier = 3 + +[selection] +save_to_clipboard = false + +[cursor] +unfocused_hollow = true + +[mouse] +hide_when_typing = true + +[keyboard] +bindings = [ + { key = "C", mods = "Alt", mode = "~Vi", action = "Copy" }, + { key = "V", mods = "Alt", mode = "~Vi", action = "Paste" }, + { key = "J", mods = "Alt|Shift", mode = "~Vi", action = "DecreaseFontSize" }, + { key = "K", mods = "Alt|Shift", mode = "~Vi", action = "IncreaseFontSize" }, + { key = "J", mods = "Alt", mode = "~Vi", action = "ScrollLineDown" }, + { key = "K", mods = "Alt", mode = "~Vi", action = "ScrollLineUp" }, + { key = "F11", action = "ToggleFullscreen" }, + { key = "F5", command = { program = "alacritty", args = [ + "msg", + "config", + "font.size=25", + ] } }, + { key = "F5", mods = "Shift", command = { program = "alacritty", args = [ + "msg", + "config", + "--reset", + ] } }, + { key = "N", mods = "Control|Shift", mode = "~Vi", action = "CreateNewWindow" }, +] diff --git a/alacritty/dot-config/alacritty/alacritty-light.toml b/alacritty/dot-config/alacritty/alacritty-light.toml new file mode 100644 index 0000000..bd55513 --- /dev/null +++ b/alacritty/dot-config/alacritty/alacritty-light.toml @@ -0,0 +1,2 @@ +[general] +import = [ "alacritty-base.toml", "light.toml" ] diff --git a/alacritty/dot-config/alacritty/alacritty.toml b/alacritty/dot-config/alacritty/alacritty.toml index 6e906f5..684ec16 100644 --- a/alacritty/dot-config/alacritty/alacritty.toml +++ b/alacritty/dot-config/alacritty/alacritty.toml @@ -1,48 +1,2 @@ [general] -live_config_reload = true - -[window] -opacity = 0.95 -padding = { x = 3, y = 3 } -dynamic_title = true - -[font] -normal = { family = "Comic Code" } -# normal = { family = "IosevkaInput" } -# italic = { family = "IosevkaInput", style = "W360 Oblique" } -size = 11 - -[scrolling] -history = 5000 -multiplier = 3 - -[selection] -save_to_clipboard = false - -[cursor] -unfocused_hollow = true - -[mouse] -hide_when_typing = true - -[keyboard] -bindings = [ - { key = "C", mods = "Alt", mode = "~Vi", action = "Copy" }, - { key = "V", mods = "Alt", mode = "~Vi", action = "Paste" }, - { key = "J", mods = "Alt|Shift", mode = "~Vi", action = "DecreaseFontSize" }, - { key = "K", mods = "Alt|Shift", mode = "~Vi", action = "IncreaseFontSize" }, - { key = "J", mods = "Alt", mode = "~Vi", action = "ScrollLineDown" }, - { key = "K", mods = "Alt", mode = "~Vi", action = "ScrollLineUp" }, - { key = "F11", action = "ToggleFullscreen" }, - { key = "F5", command = { program = "alacritty", args = [ - "msg", - "config", - "font.size=25", - ] } }, - { key = "F5", mods = "Shift", command = { program = "alacritty", args = [ - "msg", - "config", - "--reset", - ] } }, - { key = "N", mods = "Control|Shift", mode = "~Vi", action = "CreateNewWindow" }, -] +import = [ "alacritty-base.toml", "dark.toml" ] diff --git a/alacritty/dot-config/alacritty/dark.toml b/alacritty/dot-config/alacritty/dark.toml new file mode 100644 index 0000000..3bf22cf --- /dev/null +++ b/alacritty/dot-config/alacritty/dark.toml @@ -0,0 +1,14 @@ +[window] +# opacity = 0.95 + +[env] +NVIM_LIGHT = "0" + +[font] +# normal = { family = "Comic Code" } +# normal = { family = "Lambda" } +# normal = { family = "Iosevka" } +normal = { family = "Aporetic Sans Mono" } +# normal = { family = "IosevkaInput" } +# italic = { family = "IosevkaInput", style = "W360 Oblique" } +size = 11 diff --git a/alacritty/dot-config/alacritty/dayfox.toml b/alacritty/dot-config/alacritty/dayfox.toml new file mode 100644 index 0000000..049bbc3 --- /dev/null +++ b/alacritty/dot-config/alacritty/dayfox.toml @@ -0,0 +1,71 @@ +# Nightfox Alacritty Colors +## name: dayfox +## upstream: https://github.com/edeneast/nightfox.nvim/raw/main/extra/dayfox/alacritty.toml + +[colors.primary] +background = "#f6f2ee" +foreground = "#3d2b5a" +dim_foreground = "#302b5d" +bright_foreground = "#643f61" + +[colors.cursor] +text = "#3d2b5a" +cursor = "#643f61" + +[colors.vi_mode_cursor] +text = "#3d2b5a" +cursor = "#287980" + +[colors.search.matches] +foreground = "#3d2b5a" +background = "#a4c1c2" + +[colors.search.focused_match] +foreground = "#3d2b5a" +background = "#396847" + +[colors.footer_bar] +foreground = "#3d2b5a" +background = "#d3c7bb" + +[colors.hints.start] +foreground = "#3d2b5a" +background = "#955f61" + +[colors.hints.end] +foreground = "#3d2b5a" +background = "#d3c7bb" + +[colors.selection] +text = "#3d2b5a" +background = "#e7d2be" + +[colors.normal] +black = "#352c24" +red = "#a5222f" +green = "#396847" +yellow = "#ac5402" +blue = "#2848a9" +magenta = "#6e33ce" +cyan = "#287980" +white = "#f2e9e1" + +[colors.bright] +black = "#534c45" +red = "#b3434e" +green = "#577f63" +yellow = "#b86e28" +blue = "#4863b6" +magenta = "#8452d5" +cyan = "#488d93" +white = "#f4ece6" + +[colors.dim] +black = "#2d251f" +red = "#8c1d28" +green = "#30583c" +yellow = "#924702" +blue = "#223d90" +magenta = "#5e2baf" +cyan = "#22676d" +white = "#cec6bf" diff --git a/alacritty/dot-config/alacritty/light.toml b/alacritty/dot-config/alacritty/light.toml new file mode 100644 index 0000000..34da037 --- /dev/null +++ b/alacritty/dot-config/alacritty/light.toml @@ -0,0 +1,13 @@ +[general] +import = [ "dayfox.toml" ] + +[window] +opacity = 1.0 + +[env] +NVIM_LIGHT = "1" + +[font] +normal = { family = "Hack" } +# italic = { family = "IosevkaInput", style = "W360 Oblique" } +size = 11 diff --git a/bash/dot-bashrc b/bash/dot-bashrc index 678235f..cc9c324 100644 --- a/bash/dot-bashrc +++ b/bash/dot-bashrc @@ -14,21 +14,15 @@ shopt -s checkwinsize source "${XDG_CONFIG_HOME:-$HOME/.config}"/bash/gentoo-color.bash -ls() +function ls() { - if ((gentoo_color > 0)); then - command ls --color=auto "$@" - else - command ls "$@" - fi + command ls --color=auto --indicator-style=classify --human-readable --literal --group-directories-first -v "$@" # -v is for natural sort of numbers within text } # coreutils alias cp='cp -riv' -alias la='ls -la' -alias ll='ls -lah' +alias ll='ls --all -l --human-readable' # -l = long listing format alias l='ls -l' -alias ls='ls -p -hN --group-directories-first' alias mkdir='mkdir -pv' alias mv='mv -iv' alias rm='rm -iv' @@ -36,12 +30,16 @@ alias ..='echo "cd .."; cd ..' alias ...='echo "cd ../.."; cd ../..' # program aliases -alias m='neomutt' +alias m='aerc' alias p='sudo pacman' alias SS='sudo systemctl' alias Su='systemctl --user' alias v='nvim' +alias vn='NVIM_APPNAME=nvim-final nvim' +alias vv='uv run nvim' alias z='setsid runapp -- zathura' +alias todo='nvim ~/system-notes.md' +alias neofetch='fastfetch -c examples/13' # source: https://wiki.archlinux.org/title/GnuPG#Configure_pinentry_to_use_the_correct_TTY GPG_TTY="$(tty)" @@ -50,11 +48,13 @@ gpg-connect-agent updatestartuptty /bye >/dev/null # cp and mv but with rsync # source: https://wiki.archlinux.org/title/Rsync#As_cp/mv_alternative -cpr() { +cpr() +{ rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 "$@" } -mvr() { +mvr() +{ rsync --archive -hh --partial --info=stats1,progress2 --modify-window=1 --remove-source-files "$@" } @@ -62,6 +62,8 @@ source "${XDG_CONFIG_HOME:-$HOME/.config}"/bash/functions.bash bind '"\C-o":"\C-ulf\C-m"' +source "${XDG_CONFIG_HOME:-$HOME/.config}"/shellshort/shortcutrc + export FZF_DEFAULT_COMMAND='fd --type f --strip-cwd-prefix --hidden --follow --exclude .git' export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" eval "$(fzf --bash)" diff --git a/bash/dot-config/bash/gentoo-color.bash b/bash/dot-config/bash/gentoo-color.bash index f2a168d..a9abef8 100644 --- a/bash/dot-config/bash/gentoo-color.bash +++ b/bash/dot-config/bash/gentoo-color.bash @@ -2,9 +2,7 @@ # # source: https://gitweb.gentoo.org/repo/gentoo.git/plain/app-shells/bash/files/bashrc.d/10-gentoo-color-r2.bash # changes: -# - remove ls from the list of aliases (will configure it myself in bashrc) # - comment dircolor stuff at the end (don't like too many colors) -# - comment the unset gentoo_color, since I use it later for ls # # NOTE: copy this file for the root user and source it in its bashrc as well: # root # cp /home/moreka/.config/bash/gentoo-color.bash ~/.gentoo-color.bash @@ -61,7 +59,7 @@ fi if (( gentoo_color > 0 )); then # Colorize the output of diff(1), grep(1) and a few coreutils utilities. # However, do so only where no alias/function by the given name exists. - for _ in diff dir grep vdir; do + for _ in ls diff dir grep vdir; do if [[ $(type -t "$_") == file ]]; then alias "$_=$_ --color=auto" fi @@ -80,4 +78,4 @@ if (( gentoo_color > 0 )); then # fi fi -# unset -v gentoo_color +unset -v gentoo_color diff --git a/bash/dot-config/bash/path.bash b/bash/dot-config/bash/path.bash new file mode 100644 index 0000000..b4bcf55 --- /dev/null +++ b/bash/dot-config/bash/path.bash @@ -0,0 +1,202 @@ +#!/usr/bin/env bash +# +# Functions to modify colon separated variables like $PATH or $MANPATH +# +# Author: Dave Eddy <dave@daveeddy.com> +# Date: September 07, 2018 +# License: MIT +# Source: https://github.com/bahamas10/bash-path/blob/master/path.bash + +# +# path_add <path> [direction] [varname] +# +# path_add takes a directory name, an optional direction name (defaults to +# "after" to append to list) and an optional variable name (defaults to PATH) +# and adds the directory name to data stored in variable. +# +# Example +# +# given: PATH='/bin:/sbin' +# +# path_add /usr/bin +# // PATH => '/bin:/sbin:/usr/bin' +# path_add /opt/local/bin before +# // PATH => '/opt/local/bin:/bin:/sbin:/usr/bin' +# +# The variable name should be passed by name. +# foo='' +# path_add /bin after foo +# // foo => '/bin' +# +path_add() { + local var=${3:-PATH} + local path= + path=$(path_print_add "$@") || return 1 + read -r "${var?}" <<< "$path" +} + +# +# path_remove <path> [varname] +# +# path_remove takes a directory name and an optional variable name (defaults to +# PATH) and removes every instance of the directory name from the data stored in +# the variable. +# +# Example +# +# given: PATH='/bin:/sbin:/usr/bin:/usr/sbin' +# +# path_remove /usr/bin +# // PATH => '/bin:/sbin:/usr/sbin' +# path_remove /not-found +# // PATH => '/bin:/sbin:/usr/sbin' +# +# The variable name should be passed by name. +# foo='/bin:/sbin' +# path_remove /bin foo +# // foo => '/sbin' +# +path_remove() { + local var=${2:-PATH} + local path= + path=$(path_print_remove "$@") || return 1 + read -r "${var?}" <<< "$path" +} + +# +# path_clean [varname] +# +# path_clean takes an optional variable name (defaults to PATH) and "cleans" it, +# this process will: +# +# 1. Remove empty elements. +# 2. Remove relative directories. +# 3. Remove directories that don't exist/can't be accessed (checked with `cd`). +# 4. Remove duplicates (first element stays, subsequent elements are tossed). +# +# Example +# +# PATH='::/bin:/sbin:::./:../../some-path::/doesnt-exist' +# path_clean +# // PATH => '/bin:/sbin' + +# PATH='/bin:/bin//:////bin//////:/bin/dir/..::' +# path_clean +# // PATH => '/bin' +# +# The variable name should be passed by name. +# foo='/bin:/bin' +# path_clean /bin foo +# // foo => '/bin' +# +path_clean() { + local var=${1:-PATH} + local path= + path=$(path_print_clean "$@") || return 1 + read -r "${var?}" <<< "$path" +} + +# +# Exact same usage as path_add but prints the new PATH only and doesn't modify +# anything in place. +# +path_print_add() { + local p=$1 + local dir=${2:-after} + local var=${3:-PATH} + local arr + declare -A seen + + if [[ -z $p || $p == *:* ]]; then + echo "path_print_add: invalid argument: '$p'" >&2 + return 1 + fi + + IFS=: read -ra arr <<< "${!var}:" + + case "$dir" in + after) arr=("${arr[@]}" "$p");; + *) arr=("$p" "${arr[@]}");; + esac + + local IFS=: + echo "${arr[*]}" +} + +# +# Exact same usage as path_remove but prints the new PATH only and doesn't +# modify anything in place. +# +path_print_remove() { + local p=$1 + local var=${2:-PATH} + local arr + local newarr=() + declare -A seen + + if [[ -z $p || $p == *:* ]]; then + echo "path_print_remove: invalid argument: '$p'" >&2 + return 1 + fi + + IFS=: read -ra arr <<< "${!var}:" + + local _p + for _p in "${arr[@]}"; do + if [[ $p == "$_p" ]]; then + continue + fi + newarr+=("$_p") + done + + local IFS=: + echo "${newarr[*]}" +} + +# +# Exact same usage as path_clean but prints the new PATH only and doesn't +# modify anything in place. +# +path_print_clean() { + local var=${1:-PATH} + local arr + local newarr=() + declare -A seen + + # read PATH into an array, trailing ":" is due to: + # http://mywiki.wooledge.org/BashPitfalls#pf47 + IFS=: read -ra arr <<< "${!var}:" + + local p + for p in "${arr[@]}"; do + # Empty element is equivalent to CWD (weird, I know), remove it + if [[ -z $p ]]; then + continue + fi + + # Remove any relative paths + if [[ ${p:0:1} != '/' ]]; then + continue + fi + + # Normalize path and ensure we can access it + p=$(cd "$p" &>/dev/null && echo "$PWD") + + # Path doesn't exist or we can't access it + if [[ -z $p ]]; then + continue + fi + + # Filter out dups while we are here + if [[ -n ${seen[$p]} ]]; then + continue + fi + seen[$p]=true + + # Store the new path + newarr+=("$p") + done + + local IFS=: + echo "${newarr[*]}" +} diff --git a/bash/dot-config/shellshort/bm-dirs b/bash/dot-config/shellshort/bm-dirs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/bash/dot-config/shellshort/bm-dirs diff --git a/bash/dot-config/shellshort/bm-files b/bash/dot-config/shellshort/bm-files new file mode 100644 index 0000000..4e2b76d --- /dev/null +++ b/bash/dot-config/shellshort/bm-files @@ -0,0 +1,5 @@ +cala $XDG_CONFIG_HOME/alacritty/alacritty.toml +cgho $XDG_CONFIG_HOME/ghostty/config +cvim $XDG_CONFIG_HOME/nvim/init.lua +chy $XDG_CONFIG_HOME/hypr/hyprland.conf +cway $XDG_CONFIG_HOME/waybar/config.jsonc diff --git a/bash/dot-config/shellshort/shortcutrc b/bash/dot-config/shellshort/shortcutrc new file mode 100644 index 0000000..1eebef3 --- /dev/null +++ b/bash/dot-config/shellshort/shortcutrc @@ -0,0 +1,6 @@ +# vim: filetype=sh +alias cala="$EDITOR /home/moreka/.config/alacritty/alacritty.toml" \ +cgho="$EDITOR /home/moreka/.config/ghostty/config" \ +cvim="$EDITOR /home/moreka/.config/nvim/init.lua" \ +chy="$EDITOR /home/moreka/.config/hypr/hyprland.conf" \ +cway="$EDITOR /home/moreka/.config/waybar/config.jsonc" \ diff --git a/bash/dot-profile b/bash/dot-profile index f726fcc..cd3f5cd 100644 --- a/bash/dot-profile +++ b/bash/dot-profile @@ -1,7 +1,5 @@ #!/bin/sh -export PATH="$PATH:$HOME/.local/bin" - export EDITOR=nvim export SUDO_EDITOR=$EDITOR export BAT_THEME=ansi @@ -14,6 +12,10 @@ export XDG_DATA_HOME="$HOME"/.local/share export XDG_STATE_HOME="$HOME"/.local/state export XDG_BIN_HOME="$HOME"/.local/bin +source "$XDG_CONFIG_HOME"/bash/path.bash + +path_add "$XDG_BIN_HOME" + export LESSHISTFILE="$XDG_CACHE_HOME"/lesshst export CARGO_HOME="$XDG_DATA_HOME"/cargo export TEXMFHOME="$XDG_DATA_HOME"/texmf @@ -23,6 +25,9 @@ export GOPATH="$XDG_DATA_HOME"/go export GTK2_RC_FILES="$XDG_CONFIG_HOME"/gtk-2.0/gtkrc-2.0 export PASSWORD_STORE_DIR="$XDG_DATA_HOME"/pass export NOTMUCH_CONFIG="$XDG_CONFIG_HOME"/notmuch/default/config +export GEM_HOME="$(gem env user_gemhome 2>/dev/null)" + +[ -n "$GEM_HOME" ] && path_add "$GEM_HOME/bin" # [ -d "$HOME/.nix-profile" ] && export XDG_DATA_DIRS="$HOME"/.nix-profile/share:"$XDG_DATA_DIRS" # [ -d "$HOME/.nix-profile" ] && . "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh" @@ -37,6 +42,13 @@ fi export NO_AT_BRIDGE=1 export GTK_A11Y=none +path_clean + +# if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ] && [ -z "$NIRI_LOADED" ]; then +# export NIRI_LOADED=1 +# exec niri-session +# fi + if [ -z "$WAYLAND_DISPLAY" ] && [ -n "$XDG_VTNR" ] && [ "$XDG_VTNR" -eq 1 ] ; then if uwsm check may-start; then exec systemd-cat -t uwsm_start uwsm start hyprland.desktop diff --git a/email/dot-config/imapnotify/mit.yaml b/email/dot-config/imapnotify/mit.yaml new file mode 100644 index 0000000..d29f3cf --- /dev/null +++ b/email/dot-config/imapnotify/mit.yaml @@ -0,0 +1,16 @@ +configurations: + - + host: outlook.office365.com + port: 993 + tls: true + tlsOptions: + rejectUnauthorized: false + starttls: false + xoAuth2: true + username: moreka@mit.edu + passwordCmd: 'oama access moreka@mit.edu' + onNewMail: '' + onNewMailPost: SKIP + boxes: + - + mailbox: INBOX diff --git a/email/dot-config/isyncrc b/email/dot-config/isyncrc new file mode 100644 index 0000000..e57ece5 --- /dev/null +++ b/email/dot-config/isyncrc @@ -0,0 +1,50 @@ +IMAPAccount mit +Host outlook.office365.com +User moreka@mit.edu +PassCmd "oama access moreka@mit.edu" +Port 993 +AuthMechs XOAUTH2 +TLSType IMAPS + +IMAPStore mit-remote +Account mit + +MaildirStore mit-local +SubFolders Verbatim +Path /home/moreka/.local/share/mail/mit/ +Inbox /home/moreka/.local/share/mail/mit/INBOX + +Channel sync-mit-sent +Far :mit-remote:"Sent\ Items" +Near :mit-local:Sent +Create Near +SyncState * + +Channel sync-mit-deleted +Far :mit-remote:"Deleted\ Items" +Near :mit-local:Deleted +Create Near +Expunge Both +SyncState * + +Channel sync-mit-junk +Far :mit-remote:"Junk\ Email" +Near :mit-local:Spam +Create Near +Expunge Both +SyncState * + +Channel sync-mit-default +Far :mit-remote: +Near :mit-local: +Patterns "INBOX" "Archive" "Drafts" +Create Near +Expunge Both +SyncState * +ExpireUnread no + +Group mit +Channel sync-mit-default +Channel sync-mit-sent +Channel sync-mit-deleted +Channel sync-mit-junk diff --git a/email/dot-config/msmtp/config b/email/dot-config/msmtp/config new file mode 100644 index 0000000..e000852 --- /dev/null +++ b/email/dot-config/msmtp/config @@ -0,0 +1,14 @@ +defaults +auth on +tls on +tls_starttls off + +account mit +host outgoing.mit.edu +port 465 +from moreka@mit.edu +user moreka +passwordeval "pass show mail/smtp" +logfile ~/.cache/msmtp.log + +account default : mit diff --git a/email/dot-config/notmuch/default/config b/email/dot-config/notmuch/default/config new file mode 100644 index 0000000..eeacdcc --- /dev/null +++ b/email/dot-config/notmuch/default/config @@ -0,0 +1,39 @@ +[database] +path=/home/moreka/.local/share/mail + +[user] +name=Mohammad Reza Karimi +primary_email=moreka@mit.edu + +[new] +tags=new +ignore=.mbsyncstate;.uidvalidity;.mbsyncstate.new;.mbsyncstate.lock + +[search] +exclude_tags=deleted;spam + +# Maildir compatibility configuration +# +# The following option is supported here: +# +# synchronize_flags Valid values are true and false. +# +# If true, then the following maildir flags (in message filenames) +# will be synchronized with the corresponding notmuch tags: +# +# Flag Tag +# ---- ------- +# D draft +# F flagged +# P passed +# R replied +# S unread (added when 'S' flag is not present) +# +# The "notmuch new" command will notice flag changes in filenames +# and update tags, while the "notmuch tag" and "notmuch restore" +# commands will notice tag changes and update flags in filenames + +[maildir] +synchronize_flags=true + +# vim: ft=confini diff --git a/email/dot-config/notmuch/default/hooks/post-new b/email/dot-config/notmuch/default/hooks/post-new new file mode 100755 index 0000000..063888b --- /dev/null +++ b/email/dot-config/notmuch/default/hooks/post-new @@ -0,0 +1,10 @@ +#!/bin/sh + +# remove "unread" from "replied" +notmuch tag -unread -new -- tag:replied + +# tag all "new" messages "inbox" and "unread" +notmuch tag +inbox +unread -new -- '(tag:new and folder:mit/INBOX)' + +# tag my replies as "sent" +notmuch tag -new -unread +sent -- '(from:"moreka@mit.edu*" not to:"moreka@mit.edu*" not tag:archived)' diff --git a/email/dot-config/oama/config.yaml b/email/dot-config/oama/config.yaml new file mode 100644 index 0000000..7f68064 --- /dev/null +++ b/email/dot-config/oama/config.yaml @@ -0,0 +1,15 @@ +## oama version 0.22.0 - 2025-08-29 0290.e419ef10 +## This is a YAML configuration file, indentation matters. +## Double ## indicates comments while single # default values. +## Not all defaults are shown, for full list run `oama printenv` +## and look at the `services:` section. + +encryption: + tag: GPG + contents: moreka@mit.edu + + +services: + microsoft: + client_id: 9e5f94bc-e8a4-4e73-b8be-63364c29d753 + tenant: common diff --git a/email/dot-config/systemd/user/goimap.service b/email/dot-config/systemd/user/goimap.service new file mode 100644 index 0000000..d315da8 --- /dev/null +++ b/email/dot-config/systemd/user/goimap.service @@ -0,0 +1,15 @@ +[Unit] +PartOf=graphical-session.target +Description=Execute scripts on IMAP mailbox changes (new/deleted/updated messages) using IDLE, golang version. +After=graphical-session.target +After=network-online.target +Requisite=graphical-session.target + +[Service] +Type=simple +ExecStart=/usr/bin/goimapnotify -conf %h/.config/imapnotify/mit.yaml +Restart=always +RestartSec=300 + +[Install] +WantedBy=graphical-session.target diff --git a/fonts/dot-local/share/fonts/lambda/Lambda-Bold.ttf b/fonts/dot-local/share/fonts/lambda/Lambda-Bold.ttf Binary files differnew file mode 100644 index 0000000..34761b2 --- /dev/null +++ b/fonts/dot-local/share/fonts/lambda/Lambda-Bold.ttf diff --git a/fonts/dot-local/share/fonts/lambda/Lambda-BoldItalic.ttf b/fonts/dot-local/share/fonts/lambda/Lambda-BoldItalic.ttf Binary files differnew file mode 100644 index 0000000..8a26ef9 --- /dev/null +++ b/fonts/dot-local/share/fonts/lambda/Lambda-BoldItalic.ttf diff --git a/fonts/dot-local/share/fonts/lambda/Lambda-Italic.ttf b/fonts/dot-local/share/fonts/lambda/Lambda-Italic.ttf Binary files differnew file mode 100644 index 0000000..1e34287 --- /dev/null +++ b/fonts/dot-local/share/fonts/lambda/Lambda-Italic.ttf diff --git a/fonts/dot-local/share/fonts/lambda/Lambda.ttf b/fonts/dot-local/share/fonts/lambda/Lambda.ttf Binary files differnew file mode 100644 index 0000000..b055282 --- /dev/null +++ b/fonts/dot-local/share/fonts/lambda/Lambda.ttf diff --git a/gdb/dot-config/gdb/gdbinit b/gdb/dot-config/gdb/gdbinit new file mode 100644 index 0000000..2bcfa21 --- /dev/null +++ b/gdb/dot-config/gdb/gdbinit @@ -0,0 +1,3 @@ +set disassembly-flavor intel +set history save on +set history filename ~/.cache/gdb_history diff --git a/ghostty/dot-config/ghostty/config b/ghostty/dot-config/ghostty/config new file mode 100644 index 0000000..6412f21 --- /dev/null +++ b/ghostty/dot-config/ghostty/config @@ -0,0 +1,36 @@ +# font-family = Iosevka Term +font-family = Lambda + +# theme = glepnir +# theme = xterm +# theme = plain + +cursor-style = block +cursor-style-blink = false +mouse-hide-while-typing = true + +confirm-close-surface=false +resize-overlay = never + +window-decoration = none + +quit-after-last-window-closed = true +quit-after-last-window-closed-delay = 5m + +mouse-scroll-multiplier = precision:1,discrete:0.5 + +# adjust-underline-position = 3% +adjust-cursor-thickness = 150% +# adjust-cell-height = 10% +cursor-invert-fg-bg = true +selection-invert-fg-bg = true +copy-on-select = false + +bell-features = no-system,no-audio,no-attention,no-title,no-border + +shell-integration-features = no-cursor + +keybind = alt+v=paste_from_clipboard +keybind = alt+c=copy_to_clipboard +keybind = alt+shift+j=decrease_font_size:1 +keybind = alt+shift+k=increase_font_size:1 diff --git a/ghostty/dot-config/ghostty/themes/glepnir b/ghostty/dot-config/ghostty/themes/glepnir new file mode 100644 index 0000000..8c0cd67 --- /dev/null +++ b/ghostty/dot-config/ghostty/themes/glepnir @@ -0,0 +1,17 @@ +background = #002837 +foreground = #b6b6b6 + +palette = 0=#555555 +palette = 1=#ff5f59 +palette = 2=#84a800 +palette = 3=#b58900 +palette = 4=#268bd2 +palette = 5=#9884c4 +palette = 6=#2aa198 +palette = 7=#b6b6b6 + +selection-foreground = #FFFFFF +selection-background = #373737 + +cursor-color = green +cursor-text = #1e1e1e diff --git a/ghostty/dot-config/ghostty/themes/plain b/ghostty/dot-config/ghostty/themes/plain new file mode 100644 index 0000000..63dc6c9 --- /dev/null +++ b/ghostty/dot-config/ghostty/themes/plain @@ -0,0 +1,19 @@ +palette = 0=#fffcf1 +palette = 1=#a54242 +palette = 2=#8c9440 +palette = 3=#de935f +palette = 4=#5f819d +palette = 5=#85678f +palette = 6=#5e8d87 +palette = 7=#3B4252 +palette = 8=#afa39e +palette = 9=#cc6666 +palette = 10=#b5bd68 +palette = 11=#f0c674 +palette = 12=#81a2be +palette = 13=#b294bb +palette = 14=#8abeb7 +palette = 15=#4C566A + +background = #fffcf1 +foreground = #2E3440 diff --git a/ghostty/dot-config/ghostty/themes/xterm b/ghostty/dot-config/ghostty/themes/xterm new file mode 100644 index 0000000..072033d --- /dev/null +++ b/ghostty/dot-config/ghostty/themes/xterm @@ -0,0 +1,18 @@ +palette = 0=#000000 +palette = 1=#cd0000 +palette = 2=#00cd00 +palette = 3=#cdcd00 +palette = 4=#0000ee +palette = 5=#cd00cd +palette = 6=#00cdcd +palette = 7=#e5e5e5 +palette = 8=#7f7f7f +palette = 9=#ff0000 +palette = 10=#00ff00 +palette = 11=#ffff00 +palette = 12=#5c5cff +palette = 13=#ff00ff +palette = 14=#00ffff +palette = 15=#ffffff +background = #000000 +foreground = #ffffff diff --git a/git/dot-config/git/config b/git/dot-config/git/config index 8df961c..62ddc08 100644 --- a/git/dot-config/git/config +++ b/git/dot-config/git/config @@ -4,14 +4,30 @@ ci = commit s = status -sb l = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%ai%C(reset) - %C(bold white)%an%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n %C(white)%s%C(reset)' + [pull] rebase = true + [init] defaultBranch = main + [user] name = Mohammad Reza Karimi email = m.r.karimi.j@gmail.com + signingkey = 802D310CAC1F1CE6EDD55DF10A777EAC5BCAEB1B + [commit] verbose = true + gpgsign = true + +[tag] + gpgsign = true + +[diff] + algorithm = histogram + +[merge] + conflictstyle = zdiff3 + [credential "https://git.overleaf.com"] helper = !pass git/overleaf@mit diff --git a/hyprland/dot-config/hypr/hyprland.conf b/hyprland/dot-config/hypr/hyprland.conf index 731e4b6..f1cbc99 100644 --- a/hyprland/dot-config/hypr/hyprland.conf +++ b/hyprland/dot-config/hypr/hyprland.conf @@ -1,4 +1,14 @@ -monitor=,preferred,auto,auto +source = $HOME/.config/hypr/monitors.conf + +# workspace = 1, persistent:true +# workspace = 2, persistent:true +# workspace = 3, persistent:true +# workspace = 4, persistent:true +# workspace = 5, persistent:true +# workspace = 6, persistent:true +# workspace = 7, persistent:true +# workspace = 8, persistent:true +# workspace = 9, persistent:true $terminal = app2unit -- alacritty $menu = fuzzel --launch-prefix="app2unit --" @@ -10,12 +20,13 @@ $activeBorderColor = rgb(005577) # rgba(71CEADee) $inactiveBorderColor = rgb(444444) general { - gaps_in = 5 - gaps_out = 15 - border_size = 2 + # gaps_in = 5 + # gaps_out = 15 + gaps_in = 0 + gaps_out = 0 + border_size = 1 col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg - # col.active_border = $activeBorderColor col.inactive_border = $inactiveBorderColor resize_on_border = false @@ -24,7 +35,8 @@ general { } decoration { - rounding = 10 + # rounding = 10 + rounding = 0 rounding_power = 2 active_opacity = 1.0 @@ -41,7 +53,6 @@ decoration { animations { enabled = yes - # Default curves, see https://wiki.hypr.land/Configuring/Animations/#curves # NAME, X0, Y0, X1, Y1 bezier = easeOutQuint, 0.23, 1, 0.32, 1 bezier = easeInOutCubic, 0.65, 0.05, 0.36, 1 @@ -49,34 +60,32 @@ animations { bezier = almostLinear, 0.5, 0.5, 0.75, 1 bezier = quick, 0.15, 0, 0.1, 1 - # Default animations, see https://wiki.hypr.land/Configuring/Animations/ # NAME, ONOFF, SPEED, CURVE, [STYLE] animation = global, 1, 10, default - animation = border, 1, 5.39, easeOutQuint - animation = windows, 1, 4.79, easeOutQuint - animation = windowsIn, 1, 4.1, easeOutQuint, popin 87% - animation = windowsOut, 1, 1.49, linear, popin 87% - animation = fadeIn, 1, 1.73, almostLinear - animation = fadeOut, 1, 1.46, almostLinear - animation = fade, 1, 3.03, quick + animation = border, 1, 2.39, easeOutQuint + animation = windows, 0, 4.79, easeOutQuint + animation = windowsIn, 0, 1.49, easeOutQuint, popin 87% + animation = windowsOut, 0, 1.49, linear, popin 87% + animation = fadeIn, 0, 1.73, almostLinear + animation = fadeOut, 0, 1.46, almostLinear + animation = fade, 0, 3.03, quick animation = layers, 1, 3.81, easeOutQuint animation = layersIn, 1, 4, easeOutQuint, fade animation = layersOut, 1, 1.5, linear, fade animation = fadeLayersIn, 1, 1.79, almostLinear animation = fadeLayersOut, 1, 1.39, almostLinear - animation = workspaces, 1, 1.94, almostLinear, fade - animation = workspacesIn, 1, 1.21, almostLinear, fade - animation = workspacesOut, 1, 1.94, almostLinear, fade + animation = workspaces, 0, 1.94, almostLinear, fade + animation = workspacesIn, 0, 1.21, almostLinear, fade + animation = workspacesOut, 0, 1.94, almostLinear, fade animation = zoomFactor, 1, 7, quick } # Ref https://wiki.hypr.land/Configuring/Workspace-Rules/ # "Smart gaps" / "No gaps when only" -# uncomment all if you wish to use that. # workspace = w[tv1], gapsout:0, gapsin:0 # workspace = f[1], gapsout:0, gapsin:0 -# windowrule = bordersize 0, floating:0, onworkspace:w[tv1] -# windowrule = bordersize 0, floating:0, onworkspace:f[1] +# windowrule = rounding 0, bordersize 0, floating:0, onworkspace:w[tv1] +# windowrule = rounding 0, bordersize 0, floating:0, onworkspace:f[1] # See https://wiki.hypr.land/Configuring/Dwindle-Layout/ for more dwindle { @@ -93,6 +102,7 @@ master { misc { force_default_wallpaper = 0 disable_hyprland_logo = true + vfr = true } input { @@ -112,6 +122,10 @@ input { } } +cursor { + no_hardware_cursors = 1 +} + # See https://wiki.hypr.land/Configuring/Gestures # gesture = 3, horizontal, workspace @@ -119,6 +133,7 @@ $osdclient = swayosd-client --monitor "$(hyprctl monitors -j | jq -r '.[] | sele # Example binds, see https://wiki.hypr.land/Configuring/Binds/ for more bind = SUPER, return, exec, $terminal +# bind = SUPER CTRL, return, exec, $terminal --config-file "$XDG_CONFIG_HOME/alacritty/alacritty-light.toml" bind = SUPER SHIFT, C, killactive, bind = SUPER SHIFT, E, exec, $exit @@ -134,6 +149,8 @@ bind = SUPER SHIFT, comma, movewindow, mon:+1 silent bind = SUPER, P, exec, $menu bind = SUPER, B, exec, $browser bind = SUPER, X, exec, $lock +bind = SUPER, M, exec, $terminal --config-file "$XDG_CONFIG_HOME/alacritty/alacritty-light.toml" -e aerc +# bind = SUPER, M, exec, app2unit -- ghostty --theme="Belafonte Day" -e aerc # bind = SUPER, E, exec, rofi -show emoji # bind = SUPER, M, exec, app2unit -- emacsclient -c @@ -194,9 +211,9 @@ bindd = , PRINT, Screenshot with editing, exec, screenshot-hypr bindd = SHIFT, PRINT, Screenshot to clipboard, exec, screenshot-hypr smart bindd = SUPER, PRINT, Color picker, exec, pkill hyprpicker || hyprpicker -a - # Ignore maximize requests from apps. You'll probably like this. -windowrule = suppressevent maximize, class:.* +windowrule = match:class *, suppress_event maximize # Fix some dragging issues with XWayland -windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0 +# windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0 + diff --git a/hyprland/dot-config/hypr/monitors.conf b/hyprland/dot-config/hypr/monitors.conf new file mode 120000 index 0000000..7291d4a --- /dev/null +++ b/hyprland/dot-config/hypr/monitors.conf @@ -0,0 +1 @@ +/home/moreka/.config/hyprdynamicmonitors/laptop_only.conf
\ No newline at end of file diff --git a/hyprland/dot-config/hyprdynamicmonitors/config.toml b/hyprland/dot-config/hyprdynamicmonitors/config.toml new file mode 100644 index 0000000..39062a4 --- /dev/null +++ b/hyprland/dot-config/hyprdynamicmonitors/config.toml @@ -0,0 +1,34 @@ +[general] +destination = "$HOME/.config/hypr/monitors.conf" + +[profiles.laptop_only] +config_file = "laptop_only.conf" +config_file_type = "static" + +[[profiles.laptop_only.conditions.required_monitors]] +name = "eDP-1" +monitor_tag = "laptop" + +[profiles.work] +config_file = "work.conf" +config_file_type = "static" + +[[profiles.work.conditions.required_monitors]] +name = "eDP-1" +monitor_tag = "laptop" + +[[profiles.work.conditions.required_monitors]] +description = "Dell Inc. DELL P2723D FNHTH14" +monitor_tag = "external" + +[profiles.home_double] +config_file = "home_double.conf" +config_file_type = "static" + +[[profiles.home_double.conditions.required_monitors]] +name = "eDP-1" +monitor_tag = "laptop" + +[[profiles.home_double.conditions.required_monitors]] +description = "Lenovo Group Limited M15 V30ANMLM" +monitor_tag = "external" diff --git a/hyprland/dot-config/hyprdynamicmonitors/home_double.conf b/hyprland/dot-config/hyprdynamicmonitors/home_double.conf new file mode 100644 index 0000000..46e17b2 --- /dev/null +++ b/hyprland/dot-config/hyprdynamicmonitors/home_double.conf @@ -0,0 +1,2 @@ +monitor=DP-1,1920x1080@60.00,0x0,1.25,transform,1 +monitor=eDP-1,2880x1800@120,1536x0,2.0 diff --git a/hyprland/dot-config/hyprdynamicmonitors/laptop_only.conf b/hyprland/dot-config/hyprdynamicmonitors/laptop_only.conf new file mode 100644 index 0000000..b0341ba --- /dev/null +++ b/hyprland/dot-config/hyprdynamicmonitors/laptop_only.conf @@ -0,0 +1 @@ +monitor=eDP-1,2880x1800@120,0x0,2.0 diff --git a/hyprland/dot-config/hyprdynamicmonitors/work.conf b/hyprland/dot-config/hyprdynamicmonitors/work.conf new file mode 100644 index 0000000..06592cb --- /dev/null +++ b/hyprland/dot-config/hyprdynamicmonitors/work.conf @@ -0,0 +1,2 @@ +monitor=eDP-1,disable +monitor=HDMI-A-1,2560x1440@59.95,0x0,1.0 diff --git a/hyprland/dot-config/systemd/user/hyprpolkitagent.service.d/override.conf b/hyprland/dot-config/systemd/user/hyprpolkitagent.service.d/override.conf index 0f6e052..2b17997 100644 --- a/hyprland/dot-config/systemd/user/hyprpolkitagent.service.d/override.conf +++ b/hyprland/dot-config/systemd/user/hyprpolkitagent.service.d/override.conf @@ -1,3 +1,2 @@ [Service] ExecCondition=/lib/systemd/systemd-xdg-autostart-condition "Hyprland" "" -Slice=session-graphical.slice diff --git a/hyprland/dot-config/uwsm/env b/hyprland/dot-config/uwsm/env index a2bd337..447ac24 100644 --- a/hyprland/dot-config/uwsm/env +++ b/hyprland/dot-config/uwsm/env @@ -7,9 +7,9 @@ export BROWSER=qutebrowser export TERMINAL=alacritty # Wayland configuration -export GDK_BACKEND='wayland,x11,*' -export QT_QPA_PLATFORM='wayland;xcb' -export QT_STYLE_OVERRIDE=kvantum +export QT_QPA_PLATFORM=wayland +export QT_QPA_PLATFORMTHEME=qt5ct +# export QT_STYLE_OVERRIDE=kvantum export SDL_VIDEODRIVER=wayland export OZONE_PLATFORM=wayland export ELECTRON_OZONE_PLATFORM_HINT=wayland diff --git a/lf/dot-config/lf/lfrc b/lf/dot-config/lf/lfrc index 226e1aa..7e3eefe 100644 --- a/lf/dot-config/lf/lfrc +++ b/lf/dot-config/lf/lfrc @@ -25,27 +25,16 @@ cmd open ${{ cmd mkdir $mkdir -p "$@" 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 - } + filelist="" + while IFS= read -r filename; do + filelist+=" $(basename "$filename")" + done <<< "$fx" + if ouch decompress $fx; then + lf -remote "send $id echomsg \"Extracted"$filelist" with ouch.\"" + else + lf -remote "send $id echoerr \"Cannot extract"$filelist" with ouch.\"" + fi }} cmd quit-and-cd &{{ @@ -70,6 +59,36 @@ cmd dragon ${{ IFS="$(printf '\n\t')"; dragon-drop $fx }} +cmd git_branch ${{ + git branch | fzf | xargs git checkout + pwd_shell="$(pwd | sed 's/\\/\\\\/g;s/"/\\"/g')" + lf -remote "send $id updir; 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; echo "press ENTER"; read ENTER + +cmd fzf_search ${{ + cmd="rg --column --line-number --no-heading --color=always --smart-case" + fzf --ansi --disabled --layout=reverse --header="Search in files" --delimiter=: \ + --bind="start:reload([ -n {q} ] && $cmd -- {q} || true)" \ + --bind="change:reload([ -n {q} ] && $cmd -- {q} || true)" \ + --bind='enter:become(lf -remote "send $id select \"$(printf "%s" {1} | sed '\''s/\\/\\\\/g;s/"/\\"/g'\'')\"")' \ + --preview-window='+{2}-/2' \ + --preview='bat --color=always --highlight-line={2} -- {1}' +}} +map gr :fzf_search + + +cmd stwify ${{ + pkg="$1" + IFS="$(printf '\n\t')"; stowify $fx $pkg + lf -remote "send $id unselect;" +}} + +map S push :stwify<space>""<left> map Y $printf "%s" "$fx" | wl-copy map <c-n> push :mkdir<space>""<left> map D delete diff --git a/lf/dot-config/lf/shortcutrc b/lf/dot-config/lf/shortcutrc new file mode 100644 index 0000000..29fddd6 --- /dev/null +++ b/lf/dot-config/lf/shortcutrc @@ -0,0 +1,5 @@ +map Ecala $$EDITOR "/home/moreka/.config/alacritty/alacritty.toml" +map Ecgho $$EDITOR "/home/moreka/.config/ghostty/config" +map Ecvim $$EDITOR "/home/moreka/.config/nvim/init.lua" +map Echy $$EDITOR "/home/moreka/.config/hypr/hyprland.conf" +map Ecway $$EDITOR "/home/moreka/.config/waybar/config.jsonc" diff --git a/niri/dot-config/niri/config.kdl b/niri/dot-config/niri/config.kdl new file mode 100644 index 0000000..b91dff5 --- /dev/null +++ b/niri/dot-config/niri/config.kdl @@ -0,0 +1,564 @@ +// This config is in the KDL format: https://kdl.dev +// "/-" comments out the following node. +// Check the wiki for a full description of the configuration: +// https://yalter.github.io/niri/Configuration:-Introduction + +// Input device configuration. +// Find the full list of options on the wiki: +// https://yalter.github.io/niri/Configuration:-Input +input { + keyboard { + xkb { + layout "us,ir" + variant ",pes_keypad" + options "grp:shifts_toggle" + } + repeat-delay 300 + repeat-rate 50 + } + + // Next sections include libinput settings. + // Omitting settings disables them, or leaves them at their default values. + // All commented-out settings here are examples, not defaults. + touchpad { + tap + dwt + } + + mouse { + } + + trackpoint { + } + + // Uncomment this to make the mouse warp to the center of newly focused windows. + warp-mouse-to-focus + + // Focus windows and outputs automatically when moving the mouse into them. + // Setting max-scroll-amount="0%" makes it work only on windows already fully on screen. + focus-follows-mouse max-scroll-amount="0%" +} + +// You can configure outputs by their name, which you can find +// by running `niri msg outputs` while inside a niri instance. +// The built-in laptop monitor is usually called "eDP-1". +// Find more information on the wiki: +// https://yalter.github.io/niri/Configuration:-Outputs +// Remember to uncomment the node by removing "/-"! +output "eDP-1" { + mode "2880x1800@120.000" + scale 2 + transform "normal" + position x=0 y=0 +} + +// Settings that influence how windows are positioned and sized. +// Find more information on the wiki: +// https://yalter.github.io/niri/Configuration:-Layout +layout { + // Set gaps around windows in logical pixels. + gaps 5 + + // When to center a column when changing focus, options are: + // - "never", default behavior, focusing an off-screen column will keep at the left + // or right edge of the screen. + // - "always", the focused column will always be centered. + // - "on-overflow", focusing a column will center it if it doesn't fit + // together with the previously focused column. + center-focused-column "never" + + // You can customize the widths that "switch-preset-column-width" (Mod+R) toggles between. + preset-column-widths { + // Proportion sets the width as a fraction of the output width, taking gaps into account. + // For example, you can perfectly fit four windows sized "proportion 0.25" on an output. + // The default preset widths are 1/3, 1/2 and 2/3 of the output. + proportion 0.33333 + proportion 0.5 + proportion 0.66667 + + // Fixed sets the width in logical pixels exactly. + // fixed 1920 + } + + // You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between. + // preset-window-heights { } + + // You can change the default width of the new windows. + default-column-width { proportion 0.5; } + // If you leave the brackets empty, the windows themselves will decide their initial width. + // default-column-width {} + + // By default focus ring and border are rendered as a solid background rectangle + // behind windows. That is, they will show up through semitransparent windows. + // This is because windows using client-side decorations can have an arbitrary shape. + // + // If you don't like that, you should uncomment `prefer-no-csd` below. + // Niri will draw focus ring and border *around* windows that agree to omit their + // client-side decorations. + // + // Alternatively, you can override it with a window rule called + // `draw-border-with-background`. + + // You can change how the focus ring looks. + focus-ring { + // Uncomment this line to disable the focus ring. + // off + + // How many logical pixels the ring extends out from the windows. + width 1 + + // Colors can be set in a variety of ways: + // - CSS named colors: "red" + // - RGB hex: "#rgb", "#rgba", "#rrggbb", "#rrggbbaa" + // - CSS-like notation: "rgb(255, 127, 0)", rgba(), hsl() and a few others. + + // Color of the ring on the active monitor. + active-color "#7fc8ff" + + // Color of the ring on inactive monitors. + // + // The focus ring only draws around the active window, so the only place + // where you can see its inactive-color is on other monitors. + inactive-color "#505050" + + // You can also use gradients. They take precedence over solid colors. + // Gradients are rendered the same as CSS linear-gradient(angle, from, to). + // The angle is the same as in linear-gradient, and is optional, + // defaulting to 180 (top-to-bottom gradient). + // You can use any CSS linear-gradient tool on the web to set these up. + // Changing the color space is also supported, check the wiki for more info. + // + // active-gradient from="#80c8ff" to="#c7ff7f" angle=45 + + // You can also color the gradient relative to the entire view + // of the workspace, rather than relative to just the window itself. + // To do that, set relative-to="workspace-view". + // + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + } + + // You can also add a border. It's similar to the focus ring, but always visible. + border { + // The settings are the same as for the focus ring. + // If you enable the border, you probably want to disable the focus ring. + off + + width 4 + active-color "#ffc87f" + inactive-color "#505050" + + // Color of the border around windows that request your attention. + urgent-color "#9b0000" + + // Gradients can use a few different interpolation color spaces. + // For example, this is a pastel rainbow gradient via in="oklch longer hue". + // + // active-gradient from="#e5989b" to="#ffb4a2" angle=45 relative-to="workspace-view" in="oklch longer hue" + + // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" + } + + // You can enable drop shadows for windows. + shadow { + // Uncomment the next line to enable shadows. + // on + + // By default, the shadow draws only around its window, and not behind it. + // Uncomment this setting to make the shadow draw behind its window. + // + // Note that niri has no way of knowing about the CSD window corner + // radius. It has to assume that windows have square corners, leading to + // shadow artifacts inside the CSD rounded corners. This setting fixes + // those artifacts. + // + // However, instead you may want to set prefer-no-csd and/or + // geometry-corner-radius. Then, niri will know the corner radius and + // draw the shadow correctly, without having to draw it behind the + // window. These will also remove client-side shadows if the window + // draws any. + // + // draw-behind-window true + + // You can change how shadows look. The values below are in logical + // pixels and match the CSS box-shadow properties. + + // Softness controls the shadow blur radius. + softness 30 + + // Spread expands the shadow. + spread 5 + + // Offset moves the shadow relative to the window. + offset x=0 y=5 + + // You can also change the shadow color and opacity. + color "#0007" + } + + // Struts shrink the area occupied by windows, similarly to layer-shell panels. + // You can think of them as a kind of outer gaps. They are set in logical pixels. + // Left and right struts will cause the next window to the side to always be visible. + // Top and bottom struts will simply add outer gaps in addition to the area occupied by + // layer-shell panels and regular gaps. + struts { + // left 64 + // right 64 + // top 64 + // bottom 64 + } +} + +// Add lines like this to spawn processes at startup. +// Note that running niri as a session supports xdg-desktop-autostart, +// which may be more convenient to use. +// See the binds section below for more spawn examples. + +// This line starts waybar, a commonly used bar for Wayland compositors. +spawn-at-startup "waybar" + +// To run a shell command (with variables, pipes, etc.), use spawn-sh-at-startup: +// spawn-sh-at-startup "qs -c ~/source/qs/MyAwesomeShell" + +hotkey-overlay { + // Uncomment this line to disable the "Important Hotkeys" pop-up at startup. + // skip-at-startup +} + +// Uncomment this line to ask the clients to omit their client-side decorations if possible. +// If the client will specifically ask for CSD, the request will be honored. +// Additionally, clients will be informed that they are tiled, removing some client-side rounded corners. +// This option will also fix border/focus ring drawing behind some semitransparent windows. +// After enabling or disabling this, you need to restart the apps for this to take effect. +prefer-no-csd + +// You can change the path where screenshots are saved. +// A ~ at the front will be expanded to the home directory. +// The path is formatted with strftime(3) to give you the screenshot date and time. +screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png" + +// You can also set this to null to disable saving screenshots to disk. +// screenshot-path null + +// Animation settings. +// The wiki explains how to configure individual animations: +// https://yalter.github.io/niri/Configuration:-Animations +animations { + // Uncomment to turn off all animations. + // off + + // Slow down all animations by this factor. Values below 1 speed them up instead. + // slowdown 3.0 +} + +gestures { + hot-corners { + off + } +} + +// Window rules let you adjust behavior for individual windows. +// Find more information on the wiki: +// https://yalter.github.io/niri/Configuration:-Window-Rules + +// Work around WezTerm's initial configure bug +// by setting an empty default-column-width. +/-window-rule { + // This regular expression is intentionally made as specific as possible, + // since this is the default config, and we want no false positives. + // You can get away with just app-id="wezterm" if you want. + match app-id=r#"^org\.wezfurlong\.wezterm$"# + default-column-width {} +} + +// Open the Firefox picture-in-picture player as floating by default. +/-window-rule { + // This app-id regular expression will work for both: + // - host Firefox (app-id is "firefox") + // - Flatpak Firefox (app-id is "org.mozilla.firefox") + match app-id=r#"firefox$"# title="^Picture-in-Picture$" + open-floating true +} + +// Example: block out two password managers from screen capture. +// (This example rule is commented out with a "/-" in front.) +/-window-rule { + match app-id=r#"^org\.keepassxc\.KeePassXC$"# + match app-id=r#"^org\.gnome\.World\.Secrets$"# + + block-out-from "screen-capture" + + // Use this instead if you want them visible on third-party screenshot tools. + // block-out-from "screencast" +} + +// Example: enable rounded corners for all windows. +// (This example rule is commented out with a "/-" in front.) +/-window-rule { + geometry-corner-radius 12 + clip-to-geometry true +} + +binds { + // Keys consist of modifiers separated by + signs, followed by an XKB key name + // in the end. To find an XKB name for a particular key, you may use a program + // like wev. + // + // "Mod" is a special modifier equal to Super when running on a TTY, and to Alt + // when running as a winit window. + // + // Most actions that you can bind here can also be invoked programmatically with + // `niri msg action do-something`. + + // Mod-Shift-/, which is usually the same as Mod-?, + // shows a list of important hotkeys. + Mod+Shift+Slash { show-hotkey-overlay; } + + // Suggested binds for running programs: terminal, app launcher, screen locker. + Mod+Return hotkey-overlay-title="Open a Terminal: alacritty" { spawn "alacritty"; } + Mod+P hotkey-overlay-title="Run an Application: fuzzel" { spawn "fuzzel"; } + Mod+X hotkey-overlay-title="Lock the Screen: swaylock" { spawn "swaylock"; } + Mod+B hotkey-overlay-title="Open browser" { spawn "qutebrowser"; } + + // Example volume keys mappings for PipeWire & WirePlumber. + // The allow-when-locked=true property makes them work even when the session is locked. + // Using spawn-sh allows to pass multiple arguments together with the command. + // "-l 1.0" limits the volume to 100%. + XF86AudioRaiseVolume allow-when-locked=true { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1+ -l 1.0"; } + XF86AudioLowerVolume allow-when-locked=true { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1-"; } + XF86AudioMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; } + XF86AudioMicMute allow-when-locked=true { spawn-sh "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"; } + + // Example brightness key mappings for brightnessctl. + // You can use regular spawn with multiple arguments too (to avoid going through "sh"), + // but you need to manually put each argument in separate "" quotes. + XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+10%"; } + XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "10%-"; } + + // Open/close the Overview: a zoomed-out view of workspaces and windows. + // You can also move the mouse into the top-left hot corner, + // or do a four-finger swipe up on a touchpad. + Mod+O repeat=false { toggle-overview; } + + Mod+Shift+C repeat=false { close-window; } + + Mod+Left { focus-column-left; } + Mod+Down { focus-window-down; } + Mod+Up { focus-window-up; } + Mod+Right { focus-column-right; } + Mod+H { focus-column-left; } + Mod+J { focus-window-down; } + Mod+K { focus-window-up; } + Mod+L { focus-column-right; } + + Mod+Ctrl+Left { move-column-left; } + Mod+Ctrl+Down { move-window-down; } + Mod+Ctrl+Up { move-window-up; } + Mod+Ctrl+Right { move-column-right; } + Mod+Ctrl+H { move-column-left; } + Mod+Ctrl+J { move-window-down; } + Mod+Ctrl+K { move-window-up; } + Mod+Ctrl+L { move-column-right; } + + // Alternative commands that move across workspaces when reaching + // the first or last window in a column. + // Mod+J { focus-window-or-workspace-down; } + // Mod+K { focus-window-or-workspace-up; } + // Mod+Ctrl+J { move-window-down-or-to-workspace-down; } + // Mod+Ctrl+K { move-window-up-or-to-workspace-up; } + + Mod+Home { focus-column-first; } + Mod+End { focus-column-last; } + Mod+Ctrl+Home { move-column-to-first; } + Mod+Ctrl+End { move-column-to-last; } + + Mod+Shift+Left { focus-monitor-left; } + Mod+Shift+Down { focus-monitor-down; } + Mod+Shift+Up { focus-monitor-up; } + Mod+Shift+Right { focus-monitor-right; } + Mod+Shift+H { focus-monitor-left; } + Mod+Shift+J { focus-monitor-down; } + Mod+Shift+K { focus-monitor-up; } + Mod+Shift+L { focus-monitor-right; } + + Mod+Shift+Ctrl+Left { move-column-to-monitor-left; } + Mod+Shift+Ctrl+Down { move-column-to-monitor-down; } + Mod+Shift+Ctrl+Up { move-column-to-monitor-up; } + Mod+Shift+Ctrl+Right { move-column-to-monitor-right; } + Mod+Shift+Ctrl+H { move-column-to-monitor-left; } + Mod+Shift+Ctrl+J { move-column-to-monitor-down; } + Mod+Shift+Ctrl+K { move-column-to-monitor-up; } + Mod+Shift+Ctrl+L { move-column-to-monitor-right; } + + // Alternatively, there are commands to move just a single window: + // Mod+Shift+Ctrl+Left { move-window-to-monitor-left; } + // ... + + // And you can also move a whole workspace to another monitor: + // Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; } + // ... + + Mod+Page_Down { focus-workspace-down; } + Mod+Page_Up { focus-workspace-up; } + Mod+U { focus-workspace-down; } + Mod+I { focus-workspace-up; } + Mod+Ctrl+Page_Down { move-column-to-workspace-down; } + Mod+Ctrl+Page_Up { move-column-to-workspace-up; } + Mod+Ctrl+U { move-column-to-workspace-down; } + Mod+Ctrl+I { move-column-to-workspace-up; } + + // Alternatively, there are commands to move just a single window: + // Mod+Ctrl+Page_Down { move-window-to-workspace-down; } + // ... + + Mod+Shift+Page_Down { move-workspace-down; } + Mod+Shift+Page_Up { move-workspace-up; } + Mod+Shift+U { move-workspace-down; } + Mod+Shift+I { move-workspace-up; } + + // You can bind mouse wheel scroll ticks using the following syntax. + // These binds will change direction based on the natural-scroll setting. + // + // To avoid scrolling through workspaces really fast, you can use + // the cooldown-ms property. The bind will be rate-limited to this value. + // You can set a cooldown on any bind, but it's most useful for the wheel. + Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; } + Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; } + Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; } + Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; } + + Mod+WheelScrollRight { focus-column-right; } + Mod+WheelScrollLeft { focus-column-left; } + Mod+Ctrl+WheelScrollRight { move-column-right; } + Mod+Ctrl+WheelScrollLeft { move-column-left; } + + // Usually scrolling up and down with Shift in applications results in + // horizontal scrolling; these binds replicate that. + Mod+Shift+WheelScrollDown { focus-column-right; } + Mod+Shift+WheelScrollUp { focus-column-left; } + Mod+Ctrl+Shift+WheelScrollDown { move-column-right; } + Mod+Ctrl+Shift+WheelScrollUp { move-column-left; } + + // Similarly, you can bind touchpad scroll "ticks". + // Touchpad scrolling is continuous, so for these binds it is split into + // discrete intervals. + // These binds are also affected by touchpad's natural-scroll, so these + // example binds are "inverted", since we have natural-scroll enabled for + // touchpads by default. + // Mod+TouchpadScrollDown { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.02+"; } + // Mod+TouchpadScrollUp { spawn-sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.02-"; } + + // You can refer to workspaces by index. However, keep in mind that + // niri is a dynamic workspace system, so these commands are kind of + // "best effort". Trying to refer to a workspace index bigger than + // the current workspace count will instead refer to the bottommost + // (empty) workspace. + // + // For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on + // will all refer to the 3rd workspace. + Mod+1 { focus-workspace 1; } + Mod+2 { focus-workspace 2; } + Mod+3 { focus-workspace 3; } + Mod+4 { focus-workspace 4; } + Mod+5 { focus-workspace 5; } + Mod+6 { focus-workspace 6; } + Mod+7 { focus-workspace 7; } + Mod+8 { focus-workspace 8; } + Mod+9 { focus-workspace 9; } + Mod+Ctrl+1 { move-column-to-workspace 1; } + Mod+Ctrl+2 { move-column-to-workspace 2; } + Mod+Ctrl+3 { move-column-to-workspace 3; } + Mod+Ctrl+4 { move-column-to-workspace 4; } + Mod+Ctrl+5 { move-column-to-workspace 5; } + Mod+Ctrl+6 { move-column-to-workspace 6; } + Mod+Ctrl+7 { move-column-to-workspace 7; } + Mod+Ctrl+8 { move-column-to-workspace 8; } + Mod+Ctrl+9 { move-column-to-workspace 9; } + + // Alternatively, there are commands to move just a single window: + // Mod+Ctrl+1 { move-window-to-workspace 1; } + + // Switches focus between the current and the previous workspace. + // Mod+Tab { focus-workspace-previous; } + + // The following binds move the focused window in and out of a column. + // If the window is alone, they will consume it into the nearby column to the side. + // If the window is already in a column, they will expel it out. + Mod+BracketLeft { consume-or-expel-window-left; } + Mod+BracketRight { consume-or-expel-window-right; } + + // Consume one window from the right to the bottom of the focused column. + Mod+Comma { consume-window-into-column; } + // Expel the bottom window from the focused column to the right. + Mod+Period { expel-window-from-column; } + + Mod+R { switch-preset-column-width; } + // Cycling through the presets in reverse order is also possible. + // Mod+R { switch-preset-column-width-back; } + Mod+Shift+R { switch-preset-window-height; } + Mod+Ctrl+R { reset-window-height; } + Mod+F { maximize-column; } + Mod+Shift+F { fullscreen-window; } + + // Expand the focused column to space not taken up by other fully visible columns. + // Makes the column "fill the rest of the space". + Mod+Ctrl+F { expand-column-to-available-width; } + + Mod+C { center-column; } + + // Center all fully visible columns on screen. + Mod+Ctrl+C { center-visible-columns; } + + // Finer width adjustments. + // This command can also: + // * set width in pixels: "1000" + // * adjust width in pixels: "-5" or "+5" + // * set width as a percentage of screen width: "25%" + // * adjust width as a percentage of screen width: "-10%" or "+10%" + // Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0, + // set-column-width "100" will make the column occupy 200 physical screen pixels. + Mod+Minus { set-column-width "-10%"; } + Mod+Equal { set-column-width "+10%"; } + + // Finer height adjustments when in column with other windows. + Mod+Shift+Minus { set-window-height "-10%"; } + Mod+Shift+Equal { set-window-height "+10%"; } + + // Move the focused window between the floating and the tiling layout. + Mod+V { toggle-window-floating; } + Mod+Shift+V { switch-focus-between-floating-and-tiling; } + + // Toggle tabbed column display mode. + // Windows in this column will appear as vertical tabs, + // rather than stacked on top of each other. + Mod+W { toggle-column-tabbed-display; } + + // Actions to switch layouts. + // Note: if you uncomment these, make sure you do NOT have + // a matching layout switch hotkey configured in xkb options above. + // Having both at once on the same hotkey will break the switching, + // since it will switch twice upon pressing the hotkey (once by xkb, once by niri). + // Mod+Space { switch-layout "next"; } + // Mod+Shift+Space { switch-layout "prev"; } + + Print { screenshot; } + Ctrl+Print { screenshot-screen; } + Alt+Print { screenshot-window; } + + // Applications such as remote-desktop clients and software KVM switches may + // request that niri stops processing the keyboard shortcuts defined here + // so they may, for example, forward the key presses as-is to a remote machine. + // It's a good idea to bind an escape hatch to toggle the inhibitor, + // so a buggy application can't hold your session hostage. + // + // The allow-inhibiting=false property can be applied to other binds as well, + // which ensures niri always processes them, even when an inhibitor is active. + Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } + + // The quit action will show a confirmation dialog to avoid accidental exits. + Mod+Shift+E { quit; } + Ctrl+Alt+Delete { quit; } + + // Powers off the monitors. To turn them back on, do any input like + // moving the mouse or pressing any other key. + Mod+Shift+P { power-off-monitors; } +} diff --git a/nvim/dot-config/nvim-final/after/ftplugin/lua.lua b/nvim/dot-config/nvim-final/after/ftplugin/lua.lua new file mode 100644 index 0000000..53dd1d2 --- /dev/null +++ b/nvim/dot-config/nvim-final/after/ftplugin/lua.lua @@ -0,0 +1,3 @@ +vim.cmd([[ +setlocal keywordprg=:help +]]) diff --git a/nvim/dot-config/nvim-final/colors/solarized.lua b/nvim/dot-config/nvim-final/colors/solarized.lua new file mode 100644 index 0000000..090090b --- /dev/null +++ b/nvim/dot-config/nvim-final/colors/solarized.lua @@ -0,0 +1,490 @@ +local function oklab_to_linear_rgb(L, a, b) + -- Oklab to LMS conversion + -- Reference: Björn Ottosson, "A perceptual color space for image processing" + local l = L + 0.3963377774 * a + 0.2158037573 * b + local m = L - 0.1055613458 * a - 0.0638541728 * b + local s = L - 0.0894841775 * a - 1.2914855480 * b + + -- LMS to linear RGB + -- Cube the LMS values (inverse of cube root) + local l3, m3, s3 = l * l * l, m * m * m, s * s * s + + -- Linear RGB transformation matrix + local r = 4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3 + local g = -1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3 + local b_out = -0.0041960863 * l3 - 0.7034186147 * m3 + 1.7076147010 * s3 + + return r, g, b_out +end + +local function linear_to_srgb_component(c) + -- sRGB gamma correction (companding) + -- Reference: IEC 61966-2-1:1999 + if c <= 0.0031308 then + return c * 12.92 -- Linear segment + else + return 1.055 * (c ^ (1 / 2.4)) - 0.055 -- Power function (gamma ≈ 2.2) + end +end + +local function oklab_to_srgb(L, a, b) + local r, g, b_comp = oklab_to_linear_rgb(L, a, b) + + r = linear_to_srgb_component(r) + g = linear_to_srgb_component(g) + b_comp = linear_to_srgb_component(b_comp) + + -- Clamp and convert to 8-bit + r = math.floor(math.max(0, math.min(1, r)) * 255 + 0.5) + g = math.floor(math.max(0, math.min(1, g)) * 255 + 0.5) + b_comp = math.floor(math.max(0, math.min(1, b_comp)) * 255 + 0.5) + + return string.format('#%02x%02x%02x', r, g, b_comp) +end + +-- ═══════════════════════════════════════════════════════════════════════════ +-- MONOTONE COLORS +-- ═══════════════════════════════════════════════════════════════════════════ +local base03 = oklab_to_srgb(0.267337, -0.037339, -0.031128) +local base02 = oklab_to_srgb(0.309207, -0.039852, -0.033029) +local base01 = oklab_to_srgb(0.523013, -0.021953, -0.017864) +local base00 = oklab_to_srgb(0.568165, -0.021219, -0.019038) + +local base0 = oklab_to_srgb(0.709236, -0.023223, -0.013451) +local base1 = oklab_to_srgb(0.697899, -0.015223, -0.004594) +local base2 = oklab_to_srgb(0.930609, -0.001091, 0.026010) +local base3 = oklab_to_srgb(0.973528, -0.000043, 0.026053) + +-- ═══════════════════════════════════════════════════════════════════════════ +-- ACCENT COLORS +-- ═══════════════════════════════════════════════════════════════════════════ +local yellow = oklab_to_srgb(0.654479, 0.010005, 0.133641) +local orange = oklab_to_srgb(0.63, 0.133661 * 0.69, 0.110183 * 0.69) +local red = oklab_to_srgb(0.63, 0.183749 * 0.72, 0.094099 * 0.72) +local magenta = oklab_to_srgb(0.592363, 0.201958, -0.014497) +local violet = oklab_to_srgb(0.582316, 0.019953, -0.124557) +local blue = oklab_to_srgb(0.614879, -0.059069, -0.126255) +local cyan = oklab_to_srgb(0.643664, -0.101063, -0.013097) +local green = oklab_to_srgb(0.644391, -0.072203, 0.132448) + +-- ═══════════════════════════════════════════════════════════════════════════ +-- MODE SELECTION +-- ═══════════════════════════════════════════════════════════════════════════ + +-- Set to 'dark' or 'light' +local mode = vim.o.background or 'dark' + +local colors = {} + +if mode == 'dark' then + -- Dark mode: dark background, light text + colors.bg = base03 + colors.bg_highlight = base02 + colors.fg_comment = base01 + colors.fg = base0 + colors.fg_emphasis = base1 +else + colors.bg = base3 + colors.bg_highlight = base2 + colors.fg_comment = base1 + colors.fg = base00 + colors.fg_emphasis = base01 +end + +-- Accent colors are the same in both modes +colors.yellow = yellow +colors.orange = orange +colors.red = red +colors.magenta = magenta +colors.violet = violet +colors.blue = blue +colors.cyan = cyan +colors.green = green + +colors.cursorline_bg = colors.bg_highlight +colors.selection_bg = base02 +colors.visual_bg = base02 + +vim.g.colors_name = 'dicom' + +local function h(group, properties) + vim.api.nvim_set_hl(0, group, properties) +end + +local function hex_to_rgb(hex) + hex = hex:gsub('#', '') + return { + tonumber(hex:sub(1, 2), 16), + tonumber(hex:sub(3, 4), 16), + tonumber(hex:sub(5, 6), 16), + } +end + +local function rgb_to_hex(c) + return string.format('#%02x%02x%02x', c[1], c[2], c[3]) +end + +local function blend(fg, t, target_bg) + local a, b = hex_to_rgb(fg), hex_to_rgb(target_bg or colors.bg) + local c = { + math.floor(a[1] * (1 - t) + b[1] * t + 0.5), + math.floor(a[2] * (1 - t) + b[2] * t + 0.5), + math.floor(a[3] * (1 - t) + b[3] * t + 0.5), + } + return rgb_to_hex(c) +end + +-- ============================================================================= +-- Research-Driven Syntax Highlighting Strategy +-- Based on: Hannebauer et al. (2018), Tonsky (2025), Schloss (2023) +-- ============================================================================= + +-- 1. Core Editor Surface +h('Normal', { fg = colors.fg, bg = colors.bg }) +h('EndOfBuffer', { fg = colors.bg }) +h('CursorLine', { bg = colors.cursorline_bg }) +h('CursorLineNr', { fg = colors.yellow, bold = true }) +h('LineNr', { fg = colors.fg_comment }) +h('WinSeparator', { fg = colors.bg_highlight, bg = colors.bg }) + +-- 2. Visual & Search (High Arousal) +h('Visual', { bg = colors.selection_bg }) +h('Search', { fg = colors.bg, bg = colors.yellow }) +h('IncSearch', { fg = colors.bg, bg = colors.orange }) + +h('Keyword', { fg = colors.green }) +h('Statement', { fg = colors.green }) +h('Conditional', { fg = colors.green }) +h('Repeat', { fg = colors.green }) + +h('Function', { fg = colors.blue }) + +-- Types +h('Type', { fg = colors.yellow }) +h('StorageClass', { fg = colors.yellow }) +h('Structure', { fg = colors.yellow }) +h('Typedef', { fg = colors.yellow }) + +-- Constants +h('Constant', { fg = colors.cyan }) +h('String', { fg = colors.cyan }) +h('Character', { fg = colors.cyan }) +h('Number', { fg = colors.cyan }) +h('Boolean', { fg = colors.cyan }) +h('Float', { fg = colors.cyan }) + +-- PreProc +h('PreProc', { fg = colors.orange }) +h('Include', { fg = colors.orange }) +h('Define', { fg = colors.orange }) +h('Macro', { fg = colors.orange }) +h('PreCondit', { fg = colors.orange }) + +-- Special Characters - Cyan (escape/special) +h('Special', { fg = colors.cyan }) + +h('Identifier', { fg = colors.fg }) +h('Variable', { fg = colors.fg }) +h('Operator', { fg = colors.fg }) + +h('Delimiter', { fg = colors.fg }) +h('NonText', { fg = colors.bg_highlight }) + +-- ----------------------------------------------------------------------------- +-- Layer 6: COMMENTS +-- Luminance: L=comment (dimmest) +-- ----------------------------------------------------------------------------- + +h('Comment', { fg = colors.fg_comment, italic = true }) + +-- ============================================================================= +-- 4. UI Components +-- ============================================================================= + +h('StatusLine', { bg = colors.fg, fg = colors.bg_highlight }) +h('StatusLineNC', { bg = colors.fg_comment, fg = colors.bg_highlight }) +h('WildMenu', { fg = colors.bg, bg = colors.blue }) +h('ColorColumn', { bg = colors.bg_highlight }) + +-- Popup Menu +h('Pmenu', { fg = colors.fg, bg = colors.bg_highlight }) +h('PmenuSel', { fg = colors.fg_emphasis, bg = colors.selection, reverse = true }) +h('PmenuSbar', { bg = colors.bg_highlight }) +h('PmenuThumb', { bg = colors.fg_comment }) +h('PmenuMatch', { fg = colors.cyan, bold = true }) +h('PmenuMatchSel', { bg = colors.selection, bold = true, fg = colors.fg_emphasis }) + +-- Float & Borders +h('NormalFloat', { bg = colors.bg_highlight }) +h('FloatBorder', { fg = colors.comment }) +h('Title', { fg = colors.bg_highlight, bold = true }) + +-- ============================================================================= +-- 5. Diagnostics - Semantic Consistency +-- ============================================================================= +-- +-- Research basis (Schloss 2023): +-- Color-concept associations are universal: +-- Red → danger/anger (cross-cultural consistency) +-- Orange → warning/caution +-- Blue → information/calm +-- Cyan → hint/auxiliary +-- +-- This mapping perfectly aligns with research! ✓ +-- + +h('ErrorMsg', { fg = colors.red, bold = true }) +h('WarningMsg', { fg = colors.orange }) +h('ModeMsg', { fg = colors.cyan, bold = true }) +h('Todo', { fg = colors.violet, bold = true, reverse = true }) +h('MatchParen', { bg = colors.selection_bg, bold = true }) + +-- QuickFix & List +h('qfFileName', { fg = colors.blue }) +h('qfLineNr', { fg = colors.cyan }) +h('qfSeparator', { fg = colors.bg_highlight }) +h('QuickFixLine', { bg = colors.cursorline_bg, bold = true }) +h('qfText', { link = 'Normal' }) + +-- Underlined/Directory +h('Underlined', { fg = colors.violet, underline = true }) +h('Directory', { fg = colors.blue }) + +-- sync to terminal +h('Magenta', { fg = colors.magenta }) +h('Violet', { fg = colors.violet }) + +-- ============================================================================= +-- 6. Treesitter Highlights (Optimized) +-- ============================================================================= + +-- Neutral Layer ⭐️ KEY OPTIMIZATION +h('@variable', { link = 'Identifier' }) -- Neutral +h('@variable.builtin', { link = '@variable' }) -- Neutral +h('@variable.parameter', { link = '@variable' }) -- Neutral +h('@variable.parameter.builtin', { link = '@variable.builtin' }) +h('@variable.member', { link = '@variable' }) -- Neutral +h('@parameter', { fg = colors.fg }) -- Neutral +h('@property', { fg = colors.fg }) -- Neutral + +-- Constants Layer ⭐️ OPTIMIZED +h('@constant', { fg = colors.cyan }) -- Constants = frozen +h('@constant.builtin', { fg = colors.cyan }) +h('@constant.macro', { fg = colors.cyan }) + +-- Modules/Namespaces +h('@module', { link = 'Identifier' }) +h('@module.builtin', { link = '@module' }) + +-- Labels +h('@label', { link = 'Label' }) + +-- Strings Layer +h('@string', { link = 'String' }) +h('@string.documentation', { link = 'Comment' }) +h('@string.regexp', { link = '@string' }) +h('@string.escape', { link = 'Special' }) +h('@string.special', { link = '@string' }) +h('@string.special.symbol', { link = '@string' }) +h('@string.special.path', { link = '@string' }) +h('@string.special.url', { link = 'Underlined' }) + +h('@character', { link = 'String' }) +h('@character.special', { link = '@character' }) + +-- Numbers Layer +h('@boolean', { link = 'Constant' }) +h('@number', { link = 'Number' }) +h('@number.float', { link = 'Float' }) + +-- Types Layer +h('@type', { link = 'Type' }) +h('@type.builtin', { link = 'Type' }) +h('@type.definition', { link = 'Type' }) + +-- Attributes/Decorators +h('@attribute', { link = 'Macro' }) +h('@attribute.builtin', { link = 'Special' }) + +-- Functions Layer +h('@function', { link = 'Function' }) +h('@function.builtin', { link = 'Function' }) +h('@function.call', { link = '@function' }) +h('@function.macro', { link = '@function' }) +h('@function.method', { link = '@function' }) +h('@function.method.call', { link = '@function' }) +h('@constructor', { link = 'Function' }) + +-- Operators - Neutral +h('@operator', { link = 'Operator' }) + +-- Keywords Layer +h('@keyword', { link = 'Keyword' }) +h('@keyword.coroutine', { link = '@keyword' }) +h('@keyword.function', { link = 'Keyword' }) +h('@keyword.operator', { link = '@keyword' }) +h('@keyword.import', { link = 'PreProc' }) +h('@keyword.type', { link = '@keyword' }) +h('@keyword.modifier', { link = '@keyword' }) +h('@keyword.repeat', { link = 'Repeat' }) +h('@keyword.return', { link = '@keyword' }) +h('@keyword.debug', { link = '@keyword' }) +h('@keyword.exception', { link = '@keyword' }) +h('@keyword.conditional', { link = 'Conditional' }) +h('@keyword.conditional.ternary', { link = '@operator' }) +h('@keyword.directive', { link = '@keyword' }) +h('@keyword.directive.define', { link = '@keyword' }) + +-- Punctuation +h('@punctuation', { fg = colors.fg }) +h('@punctuation.delimiter', { link = '@punctuation' }) +h('@punctuation.bracket', { link = '@punctuation' }) +h('@punctuation.special', { link = '@punctuation' }) + +-- Comments Layer +h('@comment', { link = 'Comment' }) +h('@comment.documentation', { link = '@comment' }) +h('@comment.error', { fg = colors.red, bold = true }) +h('@comment.warning', { fg = colors.yellow, bold = true }) +h('@comment.todo', { link = 'Special' }) +h('@comment.note', { link = 'Special' }) + +-- Markup (Markdown, etc.) +h('@markup', { link = 'Comment' }) +h('@markup.strong', { bold = true }) +h('@markup.italic', { italic = true }) +h('@markup.strikethrough', { strikethrough = true }) +h('@markup.underline', { link = 'Underlined' }) +h('@markup.heading', { link = 'Title' }) +h('@markup.heading.1', { link = '@markup.heading' }) +h('@markup.heading.2', { link = '@markup.heading' }) +h('@markup.heading.3', { link = '@markup.heading' }) +h('@markup.heading.4', { link = '@markup.heading' }) +h('@markup.heading.5', { link = '@markup.heading' }) +h('@markup.heading.6', { link = '@markup.heading' }) +h('@markup.quote', {}) +h('@markup.math', { link = 'String' }) +h('@markup.link', { link = 'Underlined' }) +h('@markup.link.label', { link = '@markup.link' }) +h('@markup.link.url', { link = '@markup.link' }) +h('@markup.raw', {}) +h('@markup.raw.block', { link = '@markup.raw' }) +h('@markup.list', {}) +h('@markup.list.checked', { fg = colors.green }) +h('@markup.list.unchecked', { link = '@markup.list' }) + +-- Diff +h('@diff.plus', { fg = blend(colors.green, 0.5, colors.statusline_bg) }) +h('@diff.minus', { fg = blend(colors.red, 0.5, colors.statusline_bg) }) +h('@diff.delta', { fg = blend(colors.yellow, 0.5, colors.statusline_bg) }) + +-- HTML/XML +h('@tag', { fg = colors.green }) +h('@tag.attribute', { fg = colors.fg }) +h('@tag.delimiter', { fg = colors.fg }) +h('@tag.builtin', { link = 'Special' }) + +-- Vimdoc Special Handling +h('@constant.comment', { link = 'SpecialComment' }) +h('@number.comment', { link = 'Comment' }) +h('@punctuation.bracket.comment', { link = 'SpecialComment' }) +h('@punctuation.delimiter.comment', { link = 'SpecialComment' }) +h('@label.vimdoc', { link = 'String' }) +h('@markup.heading.1.delimiter.vimdoc', { link = '@markup.heading.1' }) +h('@markup.heading.2.delimiter.vimdoc', { link = '@markup.heading.2' }) + +-- Semantic Aliases +h('@class', { fg = colors.yellow }) +h('@method', { fg = colors.blue }) +h('@interface', { fg = colors.yellow }) +h('@namespace', { fg = colors.fg }) + +-- ============================================================================= +-- 7. LSP Semantic Highlights +-- ============================================================================= + +h('@lsp.type.class', { link = '@type' }) +h('@lsp.type.comment', { link = '@comment' }) +h('@lsp.type.decorator', { link = '@attribute' }) +h('@lsp.type.enum', { link = '@type' }) +h('@lsp.type.enumMember', { link = '@constant' }) +h('@lsp.type.event', { link = '@type' }) +h('@lsp.type.function', { link = '@function' }) +h('@lsp.type.interface', { link = '@type' }) +h('@lsp.type.keyword', { link = '@keyword' }) +h('@lsp.type.macro', { link = 'Macro' }) +h('@lsp.type.method', { link = '@function.method' }) +h('@lsp.type.modifier', { link = '@type.qualifier' }) +h('@lsp.type.namespace', { link = '@module' }) +h('@lsp.type.number', { link = '@number' }) +h('@lsp.type.operator', { link = '@operator' }) +h('@lsp.type.parameter', { fg = colors.fg }) +h('@lsp.type.property', { fg = colors.fg }) +h('@lsp.type.regexp', { link = '@string.regexp' }) +h('@lsp.type.string', { link = '@string' }) +h('@lsp.type.struct', { link = '@type' }) +h('@lsp.type.type', { link = '@type' }) +h('@lsp.type.typeParameter', { link = '@type.definition' }) +h('@lsp.type.variable', { link = '@variable' }) + +-- LSP Modifiers +h('@lsp.mod.abstract', {}) +h('@lsp.mod.async', {}) +h('@lsp.mod.declaration', {}) +h('@lsp.mod.defaultLibrary', {}) +h('@lsp.mod.definition', {}) +h('@lsp.mod.deprecated', { link = 'DiagnosticDeprecated' }) +h('@lsp.mod.documentation', {}) +h('@lsp.mod.modification', {}) +h('@lsp.mod.readonly', {}) +h('@lsp.mod.static', {}) + +-- ============================================================================= +-- 8. Diagnostics - Semantic Consistency (Schloss 2023) +-- ============================================================================= + +h('DiagnosticError', { fg = colors.red }) +h('DiagnosticWarn', { fg = colors.yellow }) +h('DiagnosticInfo', { fg = colors.blue }) +h('DiagnosticHint', { fg = colors.cyan }) + +h('DiagnosticVirtualTextError', { bg = blend(colors.red, 0.4) }) +h('DiagnosticVirtualTextWarn', { bg = blend(colors.yellow, 0.4) }) +h('DiagnosticVirtualTextInfo', { bg = blend(colors.blue, 0.4) }) +h('DiagnosticVirtualTextHint', { bg = blend(colors.cyan, 0.4) }) + +h('DiagnosticPrefixError', { fg = colors.red, bg = blend(colors.red, 0.25) }) +h('DiagnosticPrefixWarn', { fg = colors.yellow, bg = blend(colors.yellow, 0.25) }) +h('DiagnosticPrefixInfo', { fg = colors.blue, bg = blend(colors.blue, 0.25) }) +h('DiagnosticPrefixHint', { fg = colors.cyan, bg = blend(colors.cyan, 0.25) }) + +h('DiagnosticUnderlineError', { undercurl = true, sp = colors.red }) +h('DiagnosticUnderlineWarn', { undercurl = true, sp = colors.yellow }) +h('DiagnosticUnderlineInfo', { undercurl = true, sp = colors.blue }) +h('DiagnosticUnderlineHint', { undercurl = true, sp = colors.cyan }) +h('YankHighlight', { fg = colors.bg, bg = colors.fg }) + +-- ============================================================================= +-- 9. LSP & Other Plugin Support +-- ============================================================================= + +h('LspReferenceText', { bg = colors.selection_bg }) +h('LspReferenceRead', { bg = colors.selection_bg }) +h('LspReferenceWrite', { bg = colors.selection_bg }) +h('LspReferenceTarget', { link = 'LspReferenceText' }) +h('LspInlayHint', { link = 'NonText' }) +h('LspCodeLens', { link = 'NonText' }) +h('LspCodeLensSeparator', { link = 'NonText' }) +h('LspSignatureActiveParameter', { link = 'LspReferenceText' }) + +-- Indentmini +h('IndentLine', { link = 'Comment' }) +h('IndentLineCurrent', { link = 'Comment' }) + +-- GitSigns +h('GitSignsAdd', { fg = colors.green }) +h('GitSignsChange', { fg = colors.orange }) +h('GitSignsDelete', { fg = colors.red }) + +-- Dashboard +h('DashboardHeader', { fg = colors.green }) diff --git a/nvim/dot-config/nvim-final/init.lua b/nvim/dot-config/nvim-final/init.lua new file mode 100644 index 0000000..54dee05 --- /dev/null +++ b/nvim/dot-config/nvim-final/init.lua @@ -0,0 +1,713 @@ +vim.loader.enable(true) + +vim.pack.add({ + "https://github.com/nvim-treesitter/nvim-treesitter", +}, { confirm = false }) + +vim.pack.add({ + "https://github.com/zenbones-theme/zenbones.nvim", +}, { load = false }) + +require("mo.zen").setup("seoulbones") + +require("vim._extui").enable({}) +vim.cmd([[ packadd! nvim.undotree ]]) + +vim.cmd([[ +nnoremap <expr> [e '<Cmd>.move --' . v:count1 . '<CR>' +nnoremap <expr> ]e '<Cmd>.move +' . v:count1 . '<CR>' +xnoremap <expr> [e ':move --' . v:count1 . '<CR>gv' +xnoremap <expr> ]e ':move +' . (v:count1 + line('''>') - line('''<')) . '<CR>gv' + +function! Sort(type, ...) abort + '[,']sort + call setpos('.', getpos("''")) +endfunction +nnoremap gs m'<Cmd>set operatorfunc=Sort<CR>g@ +xnoremap gs :sort<CR> +]]) + +vim.keymap.set("n", "gK", "K") + +vim.o.breakindent = true +-- Every wrapped line will continue visually indented (same amount of +-- space as the beginning of that line), thus preserving horizontal +-- blocks of text. + +vim.o.cinoptions = "l1,:0,g0,E-s,N-s,t0,(s,J1,j1" +-- The 'cinoptions' affect the way 'cindent' reindents lines in a C +-- program. + +vim.o.colorcolumn = "+1" +-- 'colorcolumn' is a comma-separated list of screen columns that are +-- highlighted with ColorColumn |hl-ColorColumn|. Useful to align +-- text. Will make screen redrawing slower. +-- The screen column can be an absolute number, or a number preceded with +-- '+' or '-', which is added to or subtracted from 'textwidth'. +-- When 'textwidth' is zero then the items with '-' and '+' are not used. + +vim.o.completeopt = "menu,menuone,preview,noselect,fuzzy" +-- 'completeopt' 'cot' string (default "menu,popup") +-- global or local to buffer |global-local| +-- A comma-separated list of options for Insert mode completion +-- |ins-completion|. The supported values are: +-- +-- fuzzy Enable |fuzzy-matching| for completion candidates. This +-- allows for more flexible and intuitive matching, where +-- characters can be skipped and matches can be found even +-- if the exact sequence is not typed. +-- +-- longest +-- When 'autocomplete' is not active, only the longest common +-- prefix of the matches is inserted. If the popup menu is +-- displayed, you can use CTRL-L to add more characters. +-- Whether case is ignored depends on the type of completion. +-- For buffer text the 'ignorecase' option applies. +-- +-- When 'autocomplete' is active and no completion item is +-- selected, the longest common prefix of the matches is +-- inserted after the cursor. The prefix is taken either +-- from all displayed items or only from items in the current +-- buffer. The inserted text is highlighted with +-- |hl-PreInsert|, and the cursor position does not change +-- (similar to `"preinsert"`). Press CTRL-Y to accept. +-- See also |preinserted()|. +-- +-- menu Use a popup menu to show the possible completions. The +-- menu is only shown when there is more than one match and +-- sufficient colors are available. |ins-completion-menu| +-- +-- menuone Use the popup menu also when there is only one match. +-- Useful when there is additional information about the +-- match, e.g., what file it comes from. +-- +-- nearest Matches are listed based on their proximity to the cursor +-- position, unlike the default behavior, which only +-- considers proximity for matches appearing below the +-- cursor. This applies only to matches from the current +-- buffer. No effect if "fuzzy" is present. +-- +-- noinsert Do not insert any text for a match until the user selects +-- a match from the menu. Only works in combination with +-- "menu" or "menuone". No effect if "longest" is present. +-- +-- noselect Same as "noinsert", except that no menu item is +-- pre-selected. If both "noinsert" and "noselect" are +-- present, "noselect" takes precedence. This is enabled +-- automatically when 'autocomplete' is on, unless +-- "preinsert" is also enabled. +-- +-- nosort Disable sorting of completion candidates based on fuzzy +-- scores when "fuzzy" is enabled. Candidates will appear +-- in their original order. +-- +-- popup Show extra information about the currently selected +-- completion in a popup window. Only works in combination +-- with "menu" or "menuone". Overrides "preview". +-- +-- preinsert +-- Inserts the text of the first completion candidate beyond +-- the current leader, highlighted with |hl-PreInsert|. +-- The cursor does not move. +-- Requires "fuzzy" to be unset, and either "menuone" in +-- 'completeopt' or 'autocomplete' enabled. When +-- 'autocomplete' is enabled, this does not work if +-- 'ignorecase' is set without 'infercase'. +-- See also |preinserted()|. +-- +-- preview Show extra information about the currently selected +-- completion in the preview window. Only works in +-- combination with "menu" or "menuone". +-- +-- Only "fuzzy", "longest", "popup", "preinsert" and "preview" have an +-- effect when 'autocomplete' is enabled. +-- +-- This option does not apply to |cmdline-completion|. See 'wildoptions' +-- for that. +vim.opt.cpoptions:remove("~") +-- 'cpoptions' 'cpo' string (default "aABceFs_") +-- global +-- A sequence of single character flags. When a character is present +-- this indicates Vi-compatible behavior. This is used for things where +-- not being Vi-compatible is mostly or sometimes preferred. +-- 'cpoptions' stands for "compatible-options". +-- Commas can be added for readability. +-- To avoid problems with flags that are added in the future, use the +-- "+=" and "-=" feature of ":set" |add-option-flags|. +vim.o.cursorline = true +vim.o.cursorlineopt = "number" +vim.o.foldlevelstart = 99 +-- 'foldlevelstart' 'fdls' number (default -1) +-- global +-- Sets 'foldlevel' when starting to edit another buffer in a window. +-- Useful to always start editing with all folds closed (value zero), +-- some folds closed (one) or no folds closed (99). +-- This is done before reading any modeline, thus a setting in a modeline +-- overrules this option. Starting to edit a file for |diff-mode| also +-- ignores this option and closes all folds. +-- It is also done before BufReadPre autocommands, to allow an autocmd to +-- overrule the 'foldlevel' value for specific files. +-- When the value is negative, it is not used. +vim.o.foldtext = "" +-- 'foldtext' 'fdt' string (default "foldtext()") +-- local to window +-- An expression which is used to specify the text displayed for a closed +-- fold. The context is set to the script where 'foldexpr' was set, +-- script-local items can be accessed. See |fold-foldtext| for the +-- usage. +-- +-- The expression will be evaluated in the |sandbox| if set from a +-- modeline, see |sandbox-option|. +-- This option cannot be set in a modeline when 'modelineexpr' is off. +-- +-- It is not allowed to change text or jump to another window while +-- evaluating 'foldtext' |textlock|. +-- +-- When set to an empty string, foldtext is disabled, and the line +-- is displayed normally with highlighting and no line wrapping. +vim.o.ignorecase = true +-- 'ignorecase' 'ic' boolean (default off) +-- global +-- Ignore case in search patterns, |cmdline-completion|, when +-- searching in the tags file, |expr-==| and for Insert-mode completion +-- |ins-completion|. +-- Also see 'smartcase' and 'tagcase'. +-- Can be overruled by using "\c" or "\C" in the pattern, see +-- |/ignorecase|. +vim.o.smartcase = true +-- Override the 'ignorecase' option if the search pattern contains upper +-- case characters. Only used when the search pattern is typed and +-- 'ignorecase' option is on. Used for the commands "/", "?", "n", "N", +-- ":g" and ":s" and when filtering matches for the completion menu +-- |compl-states|. +-- Not used for "*", "#", "gd", tag search, etc. After "*" and "#" you +-- can make 'smartcase' used by doing a "/" command, recalling the search +-- pattern from history and hitting <Enter>. +vim.o.jumpoptions = "view,clean" +-- 'jumpoptions' 'jop' string (default "clean") +-- global +-- List of words that change the behavior of the |jumplist|. +-- stack Make the jumplist behave like the tagstack. +-- Relative location of entries in the jumplist is +-- preserved at the cost of discarding subsequent entries +-- when navigating backwards in the jumplist and then +-- jumping to a location. |jumplist-stack| +-- +-- view When moving through the jumplist, |changelist|, +-- |alternate-file|, using |mark-motions| or when popping +-- the |tagstack| try to restore the |mark-view| in which +-- the action occurred. +-- +-- clean Remove unloaded buffers from the jumplist. +-- EXPERIMENTAL: this flag may change in the future. +vim.o.linebreak = true +-- 'linebreak' 'lbr' boolean (default off) +-- local to window +-- If on, Vim will wrap long lines at a character in 'breakat' rather +-- than at the last character that fits on the screen. Unlike +-- 'wrapmargin' and 'textwidth', this does not insert <EOL>s in the file, +-- it only affects the way the file is displayed, not its contents. +-- If 'breakindent' is set, line is visually indented. Then, the value +-- of 'showbreak' is used to put in front of wrapped lines. This option +-- is not used when the 'wrap' option is off. +-- Note that <Tab> characters after an <EOL> are mostly not displayed +-- with the right amount of white space. +vim.o.list = true +-- 'list' boolean (default off) +-- local to window +-- List mode: By default, show tabs as ">", trailing spaces as "-", and +-- non-breakable space characters as "+". Useful to see the difference +-- between tabs and spaces and for trailing blanks. Further changed by +-- the 'listchars' option. +-- +-- When 'listchars' does not contain "tab" field, tabs are shown as "^I" +-- or "<09>", like how unprintable characters are displayed. +-- +-- The cursor is displayed at the start of the space a Tab character +-- occupies, not at the end as usual in Normal mode. To get this cursor +-- position while displaying Tabs with spaces, use: >vim +-- set list lcs=tab:\ \ +-- < +-- Note that list mode will also affect formatting (set with 'textwidth' +-- or 'wrapmargin') when 'cpoptions' includes 'L'. See 'listchars' for +-- changing the way tabs are displayed. +vim.opt.listchars:append("precedes:<", "extends:>") +-- 'listchars' 'lcs' string (default "tab:> ,trail:-,nbsp:+") +-- global or local to window |global-local| +-- Strings to use in 'list' mode and for the |:list| command. It is a +-- comma-separated list of string settings. *E1511* +-- +-- *lcs-eol* +-- eol:c Character to show at the end of each line. When +-- omitted, there is no extra character at the end of the +-- line. +-- *lcs-tab* +-- tab:xy[z] Two or three characters to be used to show a tab. +-- The third character is optional. +-- +-- tab:xy The 'x' is always used, then 'y' as many times as will +-- fit. Thus "tab:>-" displays: > +-- > +-- >- +-- >-- +-- etc. +-- < +-- tab:xyz The 'z' is always used, then 'x' is prepended, and +-- then 'y' is used as many times as will fit. Thus +-- "tab:<->" displays: > +-- > +-- <> +-- <-> +-- <--> +-- etc. +-- < +-- When "tab:" is omitted, a tab is shown as ^I. +-- *lcs-space* +-- space:c Character to show for a space. When omitted, spaces +-- are left blank. +-- *lcs-multispace* +-- multispace:c... +-- One or more characters to use cyclically to show for +-- multiple consecutive spaces. Overrides the "space" +-- setting, except for single spaces. When omitted, the +-- "space" setting is used. For example, +-- `:set listchars=multispace:---+` shows ten consecutive +-- spaces as: > +-- ---+---+-- +-- < +-- *lcs-lead* +-- lead:c Character to show for leading spaces. When omitted, +-- leading spaces are blank. Overrides the "space" and +-- "multispace" settings for leading spaces. You can +-- combine it with "tab:", for example: >vim +-- set listchars+=tab:>-,lead:. +-- < +-- *lcs-leadmultispace* +-- leadmultispace:c... +-- Like the |lcs-multispace| value, but for leading +-- spaces only. Also overrides |lcs-lead| for leading +-- multiple spaces. +-- `:set listchars=leadmultispace:---+` shows ten +-- consecutive leading spaces as: > +-- ---+---+--XXX +-- < +-- Where "XXX" denotes the first non-blank characters in +-- the line. +-- *lcs-trail* +-- trail:c Character to show for trailing spaces. When omitted, +-- trailing spaces are blank. Overrides the "space" and +-- "multispace" settings for trailing spaces. +-- *lcs-extends* +-- extends:c Character to show in the last column, when 'wrap' is +-- off and the line continues beyond the right of the +-- screen. +-- *lcs-precedes* +-- precedes:c Character to show in the first visible column of the +-- physical line, when there is text preceding the +-- character visible in the first column. +-- *lcs-conceal* +-- conceal:c Character to show in place of concealed text, when +-- 'conceallevel' is set to 1. A space when omitted. +-- *lcs-nbsp* +-- nbsp:c Character to show for a non-breakable space character +-- (0xA0 (160 decimal) and U+202F). Left blank when +-- omitted. +-- +-- The characters ':' and ',' should not be used. UTF-8 characters can +-- be used. All characters must be single width. *E1512* +-- +-- Each character can be specified as hex: >vim +-- set listchars=eol:\\x24 +-- set listchars=eol:\\u21b5 +-- set listchars=eol:\\U000021b5 +-- < Note that a double backslash is used. The number of hex characters +-- must be exactly 2 for \\x, 4 for \\u and 8 for \\U. +-- +-- Examples: >vim +-- set lcs=tab:>-,trail:- +-- set lcs=tab:>-,eol:<,nbsp:% +-- set lcs=extends:>,precedes:< +-- < |hl-NonText| highlighting will be used for "eol", "extends" and +-- "precedes". |hl-Whitespace| for "nbsp", "space", "tab", "multispace", +-- "lead" and "trail". +vim.o.number = true +vim.o.pumheight = 10 +-- 'pumheight' 'ph' number (default 0) +-- global +-- Maximum number of items to show in the popup menu +-- (|ins-completion-menu|). Zero means "use available screen space". +vim.o.scrolloff = 2 +-- 'scrolloff' 'so' number (default 0) +-- global or local to window |global-local| +-- Minimal number of screen lines to keep above and below the cursor. +-- This will make some context visible around where you are working. If +-- you set it to a very large value (999) the cursor line will always be +-- in the middle of the window (except at the start or end of the file or +-- when long lines wrap). +-- After using the local value, go back the global value with one of +-- these two: >vim +-- setlocal scrolloff< +-- setlocal scrolloff=-1 +-- < For scrolling horizontally see 'sidescrolloff'. +vim.o.shada = + "'100,<50,s10,:100,/100,h,r/tmp/,r/private/,rfugitive:,rzipfile:,rterm:" +-- 'shada' 'sd' string (default for +-- Win32: !,'100,<50,s10,h,rA:,rB: +-- others: !,'100,<50,s10,h) +-- global +-- When non-empty, the shada file is read upon startup and written +-- when exiting Vim (see |shada-file|). The string should be a comma- +-- separated list of parameters, each consisting of a single character +-- identifying the particular parameter, followed by a number or string +-- which specifies the value of that parameter. If a particular +-- character is left out, then the default value is used for that +-- parameter. The following is a list of the identifying characters and +-- the effect of their value. +-- CHAR VALUE ~ +-- *shada-!* +-- ! When included, save and restore global variables that start +-- with an uppercase letter, and don't contain a lowercase +-- letter. Thus "KEEPTHIS and "K_L_M" are stored, but "KeepThis" +-- and "_K_L_M" are not. Nested List and Dict items may not be +-- read back correctly, you end up with an empty item. +-- *shada-quote* +-- " Maximum number of lines saved for each register. Old name of +-- the '<' item, with the disadvantage that you need to put a +-- backslash before the ", otherwise it will be recognized as the +-- start of a comment! +-- *shada-%* +-- % When included, save and restore the buffer list. If Vim is +-- started with a file name argument, the buffer list is not +-- restored. If Vim is started without a file name argument, the +-- buffer list is restored from the shada file. Quickfix +-- ('buftype'), unlisted ('buflisted'), unnamed and buffers on +-- removable media (|shada-r|) are not saved. +-- When followed by a number, the number specifies the maximum +-- number of buffers that are stored. Without a number all +-- buffers are stored. +-- *shada-'* +-- ' Maximum number of previously edited files for which the marks +-- are remembered. This parameter must always be included when +-- 'shada' is non-empty. +-- If non-zero, then the |jumplist| and the |changelist| are also +-- stored in the shada file. +-- *shada-/* +-- / Maximum number of items in the search pattern history to be +-- saved. If non-zero, then the previous search and substitute +-- patterns are also saved. When not included, the value of +-- 'history' is used. +-- *shada-:* +-- : Maximum number of items in the command-line history to be +-- saved. When not included, the value of 'history' is used. +-- *shada-<* +-- < Maximum number of lines saved for each register. If zero then +-- registers are not saved. When not included, all lines are +-- saved. '"' is the old name for this item. +-- Also see the 's' item below: limit specified in KiB. +-- *shada-@* +-- @ Maximum number of items in the input-line history to be +-- saved. When not included, the value of 'history' is used. +-- *shada-c* +-- c Dummy option, kept for compatibility reasons. Has no actual +-- effect: ShaDa always uses UTF-8 and 'encoding' value is fixed +-- to UTF-8 as well. +-- *shada-f* +-- f Whether file marks need to be stored. If zero, file marks ('0 +-- to '9, 'A to 'Z) are not stored. When not present or when +-- non-zero, they are all stored. '0 is used for the current +-- cursor position (when exiting or when doing |:wshada|). +-- *shada-h* +-- h Disable the effect of 'hlsearch' when loading the shada +-- file. When not included, it depends on whether ":nohlsearch" +-- has been used since the last search command. +-- *shada-n* +-- n Name of the shada file. The name must immediately follow +-- the 'n'. Must be at the end of the option! If the +-- 'shadafile' option is set, that file name overrides the one +-- given here with 'shada'. Environment variables are +-- expanded when opening the file, not when setting the option. +-- *shada-r* +-- r Removable media. The argument is a string (up to the next +-- ','). This parameter can be given several times. Each +-- specifies the start of a path for which no marks will be +-- stored. This is to avoid removable media. For Windows you +-- could use "ra:,rb:". You can also use it for temp files, +-- e.g., for Unix: "r/tmp". Case is ignored. +-- *shada-s* +-- s Maximum size of an item contents in KiB. If zero then nothing +-- is saved. Unlike Vim this applies to all items, except for +-- the buffer list and header. Full item size is off by three +-- unsigned integers: with `s10` maximum item size may be 1 byte +-- (type: 7-bit integer) + 9 bytes (timestamp: up to 64-bit +-- integer) + 3 bytes (item size: up to 16-bit integer because +-- 2^8 < 10240 < 2^16) + 10240 bytes (requested maximum item +-- contents size) = 10253 bytes. +-- +-- Example: >vim +-- set shada='50,<1000,s100,:0,n~/nvim/shada +-- < +-- '50 Marks will be remembered for the last 50 files you +-- edited. +-- <1000 Contents of registers (up to 1000 lines each) will be +-- remembered. +-- s100 Items with contents occupying more then 100 KiB are +-- skipped. +-- :0 Command-line history will not be saved. +-- n~/nvim/shada The name of the file to use is "~/nvim/shada". +-- no / Since '/' is not specified, the default will be used, +-- that is, save all of the search history, and also the +-- previous search and substitute patterns. +-- no % The buffer list will not be saved nor read back. +-- no h 'hlsearch' highlighting will be restored. +-- +-- When setting 'shada' from an empty value you can use |:rshada| to +-- load the contents of the file, this is not done automatically. +-- +-- This option cannot be set from a |modeline| or in the |sandbox|, for +-- security reasons. +vim.o.sidescrolloff = 5 +-- 'sidescrolloff' 'siso' number (default 0) +-- global or local to window |global-local| +-- The minimal number of screen columns to keep to the left and to the +-- right of the cursor if 'nowrap' is set. Setting this option to a +-- value greater than 0 while having 'sidescroll' also at a non-zero +-- value makes some context visible in the line you are scrolling in +-- horizontally (except at beginning of the line). Setting this option +-- to a large value (like 999) has the effect of keeping the cursor +-- horizontally centered in the window, as long as one does not come too +-- close to the beginning of the line. +-- After using the local value, go back the global value with one of +-- these two: >vim +-- setlocal sidescrolloff< +-- setlocal sidescrolloff=-1 +-- < +-- Example: Try this together with 'sidescroll' and 'listchars' as in the +-- following example to never allow the cursor to move onto the +-- "extends" character: >vim +-- +-- set nowrap sidescroll=1 listchars=extends:>,precedes:< +-- set sidescrolloff=1 +-- < +vim.o.smartcase = true +-- 'smartcase' 'scs' boolean (default off) +-- global +-- Override the 'ignorecase' option if the search pattern contains upper +-- case characters. Only used when the search pattern is typed and +-- 'ignorecase' option is on. Used for the commands "/", "?", "n", "N", +-- ":g" and ":s" and when filtering matches for the completion menu +-- |compl-states|. +-- Not used for "*", "#", "gd", tag search, etc. After "*" and "#" you +-- can make 'smartcase' used by doing a "/" command, recalling the search +-- pattern from history and hitting <Enter>. +vim.o.smoothscroll = true +-- 'smoothscroll' 'sms' boolean (default off) +-- local to window +-- Scrolling works with screen lines. When 'wrap' is set and the first +-- line in the window wraps part of it may not be visible, as if it is +-- above the window. "<<<" is displayed at the start of the first line, +-- highlighted with |hl-NonText|. +-- You may also want to add "lastline" to the 'display' option to show as +-- much of the last line as possible. +-- NOTE: partly implemented, doesn't work yet for |gj| and |gk|. +vim.o.splitright = true +-- 'splitright' 'spr' boolean (default off) +-- global +-- When on, splitting a window will put the new window right of the +-- current one. |:vsplit| +vim.o.statuscolumn = "%s%=%l%{%&nu||&rnu?'%#WinSeparator#│':''%}" +-- 'statuscolumn' 'stc' string (default "") +-- local to window +-- When non-empty, this option determines the content of the area to the +-- side of a window, normally containing the fold, sign and number columns. +-- The format of this option is like that of 'statusline'. +-- +-- Some of the items from the 'statusline' format are different for +-- 'statuscolumn': +-- +-- %l line number column for currently drawn line +-- %s sign column for currently drawn line +-- %C fold column for currently drawn line +-- +-- The 'statuscolumn' width follows that of the default columns and +-- adapts to the 'numberwidth', 'signcolumn' and 'foldcolumn' option values +-- (regardless of whether the sign and fold items are present). +-- Additionally, the 'statuscolumn' grows with the size of the evaluated +-- format string, up to a point (following the maximum size of the default +-- fold, sign and number columns). Shrinking only happens when the number +-- of lines in a buffer changes, or the 'statuscolumn' option is set. +-- +-- The |v:lnum| variable holds the line number to be drawn. +-- The |v:relnum| variable holds the relative line number to be drawn. +-- The |v:virtnum| variable is negative when drawing virtual lines, zero +-- when drawing the actual buffer line, and positive when +-- drawing the wrapped part of a buffer line. +-- +-- When using |v:relnum|, keep in mind that cursor movement by itself will +-- not cause the 'statuscolumn' to update unless 'relativenumber' is set. +-- +-- NOTE: The %@ click execute function item is supported as well but the +-- specified function will be the same for each row in the same column. +-- It cannot be switched out through a dynamic 'statuscolumn' format, the +-- handler should be written with this in mind. +-- +-- Examples: >vim +-- " Line number with bar separator and click handlers: +-- set statuscolumn=%@SignCb@%s%=%T%@NumCb@%l│%T +-- +-- " Line numbers in hexadecimal for non wrapped part of lines: +-- let &stc='%=%{v:virtnum>0?"":printf("%x",v:lnum)} ' +-- +-- " Human readable line numbers with thousands separator: +-- let &stc='%{substitute(v:lnum,"\\d\\zs\\ze\\' +-- . '%(\\d\\d\\d\\)\\+$",",","g")}' +-- +-- " Both relative and absolute line numbers with different +-- " highlighting for odd and even relative numbers: +-- let &stc='%#NonText#%{&nu?v:lnum:""}' . +-- '%=%{&rnu&&(v:lnum%2)?"\ ".v:relnum:""}' . +-- '%#LineNr#%{&rnu&&!(v:lnum%2)?"\ ".v:relnum:""}' +-- +-- < WARNING: this expression is evaluated for each screen line so defining +-- an expensive expression can negatively affect render performance. +-- +vim.o.tagcase = "match" +-- 'tagcase' 'tc' string (default "followic") +-- global or local to buffer |global-local| +-- This option specifies how case is handled when searching the tags +-- file: +-- followic Follow the 'ignorecase' option +-- followscs Follow the 'smartcase' and 'ignorecase' options +-- ignore Ignore case +-- match Match case +-- smart Ignore case unless an upper case letter is used +vim.o.title = true +-- 'title' boolean (default off) +-- global +-- When on, the title of the window will be set to the value of +-- 'titlestring' (if it is not empty), or to: +-- filename [+=-] (path) - Nvim +-- Where: +-- filename the name of the file being edited +-- - indicates the file cannot be modified, 'ma' off +-- + indicates the file was modified +-- = indicates the file is read-only +-- =+ indicates the file is read-only and modified +-- (path) is the path of the file being edited +-- - Nvim the server name |v:servername| or "Nvim" +vim.o.undofile = true +-- 'undofile' 'udf' boolean (default off) +-- local to buffer +-- When on, Vim automatically saves undo history to an undo file when +-- writing a buffer to a file, and restores undo history from the same +-- file on buffer read. +-- The directory where the undo file is stored is specified by 'undodir'. +-- For more information about this feature see |undo-persistence|. +-- The undo file is not read when 'undoreload' causes the buffer from +-- before a reload to be saved for undo. +-- When 'undofile' is turned off the undo file is NOT deleted. +vim.o.updatetime = 250 +-- 'updatetime' 'ut' number (default 4000) +-- global +-- If this many milliseconds nothing is typed the swap file will be +-- written to disk (see |crash-recovery|). Also used for the +-- |CursorHold| autocommand event. +vim.opt.wildignore:append({ "*.pyc", "__pycache__", "*~", "#*#", "*.o" }) +-- 'wildignore' 'wig' string (default "") +-- global +-- A list of file patterns. A file that matches with one of these +-- patterns is ignored when expanding |wildcards|, completing file or +-- directory names, and influences the result of |expand()|, |glob()| and +-- |globpath()| unless a flag is passed to disable this. +-- The pattern is used like with |:autocmd|, see |autocmd-pattern|. +-- Also see 'suffixes'. +-- Example: >vim +-- set wildignore=*.o,*.obj +-- < The use of |:set+=| and |:set-=| is preferred when adding or removing +-- a pattern from the list. This avoids problems when a future version +-- uses another default. +vim.o.wildignorecase = true +-- 'wildignorecase' 'wic' boolean (default off) +-- global +-- When set case is ignored when completing file names and directories. +-- Has no effect when 'fileignorecase' is set. +-- Does not apply when the shell is used to expand wildcards, which +-- happens when there are special characters. +vim.o.wildmode = "longest:full,full" +-- 'wildmode' 'wim' string (default "full") +-- global +-- Completion mode used for the character specified with 'wildchar'. +-- This option is a comma-separated list of up to four parts, +-- corresponding to the first, second, third, and fourth presses of +-- 'wildchar'. Each part is a colon-separated list of completion +-- behaviors, which are applied simultaneously during that phase. +-- +-- The possible behavior values are: +-- "" Only complete (insert) the first match. No further +-- matches are cycled or listed. +-- "full" Complete the next full match. Cycles through all +-- matches, returning to the original input after the +-- last match. If 'wildmenu' is enabled, it will be +-- shown. +-- "longest" Complete to the longest common substring. If this +-- doesn't extend the input, the next 'wildmode' part is +-- used. +-- "list" If multiple matches are found, list all of them. +-- "lastused" When completing buffer names, sort them by most +-- recently used (excluding the current buffer). Only +-- applies to buffer name completion. +-- "noselect" If 'wildmenu' is enabled, show the menu but do not +-- preselect the first item. +-- If only one match exists, it is completed fully, unless "noselect" is +-- specified. +-- +-- Some useful combinations of colon-separated values: +-- "longest:full" Start with the longest common string and show +-- 'wildmenu' (if enabled). Does not cycle +-- through full matches. +-- "list:full" List all matches and complete first match. +-- "list:longest" List all matches and complete till the longest +-- common prefix. +-- "list:lastused" List all matches. When completing buffers, +-- sort them by most recently used (excluding the +-- current buffer). +-- "noselect:lastused" Do not preselect the first item in 'wildmenu' +-- if it is active. When completing buffers, +-- sort them by most recently used (excluding the +-- current buffer). +-- +-- Examples: >vim +-- set wildmode=full +-- < Complete full match on every press (default behavior) >vim +-- set wildmode=longest,full +-- < First press: longest common substring +-- Second press: cycle through full matches >vim +-- set wildmode=list:full +-- < First press: list all matches and complete the first one >vim +-- set wildmode=list,full +-- < First press: list matches only +-- Second press: complete full matches >vim +-- set wildmode=longest,list +-- < First press: longest common substring +-- Second press: list all matches >vim +-- set wildmode=noselect:full +-- < First press: show 'wildmenu' without completing or selecting +-- Second press: cycle full matches >vim +-- set wildmode=noselect:lastused,full +-- < Same as above, but buffer matches are sorted by time last used +-- More info here: |cmdline-completion|. +vim.o.winborder = "none" +-- 'winborder' string (default "") +-- global +-- Defines the default border style of floating windows. The default value +-- is empty, which is equivalent to "none". Valid values include: +-- - "bold": Bold line box. +-- - "double": Double-line box. +-- - "none": No border. +-- - "rounded": Like "single", but with rounded corners ("╭" etc.). +-- - "shadow": Drop shadow effect, by blending with the background. +-- - "single": Single-line box. +-- - "solid": Adds padding by a single whitespace cell. +-- - custom: comma-separated list of exactly 8 characters in clockwise +-- order starting from topleft. Example: >lua +-- vim.o.winborder='+,-,+,|,+,-,+,|' +-- < diff --git a/nvim/dot-config/nvim-final/lua/mo/zen.lua b/nvim/dot-config/nvim-final/lua/mo/zen.lua new file mode 100644 index 0000000..eb674ba --- /dev/null +++ b/nvim/dot-config/nvim-final/lua/mo/zen.lua @@ -0,0 +1,89 @@ +local M = {} +M.themes = { + dark = { + "seoulbones", + "rosebones", + "forestbones", + "zenwritten", + }, + light = { + "seoulbones", + "vimbones", + "rosebones", + "forestbones", + }, +} +M.current = { + dark = 1, + light = 1, +} +M.bg = "dark" + +M.cycle = function() + M.current[M.bg] = M.current[M.bg] + 1 + if M.current[M.bg] > #M.themes[M.bg] then M.current[M.bg] = 1 end + M.set() +end + +M.set = function() + vim.o.background = M.bg + local theme = M.themes[M.bg][M.current[M.bg]] + vim.print("Switching to " .. theme) + + vim.g[theme .. "_compat"] = 1 + vim.cmd.colorscheme(theme) + + -- make strings nonitalic + local str_highlight = + vim.api.nvim_get_hl(0, { name = "String", link = false }) + vim.api.nvim_set_hl( + 0, + "String", + { fg = str_highlight.fg, italic = false, force = true } + ) + + -- make booleans nonitalic and bold + local bool_highlight = + vim.api.nvim_get_hl(0, { name = "Boolean", link = false }) + vim.api.nvim_set_hl( + 0, + "Boolean", + { fg = bool_highlight.fg, italic = false, bold = true, force = true } + ) + + -- make normals in seoulbones darker + if theme == "seoulbones" and M.bg == "dark" then + local norm_highlight = + vim.api.nvim_get_hl(0, { name = "Normal", link = false }) + vim.api.nvim_set_hl( + 0, + "Normal", + { fg = norm_highlight.fg, bg = "#313131", force = true } + ) + end +end + +M.togglebg = function() + M.bg = M.bg == "dark" and "light" or "dark" + M.set() +end + +---@param theme string? +---@param bg "dark"|"light"|nil +M.setup = function(theme, bg) + vim.cmd("packadd zenbones.nvim") + if bg then M.bg = bg end + if theme then + for i, th in ipairs(M.themes[M.bg]) do + if th == theme then + M.current[M.bg] = i + break + end + end + end + M.set() + vim.keymap.set("n", "<F3>", M.cycle, {}) + vim.keymap.set("n", "<F12>", M.togglebg, {}) +end + +return M diff --git a/nvim/dot-config/nvim-final/nvim-pack-lock.json b/nvim/dot-config/nvim-final/nvim-pack-lock.json new file mode 100644 index 0000000..506d313 --- /dev/null +++ b/nvim/dot-config/nvim-final/nvim-pack-lock.json @@ -0,0 +1,12 @@ +{ + "plugins": { + "nvim-treesitter": { + "rev": "300b906a9514d5e0ce02911d371445382fe35a31", + "src": "https://github.com/nvim-treesitter/nvim-treesitter" + }, + "zenbones.nvim": { + "rev": "4635a3f46d1066975d1074cd9f61f93cb1e32f64", + "src": "https://github.com/zenbones-theme/zenbones.nvim" + } + } +}
\ No newline at end of file diff --git a/nvim/dot-config/nvim-final/plugin/autocommands.lua b/nvim/dot-config/nvim-final/plugin/autocommands.lua new file mode 100644 index 0000000..b64ac07 --- /dev/null +++ b/nvim/dot-config/nvim-final/plugin/autocommands.lua @@ -0,0 +1,7 @@ +vim.api.nvim_create_autocmd("BufWritePre", { + pattern = "*", + callback = function(ev) + vim.cmd('execute "normal! mz" | keeppatterns %s/\\v\\s+$//e | normal `z') + end, + desc = "Strip whitespace from file" +}) diff --git a/nvim/dot-config/nvim-final/stylua.toml b/nvim/dot-config/nvim-final/stylua.toml new file mode 100644 index 0000000..4ac5841 --- /dev/null +++ b/nvim/dot-config/nvim-final/stylua.toml @@ -0,0 +1,12 @@ +call_parentheses = "Always" +collapse_simple_statement = "Always" +column_width = 80 +indent_type = "Spaces" +indent_width = 4 +line_endings = "Unix" +quote_style = "AutoPreferDouble" +space_after_function_names = "Never" +syntax = "LuaJIT" + +[sort_requires] +enabled = true diff --git a/qute/dot-config/qutebrowser/autoconfig.yml b/qute/dot-config/qutebrowser/autoconfig.yml new file mode 100644 index 0000000..46b73d3 --- /dev/null +++ b/qute/dot-config/qutebrowser/autoconfig.yml @@ -0,0 +1,34 @@ +# If a config.py file exists, this file is ignored unless it's explicitly loaded +# via config.load_autoconfig(). For more information, see: +# https://github.com/qutebrowser/qutebrowser/blob/main/doc/help/configuring.asciidoc#loading-autoconfigyml +# DO NOT edit this file by hand, qutebrowser will overwrite it. +# Instead, create a config.py - see :help for details. + +config_version: 2 +settings: + content.blocking.hosts.lists: + global: + - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts + content.headers.user_agent: + https://accounts.google.com/*: Mozilla/5.0 ({os_info}; rv:131.0) Gecko/20100101 + Firefox/131.0 + content.javascript.clipboard: + https://github.com: access-paste + content.notifications.enabled: + https://web.whatsapp.com: true + content.register_protocol_handler: + https://calendar.google.com?cid=%25s: true + https://outlook.office.com?mailtouri=%25s: false + content.user_stylesheets: + global: null + downloads.location.suggestion: + global: both + spellcheck.languages: + global: + - en-US + tabs.last_close: + global: close + url.default_page: + global: file:///home/moreka/.config/qutebrowser/startpage.html + url.start_pages: + global: file:///home/moreka/.config/qutebrowser/startpage.html diff --git a/qute/dot-config/qutebrowser/config.py b/qute/dot-config/qutebrowser/config.py index 1a5c3ee..54f3f6d 100644 --- a/qute/dot-config/qutebrowser/config.py +++ b/qute/dot-config/qutebrowser/config.py @@ -18,6 +18,10 @@ c.completion.open_categories = [ "filesystem", ] +c.new_instance_open_target = "tab-bg" + +c.tabs.show = "multiple" + config.load_autoconfig() # load settings done via the gui config.bind( @@ -37,13 +41,34 @@ config.bind( "spawn --userscript qute-pass --otp-only --username-pattern='login: (.*)' --username-target=secret", ) +config.bind( + ",m", + "spawn mpv {url}", +) + +config.bind( + ",M", + "hint links spawn spawn mpv {hint-url}", +) + c.editor.command = ["alacritty", "-e", "nvim", "{file}", "-c", "normal {line}G{column}"] +c.colors.statusbar.private.bg = "#CF87E8" + +c.colors.webpage.preferred_color_scheme = "dark" +# c.colors.webpage.darkmode.enabled = True +# c.colors.webpage.darkmode.algorithm = "lightness-cielab" +# c.colors.webpage.darkmode.threshold.foreground = 150 +# c.colors.webpage.darkmode.threshold.background = 100 +# c.colors.webpage.darkmode.policy.images = "smart" + +# config.set("colors.webpage.bg", "#282828") + # NOTE: to make Slack sign-in work: -# c.content.unknown_url_scheme_policy = "allow-all" +c.content.unknown_url_scheme_policy = "allow-all" c.content.blocking.enabled = True -c.content.blocking.method = "adblock" +c.content.blocking.method = "both" # c.content.blocking.adblock.lists = [ # "https://github.com/uBlockOrigin/uAssets/raw/master/filters/legacy.txt", diff --git a/qute/dot-config/qutebrowser/greasemonkey/whatsapp.js b/qute/dot-config/qutebrowser/greasemonkey/whatsapp.js new file mode 100644 index 0000000..a7c9a42 --- /dev/null +++ b/qute/dot-config/qutebrowser/greasemonkey/whatsapp.js @@ -0,0 +1,29 @@ +// ==UserScript== +// @name Whatsapp quircks +// @version 1.0.0 +// @description Some Whatsapp quircks that I have to set +// @author moreka +// @match *://*.whatsapp.com/* +// @run-at document-end +// ==/UserScript== + +(function() { + 'use strict'; + + document.addEventListener('load', () => { + if (document.getElementById("farsi-style") === null) { + var style = document.createElement('style'); + style.id = "farsi-style"; + style.innerHTML = `span[data-testid="selectable-text"][dir="rtl"] span { + font-family: "Vazirmatn RD UI" !important; + } + span[dir="rtl"] { + font-family: "Vazirmatn RD UI" !important; + } + footer p[dir="rtl"] span { + font-family: "Vazirmatn RD UI" !important; + }`; + document.head.appendChild(style); + } + }, true); +})(); diff --git a/qute/dot-config/qutebrowser/greasemonkey/yt-ads.js b/qute/dot-config/qutebrowser/greasemonkey/yt-ads.js new file mode 100644 index 0000000..db98c6b --- /dev/null +++ b/qute/dot-config/qutebrowser/greasemonkey/yt-ads.js @@ -0,0 +1,227 @@ +// ==UserScript== +// for more updated scripts, see: https://greasyfork.org/en/scripts/by-site/youtube.com +// @name Auto Skip YouTube Ads +// @version 1.1.0 +// @description Speed up and skip YouTube ads automatically +// @author jso8910 and others +// @match *://*.youtube.com/* +// ==/UserScript== + +// NOTE: this is the previous version I had +// document.addEventListener('load', () => { +// const btn = document.querySelector('.videoAdUiSkipButton,.ytp-ad-skip-button-modern') +// if (btn) { +// btn.click() +// } +// const ad = [...document.querySelectorAll('.ad-showing')][0]; +// if (ad) { +// document.querySelector('video').currentTime = 9999999999; +// } +// }, true); + + +// this newer version is from +// https://greasyfork.org/en/scripts/553239-auto-skip-youtube-ads/ + +function skipAd() { + if (checkIsYouTubeShorts()) return + + // This element appears when a video ad appears. + const adShowing = document.querySelector('.ad-showing') + + // Timed pie countdown ad. + const pieCountdown = document.querySelector('.ytp-ad-timed-pie-countdown-container') + + // Survey questions in video player. + const surveyQuestions = document.querySelector('.ytp-ad-survey-questions') + + if (adShowing === null && pieCountdown === null && surveyQuestions === null) return + + const moviePlayerEl = document.querySelector('#movie_player') + let playerEl + let player + + if (isYouTubeMobile || isYouTubeMusic) { + playerEl = moviePlayerEl + player = playerEl + } else { + playerEl = document.querySelector('#ytd-player') + player = playerEl && playerEl.getPlayer() + } + + if (playerEl === null || player === null) { + console.log({ + message: 'Player not found', + timeStamp: getCurrentTimeString() + }) + return + } + + // ad.classList.remove('ad-showing') + + let adVideo = null + + if (pieCountdown === null && surveyQuestions === null) { + adVideo = document.querySelector( + '#ytd-player video.html5-main-video, #song-video video.html5-main-video' + ) + + console.table({ + message: 'Ad video', + video: adVideo !== null, + src: adVideo?.src, + paused: adVideo?.paused, + currentTime: adVideo?.currentTime, + duration: adVideo?.duration, + timeStamp: getCurrentTimeString() + }) + + if (adVideo !== null) { + adVideo.muted = true + } + if (adVideo === null || !adVideo.src || adVideo.paused || isNaN(adVideo.duration)) { + return + } + + console.log({ + message: 'Ad video has finished loading', + timeStamp: getCurrentTimeString() + }) + } + + if (isYouTubeMusic && adVideo !== null) { + adVideo.currentTime = adVideo.duration + + console.table({ + message: 'Ad skipped', + timeStamp: getCurrentTimeString(), + adShowing: adShowing !== null, + pieCountdown: pieCountdown !== null, + surveyQuestions: surveyQuestions !== null + }) + } else { + const videoData = player.getVideoData() + const videoId = videoData.video_id + const start = Math.floor(player.getCurrentTime()) + + if (moviePlayerEl !== null && moviePlayerEl.isSubtitlesOn()) { + window.setTimeout(moviePlayerEl.toggleSubtitlesOn, 1000) + } + + if ('loadVideoWithPlayerVars' in playerEl) { + playerEl.loadVideoWithPlayerVars({ videoId, start }) + } else { + playerEl.loadVideoByPlayerVars({ videoId, start }) + } + + console.table({ + message: 'Ad skipped', + videoId, + start, + title: videoData.title, + timeStamp: getCurrentTimeString(), + adShowing: adShowing !== null, + pieCountdown: pieCountdown !== null, + surveyQuestions: surveyQuestions !== null + }) + } +} + +function checkIsYouTubeShorts() { + return location.pathname.startsWith('/shorts/') +} + +function getCurrentTimeString() { + return new Date().toTimeString().split(' ', 1)[0] +} + +function addCss() { + const adsSelectors = [ + // Ad banner in the upper right corner, above the video playlist. + '#player-ads', + '#panels > ytd-engagement-panel-section-list-renderer[target-id="engagement-panel-ads"]', + + // Masthead ad on home page. + '#masthead-ad', + + // Sponsored ad video items on home page. + // 'ytd-ad-slot-renderer', + + // '.ytp-suggested-action', + '.yt-mealbar-promo-renderer', + + // Featured product ad banner at the bottom left of the video. + '.ytp-featured-product', + + // Products shelf ad banner below the video description. + 'ytd-merch-shelf-renderer', + + // YouTube Music Premium trial promotion dialog, bottom left corner. + 'ytmusic-mealbar-promo-renderer', + + // YouTube Music Premium trial promotion banner on home page. + 'ytmusic-statement-banner-renderer' + ] + const adsSelector = adsSelectors.join(',') + const css = `${adsSelector} { display: none !important; }` + const style = document.createElement('style') + style.textContent = css + document.head.appendChild(style) +} + +/** + * Remove ad elements using JavaScript because these selectors require the use of the CSS + * `:has` selector which is not supported in older browser versions. + */ +function removeAdElements() { + const adSelectors = [ + // Sponsored ad video items on home page. + // ['ytd-rich-item-renderer', '.ytd-ad-slot-renderer'], + + // ['ytd-rich-section-renderer', '.ytd-statement-banner-renderer'], + + // Ad videos on YouTube Shorts. + ['ytd-reel-video-renderer', '.ytd-ad-slot-renderer'] + + // Ad blocker warning dialog. + // ['tp-yt-paper-dialog', '#feedback.ytd-enforcement-message-view-model'], + + // Survey dialog on home page, located at bottom right. + // ['tp-yt-paper-dialog', ':scope > ytd-checkbox-survey-renderer'], + + // Survey to rate suggested content, located at bottom right. + // ['tp-yt-paper-dialog', ':scope > ytd-single-option-survey-renderer'] + ] + for (const adSelector of adSelectors) { + const adEl = document.querySelector(adSelector[0]) + if (adEl === null) continue + const neededEl = adEl.querySelector(adSelector[1]) + if (neededEl === null) continue + adEl.remove() + } +} + +const isYouTubeMobile = location.hostname === 'm.youtube.com' +const isYouTubeDesktop = !isYouTubeMobile + +const isYouTubeMusic = location.hostname === 'music.youtube.com' +const isYouTubeVideo = !isYouTubeMusic + +addCss() + +if (isYouTubeVideo) { +window.setInterval(removeAdElements, 1000) +removeAdElements() +} + +window.setInterval(skipAd, 500) +skipAd() + + +// const observer = new MutationObserver(skipAd) +// observer.observe(document.body, { +// attributes: true, +// attributeFilter: ['class'], +// childList: true, +// subtree: true +// }) diff --git a/qute/dot-config/qutebrowser/quickmarks b/qute/dot-config/qutebrowser/quickmarks new file mode 100644 index 0000000..f1aabfe --- /dev/null +++ b/qute/dot-config/qutebrowser/quickmarks @@ -0,0 +1,13 @@ +vim plaintext mail https://aliquote.org/post/wrap-and-reflow/ +neovim markdown https://aliquote.org/post/neovim-markdown/ +aliquote https://aliquote.org/post/ +color picker https://bottosson.github.io/misc/colorpicker/ +site example http://bettermotherfuckingwebsite.com/ +htmx https://pleasejusttryhtmx.com/ +productivity txt https://jeffhuang.com/productivity_text_file/ +replace js with just html https://www.htmhell.dev/adventcalendar/2025/27/ +christian final lecture https://video.ethz.ch/speakers/lecture/v/:5c417d5c-314b-4f11-bffc-5b3810a08c1a +typography https://practicaltypography.com/ +nice font https://lambdaland.org/posts/2025-06-24_reading_blogs/ +nice https://henry.codes/writing/a-website-to-destroy-all-websites/ +reboot https://takes.jamesomalley.co.uk/p/this-might-be-oversharing diff --git a/qute/dot-config/qutebrowser/startpage.html b/qute/dot-config/qutebrowser/startpage.html new file mode 100644 index 0000000..51b294b --- /dev/null +++ b/qute/dot-config/qutebrowser/startpage.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> + <title>about:blank</title> + <style> + body { + background-color: #2e3440; /* Dark background example */ + /* color: #eceff4; */ + font-family: "Bitter Pro"; + letter-spacing: 1px; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; + } + h1 { + margin: 0; + font-weight: 400; + font-size: 40px; + text-align: center; + color: #f35626; + background-image: -webkit-linear-gradient(92deg, #f35626, #feab3a); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + -webkit-animation: hue 10s infinite linear; + } + + @-webkit-keyframes hue { + from { + -webkit-filter: hue-rotate(0deg); + } + to { + -webkit-filter: hue-rotate(-360deg); + } + } + </style> +</head> +<body> + <h1>Welcome to QuteBrowser!</h1> +</body> +</html> diff --git a/scripts/dot-local/bin/rotdir b/scripts/dot-local/bin/rotdir new file mode 100755 index 0000000..d171f29 --- /dev/null +++ b/scripts/dot-local/bin/rotdir @@ -0,0 +1,12 @@ +#!/bin/sh + +# When I open an image from the file manager in nsxiv (the image viewer), I want +# to be able to press the next/previous keys to key through the rest of the +# images in the same directory. This script "rotates" the content of a +# directory based on the first chosen file, so that if I open the 15th image, +# if I press next, it will go to the 16th etc. Autistic, I know, but this is +# one of the reasons that nsxiv is great for being able to read standard input. + +[ -z "$1" ] && echo "usage: rotdir regex 2>&1" && exit 1 +base="$(basename "$1")" +ls "$PWD" | awk -v BASE="$base" 'BEGIN { lines = ""; m = 0; } { if ($0 == BASE) { m = 1; } } { if (!m) { if (lines) { lines = lines"\n"; } lines = lines""$0; } else { print $0; } } END { print lines; }' diff --git a/scripts/dot-local/bin/screenshot-hypr b/scripts/dot-local/bin/screenshot-hypr new file mode 100755 index 0000000..d949a80 --- /dev/null +++ b/scripts/dot-local/bin/screenshot-hypr @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +OUTPUT_DIR="$HOME/Pictures/scrots" +TIMESTAMP="$(date +'%Y-%m-%d_%H-%M-%S')" +OUTPUT_FILE="$OUTPUT_DIR/screenshot-$TIMESTAMP.png" + +pkill slurp && exit 0 + +MODE="${1:-smart}" +PROCESSING="${2:-slurp}" + +get_rectangles() +{ + local active_workspace=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .activeWorkspace.id') + hyprctl monitors -j | jq -r --arg ws "$active_workspace" '.[] | select(.activeWorkspace.id == ($ws | tonumber)) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"' + hyprctl clients -j | jq -r --arg ws "$active_workspace" '.[] | select(.workspace.id == ($ws | tonumber)) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' +} + +# Select based on mode +case "$MODE" in + region) + wayfreeze & + PID=$! + sleep .1 + SELECTION=$(slurp 2>/dev/null) + kill $PID 2>/dev/null + ;; + windows) + wayfreeze & + PID=$! + sleep .1 + SELECTION=$(get_rectangles | slurp -r 2>/dev/null) + kill $PID 2>/dev/null + ;; + fullscreen) + SELECTION=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x),\(.y) \((.width / .scale) | floor)x\((.height / .scale) | floor)"') + ;; + smart | *) + RECTS=$(get_rectangles) + wayfreeze & + PID=$! + sleep .1 + SELECTION=$(echo "$RECTS" | slurp 2>/dev/null) + kill $PID 2>/dev/null + + # If the selction area is L * W < 20, we'll assume you were trying to select whichever + # window or output it was inside of to prevent accidental 2px snapshots + if [[ "$SELECTION" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+)$ ]]; then + if ((${BASH_REMATCH[3]} * ${BASH_REMATCH[4]} < 20)); then + click_x="${BASH_REMATCH[1]}" + click_y="${BASH_REMATCH[2]}" + + while IFS= read -r rect; do + if [[ "$rect" =~ ^([0-9]+),([0-9]+)[[:space:]]([0-9]+)x([0-9]+) ]]; then + rect_x="${BASH_REMATCH[1]}" + rect_y="${BASH_REMATCH[2]}" + rect_width="${BASH_REMATCH[3]}" + rect_height="${BASH_REMATCH[4]}" + + if ((click_x >= rect_x && click_x < rect_x + rect_width && click_y >= rect_y && click_y < rect_y + rect_height)); then + SELECTION="${rect_x},${rect_y} ${rect_width}x${rect_height}" + break + fi + fi + done <<<"$RECTS" + fi + fi + ;; +esac + +[ -z "$SELECTION" ] && exit 0 + +if [[ $PROCESSING == "slurp" ]]; then + grim -g "$SELECTION" - | + satty --filename - \ + --output-filename "$OUTPUT_FILE" \ + --actions-on-enter="save-to-file,exit" \ + --actions-on-escape="save-to-clipboard,exit" \ + --initial-tool=arrow +else + grim -g "$SELECTION" - | wl-copy +fi diff --git a/scripts/dot-local/bin/shortcuts b/scripts/dot-local/bin/shortcuts new file mode 100755 index 0000000..d5644c0 --- /dev/null +++ b/scripts/dot-local/bin/shortcuts @@ -0,0 +1,46 @@ +#!/bin/sh + +confdir="${XDG_CONFIG_HOME:-$HOME/.config}/shellshort" + +bmdirs="$confdir/bm-dirs" +bmfiles="$confdir/bm-files" + +# Output locations. Unactivated progs should go to /dev/null. +shell_shortcuts="$confdir/shortcutrc" +shell_env_shortcuts="/dev/null" +zsh_named_dirs="/dev/null" +lf_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/lf/shortcutrc" +vim_shortcuts="/dev/null" +qute_shortcuts="/dev/null" +fish_shortcuts="/dev/null" +vifm_shortcuts="/dev/null" + +# Remove, prepare files +rm -f "$lf_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" "$vim_shortcuts" 2>/dev/null +printf "# vim: filetype=sh\\n" >"$fish_shortcuts" +printf "# vim: filetype=sh\\nalias " >"$shell_shortcuts" +printf "# vim: filetype=sh\\n" >"$shell_env_shortcuts" +printf "\" vim: filetype=vim\\n" >"$vifm_shortcuts" + +# Format the `directories` file in the correct syntax and sent it to all three configs. +eval "echo \"$(cat "$bmdirs")\"" | + awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\"); + printf(\"%s=\42cd %s && ls -A\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ; + printf(\"[ -n \42%s\42 ] && export %s=\42%s\42 \n\",\$1,\$1,\$2) >> \"$shell_env_shortcuts\" ; + printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ; + printf(\"abbr %s \42cd %s; and ls -A\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ; + printf(\"map g%s :cd %s<CR>\nmap t%s <tab>:cd %s<CR><tab>\nmap M%s <tab>:cd %s<CR><tab>:mo<CR>\nmap Y%s <tab>:cd %s<CR><tab>:co<CR> \n\",\$1,\$2, \$1, \$2, \$1, \$2, \$1, \$2) >> \"$vifm_shortcuts\" ; + printf(\"config.bind(';%s', \42set downloads.location.directory %s ;; hint links download\42) \n\",\$1,\$2) >> \"$qute_shortcuts\" ; + printf(\"map C%s cd \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ; + printf(\"vim.keymap.set('c', ';%s', '%s', { noremap=true })\n\",\$1,\$2) >> \"$vim_shortcuts\" }" + +# Format the `files` file in the correct syntax and sent it to both configs. +eval "echo \"$(cat "$bmfiles")\"" | + awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\"); + printf(\"%s=\42\$EDITOR %s\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ; + printf(\"[ -n \42%s\42 ] && export %s=\42%s\42 \n\",\$1,\$1,\$2) >> \"$shell_env_shortcuts\" ; + printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ; + printf(\"abbr %s \42\$EDITOR %s\42 \n\",\$1,\$2) >> \"$fish_shortcuts\" ; + printf(\"map %s :e %s<CR> \n\",\$1,\$2) >> \"$vifm_shortcuts\" ; + printf(\"map E%s \$\$EDITOR \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ; + printf(\"vim.keymap.set('c', ';%s', '%s', { noremap=true })\n\",\$1,\$2) >> \"$vim_shortcuts\" }" diff --git a/scripts/dot-local/bin/stowify b/scripts/dot-local/bin/stowify new file mode 100755 index 0000000..fb51025 --- /dev/null +++ b/scripts/dot-local/bin/stowify @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +set -Eeuo pipefail + +if [ $# -lt 2 ]; then + echo "Usage: $0 <source1> [source2 ...] <package_name>" + return 1 +fi + +pkg="${@:$#}" +stowdir="$HOME/dotfiles" +sources=("${@:1:$#-1}") + +mkdir -p "$stowdir/$pkg" + +_stowify_convert_path() { + local rel_path="$1" + local IFS='/' + local parts out_parts part + + read -ra parts <<<"$rel_path" + for part in "${parts[@]}"; do + if [[ $part == .* ]]; then + out_parts+=("dot-${part#.}") + else + out_parts+=("$part") + fi + done + + local out="" + for part in "${out_parts[@]}"; do + if [ -z "$out" ]; then + out="$part" + else + out="$out/$part" + fi + done + printf '%s\n' "$out" +} + +for src in "${sources[@]}"; do + src="$(realpath -m "$src")" # expand to absolute path + + if [ ! -e "$src" ]; then + echo "Error: $src does not exist" + continue + fi + + if [[ $src == "$HOME"/* ]]; then + rel_path="${src#"$HOME"/}" + else + echo "Warning: $src is not under \$HOME — skipping" + continue + fi + + conv_rel_path="$(_stowify_convert_path "$rel_path")" || continue + + dest_path="$stowdir/$pkg/$conv_rel_path" + dest_dir="$(dirname "$dest_path")" + + echo "$dest_dir" + echo "$dest_path" + + mkdir -pv "$dest_dir" || { + echo "Failed to create $dest_dir" + continue + } + mv -v "$src" "$dest_path" || { + echo "Failed to move $src" + continue + } +done + +stow -d "$stowdir" -v --dotfiles "$pkg" diff --git a/scripts/dot-local/bin/update-led-mute b/scripts/dot-local/bin/update-led-mute new file mode 100755 index 0000000..49832e1 --- /dev/null +++ b/scripts/dot-local/bin/update-led-mute @@ -0,0 +1,16 @@ +#!/bin/sh + +case $1 in + source) # mic + val=$(wpctl get-volume '@DEFAULT_AUDIO_SOURCE@' | grep -q MUTED && echo 1 || echo 0) + echo "$val" | sudo tee /sys/class/leds/platform::micmute/brightness + ;; + sink) # speaker + val=$(wpctl get-volume '@DEFAULT_AUDIO_SINK@' | grep -q MUTED && echo 1 || echo 0) + echo "$val" | sudo tee /sys/class/leds/platform::mute/brightness + ;; + *) + echo "Usage: $0 source|sink" + exit 1 + ;; +esac diff --git a/system-notes.md b/system-notes.md new file mode 100644 index 0000000..f53fb0c --- /dev/null +++ b/system-notes.md @@ -0,0 +1,288 @@ +# Archlinux System Setup for Markov + +## `aconfmgr` + +To use, first install from AUR. +Then clone the repo in `~/.config/aconfmgr` and run `aconfmgr apply`. + +## Firefox + +- [arkenfox gui](https://arkenfox.github.io/gui/) +- [arkenfox user.js](https://github.com/arkenfox/user.js/wiki/2.1-User.js) +- See [here](https://github.com/arkenfox/user.js/wiki/4.1-Extensions#-recommended) for uBlock. +- Add +``` +! Those incessant "Sign in with Google" boxes +accounts.google.com/gsi/* +``` + to my custom filters. + +# TODOs + +- complete the script `~/.local/bin/moreka` +- verify if `~/.local/bin/moreka-open` works +- XF86 keys not working... + +# pam + +run `gpg -K --with-keygrip` and get the Keygrip (the one under ssb), put it in +`~/.config/pam-gnupg` + +# oama +oama authorize microsoft moreka@mit.edu --device + +# to clone a git forked repo and add upstream repo as well +```sh +git remote add upstream https://github.com/.../....git +git fetch upstream +git branch -r # gives all branches +git checkout main # or master (my local branch) +git pull --rebase upstream main # or master +git push origin main +``` + +Then, start working on a fix branch: +```sh +git checkout -b feature/my-new-thing +git push -u origin feature/my-new-thing +``` + +From time to time, update the main branch: +```sh +git checkout main +git fetch upstream +git rebase upstream/main +git push origin main +``` +and if the feature branch has diverged +```sh +git checkout feature/my-new-thing +git rebase main +``` + +**Always keep main clean!** + +# bash inputrc + +Some useful stuff here: +``` +C-x p --> edit the path +C-x " --> prepare to type a quoted word +C-x q --> quote the current or previous word +C-x r --> redraw the current line +``` + +# GPG + +```bash +gpg --import your@id.here.pub.asc +gpg --import your@id.here.priv.asc +gpg --import your@id.here.sub_priv.asc +gpg --import-ownertrust ownertrust.txt + +gpg --edit-key your@id.here +``` +```cmd +gpg> trust +Your decision? 5 +``` + +# fingerprint + +1. fprintd, imagemagick installed +2. pam stuff (changed hyprlock and polkit-1): +```sh +cp /usr/share/polkit-1/rules.d/50-default.rules /etc/polkit-1/rules.d/ +``` + +```rules +polkit.addAdminRule(function(action, subject) { + return ["unix-group:wheel"]; +}); +``` + +3. sudo fprintd-enroll -f right-index-finger moreka +4. fprintd-verify +5. sudo fprintd-enroll -f left-index-finger moreka +4. fprintd-verify + +# LESS + +&pattern -> display only matching lines +ESC-u -> toggle search highlight +^O^N -> search forward for OSC8 hyperlink +^O^P -> search backward for OSC8 hyperlink +^O^L -> jump to currently selected OSC8 +^O^O -> open currently selected OSC8 +v -> edit file with editor +| ??? +s -> save to file + +-i -> ignore case + +t, T -> go to next/prev tag +m<letter> -> mark top line +'<letter> -> goto mark +'' -> goto previous pos + +# iPhone + +works surprisingly well! Wow! + +main link: [archwiki](https://wiki.archlinux.org/title/IOS) + +install `libimobiledevice`, `usbmuxd`, and `ifuse`. + +## Mounting iOS + +After connecting, check `systemctl status usbmuxd.service`. It should be running automatically. + +```bash +# pairing +idevicepair pair # might need to enter passcode and trust the computer on iphone +idevicepair validate + +# data +ifuse some_user_mountpoint + +# list apps +ifuse --list-apps +ifuse --documents APPID some_other_mountpoint # wasn't that useful +``` +Pictures/videos are going to be in `DCIM/`. + +When done, `fusermount -u mount_point`. + + +## Backup + +```bash +# to backup +idevicebackup2 backup --full some_folder + +# to restore +idevicebackup2 restore some_folder +``` + +- [GUI for exploring files in a backup](https://github.com/MaxiHuHe04/iTunes-Backup-Explorer) +- [Restoring firmware](https://github.com/libimobiledevice/idevicerestore) (also in the AUR: `idevicerestore-git`) + +# VIM +- Interesting. Vim has a confini filetype (can be used for Python's configparser-type configs) + +- using `:oldfiles`, you can do `:e #<1` to edit the first item (replace 1 with any item number) + +# some links +https://www.youtube.com/watch?v=Jllnhid7O7w + + +# CachyOS Kernel Install +```bash +sudo pacman-key --recv-keys F3B607488DB35A47 --keyserver keyserver.ubuntu.com +sudo pacman-key --lsign-key F3B607488DB35A47 + +sudo pacman -U \ + 'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-keyring-20240331-1-any.pkg.tar.zst' \ + 'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-mirrorlist-22-1-any.pkg.tar.zst' \ + 'https://mirror.cachyos.org/repo/x86_64/cachyos/cachyos-v3-mirrorlist-22-1-any.pkg.tar.zst' +``` + +Then, in `pacman.conf`: +```confini +Architecture = x86_64 x86_64_v3 # replace the existing "auto" + +[multilib] +Include = /etc/pacman.d/mirrorlist + +[cachyos-v3] +Include = /etc/pacman.d/cachyos-v3-mirrorlist + +[cachyos-core-v3] +Include = /etc/pacman.d/cachyos-v3-mirrorlist + +[cachyos-extra-v3] +Include = /etc/pacman.d/cachyos-v3-mirrorlist +``` +Then, +```bash +sudo pacman -Syu +sudo pacman -S linux-cachyos linux-cachyos-headers +``` + +Then, copy the default loader into `/boot/loader/entries/cachyos-kernel.conf` and change: +``` +title Arch Linux (with cachyos kernel) +linux /vmlinuz-linux-cachyos +initrd /initramfs-linux-cachyos.img +options [same as the default] +``` + +# I also installed UEFI shell `edk2-shell` following Archwiki's guide +[link](https://wiki.archlinux.org/title/Systemd-boot#UEFI_Shells_or_other_EFI_applications) + +# Fzflua undotree + +# HDMI sound + +```sh +wpctl status | less +``` +then see what is the default at the bottom and take note of the number of the HDMI output. +After that, use +```sh +wpctl set-default 58 +``` + +# Mirroring + +Use `hyprmon`. Don't forget to apply (`A`). + +# Revert back to markdown todos + +# etc-update from gentoo... check it out (related to `pacdiff` from `pacman-contrib`) + +# mount + +```bash +udiskctl mount -b /dev/sda3 +``` + +# paccat + +# installed HyprDynamicMonitos-bin + +# stow -R for restow + +# qutebrowser +- [Greasemonkey · Issue #926 · darkreader/darkreader](https://github.com/darkreader/darkreader/issues/926#issuecomment-575893299) +- need `python-idna` and `python-tldextract` for the qute-pass userscript to work; see [here](/usr/share/qutebrowser/userscripts/qute-pass:43-52). + +# pasteimg in neovim is on the go! + +# podman + +```sh +pacman -S podman + +``` + +# treesitter-modules.nvim + +# lambda font +```sh +curl -LO https://github.com/glepnir/dotfiles/raw/refs/heads/master/fonts/Lambda/Lambda.ttf +curl -LO https://github.com/glepnir/dotfiles/raw/refs/heads/master/fonts/Lambda/Lambda-Bold.ttf +curl -LO https://github.com/glepnir/dotfiles/raw/refs/heads/master/fonts/Lambda/Lambda-BoldItalic.ttf +curl -LO https://github.com/glepnir/dotfiles/raw/refs/heads/master/fonts/Lambda/Lambda-Italic.ttf +``` + + +# Alacritty.nvim issue repro + + +sudo rsync -avxHAX /home/yourusername/ /path/to/your/backup/location/ + +# Some todos +- call/email US embassy for getting an appointment +- call/email [headstart](https://www.caasomerville.org/head-start/) + diff --git a/waybar/dot-config/waybar/config.jsonc b/waybar/dot-config/waybar/config.jsonc new file mode 100644 index 0000000..6e8d81e --- /dev/null +++ b/waybar/dot-config/waybar/config.jsonc @@ -0,0 +1,139 @@ +{ + "position": "top", + "height": 15, + "spacing": 5, + "reload_style_on_change": true, + "modules-left": [ + "hyprland/workspaces" + // "niri/workspaces" + ], + "modules-center": [ + "hyprland/window" + // "niri/window" + ], + "modules-right": [ + "custom/weather", + "idle_inhibitor", + "wireplumber", + "network", + "power-profiles-daemon", + "backlight", + "hyprland/language", + // "niri/language", + "battery", + "tray", + "clock" + ], + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": "", + "deactivated": "" + } + }, + "tray": { + "icon-size": 12, + "spacing": 5 + }, + "clock": { + "interval": 1, + "format": "{:%a %d %b %H:%M:%S}", + "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>" + }, + "backlight": { + "format": "{percent}% {icon}", + "format-icons": [ + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + "battery": { + "states": { + "warning": 30, + "critical": 10 + }, + "format": "{capacity}% {icon}", + "format-full": "{capacity}% {icon}", + "format-charging": "{capacity}% ", + "format-plugged": "{capacity}% ", + "format-alt": "{power} {icon}", + "format-icons": [ + "", + "", + "", + "", + "" + ] + }, + "power-profiles-daemon": { + "format": "{icon}", + "tooltip-format": "Power profile: {profile}\nDriver: {driver}", + "tooltip": true, + "format-icons": { + "performance": "", + "balanced": "", + "power-saver": "" + } + }, + "network": { + "format-wifi": "{essid} ({signalStrength}%) ", + "format-ethernet": "{ipaddr}/{cidr} ", + "tooltip-format": "{ifname} via {gwaddr} ", + "format-linked": "{ifname} (No IP) ", + "format-disconnected": "Disconnected ⚠", + "format-alt": "{ifname}: {ipaddr}/{cidr}" + }, + "wireplumber": { + "format": "{volume}% {icon}", + "format-muted": "", + "on-click": "app2unit-term -- bash -c 'wpctl status | less'", + "on-click-right": "swayosd-client --output-volume mute-toggle && update-led-mute sink", + "max-volume": 100, + "scroll-step": 5, + "format-icons": { + "headphone": "", + "hands-free": "", + "headset": "", + "phone": "", + "portable": "", + "car": "", + "default": [ + "", + "", + "" + ] + } + }, + "hyprland/language": { + "format": "{}", + "format-en": "en", + "format-fa": "فارسی" + }, + "niri/language": { + "format": "{}", + "format-en": "en", + "format-fa": "فارسی" + }, + "hyprland/window": { + "icon": true, + "icon-size": 13 + }, + "niri/window": { + "icon": true, + "icon-size": 13 + }, + "custom/weather": { + "format": "{}°", + "tooltip": true, + "interval": 3600, + "exec": "wttrbar", + "return-type": "json" + } +} diff --git a/waybar/dot-config/waybar/style.css b/waybar/dot-config/waybar/style.css new file mode 100644 index 0000000..9d5c585 --- /dev/null +++ b/waybar/dot-config/waybar/style.css @@ -0,0 +1,186 @@ +* { + font-family: Hack, Vazirmatn UI; + font-size: 10px; + min-height: 0; + color: #eeeeee; +} + +window#waybar { + /* background: rgba(0, 0, 0, 0.5); */ + background-color: #222222; +} + +tooltip { + background: #000000; + padding: 4px; +} + +tooltip label { + color: white; + padding: 0; + margin: 0; +} + +button { + border: none; + border-radius: 0; +} + +/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ +button:hover { + background: inherit; +} + +#workspaces button { + padding: 0 2px; + background-color: transparent; +} + +#workspaces button label { + color: #bbbbbb; +} + +#workspaces button:hover { + background-color: rgba(0, 0, 0, 0.2); +} + + +#workspaces button.active.empty { + background-color: #005577; +} + +#workspaces button.active:not(.empty) { + background-color: #005577; + background-image: linear-gradient(white, white); /* the square */ + background-repeat: no-repeat; + background-size: 5px 5px; + background-position: 0px 0px; +} + +#workspaces button.active label { + /* font-weight: bolder; */ + color: #eeeeee; +} + +#workspaces button:not(.active):not(.empty) { + background-image: + linear-gradient(white, white), /* top */ + linear-gradient(white, white), /* right */ + linear-gradient(white, white), /* bottom */ + linear-gradient(white, white); /* left */ + background-repeat: no-repeat; + background-size: + 5px 0.5px, /* top border width and thickness */ + 0.5px 5.5px, /* right */ + 5px 0.5px, /* bottom */ + 0.5px 5px; /* left */ + background-position: + 0px 0px, /* top */ + 5px 0px, /* right */ + 0px 5px, /* bottom */ + 0px 0px; /* left */ +} + + +#workspaces button.urgent { + background-color: #eb4d4b; +} + + +#clock, +#battery, +#cpu, +#memory, +#disk, +#temperature, +#backlight, +#network, +#pulseaudio, +#wireplumber, +#custom-media, +#tray, +#mode, +#idle_inhibitor, +#scratchpad, +#power-profiles-daemon, +#mpd { + padding: 0 5px; +} + +#clock { + font-weight: bold; +} + +#window, +#workspaces { + margin: 0 4px; +} + +/* #window { */ +/* font-weight: bold; */ +/* } */ + +/* If workspaces is the leftmost module, omit left margin */ +.modules-left > widget:first-child > #workspaces { + margin-left: 0; +} + +/* If workspaces is the rightmost module, omit right margin */ +.modules-right > widget:last-child > #workspaces { + margin-right: 0; +} + +@keyframes blink { + to { + background-color: #ffffff; + color: #000000; + } +} + +#battery.critical:not(.charging) { + background-color: #f53c3c; + color: #ffffff; + animation-name: blink; + animation-duration: 0.5s; + animation-timing-function: steps(12); + animation-iteration-count: infinite; + animation-direction: alternate; +} + +#power-profiles-daemon.performance { + background-color: #f53c3c; + color: #ffffff; +} + +label:focus { + background-color: #000000; +} + +#temperature.critical { + background-color: #eb4d4b; +} + +#tray > .passive { + -gtk-icon-effect: dim; +} + +#tray > .needs-attention { + -gtk-icon-effect: highlight; + background-color: #eb4d4b; +} + +#idle_inhibitor.activated { + background-color: #ecf0f1; + color: #2d3436; +} + +#workspaces .taskbar-window { + font-weight: normal; + padding-left: 5px; + padding-right: 5px; + margin-right: 0; +} + +#workspaces .taskbar-window.active { + background-color: rgba(255, 255, 255, 0.25); +} diff --git a/wayland-basics/dot-config/autostart/at-spi-dbus-bus.desktop b/wayland-basics/dot-config/autostart/at-spi-dbus-bus.desktop new file mode 100644 index 0000000..9baab50 --- /dev/null +++ b/wayland-basics/dot-config/autostart/at-spi-dbus-bus.desktop @@ -0,0 +1 @@ +Hidden=true diff --git a/wayland-basics/dot-config/kanshi/reload.sh b/wayland-basics/dot-config/kanshi/reload.sh index ce74a3f..e3c7dad 100755 --- a/wayland-basics/dot-config/kanshi/reload.sh +++ b/wayland-basics/dot-config/kanshi/reload.sh @@ -1,6 +1,6 @@ #!/bin/sh -if [ -n "$HYPRLAND_INSTANCE_SIGNATURE" ]; then - hyprctl reload - hyprctl dispatch workspace 1 -fi +# if [ -n "$HYPRLAND_INSTANCE_SIGNATURE" ]; then +# hyprctl reload +# hyprctl dispatch workspace 1 +# fi diff --git a/wayland-basics/dot-config/satty/config.toml b/wayland-basics/dot-config/satty/config.toml new file mode 100644 index 0000000..b558715 --- /dev/null +++ b/wayland-basics/dot-config/satty/config.toml @@ -0,0 +1,24 @@ +[general] +fullscreen = false +early-exit = true +initial-tool = "brush" +copy-command = "wl-copy" +default-hide-toolbars = false +primary-highlighter = "block" +disable-notifications = false +brush-smooth-history-size = 5 + +[font] +family = "IBM Plex Sans" +style = "Regular" + +[color-palette] + +palette = [ + "#ffd700", + "#00ffff", + "#a52a2a", + "#dc143c", + "#ff1493", + "#008000", +] diff --git a/wayland-basics/dot-config/systemd/user/minibar.service b/wayland-basics/dot-config/systemd/user/minibar.service new file mode 100644 index 0000000..2d00d3a --- /dev/null +++ b/wayland-basics/dot-config/systemd/user/minibar.service @@ -0,0 +1,13 @@ +[Unit] +Description=My minimal bar made with GTK4-rs +PartOf=graphical-session.target +After=graphical-session.target +Requisite=graphical-session.target + +[Service] +ExecStart=/home/moreka/.local/bin/minibar +Restart=on-failure +Slice=app-graphical.slice + +[Install] +WantedBy=graphical-session.target diff --git a/wayland-basics/dot-config/systemd/user/swaybg.service b/wayland-basics/dot-config/systemd/user/swaybg.service index 719900d..d8efd5b 100644 --- a/wayland-basics/dot-config/systemd/user/swaybg.service +++ b/wayland-basics/dot-config/systemd/user/swaybg.service @@ -6,8 +6,8 @@ Requisite=graphical-session.target [Service] Type=exec -# ExecStart=/usr/bin/swaybg -m fill -i /home/moreka/Pictures/ethereal.jpg -ExecStart=/usr/bin/swaybg -c '#002B36' +ExecStart=/usr/bin/swaybg -m fill -i /home/moreka/Pictures/wallpapers/dark_mode_windows_xp_background_wallpaper.png +; ExecStart=/usr/bin/swaybg -c '#002B36' Restart=on-failure Slice=background-graphical.slice |
