This commit is contained in:
coast 2025-07-24 17:50:25 +03:30
parent 957bb23cb5
commit 291b957aae
4 changed files with 267 additions and 155 deletions

View file

@ -1,46 +1,100 @@
;;; init.el --- Coast's ~/.emacs.d/init.el
;;
;;; Commentary:
;; This is my GNU/Emacs configuration --
;; It has:
;; - (TEMPORARY) Evil mode; as I've gotten used to Vim binds when I was away from GNU/Emacs for a bit.
;; - Automatic syntax-highlighting.
;; - Has a minimap.
;; - Bad theme; it's fine on my eyes, though -- I like the 'solarized' theme >:3
;; - It's also gay.
;;
;;; Code:
;;
(require 'package) (require 'package)
(setq package-archives (setq package-archives
'(("gnu" . "https://elpa.gnu.org/packages/") '(("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/"))) ("melpa" . "https://melpa.org/packages/")))
(package-initialize) (package-initialize)
(unless package-archive-contents (unless package-archive-contents
(package-refresh-contents)) (package-refresh-contents))
(require 'use-package) (require 'use-package)
;;; Message:
;; "run" command (M-x / evil)
(defun coast/run-current-file ()
(interactive)
(let ((file (buffer-file-name)))
(cond
((not file)
(message "no file to run!"))
((string-match "\\.py\\'" file)
(compile (format "python3 %s" file)))
((string-match "\\.c\\'" file)
(let* ((out (concat (file-name-sans-extension file) ".out")))
(compile (format "gcc %s -o %s && %s" file out out))))
((string-match "\\.sh\\'" file)
(compile (format "bash %s" file)))
((string-match "\\.rs\\'" file)
(let* ((out (file-name-sans-extension file)))
(compile (format "rustc %s && %s" file out))))
((string-match "\\.lua\\'" file)
(compile (format "lua %s" file)))
((string-match "\\.js\\'" file)
(compile (format "node %s" file)))
((coast/file-has-shebang-p file)
(compile (format "%s" file)))
(t (message "dunno how to run this file >:(")))))
(defun coast/file-has-shebang-p (file)
(when (and file (file-readable-p file))
(with-temp-buffer
(insert-file-contents-literally file nil 0 128)
(goto-char (point-min))
(looking-at "^#!"))))
(defalias 'run #'coast/run-current-file)
(menu-bar-mode -1) (menu-bar-mode -1)
(tool-bar-mode -1) (tool-bar-mode -1)
(scroll-bar-mode -1) (scroll-bar-mode -1)
(global-display-line-numbers-mode 1) (global-display-line-numbers-mode 1)
(global-hl-line-mode 1) (global-hl-line-mode 1)
(electric-pair-mode 1)
(use-package rainbow-mode :ensure t :hook (prog-mode . rainbow-mode)) (setq-default electric-pair-pairs
(use-package all-the-icons :ensure t :if (display-graphic-p)) '((?\" . ?\")
(use-package elcord :ensure t :config (elcord-mode 1)) (?\{ . ?\})
(?\( . ?\))
(?\[ . ?\])
(?\< . ?\>)))
(load-theme 'doom-ir-black t) (setq-default electric-pair-text-pairs electric-pair-pairs)
(set-frame-parameter (selected-frame) 'alpha '(90 . 90)) (set-frame-parameter (selected-frame) 'alpha '(95 . 95))
(add-to-list 'default-frame-alist '(alpha . (90 . 90))) (add-to-list 'default-frame-alist '(alpha . (95 . 95)))
(set-face-attribute 'default nil :family "Departure Mono" :height 130) (set-face-attribute 'default nil :family "Inconsolata" :height 180)
(setq backup-directory-alist (setq backup-directory-alist `((".*" . "~/.local/tmp/emacsbackup/")))
`((".*" . "~/.local/tmp/emacsbackup/")))
(setq make-backup-files t) (setq make-backup-files t)
(setq backup-by-copying t) (setq backup-by-copying t)
(use-package neotree :ensure t :bind ("<f9>" . neotree-toggle)) (use-package solarized-theme :ensure t)
(load-theme 'solarized-selenized-dark t)
(use-package vertico (use-package all-the-icons :ensure t :if (display-graphic-p))
:ensure t (use-package rainbow-mode :ensure t :hook (prog-mode . rainbow-mode))
:config (use-package elcord :ensure t :config (elcord-mode 1))
(vertico-mode 1))
(use-package marginalia :ensure t :hook (vertico-mode . marginalia-mode)) (use-package neotree :ensure t :bind ("<f9>" . neotree-toggle))
(use-package vertico :ensure t :config (vertico-mode 1))
(use-package marginalia :ensure t :hook (vertico-mode . marginalia-mode))
(use-package consult (use-package consult
:ensure t :ensure t
:bind (("C-s" . consult-line) ("C-x b" . consult-buffer))) :bind (("C-x b" . consult-buffer)
("C-s" . consult-line)))
(use-package which-key :ensure t :config (which-key-mode 1)) (use-package which-key :ensure t :config (which-key-mode 1))
@ -48,19 +102,7 @@
(use-package yasnippet :ensure t :hook (prog-mode . yas-minor-mode)) (use-package yasnippet :ensure t :hook (prog-mode . yas-minor-mode))
(use-package flycheck :ensure t :hook (prog-mode . flycheck-mode)) (use-package flycheck :ensure t :hook (prog-mode . flycheck-mode))
(use-package lsp-mode
:ensure t
:commands lsp
:init (setq lsp-keymap-prefix "C-c l")
:hook ((java-mode c-mode sh-mode python-mode rust-mode go-mode typescript-mode
lua-mode zig-mode web-mode) . lsp))
(use-package lsp-ui
:ensure t
:config (require 'lsp-java-boot))
(global-set-key (kbd "C-c t") 'ansi-term) (global-set-key (kbd "C-c t") 'ansi-term)
(global-set-key (kbd "C-s") 'swiper)
(use-package web-mode (use-package web-mode
:ensure t :ensure t
@ -76,95 +118,131 @@
:config :config
(setq emmet-expand-jsx-className? t)) (setq emmet-expand-jsx-className? t))
(electric-pair-mode 1)
(setq electric-pair-pairs '((?\" . ?\") (?\{ . ?\}) (?\( . ?\)) (?\[ . ?\]) (?\< . ?\>)))
(setq electric-pair-text-pairs electric-pair-pairs)
(use-package nix-mode :ensure t :mode "\\.nix\\'")
(use-package python :mode "\\.py\\'") (use-package python :mode "\\.py\\'")
(use-package sh-script :mode "\\.sh\\'") (use-package sh-script :mode "\\.sh\\'")
(use-package fennel-mode :ensure t :mode "\\.fnl\\'" :hook (fennel-mode . macrostep-mode))
(use-package macrostep :ensure t)
(use-package zig-mode :ensure t :mode "\\.zig\\'" :hook (zig-mode . lsp-deferred))
(use-package cc-mode) (use-package cc-mode)
(use-package markdown-mode :ensure t :mode "\\.md\\'") (use-package markdown-mode :ensure t :mode "\\.md\\'")
(use-package lua-mode :ensure t :mode "\\.lua\\'")
(use-package rust-mode :ensure t :mode "\\.rs\\'")
(use-package go-mode :ensure t :mode "\\.go\\'")
(use-package typescript-mode :ensure t :mode "\\.ts\\'")
(use-package toml-mode :ensure t :mode "\\.toml\\'")
(use-package yaml-mode :ensure t :mode "\\.ya?ml\\'") (use-package yaml-mode :ensure t :mode "\\.ya?ml\\'")
(use-package tuareg (use-package macrostep :ensure t)
:ensure t
:mode ("\\.ml\\'" "\\.mli\\'")
:hook (tuareg-mode . merlin-mode))
(use-package merlin ;;; Message:
;; Language-setup.
(use-package python
:mode ("\\.py\\'" . python-mode)
:interpreter ("python" . python-mode))
(use-package rust-mode
:ensure t :ensure t
:hook ((tuareg-mode caml-mode) . merlin-mode) :mode ("\\.rs\\'" . rust-mode))
:config
(setq merlin-command 'opam)) (use-package sh-script
:mode (("\\.sh\\'" . sh-mode)
("\\.bash\\'" . sh-mode)
("\\.zsh\\'" . sh-mode))
:interpreter (("bash" . sh-mode)
("sh" . sh-mode)
("zsh" . sh-mode)))
(use-package merlin-eldoc (use-package lua-mode
:ensure t :ensure t
:hook (merlin-mode . merlin-eldoc-setup)) :mode ("\\.lua\\'" . lua-mode))
(use-package utop (use-package cc-mode
:mode (("\\.c\\'" . c-mode)
("\\.h\\'" . c-mode)
("\\.cpp\\'" . c++-mode)
("\\.hpp\\'" . c++-mode))
:interpreter (("c" . c-mode)
("cpp" . c++-mode)))
(use-package markdown-mode
:ensure t :ensure t
:hook (tuareg-mode . utop-minor-mode) :mode ("\\.md\\'" . markdown-mode))
:config
(setq utop-command "utop -emacs"))
(use-package ocamlformat (use-package yaml-mode
:ensure t :ensure t
:hook (tuareg-mode . ocamlformat-setup-indent) :mode ("\\.ya?ml\\'" . yaml-mode))
:custom
(ocamlformat-enable 'enable-outside-detected-project))
;;; Message
;; -- Set window title --
(setq frame-title-format '("%b —— GNU/Emacs"))
;;; Message:
;; -- The below may have been temporarily added --
(use-package doom-modeline (use-package doom-modeline
:ensure t :ensure t
:init :init
(setq doom-modeline-height 25) (setq doom-modeline-height 25
(setq doom-modeline-bar-width 3) doom-modeline-bar-width 3
(setq doom-modeline-buffer-file-name-style 'truncate-with-project) doom-modeline-buffer-file-name-style 'truncate-with-project
(setq doom-modeline-icon t) doom-modeline-icon t
(setq doom-modeline-major-mode-icon t) doom-modeline-major-mode-icon t
(setq doom-modeline-enable-word-count t) doom-modeline-enable-word-count t
(setq doom-modeline-vcs-max-length 12) doom-modeline-vcs-max-length 12
(setq doom-modeline-mode-icon nil) doom-modeline-minor-modes nil)
(setq doom-modeline-minor-modes nil) :config
(doom-modeline-mode 1))
(setq evil-want-keybinding nil)
(use-package evil
:ensure t
:init (setq evil-want-integration t
evil-want-C-u-scroll t)
:config (evil-mode 1))
(use-package evil-collection
:after evil
:ensure t
:config (evil-collection-init))
(use-package evil-leader
:ensure t
:config :config
(doom-modeline-mode 1) (global-evil-leader-mode)
(set-face-attribute 'mode-line nil (evil-leader/set-leader "<SPC>")
:background "#000000" (evil-leader/set-key
:foreground "#ffffff" "f" 'find-file
:box nil) "b" 'switch-to-buffer
(set-face-attribute 'mode-line-inactive nil "k" 'kill-buffer
:background "#111111" "t" 'ansi-term
:foreground "#888888" "e" 'eval-buffer
:box nil)) "r" 'coast/run-current-file))
(use-package evil-surround :ensure t :config (global-evil-surround-mode 1))
(use-package evil-commentary :ensure t :config (evil-commentary-mode 1))
(use-package corfu
:ensure t
:custom
(corfu-auto t)
(corfu-cycle t)
(corfu-quit-no-match nil)
:init
(global-corfu-mode))
(use-package cape
:ensure t)
(defun my/evil-ex-corfu-setup ()
(setq-local completion-at-point-functions
(list (cape-super-capf #'completion-at-point))))
(add-hook 'evil-ex-completion-hook #'my/evil-ex-corfu-setup)
(custom-set-variables (custom-set-variables
;; custom-set-variables was added by Custom. ;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful. ;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance. ;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right. ;; If there is more than one, they won't work right.
'(custom-safe-themes '(warning-suppress-log-types '((use-package))))
'("014cb63097fc7dbda3edf53eb09802237961cbb4c9e9abd705f23b86511b0a69"
"c5801b68568b59976a8e58104c40c9b052d46cca72e367c2e43c1f36a9e79abb"
default))
'(package-selected-packages
'(all-the-icons company consult doom-modeline doom-themes elcord
emmet-mode fennel-mode flycheck go-mode lsp-java
lsp-ui lua-mode macrostep marginalia merlin
merlin-eldoc nano-modeline neotree nix-mode
ocaml-eglot ocamlformat rainbow-mode rust-mode
swiper toml-mode tuareg typescript-mode utop
vertico web-mode yaml-mode yasnippet zig-mode)))
(custom-set-faces (custom-set-faces
;; custom-set-faces was added by Custom. ;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful. ;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance. ;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right. ;; If there is more than one, they won't work right.
) )
(provide 'init)
;;; init.el ends here

View file

@ -49,7 +49,7 @@ _CONSTANTS = {
"nan": math.nan, "nan": math.nan,
} }
class MathEvaluator(ast.NodeVisitor): class matheval(ast.NodeVisitor):
def visit(self, node): def visit(self, node):
if isinstance(node, ast.Expression): if isinstance(node, ast.Expression):
return self.visit(node.body) return self.visit(node.body)
@ -110,7 +110,7 @@ def main():
try: try:
tree = ast.parse(expr, mode="eval") tree = ast.parse(expr, mode="eval")
evaluator = MathEvaluator() evaluator = matheval()
result = evaluator.visit(tree) result = evaluator.visit(tree)
if isinstance(result, float) and result.is_integer(): if isinstance(result, float) and result.is_integer():
print(int(result)) print(int(result))

View file

@ -1,72 +1,92 @@
#!/usr/bin/env bash #!/usr/bin/env python3
set -euo pipefail import os
export DISPLAY="${DISPLAY:-:0}" import sys
import subprocess
import tempfile
from pathlib import Path
from datetime import datetime
# Dependencies check def check_cmds(cmds):
for cmd in xclip import notify-send; do command -v "$cmd" &>/dev/null || { echo "Missing: $cmd" >&2; exit 1; }; done for cmd in cmds:
if subprocess.call(["which", cmd], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0:
print(f"Missing: {cmd}", file=sys.stderr)
sys.exit(1)
OUTDIR="${2:-$HOME/files/pics/screenies}"; mkdir -p "$OUTDIR" def show_help():
FILE="$OUTDIR/$(date +%Y%m%d_%H%M%S).png" print(f"""Usage: {sys.argv[0]} [color|full|window] [output_dir]\nEnvironment options:\n WATERMARK=1\n WATERMARK_TEXT='text'\n WATERMARK_POS=position\n WATERMARK_SIZE=px\n WATERMARK_BG='#rrggbbaa'\n""")
TMP=$(mktemp --suffix=.png); trap 'rm -f "$TMP"' EXIT
show_help(){ def post(file):
cat <<EOF if os.environ.get("WATERMARK") == "1":
Usage: $0 [color|full|window] [output_dir] check_cmds(["magick"])
Environment options: watermark_text = os.environ.get("WATERMARK_TEXT", datetime.now().strftime("%Y-%m-%d %H:%M"))
WATERMARK=1 watermark_pos = os.environ.get("WATERMARK_POS", "southeast")
WATERMARK_TEXT='text' watermark_size = os.environ.get("WATERMARK_SIZE", "28")
WATERMARK_POS=position watermark_bg = os.environ.get("WATERMARK_BG", "#00000080")
WATERMARK_SIZE=px subprocess.run([
WATERMARK_BG='#rrggbbaa' "magick", file,
EOF "-gravity", watermark_pos,
} "-pointsize", watermark_size,
"-fill", "white",
"-undercolor", watermark_bg,
"-annotate", "+20+20", watermark_text,
file
], check=True)
subprocess.run(["xclip", "-selection", "clipboard", "-t", "image/png", "-i", file], check=True)
subprocess.run(["notify-send", "-i", file, f"Screenshot: {os.path.basename(file)}"], check=True)
post(){ def colorpicker(tmp):
[[ "${WATERMARK:-}" == "1" ]] && { check_cmds(["magick"])
command -v magick &>/dev/null || { echo "Missing: magick" >&2; exit 1; } if subprocess.call(["which", "slop"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0:
# Watermark subsystem (env overrides supported) slop = subprocess.run(["slop", "--tolerance=0"], capture_output=True, text=True)
magick "$FILE" \ if slop.returncode != 0:
-gravity "${WATERMARK_POS:-southeast}" \ sys.exit(1)
-pointsize "${WATERMARK_SIZE:-28}" \ crop = slop.stdout.strip()
-fill white -undercolor "${WATERMARK_BG:-#00000080}" \ subprocess.run(["import", "-window", "root", "-crop", crop, tmp], check=True)
-annotate +20+20 "${WATERMARK_TEXT:-$(date '+%Y-%m-%d %H:%M')}" \ else:
"$FILE" subprocess.run(["import", tmp], check=True)
} try:
xclip -selection clipboard -t image/png -i "$FILE" && notify-send -i "$FILE" "Screenshot: $(basename "$FILE")" hexcolor = subprocess.check_output([
} "magick", tmp, "-scale", "1x1!", "-format", "#%[hex:p{0,0}]", "info:"
], stderr=subprocess.DEVNULL, text=True).strip()
except subprocess.CalledProcessError:
hexcolor = "#??????"
subprocess.run(["xclip", "-selection", "clipboard", "-i"], input=hexcolor.encode(), check=True)
subprocess.run(["notify-send", "-i", tmp, f"Color: {hexcolor}"], check=True)
colorpicker(){ def capture_full(file):
command -v magick &>/dev/null || { notify-send "Missing: magick"; exit 1; } subprocess.run(["import", "-window", "root", file], check=True)
if command -v slop &>/dev/null; then post(file)
import -window root -crop "$(slop --tolerance=0 || exit 1)" "$TMP"
else
import "$TMP"
fi
hex=$(magick "$TMP" -scale 1x1\! -format "#%[hex:p{0,0}]" info: 2>/dev/null || echo "#??????")
echo "$hex" | xclip -selection clipboard -i && notify-send -i "$TMP" "Color: $hex"
}
capture_full(){ def capture_window(file):
import -window root "$FILE" && post check_cmds(["xdotool"])
} winid = subprocess.check_output(["xdotool", "getwindowfocus", "-f"], text=True).strip()
subprocess.run(["import", "-window", winid, file], check=True)
post(file)
capture_window(){ def capture_selection(file):
command -v xdotool &>/dev/null || { echo "Missing: xdotool" >&2; exit 1; } subprocess.run(["import", file], check=True)
import -window "$(xdotool getwindowfocus -f)" "$FILE" && post post(file)
}
capture_selection(){ def main():
import "$FILE" && post check_cmds(["xclip", "import", "notify-send"])
} outdir = Path(sys.argv[2]) if len(sys.argv) > 2 else Path.home() / "files" / "pics" / "screenies"
outdir.mkdir(parents=True, exist_ok=True)
file = str(outdir / (datetime.now().strftime("%Y%m%d_%H%M%S") + ".png"))
with tempfile.NamedTemporaryFile(suffix=".png", delete=True) as tmp:
if len(sys.argv) > 1:
arg = sys.argv[1]
else:
arg = ""
if arg in ("-h", "--help"):
show_help()
elif arg.startswith("color"):
colorpicker(tmp.name)
elif arg == "full":
capture_full(file)
elif arg == "window":
capture_window(file)
else:
capture_selection(file)
main(){ if __name__ == "__main__":
case "${1:-}" in main()
-h|--help) show_help ;;
color*) colorpicker ;;
full) capture_full ;;
window) capture_window ;;
*) capture_selection ;;
esac
}
main "$@"

14
local/bin/yellusb Executable file
View file

@ -0,0 +1,14 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pyudev
import subprocess
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='block')
for device in iter(monitor.poll, None):
if device.action == 'add':
print(f"New device detected: {device.device_node}")
subprocess.run(f"notify-send 'New device connected: {device.device_node}'", shell=True)