enabled tailscale
removed the dumb xdg terminal exec flake; look into this later replaced kitty with wezterm as terminal emulator. look into problems with WM-related crashes added gimp, inkscape, factorio, ibm plex fonts to home packages added VISUAL=nvim to bash profile added thunderbird added options to neovim init.lua
This commit is contained in:
parent
31b9d6838b
commit
51c4c60399
|
|
@ -139,6 +139,9 @@
|
||||||
# Enable gvfs; handles trash
|
# Enable gvfs; handles trash
|
||||||
services.gvfs.enable = true;
|
services.gvfs.enable = true;
|
||||||
|
|
||||||
|
# Enable tailscale
|
||||||
|
services.tailscale.enable = true;
|
||||||
|
|
||||||
# Some programs need SUID wrappers, can be configured further or are
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
# started in user sessions.
|
# started in user sessions.
|
||||||
# programs.mtr.enable = true;
|
# programs.mtr.enable = true;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
export PATH="$coreutils/bin"
|
|
||||||
mkdir $out
|
|
||||||
mkdir $out/bin
|
|
||||||
cp $src $out/bin/xdg-terminal-exec
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1704161960,
|
|
||||||
"narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "63143ac2c9186be6d9da6035fa22620018c85932",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
description = "A very basic flake for building xdg-terminal-exec";
|
|
||||||
|
|
||||||
outputs = { self, nixpkgs }: {
|
|
||||||
|
|
||||||
packages.x86_64-linux.xdg-terminal-exec = import ./xdg-terminal-exec.nix (import <nixpkgs>);
|
|
||||||
|
|
||||||
packages.x86_64-linux.default = self.packages.x86_64-linux.xdg-terminal-exec;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/nix/store/gb9xw4vfrq50f63hpzwq1rxda25hjc2k-xdg-terminal-exec
|
|
||||||
|
|
@ -1,599 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Proposal for XDG terminal execution utility
|
|
||||||
#
|
|
||||||
# by Vladimir Kudrya
|
|
||||||
# https://github.com/Vladimir-csp/
|
|
||||||
#
|
|
||||||
# This script is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version. See <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# Contributors:
|
|
||||||
# Roman Chistokhodov https://github.com/FreeSlave/
|
|
||||||
# fluvf https://github.com/fluvf
|
|
||||||
|
|
||||||
# Treat non-zero exit status from simple commands as an error
|
|
||||||
# Treat unset variables as errors when performing parameter expansion
|
|
||||||
# Disable pathname expansion
|
|
||||||
set -euf
|
|
||||||
|
|
||||||
# Store original IFS value, assumed to contain the default: <space><tab><newline>
|
|
||||||
OIFS="$IFS"
|
|
||||||
# Newline, utility variable used throughout the script
|
|
||||||
N='
|
|
||||||
'
|
|
||||||
|
|
||||||
# Utility function to print messages to stderr
|
|
||||||
error() { printf '%s\n' "$@" >&2; }
|
|
||||||
|
|
||||||
check_bool() {
|
|
||||||
case "$1" in
|
|
||||||
true | True | TRUE | yes | Yes | YES | 1) return 0 ;;
|
|
||||||
false | False | FALSE | no | No | NO | 0) return 1 ;;
|
|
||||||
*)
|
|
||||||
error "Assuming '$1' means no"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Utility function to print debug messages to stderr (or not)
|
|
||||||
if check_bool "${DEBUG-0}"; then
|
|
||||||
debug() { printf 'D: %s\n' "$@" >&2; }
|
|
||||||
else
|
|
||||||
debug() { :; }
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Populates global constants and lists for later use and iteration
|
|
||||||
make_paths() {
|
|
||||||
IFS=':'
|
|
||||||
|
|
||||||
# Populate list of config files to read, in descending order of preference
|
|
||||||
for dir in ${XDG_CONFIG_HOME:-"${HOME}/.config"}${IFS}${XDG_CONFIG_DIRS:-/etc/xdg}; do
|
|
||||||
# Normalise base path and append the data subdirectory with a trailing '/'
|
|
||||||
for desktop in ${LOWERCASE_XDG_CURRENT_DESKTOP}; do
|
|
||||||
CONFIGS=${CONFIGS:+${CONFIGS}${IFS}}${dir%/}/${desktop}-xdg-terminals.list
|
|
||||||
done
|
|
||||||
CONFIGS=${CONFIGS:+${CONFIGS}${IFS}}${dir%/}/xdg-terminals.list
|
|
||||||
done
|
|
||||||
|
|
||||||
# Populate list of directories to search for entries in, in ascending order of preference
|
|
||||||
for dir in ${XDG_DATA_HOME:-${HOME}/.local/share}${IFS}${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
|
|
||||||
# Normalise base path and append the data subdirectory with a trailing '/'
|
|
||||||
APPLICATIONS_DIRS=${dir%/}/applications/${APPLICATIONS_DIRS:+${IFS}${APPLICATIONS_DIRS}}
|
|
||||||
done
|
|
||||||
|
|
||||||
# cache
|
|
||||||
XDG_CACHE_HOME=${XDG_CACHE_HOME:-"${HOME}/.cache"}
|
|
||||||
CACHE_FILE="${XDG_CACHE_HOME}/xdg-terminal-exec"
|
|
||||||
|
|
||||||
debug "paths:" "CONFIGS=${CONFIGS}" "APPLICATIONS_DIRS=${APPLICATIONS_DIRS}"
|
|
||||||
}
|
|
||||||
# Mask IFS withing function to allow temporary changes
|
|
||||||
alias make_paths='IFS= make_paths'
|
|
||||||
|
|
||||||
gen_hash() {
|
|
||||||
# return md5 of XDG_CURRENT DESKTOP and ls -LRl output for config and data paths
|
|
||||||
# md5 is 4x faster than sha*, and there is no need for cryptography here
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
read -r hash drop <<- EOH
|
|
||||||
$(
|
|
||||||
hash_paths="${CONFIGS}:${APPLICATIONS_DIRS}"
|
|
||||||
{
|
|
||||||
echo "${XDG_CURRENT_DESKTOP-}"
|
|
||||||
IFS=':'
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
debug "> hashing '${XDG_CURRENT_DESKTOP-}' and listing of:" $hash_paths "^ end of hash listing"
|
|
||||||
# shellcheck disable=SC2012,SC2086
|
|
||||||
LANG=C ls -LRl ${hash_paths} 2> /dev/null
|
|
||||||
} | md5sum 2> /dev/null
|
|
||||||
)
|
|
||||||
EOH
|
|
||||||
case "$hash" in
|
|
||||||
[0-9a-f]??????????????????????????????[0-9a-f])
|
|
||||||
debug "got fresh hash '$hash'"
|
|
||||||
echo "$hash"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
debug "failed to get fresh hash, got '$hash'"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
read_cache() {
|
|
||||||
# reads $cached_hash, $cached_exec, $cached_execarg, $cached_cmd from cache file,
|
|
||||||
# checks if cache is actual and applies it, otherwise returns 1
|
|
||||||
# tries to bail out as soon as possible if something does not fit
|
|
||||||
if [ -f "${CACHE_FILE}" ]; then
|
|
||||||
IFS=${N}
|
|
||||||
line_num=0
|
|
||||||
while read -r line; do
|
|
||||||
line_num=$((line_num + 1))
|
|
||||||
case "${line_num}_${line}" in
|
|
||||||
1_[0-9a-f]??????????????????????????????[0-9a-f]) cached_hash=$line ;;
|
|
||||||
2_*) cached_exec=$line ;;
|
|
||||||
3_ | 3_*) cached_execarg=$line ;;
|
|
||||||
4_*)
|
|
||||||
# get cmd and break right away, line_num will be left at 4
|
|
||||||
cached_cmd=$line
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
debug "cache line ${line_num} is invalid: ${line}"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done < "${CACHE_FILE}"
|
|
||||||
if [ "$line_num" = "4" ]; then
|
|
||||||
debug "got cache:" "${cached_hash}" "${cached_exec}" "${cached_execarg}" "${cached_cmd}"
|
|
||||||
IFS=$OIFS
|
|
||||||
HASH=$(gen_hash) || return 1
|
|
||||||
if [ "$HASH" = "$cached_hash" ] && command -v "$cached_cmd" > /dev/null; then
|
|
||||||
debug "cache is actual"
|
|
||||||
EXEC=${cached_exec}
|
|
||||||
EXECARG=${cached_execarg}
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
debug "cache is out-of-date"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
debug "invalid cache data"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
debug "no cache data"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
# Mask IFS withing function to allow temporary changes
|
|
||||||
alias read_cache='IFS= read_cache'
|
|
||||||
|
|
||||||
save_cache() {
|
|
||||||
# saves $HASH, $EXEC, $EXECARG, $1 (executable) to cache file or removes it if CACHE_ENABLE is false
|
|
||||||
if check_bool "$CACHE_ENABLED"; then
|
|
||||||
[ ! -d "${XDG_CACHE_HOME}" ] && mkdir -p "${XDG_CACHE_HOME}"
|
|
||||||
if [ -z "${HASH-}" ]; then
|
|
||||||
HASH=$(gen_hash) || {
|
|
||||||
echo "could not hash listing, removing '${CACHE_FILE}'" >&2
|
|
||||||
rm -f "${CACHE_FILE}"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
UM=$(umask)
|
|
||||||
umask 0077
|
|
||||||
printf '%s\n' "${HASH}" "${EXEC}" "${EXECARG}" "${1}" > "${CACHE_FILE}"
|
|
||||||
umask "$UM"
|
|
||||||
debug "> saved cache:" "${HASH}" "${EXEC}" "${EXECARG}" "${1}" "^ end of saved cache"
|
|
||||||
else
|
|
||||||
debug "cache is disabled, removing '${CACHE_FILE}'"
|
|
||||||
rm -f "${CACHE_FILE}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse all config files and populate $ENTRY_IDS with read desktop entry IDs
|
|
||||||
read_config_paths() {
|
|
||||||
# All config files are read immediatelly, rather than on demand, even if it's more IO intensive
|
|
||||||
# This way all IDs are already known, and in order of preference, before iterating over them
|
|
||||||
IFS=':'
|
|
||||||
for config_path in ${CONFIGS}; do
|
|
||||||
debug "reading config '$config_path'"
|
|
||||||
# Nonexistant file is not an error
|
|
||||||
[ -f "$config_path" ] || continue
|
|
||||||
# Let `read` trim leading/trailing whitespace from the line
|
|
||||||
while IFS="$OIFS" read -r line; do
|
|
||||||
#debug "read line '$line'"
|
|
||||||
case $line in
|
|
||||||
|
|
||||||
# Catch directives first
|
|
||||||
|
|
||||||
# cache control
|
|
||||||
/enable_cache)
|
|
||||||
debug "found '$line' directive${XTE_CACHE_ENABLED+ (ignored)}"
|
|
||||||
CACHE_ENABLED=${XTE_CACHE_ENABLED-true}
|
|
||||||
;;
|
|
||||||
/disable_cache)
|
|
||||||
debug "found '$line' directive${XTE_CACHE_ENABLED+ (ignored)}"
|
|
||||||
CACHE_ENABLED=${XTE_CACHE_ENABLED-false}
|
|
||||||
;;
|
|
||||||
|
|
||||||
# `[The extensionless entry filename] should be a valid D-Bus well-known name.`
|
|
||||||
# `a sequence of non-empty elements separated by dots (U+002E FULL STOP),
|
|
||||||
# none of which starts with a digit, and each of which contains only characters from the set [a-zA-Z0-9-_]`
|
|
||||||
# Stricter parts seem to be related only to reversed DNS notation but not common naming
|
|
||||||
# i.e. there is `2048-qt.desktop`.
|
|
||||||
# I do not know of any terminal that starts with a number, but it's valid.
|
|
||||||
|
|
||||||
# Catch and validate potential entry ID with action ID (be graceful about an empty one)
|
|
||||||
[a-zA-Z0-9_]*)
|
|
||||||
# consider only the first ':' as a delimiter
|
|
||||||
IFS=':' read -r entry_id action_id <<- EOL
|
|
||||||
$line
|
|
||||||
EOL
|
|
||||||
if validate_entry_id "${entry_id}" && validate_action_id "${action_id}"; then
|
|
||||||
ENTRY_IDS=${ENTRY_IDS:+${ENTRY_IDS}${N}}$line
|
|
||||||
debug "added entry ID with action ID '$line'"
|
|
||||||
else
|
|
||||||
error "Discarded possibly misspelled entry '$line'"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
esac
|
|
||||||
# By default empty lines and comments get ignored
|
|
||||||
done < "$config_path"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
# Mask IFS withing function to allow temporary changes
|
|
||||||
alias read_config_paths='IFS= read_config_paths'
|
|
||||||
|
|
||||||
replace() {
|
|
||||||
# takes $1, finds $2, replaces with $3
|
|
||||||
# does it in large chunks
|
|
||||||
|
|
||||||
# var to be modified
|
|
||||||
string=${1}
|
|
||||||
# right part of string
|
|
||||||
r_string=${1}
|
|
||||||
# left part of string
|
|
||||||
l_string=''
|
|
||||||
# previous right part of string
|
|
||||||
prev_r_string=''
|
|
||||||
while true; do
|
|
||||||
# save previous r_string
|
|
||||||
prev_r_string=${r_string}
|
|
||||||
# cut the right part with search string from the left
|
|
||||||
r_string=${r_string#*"${2}"}
|
|
||||||
# cut the left part with search string and rigth part from the right
|
|
||||||
l_string=${string%"${2}${r_string}"}
|
|
||||||
case "$r_string" in
|
|
||||||
# if the right part was not unmodified, there is nothing to replace
|
|
||||||
"$prev_r_string") break ;;
|
|
||||||
# if the right part was is modified, update string with:
|
|
||||||
# the left part, replace string, the right part
|
|
||||||
*) string=${l_string}${3}${r_string} ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
echo "$string"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and map all desktop entry files from standardised paths into aliases
|
|
||||||
find_entry_paths() {
|
|
||||||
debug "registering entries"
|
|
||||||
# Append application directory paths to be searched
|
|
||||||
IFS=':'
|
|
||||||
for directory in $APPLICATIONS_DIRS; do
|
|
||||||
# Append '.' to delimit start of entry ID
|
|
||||||
set -- "$@" "$directory".
|
|
||||||
done
|
|
||||||
|
|
||||||
# Find all desktop entries with valid names
|
|
||||||
set -- "$@" -type f -name '[a-zA-Z0-9_]*.desktop' ! -path '*[^a-zA-Z0-9_./-]*'
|
|
||||||
|
|
||||||
# Loop through found entry paths and IDs
|
|
||||||
IFS=$N
|
|
||||||
while read -r entry_path && read -r entry_id; do
|
|
||||||
# Entries are checked in ascending order of preference, so use last found if duplicate
|
|
||||||
# shellcheck disable=SC2139
|
|
||||||
alias "$entry_id"="entry_path='$entry_path'"
|
|
||||||
debug "registered '$entry_path' as entry '$entry_id'"
|
|
||||||
# Add as a fallback ID regardles if it's a duplicate
|
|
||||||
FALLBACK_ENTRY_IDS=${entry_id}${FALLBACK_ENTRY_IDS:+${N}${FALLBACK_ENTRY_IDS}}
|
|
||||||
debug "added fallback ID '$entry_id'"
|
|
||||||
done <<- EOE
|
|
||||||
$(
|
|
||||||
# Don't complain about nonexistent directories
|
|
||||||
find -L "$@" 2> /dev/null |
|
|
||||||
# Print entry path and convert it into an ID and print that too
|
|
||||||
awk '{ print; sub(".*/[.]/", ""); gsub("/", "-"); print }'
|
|
||||||
)
|
|
||||||
EOE
|
|
||||||
}
|
|
||||||
# Mask IFS withing function to allow temporary changes
|
|
||||||
alias find_entry_paths='IFS= find_entry_paths'
|
|
||||||
|
|
||||||
# Check validity of a given entry key - value pair
|
|
||||||
# Modifies following global variables:
|
|
||||||
# EXEC : Program to execute, possibly with arguments. See spec for details.
|
|
||||||
# EXECARG : Execution argument for the terminal emulator.
|
|
||||||
# TERMINAL : Set if application has been categorized as a terminal emulator
|
|
||||||
check_entry_key() {
|
|
||||||
key="$1"
|
|
||||||
value="$2"
|
|
||||||
action="$3"
|
|
||||||
read_exec="$4"
|
|
||||||
de_checks="$5"
|
|
||||||
|
|
||||||
# Order of checks is important
|
|
||||||
case $key in
|
|
||||||
'Categories'*=*)
|
|
||||||
debug "checking for 'TerminalEmulator' in Categories '$value'"
|
|
||||||
IFS=';'
|
|
||||||
for category in $value; do
|
|
||||||
[ "$category" = "TerminalEmulator" ] && {
|
|
||||||
TERMINAL=true
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
done
|
|
||||||
# Default in this case is to fail
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
'Actions'*=*)
|
|
||||||
# `It is not valid to have an action group for an action identifier not mentioned in the Actions key.
|
|
||||||
# Such an action group must be ignored by implementors.`
|
|
||||||
# ignore if no action requested
|
|
||||||
[ -z "$action" ] && return 0
|
|
||||||
debug "checking for '$action' in Actions '$value'"
|
|
||||||
IFS=';'
|
|
||||||
for check_action in $value; do
|
|
||||||
[ "$check_action" = "$action" ] && return 0
|
|
||||||
done
|
|
||||||
# Default in this case is to fail
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
'OnlyShowIn'*=*)
|
|
||||||
case "$de_checks" in
|
|
||||||
true) debug "checking for intersecion between '${XDG_CURRENT_DESKTOP-}' and OnlyShowIn '$value'" ;;
|
|
||||||
false)
|
|
||||||
debug "skipping OnlyShowIn check"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
IFS=';'
|
|
||||||
for target in $value; do
|
|
||||||
IFS=':'
|
|
||||||
for desktop in ${XDG_CURRENT_DESKTOP-}; do
|
|
||||||
[ "$desktop" = "$target" ] && return 0
|
|
||||||
done
|
|
||||||
done
|
|
||||||
# Default in this case is to fail
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
'NotShowIn'*=*)
|
|
||||||
case "$de_checks" in
|
|
||||||
true) debug "checking for intersecion between '${XDG_CURRENT_DESKTOP-}' and NotShowIn '$value'" ;;
|
|
||||||
false)
|
|
||||||
debug "skipping NotShowIn check"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
IFS=';'
|
|
||||||
for target in $value; do
|
|
||||||
IFS=':'
|
|
||||||
for desktop in ${XDG_CURRENT_DESKTOP-}; do
|
|
||||||
debug "checking NotShowIn match '$desktop'='$target'"
|
|
||||||
[ "$desktop" = "$target" ] && return 1
|
|
||||||
done
|
|
||||||
done
|
|
||||||
# Default in this case is to succeed
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
'X-ExecArg'*=* | 'ExecArg'*=*)
|
|
||||||
# Set global variable
|
|
||||||
EXECARG=$value
|
|
||||||
debug "read ExecArg '$EXECARG'"
|
|
||||||
;;
|
|
||||||
'TryExec'*=*)
|
|
||||||
debug "checking TryExec executable '$value'"
|
|
||||||
command -v "$value" > /dev/null || return 1
|
|
||||||
;;
|
|
||||||
'Hidden'*=*)
|
|
||||||
debug "checking boolean Hidden '$value'"
|
|
||||||
[ "$value" = 'true' ] && return 1
|
|
||||||
;;
|
|
||||||
'Exec'*=*)
|
|
||||||
case "$read_exec" in
|
|
||||||
false)
|
|
||||||
debug "ignored Exec from wrong section"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
debug "read Exec '$value'"
|
|
||||||
# Set global variable
|
|
||||||
EXEC=$value
|
|
||||||
# Get first word from read Exec value
|
|
||||||
IFS="$OIFS"
|
|
||||||
eval "set -- $EXEC"
|
|
||||||
debug "checking Exec[0] executable '$1'"
|
|
||||||
command -v "$1" > /dev/null || return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
# By default unrecognised keys, empty lines and comments get ignored
|
|
||||||
}
|
|
||||||
# Mask IFS withing function to allow temporary changes
|
|
||||||
alias check_entry='IFS= check_entry'
|
|
||||||
|
|
||||||
# Read entry from given path
|
|
||||||
read_entry_path() {
|
|
||||||
entry_path="$1"
|
|
||||||
entry_action="$2"
|
|
||||||
de_checks="$3"
|
|
||||||
read_exec=false
|
|
||||||
# shellcheck disable=SC2016
|
|
||||||
debug "reading desktop entry '$entry_path'${entry_action:+ action '}$entry_action${entry_action:+'}"
|
|
||||||
# Let `read` trim leading/trailing whitespace from the line
|
|
||||||
while IFS="$OIFS" read -r line; do
|
|
||||||
case $line in
|
|
||||||
# `There should be nothing preceding [the Desktop Entry group] in the desktop entry file but [comments]`
|
|
||||||
# if entry_action is not requested, allow reading Exec right away from the main group
|
|
||||||
'[Desktop Entry]'*) [ -z "$entry_action" ] && read_exec=true ;;
|
|
||||||
# A `Key=Value` pair
|
|
||||||
[a-zA-Z0-9-]*)
|
|
||||||
# Split value from pair
|
|
||||||
value=${line#*=}
|
|
||||||
# Remove all but leading spaces, and trim that from the value
|
|
||||||
value=${value#"${value%%[! ]*}"}
|
|
||||||
# Check the key
|
|
||||||
check_entry_key "$line" "$value" "$entry_action" "$read_exec" "$de_checks" && continue
|
|
||||||
# Reset values that might have been set
|
|
||||||
unset EXEC
|
|
||||||
unset EXECARG
|
|
||||||
unset TERMINAL
|
|
||||||
# shellcheck disable=SC2016
|
|
||||||
debug "entry discarded"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
# found requested action, allow reading Exec
|
|
||||||
"[Desktop Action ${entry_action}]"*) read_exec=true ;;
|
|
||||||
# Start of the next group header, stop if already read exec
|
|
||||||
'['*) [ "$read_exec" = "true" ] && break ;;
|
|
||||||
esac
|
|
||||||
# By default empty lines and comments get ignored
|
|
||||||
done < "$entry_path"
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_entry_id() {
|
|
||||||
# validates entry ID ($1)
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
# invalid characters or degrees of emptiness
|
|
||||||
*[!a-zA-Z0-9_.-]* | *[!a-zA-Z0-9_.-] | [!a-zA-Z0-9_.-]* | [!a-zA-Z0-9_.-] | '' | .desktop)
|
|
||||||
debug "string not valid as Entry ID: '$1'"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
# all that left with .desktop
|
|
||||||
*.desktop) return 0 ;;
|
|
||||||
# and without
|
|
||||||
*)
|
|
||||||
debug "string not valid as Entry ID '$1'"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_action_id() {
|
|
||||||
# validates action ID ($1)
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
# empty is ok
|
|
||||||
'') return 0 ;;
|
|
||||||
# invalid characters
|
|
||||||
*[!a-zA-Z0-9-]* | *[!a-zA-Z0-9-] | [!a-zA-Z0-9-]* | [!a-zA-Z0-9-])
|
|
||||||
debug "string not valid as Action ID: '$1'"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
# all that left
|
|
||||||
*) return 0 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Loop through IDs and try to find a valid entry
|
|
||||||
find_entry() {
|
|
||||||
# for explicitly listed entries do not apply DE *ShowIn limits
|
|
||||||
de_checks=false
|
|
||||||
IFS="$N"
|
|
||||||
for entry_id in ${ENTRY_IDS}${N}//fallback_start//${N}$FALLBACK_ENTRY_IDS; do
|
|
||||||
case "$entry_id" in
|
|
||||||
# entry has an action appended
|
|
||||||
*:*)
|
|
||||||
entry_action=${entry_id#*:}
|
|
||||||
entry_id=${entry_id%:*}
|
|
||||||
;;
|
|
||||||
# skip empty line
|
|
||||||
'') continue ;;
|
|
||||||
# fallback entries ahead, enable *ShowIn checks
|
|
||||||
'//fallback_start//')
|
|
||||||
de_checks=true
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
# nullify action
|
|
||||||
*) entry_action='' ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
debug "matching path for entry ID '$entry_id'"
|
|
||||||
# Check if a matching path was found for ID
|
|
||||||
alias "$entry_id" > /dev/null 2>&1 || continue
|
|
||||||
# Evaluates the alias, it sets $entry_path
|
|
||||||
eval "$entry_id"
|
|
||||||
# Unset the alias, so duplicate entries are skipped
|
|
||||||
unalias "$entry_id"
|
|
||||||
read_entry_path "$entry_path" "$entry_action" "$de_checks" || continue
|
|
||||||
# Check that the entry is actually executable
|
|
||||||
[ -z "${EXEC-}" ] && continue
|
|
||||||
# ensure entry is a Terminal Emulator
|
|
||||||
[ -z "${TERMINAL-}" ] && continue
|
|
||||||
# Set defaults
|
|
||||||
: "${EXECARG="-e"}"
|
|
||||||
# Entry is valid, stop
|
|
||||||
return 0
|
|
||||||
done
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
IFS=':' error "No valid terminal entry was found in:" ${APPLICATIONS_DIRS}
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
# Mask IFS withing function to allow temporary changes
|
|
||||||
alias find_entry='IFS= find_entry'
|
|
||||||
|
|
||||||
## globals
|
|
||||||
LOWERCASE_XDG_CURRENT_DESKTOP=$(echo "${XDG_CURRENT_DESKTOP-}" | tr '[:upper:]' '[:lower:]')
|
|
||||||
|
|
||||||
# this will receive proper value later
|
|
||||||
APPLICATIONS_DIRS=''
|
|
||||||
|
|
||||||
# path iterators
|
|
||||||
make_paths
|
|
||||||
|
|
||||||
# At this point we have no way of telling if cache is enabled or not, unless XTE_CACHE_ENABLED is set,
|
|
||||||
# so just try reading it as if default is true, otherwise do the usual thing.
|
|
||||||
# Editing config to disable cache should invalidate the cache.
|
|
||||||
# The true default is false though:
|
|
||||||
CACHE_ENABLED=${XTE_CACHE_ENABLED-false}
|
|
||||||
|
|
||||||
# HASH can be reused
|
|
||||||
HASH=''
|
|
||||||
|
|
||||||
if check_bool "${XTE_CACHE_ENABLED-true}" && read_cache; then
|
|
||||||
CACHE_USED=true
|
|
||||||
else
|
|
||||||
# continue with globals
|
|
||||||
CACHE_USED=false
|
|
||||||
|
|
||||||
# All desktop entry ids in descending order of preference from *xdg-terminals.list configs,
|
|
||||||
# with duplicates removed
|
|
||||||
ENTRY_IDS=''
|
|
||||||
# All desktop entry ids found in data dirs in descending order of preference,
|
|
||||||
# with duplicates (including those in $ENTRY_IDS) removed
|
|
||||||
FALLBACK_ENTRY_IDS=''
|
|
||||||
|
|
||||||
# Modifies $ENTRY_IDS
|
|
||||||
read_config_paths
|
|
||||||
# Modifies $ENTRY_IDS and sets global aliases
|
|
||||||
find_entry_paths
|
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
IFS="$N" debug "> final entry ID list:" ${ENTRY_IDS} "^ end of final entry ID list"
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
IFS="$N" debug "> final fallback entry ID list:" ${FALLBACK_ENTRY_IDS} "^ end of final fallback entry ID list"
|
|
||||||
|
|
||||||
# walk ID lists and find first applicable
|
|
||||||
find_entry || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Store original argument list, before it's modified
|
|
||||||
debug "> original args:" "$@" "^ end of original args" "EXEC=$EXEC" "EXECARG=$EXECARG"
|
|
||||||
|
|
||||||
# drop -e or custom ExecArg if given as the first arg
|
|
||||||
case "${1-}" in
|
|
||||||
'-e' | "$EXECARG")
|
|
||||||
debug "dropping '$1' from received args"
|
|
||||||
shift ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# `Implementations must undo quoting [in the Exec argument(s)][...]`
|
|
||||||
if [ "$#" -gt 0 ]; then
|
|
||||||
eval "set -- $EXEC ${EXECARG:+'"$EXECARG"'} \"\$@\""
|
|
||||||
else
|
|
||||||
eval "set -- $EXEC"
|
|
||||||
fi
|
|
||||||
|
|
||||||
debug "> final args:" "$@" "^ end of final args"
|
|
||||||
|
|
||||||
if [ "$CACHE_USED" = "false" ]; then
|
|
||||||
# saves or removes cache, forked out of the way
|
|
||||||
save_cache "$1" &
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
{ pkgs }:
|
|
||||||
pkgs.stdenv.mkDerivation {
|
|
||||||
name = "xdg-terminal-exec";
|
|
||||||
builder = "${pkgs.bash}/bin/bash";
|
|
||||||
args = [ ./builder.sh ];
|
|
||||||
coreutils = pkgs.coreutils;
|
|
||||||
src = ./xdg-terminal-exec;
|
|
||||||
system = builtins.currentSystem;
|
|
||||||
}
|
|
||||||
46
home.nix
46
home.nix
|
|
@ -22,11 +22,12 @@ in
|
||||||
[ ocaml ] ++ # OCaml
|
[ ocaml ] ++ # OCaml
|
||||||
[ grim slurp wl-clipboard jq ] ++ # Basic utilities
|
[ grim slurp wl-clipboard jq ] ++ # Basic utilities
|
||||||
[ bitwarden-cli ] ++ # Personalized selection of command-line (CLI/TUI) apps
|
[ bitwarden-cli ] ++ # Personalized selection of command-line (CLI/TUI) apps
|
||||||
[ kitty ] ++ # Terminal emulator
|
[ wezterm ] ++ # Terminal emulator
|
||||||
[ firefox cinnamon.nemo gnome.file-roller cinnamon.nemo-fileroller imv vlc pavucontrol grim slurp wl-clipboard ] ++ # Basic graphical apps
|
[ firefox cinnamon.nemo gnome.file-roller cinnamon.nemo-fileroller imv vlc pavucontrol grim slurp wl-clipboard ] ++ # Basic graphical apps
|
||||||
[ libreoffice signal-desktop element-desktop prismlauncher mumble ] ++ # Personalized selection of graphical apps
|
[ libreoffice signal-desktop element-desktop prismlauncher mumble gimp inkscape ] ++ # Personalized selection of graphical apps
|
||||||
|
# [ factorio ] ++ # Games
|
||||||
[ bemenu j4-dmenu-desktop ] ++ # Sway-related packages
|
[ bemenu j4-dmenu-desktop ] ++ # Sway-related packages
|
||||||
[ noto-fonts redhat-official-fonts overpass ] ++ # Fonts
|
[ noto-fonts redhat-official-fonts overpass ibm-plex ] ++ # Fonts
|
||||||
# [ vanilla-dmz ] ++ # Cursor
|
# [ vanilla-dmz ] ++ # Cursor
|
||||||
[ ];
|
[ ];
|
||||||
|
|
||||||
|
|
@ -35,6 +36,7 @@ in
|
||||||
# Enabling bash from home-manager means environment variables set by HM get set correctly
|
# Enabling bash from home-manager means environment variables set by HM get set correctly
|
||||||
programs.bash = {
|
programs.bash = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
profileExtra = "export VISUAL=nvim";
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.git = {
|
programs.git = {
|
||||||
|
|
@ -64,15 +66,34 @@ in
|
||||||
xdg.configFile."fontconfig/conf.d/20-default.fonts.conf".source = ./config/20-default-fonts.conf;
|
xdg.configFile."fontconfig/conf.d/20-default.fonts.conf".source = ./config/20-default-fonts.conf;
|
||||||
|
|
||||||
# fix nemo terminal integration
|
# fix nemo terminal integration
|
||||||
dconf.settings."org/cinnamon/desktop/applications/terminal".exec = "kitty";
|
dconf.settings."org/cinnamon/desktop/applications/terminal".exec = "wezterm";
|
||||||
|
|
||||||
programs.kitty = {
|
# programs.kitty = {
|
||||||
|
# enable = true;
|
||||||
|
# font = {
|
||||||
|
# name = "NotoMono";
|
||||||
|
# size = 11;
|
||||||
|
# };
|
||||||
|
# shellIntegration.enableBashIntegration = true;
|
||||||
|
# };
|
||||||
|
programs.wezterm = {
|
||||||
enable = true;
|
enable = true;
|
||||||
font = {
|
enableBashIntegration = true;
|
||||||
name = "NotoMono";
|
extraConfig = ''
|
||||||
size = 11;
|
-- Use Config Builder
|
||||||
};
|
config = wezterm.config_builder()
|
||||||
shellIntegration.enableZshIntegration = true;
|
|
||||||
|
config.hide_tab_bar_if_only_one_tab = true
|
||||||
|
config.enable_scroll_bar = true
|
||||||
|
config.window_padding = {
|
||||||
|
left = 0,
|
||||||
|
right = 1,
|
||||||
|
top = 0,
|
||||||
|
bottom = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
return config
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.neovim = import ./programs/neovim.nix;
|
programs.neovim = import ./programs/neovim.nix;
|
||||||
|
|
@ -83,7 +104,4 @@ in
|
||||||
|
|
||||||
programs.firefox = import ./programs/firefox.nix {inherit pkgs;};
|
programs.firefox = import ./programs/firefox.nix {inherit pkgs;};
|
||||||
|
|
||||||
# programs.thunderbird = {
|
programs.thunderbird = import ./programs/thunderbird.nix;
|
||||||
# enable = true;
|
|
||||||
# };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
-- Options
|
-- Options
|
||||||
--- ui
|
--- ui
|
||||||
vim.opt.number = true
|
vim.opt.number = true
|
||||||
|
vim.opt.syntax = 'on'
|
||||||
|
vim.opt.smartcase = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ let
|
||||||
in {
|
in {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = rec {
|
config = rec {
|
||||||
terminal = "kitty";
|
terminal = "wezterm";
|
||||||
modifier = "Mod4";
|
modifier = "Mod4";
|
||||||
fonts = {
|
fonts = {
|
||||||
names = [ "Red Hat Display" ];
|
names = [ "Red Hat Display" ];
|
||||||
|
|
@ -37,7 +37,7 @@ in {
|
||||||
"${mod}+XF86AudioRaiseVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 0.05+";
|
"${mod}+XF86AudioRaiseVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 0.05+";
|
||||||
"${mod}+XF86AudioLowerVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 0.05-";
|
"${mod}+XF86AudioLowerVolume" = "exec wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 0.05-";
|
||||||
});
|
});
|
||||||
menu = "j4-dmenu-desktop --no-generic --term=kitty --dmenu='bemenu -i --fn Red Hat Display 12 -H 24 -p \"\" -B 2 --hp 5'"; # I don't like hardcoding kitty here, TODO think of better way to do it
|
menu = "j4-dmenu-desktop --no-generic --term=wezterm --dmenu='bemenu -i --fn Red Hat Display 12 -H 24 -p \"\" -B 2 --hp 5'"; # I don't like hardcoding kitty here, TODO think of better way to do it
|
||||||
focus.followMouse = false;
|
focus.followMouse = false;
|
||||||
};
|
};
|
||||||
extraConfig =
|
extraConfig =
|
||||||
|
|
|
||||||
9
programs/thunderbird.nix
Normal file
9
programs/thunderbird.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
profiles = {
|
||||||
|
main = {
|
||||||
|
isDefault = true;
|
||||||
|
name = "Main";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
2
todo
2
todo
|
|
@ -1,7 +1,7 @@
|
||||||
# enable NUR and firefox extensions
|
# enable NUR and firefox extensions
|
||||||
split app configs off into separate files
|
split app configs off into separate files
|
||||||
switch to zsh
|
|
||||||
set up a keyring and store networkmanager wifi passwords in there instead of plain text
|
set up a keyring and store networkmanager wifi passwords in there instead of plain text
|
||||||
fnott: notifications
|
fnott: notifications
|
||||||
neovim and vimtex config
|
neovim and vimtex config
|
||||||
mute button
|
mute button
|
||||||
|
i3status bar
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue