mirror of
https://git.sr.ht/~coasteen/dotfiles
synced 2025-11-04 14:47:38 +01:00
suicide
This commit is contained in:
parent
957bb23cb5
commit
291b957aae
4 changed files with 267 additions and 155 deletions
256
.emacs.d/init.el
256
.emacs.d/init.el
|
|
@ -1,3 +1,16 @@
|
|||
;;; 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)
|
||||
(setq package-archives
|
||||
'(("gnu" . "https://elpa.gnu.org/packages/")
|
||||
|
|
@ -7,40 +20,81 @@
|
|||
(package-refresh-contents))
|
||||
(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)
|
||||
(tool-bar-mode -1)
|
||||
(scroll-bar-mode -1)
|
||||
(global-display-line-numbers-mode 1)
|
||||
(global-hl-line-mode 1)
|
||||
(electric-pair-mode 1)
|
||||
|
||||
(use-package rainbow-mode :ensure t :hook (prog-mode . rainbow-mode))
|
||||
(use-package all-the-icons :ensure t :if (display-graphic-p))
|
||||
(use-package elcord :ensure t :config (elcord-mode 1))
|
||||
(setq-default electric-pair-pairs
|
||||
'((?\" . ?\")
|
||||
(?\{ . ?\})
|
||||
(?\( . ?\))
|
||||
(?\[ . ?\])
|
||||
(?\< . ?\>)))
|
||||
|
||||
(load-theme 'doom-ir-black t)
|
||||
(setq-default electric-pair-text-pairs electric-pair-pairs)
|
||||
|
||||
(set-frame-parameter (selected-frame) 'alpha '(90 . 90))
|
||||
(add-to-list 'default-frame-alist '(alpha . (90 . 90)))
|
||||
(set-frame-parameter (selected-frame) 'alpha '(95 . 95))
|
||||
(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
|
||||
`((".*" . "~/.local/tmp/emacsbackup/")))
|
||||
(setq backup-directory-alist `((".*" . "~/.local/tmp/emacsbackup/")))
|
||||
(setq make-backup-files 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
|
||||
:ensure t
|
||||
:config
|
||||
(vertico-mode 1))
|
||||
(use-package all-the-icons :ensure t :if (display-graphic-p))
|
||||
(use-package rainbow-mode :ensure t :hook (prog-mode . rainbow-mode))
|
||||
(use-package elcord :ensure t :config (elcord-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
|
||||
: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))
|
||||
|
||||
|
|
@ -48,19 +102,7 @@
|
|||
(use-package yasnippet :ensure t :hook (prog-mode . yas-minor-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-s") 'swiper)
|
||||
|
||||
(use-package web-mode
|
||||
:ensure t
|
||||
|
|
@ -76,95 +118,131 @@
|
|||
:config
|
||||
(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 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 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 tuareg
|
||||
:ensure t
|
||||
:mode ("\\.ml\\'" "\\.mli\\'")
|
||||
:hook (tuareg-mode . merlin-mode))
|
||||
(use-package macrostep :ensure t)
|
||||
|
||||
(use-package merlin
|
||||
;;; Message:
|
||||
;; Language-setup.
|
||||
(use-package python
|
||||
:mode ("\\.py\\'" . python-mode)
|
||||
:interpreter ("python" . python-mode))
|
||||
|
||||
(use-package rust-mode
|
||||
:ensure t
|
||||
:hook ((tuareg-mode caml-mode) . merlin-mode)
|
||||
:config
|
||||
(setq merlin-command 'opam))
|
||||
:mode ("\\.rs\\'" . rust-mode))
|
||||
|
||||
(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
|
||||
: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
|
||||
:hook (tuareg-mode . utop-minor-mode)
|
||||
:config
|
||||
(setq utop-command "utop -emacs"))
|
||||
:mode ("\\.md\\'" . markdown-mode))
|
||||
|
||||
(use-package ocamlformat
|
||||
(use-package yaml-mode
|
||||
:ensure t
|
||||
:hook (tuareg-mode . ocamlformat-setup-indent)
|
||||
:custom
|
||||
(ocamlformat-enable 'enable-outside-detected-project))
|
||||
:mode ("\\.ya?ml\\'" . yaml-mode))
|
||||
|
||||
;;; Message
|
||||
;; -- Set window title --
|
||||
(setq frame-title-format '("%b —— GNU/Emacs"))
|
||||
|
||||
;;; Message:
|
||||
;; -- The below may have been temporarily added --
|
||||
|
||||
(use-package doom-modeline
|
||||
:ensure t
|
||||
:init
|
||||
(setq doom-modeline-height 25)
|
||||
(setq doom-modeline-bar-width 3)
|
||||
(setq doom-modeline-buffer-file-name-style 'truncate-with-project)
|
||||
(setq doom-modeline-icon t)
|
||||
(setq doom-modeline-major-mode-icon t)
|
||||
(setq doom-modeline-enable-word-count t)
|
||||
(setq doom-modeline-vcs-max-length 12)
|
||||
(setq doom-modeline-mode-icon nil)
|
||||
(setq doom-modeline-minor-modes nil)
|
||||
(setq doom-modeline-height 25
|
||||
doom-modeline-bar-width 3
|
||||
doom-modeline-buffer-file-name-style 'truncate-with-project
|
||||
doom-modeline-icon t
|
||||
doom-modeline-major-mode-icon t
|
||||
doom-modeline-enable-word-count t
|
||||
doom-modeline-vcs-max-length 12
|
||||
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
|
||||
(doom-modeline-mode 1)
|
||||
(set-face-attribute 'mode-line nil
|
||||
:background "#000000"
|
||||
:foreground "#ffffff"
|
||||
:box nil)
|
||||
(set-face-attribute 'mode-line-inactive nil
|
||||
:background "#111111"
|
||||
:foreground "#888888"
|
||||
:box nil))
|
||||
(global-evil-leader-mode)
|
||||
(evil-leader/set-leader "<SPC>")
|
||||
(evil-leader/set-key
|
||||
"f" 'find-file
|
||||
"b" 'switch-to-buffer
|
||||
"k" 'kill-buffer
|
||||
"t" 'ansi-term
|
||||
"e" 'eval-buffer
|
||||
"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 was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(custom-safe-themes
|
||||
'("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)))
|
||||
'(warning-suppress-log-types '((use-package))))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
)
|
||||
|
||||
(provide 'init)
|
||||
;;; init.el ends here
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ _CONSTANTS = {
|
|||
"nan": math.nan,
|
||||
}
|
||||
|
||||
class MathEvaluator(ast.NodeVisitor):
|
||||
class matheval(ast.NodeVisitor):
|
||||
def visit(self, node):
|
||||
if isinstance(node, ast.Expression):
|
||||
return self.visit(node.body)
|
||||
|
|
@ -110,7 +110,7 @@ def main():
|
|||
|
||||
try:
|
||||
tree = ast.parse(expr, mode="eval")
|
||||
evaluator = MathEvaluator()
|
||||
evaluator = matheval()
|
||||
result = evaluator.visit(tree)
|
||||
if isinstance(result, float) and result.is_integer():
|
||||
print(int(result))
|
||||
|
|
|
|||
|
|
@ -1,72 +1,92 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
export DISPLAY="${DISPLAY:-:0}"
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Dependencies check
|
||||
for cmd in xclip import notify-send; do command -v "$cmd" &>/dev/null || { echo "Missing: $cmd" >&2; exit 1; }; done
|
||||
def check_cmds(cmds):
|
||||
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"
|
||||
FILE="$OUTDIR/$(date +%Y%m%d_%H%M%S).png"
|
||||
TMP=$(mktemp --suffix=.png); trap 'rm -f "$TMP"' EXIT
|
||||
def show_help():
|
||||
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""")
|
||||
|
||||
show_help(){
|
||||
cat <<EOF
|
||||
Usage: $0 [color|full|window] [output_dir]
|
||||
Environment options:
|
||||
WATERMARK=1
|
||||
WATERMARK_TEXT='text'
|
||||
WATERMARK_POS=position
|
||||
WATERMARK_SIZE=px
|
||||
WATERMARK_BG='#rrggbbaa'
|
||||
EOF
|
||||
}
|
||||
def post(file):
|
||||
if os.environ.get("WATERMARK") == "1":
|
||||
check_cmds(["magick"])
|
||||
watermark_text = os.environ.get("WATERMARK_TEXT", datetime.now().strftime("%Y-%m-%d %H:%M"))
|
||||
watermark_pos = os.environ.get("WATERMARK_POS", "southeast")
|
||||
watermark_size = os.environ.get("WATERMARK_SIZE", "28")
|
||||
watermark_bg = os.environ.get("WATERMARK_BG", "#00000080")
|
||||
subprocess.run([
|
||||
"magick", file,
|
||||
"-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(){
|
||||
[[ "${WATERMARK:-}" == "1" ]] && {
|
||||
command -v magick &>/dev/null || { echo "Missing: magick" >&2; exit 1; }
|
||||
# Watermark subsystem (env overrides supported)
|
||||
magick "$FILE" \
|
||||
-gravity "${WATERMARK_POS:-southeast}" \
|
||||
-pointsize "${WATERMARK_SIZE:-28}" \
|
||||
-fill white -undercolor "${WATERMARK_BG:-#00000080}" \
|
||||
-annotate +20+20 "${WATERMARK_TEXT:-$(date '+%Y-%m-%d %H:%M')}" \
|
||||
"$FILE"
|
||||
}
|
||||
xclip -selection clipboard -t image/png -i "$FILE" && notify-send -i "$FILE" "Screenshot: $(basename "$FILE")"
|
||||
}
|
||||
def colorpicker(tmp):
|
||||
check_cmds(["magick"])
|
||||
if subprocess.call(["which", "slop"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0:
|
||||
slop = subprocess.run(["slop", "--tolerance=0"], capture_output=True, text=True)
|
||||
if slop.returncode != 0:
|
||||
sys.exit(1)
|
||||
crop = slop.stdout.strip()
|
||||
subprocess.run(["import", "-window", "root", "-crop", crop, tmp], check=True)
|
||||
else:
|
||||
subprocess.run(["import", tmp], check=True)
|
||||
try:
|
||||
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(){
|
||||
command -v magick &>/dev/null || { notify-send "Missing: magick"; exit 1; }
|
||||
if command -v slop &>/dev/null; then
|
||||
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"
|
||||
}
|
||||
def capture_full(file):
|
||||
subprocess.run(["import", "-window", "root", file], check=True)
|
||||
post(file)
|
||||
|
||||
capture_full(){
|
||||
import -window root "$FILE" && post
|
||||
}
|
||||
def capture_window(file):
|
||||
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(){
|
||||
command -v xdotool &>/dev/null || { echo "Missing: xdotool" >&2; exit 1; }
|
||||
import -window "$(xdotool getwindowfocus -f)" "$FILE" && post
|
||||
}
|
||||
def capture_selection(file):
|
||||
subprocess.run(["import", file], check=True)
|
||||
post(file)
|
||||
|
||||
capture_selection(){
|
||||
import "$FILE" && post
|
||||
}
|
||||
def main():
|
||||
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(){
|
||||
case "${1:-}" in
|
||||
-h|--help) show_help ;;
|
||||
color*) colorpicker ;;
|
||||
full) capture_full ;;
|
||||
window) capture_window ;;
|
||||
*) capture_selection ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
14
local/bin/yellusb
Executable file
14
local/bin/yellusb
Executable 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)
|
||||
Loading…
Add table
Reference in a new issue