# HG changeset patch # User Steve Losh # Date 1530038952 14400 # Node ID 493c5e72391dea4d334f2fdb2499ccc653086ab4 # Parent 9eee230725387e1930bb92b05c24835809cb7e28 Add missing file diff -r 9eee23072538 -r 493c5e72391d stumpwmrc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stumpwmrc Tue Jun 26 14:49:12 2018 -0400 @@ -0,0 +1,267 @@ +(in-package :stumpwm-user) + +(ql:quickload '(:losh :split-sequence :alexandria) :silent t) +(use-package :losh) + +;;;; Config ------------------------------------------------------------------- +(set-prefix-key (kbd "C-space")) + +(setf *mouse-focus-policy* :click + *message-window-gravity* :center + *input-window-gravity* :center + *shell-program* "/bin/bash") + + +;;;; Utils -------------------------------------------------------------------- +(defun ensure-mode-line () + (when (not (stumpwm::head-mode-line (current-head))) + (toggle-mode-line (current-screen) (current-head)))) + + +(defun string-contains (needle string) + (and (search needle string :test #'char=) t)) + +(defun string-grep (needle text &key first-only) + (-<> text + (split-sequence:split-sequence #\newline <>) + (if first-only + (find needle <> :test #'string-contains) + (remove-if-not (alexandria:curry #'string-contains needle) <>)))) + +(defun string-split (delimiters string) + (split-sequence:split-sequence delimiters string + :test (lambda (bag ch) + (find ch bag :test #'char=)))) + + +(defun volume () + (-<> (run-shell-command "amixer sget Master" t) + (string-grep "Front Left:" <> :first-only t) + (string-split "[]" <>) + second + (string-trim "%" <>) + parse-integer)) + + +(defun battery () + (run-shell-command + "acpi -b | awk -F '[ ,]' '{printf \"%s%s\", $3, $5}' | sed s/Discharging// | sed s/Unknown// | sed s/Full// | sed s/Charging/+/" + t)) + + +(defun current-frame () + (stumpwm::tile-group-current-frame (current-group))) + + +(defun debug-log (&rest args) + (with-open-file (s "/home/sjl/stumpwm.debug.log" + :direction :output + :if-exists :append + :if-does-not-exist :create) + (apply #'format s args))) + + +;;;; Regroup ------------------------------------------------------------------- +(defparameter *class-groups* + '(("zoom" . "zoom") + ("jetbrains-idea-ce" . "ij")) + "An alist of window classes to be regrouped and their targets") + +(defun regroup (win) + "Regroup window by class." + (let* ((class (window-class win)) + (target (cdr (assoc class *class-groups* :test #'string=)))) + (when target + (let ((group (stumpwm::find-group (current-screen) target))) + (when group + (debug-log "Regrouping ~A window to ~A group.~%" class group) + (move-window-to-group win group) + (stumpwm::update-all-mode-lines)))))) + +(add-hook *new-window-hook* 'regroup) + + +;;;; Load --------------------------------------------------------------------- +(load-module "pass") + +;;;; Commands ----------------------------------------------------------------- +(defcommand sane-hsplit () () + (hsplit) + (move-focus :right)) + +(defcommand sane-vsplit () () + (vsplit) + (move-focus :down)) + +(defcommand sane-move-window (direction) + ((:direction "Enter a direction: ")) + (banish) + (move-window direction)) + +(defcommand move-focus* (direction) + ((:direction "Enter a direction: ")) + (labels ((in-float-p () + (typep (current-group) 'stumpwm::float-group)) + (focus-first-frame () + (unless (in-float-p) + (dotimes (i 10) + (move-focus (ecase direction + (:left :right) + (:right :left)))))) + (next-group () + (ecase direction + (:right (gnext)) + (:left (gprev))) + (focus-first-frame))) + (unless (in-float-p) + (banish)) + (if (in-float-p) + (next-group) + (let ((frame (current-frame))) + (move-focus direction) + (when (eql frame (current-frame)) + (next-group)))))) + +(defcommand screen-single () () + (loop with laptop = "eDP1" + with extern = "HDMI2" + for (output commands) in `((,extern ("--off")) + ;; (,rhs-name ("--auto")) + ;; (,rhs-name ("--primary")) + (,laptop ("--off")) + (,laptop ("--auto")) + ;; (,laptop ("--left-of" ,rhs-name)) + ;; (,laptop ("--rotate" "left")) + ) + do (uiop:run-program `("xrandr" "--output" ,output ,@commands)))) + +(defcommand screen-multi () () + (loop with laptop = "eDP1" + with extern = "DP1" + for (output commands) in `((,laptop ("--off")) + (,extern ("--off")) + (,laptop ("--auto")) + (,laptop ("--primary")) + (,extern ("--mode" "3440x1440")) + (,extern ("--left-of" ,laptop))) + do (uiop:run-program `("xrandr" "--output" ,output ,@commands)))) + +(defcommand vlime () () + (load "~/lib/dotfiles/vim/bundle/vlime/lisp/start-vlime.lisp")) + +(defcommand toggle-current-mode-line () () + (toggle-mode-line (current-screen) (current-head))) + +(defcommand pass-personal () () + (let ((pass:*password-store* "/home/sjl/Dropbox/password-store/")) + (pass:pass-copy))) + +(defcommand pass-work () () + (let ((pass:*password-store* "/home/sjl/.password-store-work/") + (pass:*pass* "/home/sjl/lib/dotfiles/bin/pass-work")) + (pass:pass-copy))) + + +;;;; Applications ------------------------------------------------------------- +(defcommand spotify () () + (run-or-raise "spotify" '(:class "Spotify"))) + +(defcommand intellij () () + (run-or-raise "~/intellij/bin/idea.sh" '(:class "jetbrains-idea-ce"))) + + +;;;; Key Mapping -------------------------------------------------------------- +(defmacro define-top-keys (&body keyforms) + `(progn ,@(loop :for form :in keyforms + :collect `(define-key *top-map* + (kbd ,(first form)) + ,(second form))))) + + +(define-top-keys ;; application shortcuts + ("H-m" "exec st") + ("H-\\" "pass-personal") + ("H-|" "pass-work") + ("H-b" "exec google-chrome") + ("H-o" "spotify") + ("H-I" "intellij") + ("H-q" "exec slock") + ("H-y" "exec scrot 'screenshot_%Y-%m-%d_%H-%M-%S.png' -s -e 'mv $f ~/screenshots && echo -n ~/screenshots/$f' | xclip -sel clip") + ("H-Y" "exec scrot 'screenshot_%Y-%m-%d_%H-%M-%S.png' -m 'mv $f ~/screenshots && echo -n ~/screenshots/$f' | xclip -sel clip") + ("H-r" "loadrc") + ("H-V" "vlime")) + +(define-top-keys ;; movement + ("H-h" "move-focus* left") + ("H-j" "move-focus down") + ("H-k" "move-focus up") + ("H-l" "move-focus* right") + + ("H-H" "sane-move-window left") + ("H-J" "sane-move-window down") + ("H-K" "sane-move-window up") + ("H-L" "sane-move-window right") + + ("H-n" "next-in-frame") + ("H-p" "prev-in-frame") + ("H-N" "pull-hidden-next")) + +(define-top-keys ;; splitting + ("H-s" "sane-vsplit") + ("H-v" "sane-hsplit")) + +(define-top-keys ;; killing + ("H-w" "delete") + ("H-W" "kill") + ("H-BackSpace" "remove")) + +(define-top-keys ;; screen + ("H-F5" "exec xbacklight -dec 10") + ("H-F6" "exec xbacklight -inc 10") + ("H-F7" "screen-single") + ("H-F8" "screen-multi")) + +(define-top-keys ;; sound + ("H-F2" "exec amixer -q sset Master 5%-") + ("H-F3" "exec amixer -q sset Master 5%+")) + +(define-top-keys ;; stump + ("H-F9" "exec systemctl suspend") + ("H-F10" "exec keysettings") + ("C-F10" "exec keysettings") ; hack + ("H-F11" "toggle-current-mode-line") + ("H-F12" "restart-hard")) + + +;;;; Modeline ----------------------------------------------------------------- +(setf + *time-modeline-string* + "%a %b %e %k:%M" + *screen-mode-line-format* + (list "[^B%n^b] %W^>" + "(V " + ;; '(:eval (volume)) + ")" + " " + "(B " + '(:eval (battery)) + ")" + " %d %T")) + +(setf *mode-line-timeout* 10) +(setf *mode-line-background-color* "#111111") + +(ensure-mode-line) + + +;;;; System Tray -------------------------------------------------------------- +(load-module "stumptray") +(run-commands "stumptray") + +(run-shell-command "nm-applet --sm-disable") +(run-shell-command "~/.dropbox-dist/dropboxd") +(run-shell-command "/usr/bin/dunst -conf ~/.dunstrc") + +;;;; Notifications ------------------------------------------------------------- +;; (load-module "notify") +;; (notify:notify-server-off)