1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | ;; ________ .__ _________ _____
;; \_____ \ | |__ \_ ___ \ ____ _____/ ____\
;; / | \| | \/ \ \/ / _ \ / \ __\
;; / | \ Y \ \___( <_> ) | \ |
;; \_______ /___| /\______ /\____/|___| /__|
;; \/ \/ \/ \/
;; Everything in this file is completely public domain.
;; Anyone may use it for whatever they'd like.
;; The main goal of this configuration is to
;; utilize both the benefits of placement-based
;; bindings like XFK, while keeping the vim
;; movement keys, and mnemonic leader keybinds.
;; Everything is meant to be configured to *my*
;; liking, so there may be some things others
;; would like to tweak to their own preference.
;;;;;;;;;;;;;;;;;;;;;;;;;
;;; -- startup ops -- ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Temporarily reduce garbage collection during startup. Inspect `gcs-done'.
(defun ambrevar/reset-gc-cons-threshold ()
(setq gc-cons-threshold (car (get 'gc-cons-threshold 'standard-value))))
(setq gc-cons-threshold (* 64 1024 1024))
(add-hook 'after-init-hook #'ambrevar/reset-gc-cons-threshold)
;;; Temporarily disable the file name handler.
(setq default-file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)
(defun ambrevar/reset-file-name-handler-alist ()
(setq file-name-handler-alist
(append default-file-name-handler-alist
file-name-handler-alist))
(cl-delete-duplicates file-name-handler-alist :test 'equal))
(add-hook 'after-init-hook #'ambrevar/reset-file-name-handler-alist)
;;;;;;;;;;;;;;;;;;;;;;;;
;;; -- the basics -- ;;;
;;;;;;;;;;;;;;;;;;;;;;;;
;; initialize packages
(package-initialize)
;; -- load packages, bootstrap use-package -- ;;
(require 'package) ;; Emacs builtin
;; set package.el repositories
(setq package-archives '(("org" . "https://orgmode.org/elpa/")
("gnu" . "https://elpa.gnu.org/packages/")
("melpa" . "https://melpa.org/packages/")))
;; update packages list if we are on a new install
(unless package-archive-contents
(package-refresh-contents))
;; a list of pkgs to programmatically install
;; ensure installed via package.el
(setq my-package-list '(use-package))
;; programmatically install/ensure installed
;; pkgs in your personal list
(dolist (package my-package-list)
(unless (package-installed-p package)
(package-install package)))
;; source local files
(add-to-list 'load-path (expand-file-name "~/.emacs.d/lisp/"))
(add-to-list 'custom-theme-load-path (expand-file-name "~/.emacs.d/themes/"))
;; require packages from load path
(require 'o-modeline) ; time inside modeline
(require 'misc-packages) ; misc packages for stuff i do with emacs .. duh
(require 'o-erc) ; IRC setup
(require 'pdf-images) ; support for PDF and image viewing inside emacs
(require 'bind-fun) ; personal functions for binding in Oh-Mode
;; basic changes
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(fringe-mode 0)
(xclip-mode 1)
(global-display-line-numbers-mode 1)
;; set variables
(setq-default
display-line-numbers-type 'relative
cursor-in-non-selected-windows nil
cursor-type 'bar
show-smartparens-mode 1
mouse-wheel-scroll-amount '(1)
mouse-wheel-progressive-speed 'nil
search-whitespace-regexp ".*"
isearch-lax-whitespace t
backup-by-copying t
backup-directory-alist '((".*" . "~/.cache/emacs-backups/"))
delete-old-versions t
keep-new-versions 5
keep-old-versions 2
version-control t
auto-save-file-name-transforms '((".*" "~/.cache/emacs-autosave/" t))
auto-save-list-file-prefix "~/.cache/emacs-autosave/"
create-lockfiles nil
require-final-newline t
enable-local-eval t
indent-tabs-mode t
tab-width 4
load-prefer-newer t
custom-file (concat user-emacs-directory "/custom.el")
explicit-shell-file-name "/home/orion/.nix-profile/bin/fish")
(defalias 'yes-or-no-p 'y-or-n-p)
;; fonts and colors
(load "/home/orion/.emacs.d/themes/xresources-theme.el")
(load-theme 'xresources t)
(set-face-attribute 'default nil :font "IBM Plex Mono" :height 100)
(set-face-attribute 'mode-line-inactive nil :background "#afafaf")
;; smart pairs
(electric-pair-mode)
;; show parens
(show-paren-mode 1)
;; discord rich presence
(use-package elcord :ensure t)
;;;;;;;;;;;;;;;;;;;;
;;; -- OhMode -- ;;;
;;;;;;;;;;;;;;;;;;;;
;;; --- external files --- ;;;
;; Feeling some EXWM?
(require 'exwm-systemtray)
(exwm-systemtray-enable)
(require 'my-exwm)
(defun wm-xmodmap()
(call-process "xmodmap" nil (get-buffer-create "wm") nil (expand-file-name "~/.qwerty"))
(call-process "xset" nil (get-buffer-create "wm") nil (expand-file-name "r rate 275 80")))
(wm-xmodmap)
(require 'scrot)
;;; --- [non-modal bindings] --- ;;;
;; window navigation
(global-set-key (kbd "C-c h") 'windmove-left)
(global-set-key (kbd "C-c j") 'windmove-down)
(global-set-key (kbd "C-c k") 'windmove-up)
(global-set-key (kbd "C-c l") 'windmove-right)
;; misc
(global-set-key (kbd "C-c a") 'ace-window)
(global-set-key (kbd "C-c g") 'god-local-mode)
;; misc
(define-key input-decode-map
(kbd "C-[")
[control-bracketleft])
(global-set-key [control-bracketleft] 'hippie-expand)
(global-set-key (kbd "<M-up>") 'drag-stuff-up)
(global-set-key (kbd "<M-down>") 'drag-stuff-down)
(global-set-key (kbd "C-;") 'isearch-backward)
(global-set-key (kbd "C-'") 'isearch-forward)
;; hydras
(require 'o-hydras)
;;; --- Oh Mode - personal modal editing --- ;;;
(require 'oh-mode)
|
x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | (use-package general
:config
(general-define-key
:keymaps 'god-local-mode-map
"h" 'backward-char
"j" 'next-line
"k" 'previous-line
"l" 'forward-char))
(use-package ryo-modal
:commands ryo-modal-mode
:bind ("<escape>" . o/ryo-stick)
:after hydra
:config
(ryo-modal-key
"SPC" '(("h" move-beginning-of-line)
("j" end-of-buffer)
("k" beginning-of-buffer)
("l" move-end-of-line)
("e"
(("b" eval-buffer)
("e" eval-last-sexp)))
("f"
(("f" find-file)
("j" split-window-below)
("k" split-window-right)
("h" describe-function)))
("g" goto-line)
("i" back-to-indentation)
("c"
(("j"
(("n" paredit-join-with-next-list)
("p" paredit-join-with-previous-list)))))
("q"
(("q" delete-window)
("w" kill-buffer)))
("s"
(("t" switch-to-buffer)
("s" save-buffer)
("q" save-buffers-kill-emacs)))
("x"
(("c" kill-emacs)))))
(ryo-modal-keys
("a" "M-x")
("b" xah-goto-matching-bracket)
("c" "M-w")
("d" o/delete)
("e" er/expand-region)
("e" er/expand-region)
("F" o/insert-forward)
("f" ryo-modal-mode)
("g"
(("c" "C-c")
("h" "C-h")
("x" "C-x")))
("h" backward-char)
("H" beginning-of-defun)
("i" undo)
("J" forward-paragraph)
("j" next-line)
("K" backward-paragraph)
("k" previous-line)
("L" end-of-defun)
("l" forward-char)
("n" ryo-modal-repeat)
("o" forward-same-syntax :first '(kakoune-set-mark-here))
("O" forward-same-syntax :first '(kakoune-set-mark-if-inactive))
("q" o/quit)
("r" xah-forward-right-bracket)
("s" o/newline)
("S" o/newline-up)
("T" rectangle-mark-mode)
("t" set-mark-command)
("u" kakoune-backward-same-syntax :first '(kakoune-set-mark-here))
("U" kakoune-backward-same-syntax :first '(kakoune-set-mark-if-inactive))
("v" "C-y")
("w" xah-backward-left-bracket)
("x" kakoune-x)
("y" xah-toggle-letter-case)
("z" comment-line)
("," xah-beginning-of-line-or-block)
("." xah-end-of-line-or-block)
("(" paredit-wrap-sexp)
(")" paredit-split-sexp)
("[" paredit-wrap-square)
("{" paredit-wrap-curly)
("<" paredit-wrap-angled)
("/" avy-goto-char-timer)
("'" xah-cycle-hyphen-underscore-space)
("\"" xah-shrink-whitespaces)
("-" xah-backward-punct)
("=" xah-forward-punct)
("m" ace-window))
(ryo-modal-keys
(:norepeat t)
("0" "M-0")
("1" "M-1")
("2" "M-2")
("3" "M-3")
("4" "M-4")
("5" "M-5")
("6" "M-6")
("7" "M-7")
("8" "M-8")
("9" "M-9")))
(ryo-modal-mode 1)
(provide 'oh-mode)
|
x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | (use-package xah-fly-keys)
(use-package kakoune)
(use-package expand-region)
(use-package hydra)
(use-package drag-stuff)
(use-package request)
;;; -- my personal functions -- ;;
(defun o/ryo-stick ()
(interactive)
(if (ryo-modal-mode)
'(nil)
(ryo-modal-mode 1)))
(defun o/quit ()
(interactive)
(execute-kbd-macro (kbd "C-g")))
(defun o/newline ()
(interactive)
(end-of-line)
(newline))
(defun o/newline-up ()
(interactive)
(beginning-of-line)
(newline)
(forward-line -1))
(defun o/insert-forward ()
(interactive)
(forward-char)
(ryo-modal-mode -1))
(defun gk-pop-shell (arg)
"Pop a shell in a side window.
Pass arg to ‘shell’."
(interactive "P")
(select-window
(display-buffer-in-side-window
(save-window-excursion
(let ((prefix-arg arg))
(call-interactively #'shell))
(current-buffer))
'((side . bottom)))))
(global-set-key (kbd "M-c") 'gk-pop-shell)
(defun o/delete ()
(interactive)
(if (use-region-p)
(xah-cut-line-or-region)
(delete-char 1)))
(defun o/voldown ()
(interactive)
(shell-command "pamixer -d 5"))
(defun o/volup ()
(interactive)
(shell-command "pamixer -i 5"))
(global-set-key (kbd "<XF86AudioLowerVolume>") 'o/voldown)
(global-set-key (kbd "<XF86AudioRaiseVolume>") 'o/volup)
;; Print screen
(global-set-key
(kbd "<print>")
(lambda ()
(interactive)
(let ((path (concat "~/Documents/Screenshot-" (format-time-string "%Y-%m-%d,%H:%M:%S") ".png")))
(start-process-shell-command
"scrot" nil (concat "scrot -s -f " path))
(message (concat "Screenshot saved to " path)))))
;; (defun x11-yank-image-at-point-as-image ()
;; "Yank the image at point to the X11 clipboard as image/png."
;; (interactive)
;; (let ((image (get-text-property (point) 'display)))
;; (if (eq (car image) 'image)
;; (let ((data (plist-get (cdr image) ':data))
;; (file (plist-get (cdr image) ':file)))
;; (cond (data
;; (with-temp-buffer
;; (insert data)
;; (call-shell-region
;; (point-min) (point-max)
;; "xclip -i -selection clipboard -t image/png")))
;; (file
;; (if (file-exists-p file)
;; (start-process
;; "xclip-proc" nil "xclip"
;; "-i" "-selection" "clipboard" "-t" "image/png"
;; "-quiet" (file-truename file))))
;; (t (message "The image seems to be malformed."))))
;; (message "Point is not at an image."))))
;; (global-set-key (kbd "M-p") 'x11-yank-image-at-point-as-image)
(defun xah-insert-column-az ()
"Insert letters A to Z vertically, similar to `rectangle-number-lines'.
The commpand will prompt for a start char, and number of chars to insert.
The start char can be any char in Unicode.
URL `http://ergoemacs.org/emacs/emacs_insert-alphabets.html'
Version 2019-03-07"
(interactive)
(let (
($startChar (string-to-char (read-string "Start char: " "a")))
($howmany (string-to-number (read-string "How many: " "26")))
($colpos (- (point) (line-beginning-position))))
(dotimes ($i $howmany )
(progn
(insert-char (+ $i $startChar))
(forward-line)
(beginning-of-line)
(forward-char $colpos)))))
(global-set-key (kbd "C-c z") 'xah-insert-column-az)
(provide 'bind-fun)
|
x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | ;; icons
(use-package all-the-icons)
;; dashboard
(use-package dashboard
:config
(dashboard-setup-startup-hook)
(setq dashboard-startup-banner 'logo))
;; ace window
(use-package ace-window)
;; completion
(use-package company
:config
(add-hook 'prog-mode-hook 'company-mode))
(use-package ivy)
(ivy-mode 1)
(use-package nix-mode
:mode "\\.nix\\'")
(use-package tex
:defer t
:ensure auctex
:config
(setq TeX-auto-save t))
(use-package treemacs :bind ("C-c n" . treemacs))
(use-package lua-mode
:config
(autoload 'lua-mode "lua-mode" "Lua editing mode." t)
(add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode))
(add-to-list 'interpreter-mode-alist '("lua" . lua-mode)))
(use-package lsp-mode
:ensure lsp-ivy
:config
(setq keymap-prefix "s-l")
:hook ((lua-mode . lsp-deferred)
(python-mode . lsp-deferred)
(clojure-mode . lsp-deferred))
:commands lsp lsp-deferred lsp-ivy-workspace-symbol)
(use-package paredit)
(use-package god-mode)
(provide 'misc-packages)
|
x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | ;;; -*- lexical-binding: t; -*-
(use-package exwm
:ensure t
:config
;; necessary to configure exwm manually
(require 'exwm-config)
;; fringe size, most people prefer 1
;; (fringe-mode 3)
;; emacs as a daemon, use "emacsclient <filename>" to seamlessly edit files from the terminal directly in the exwm instance
(server-start)
;; this fixes issues with ido mode, if you use helm, get rid of it
(exwm-config-ido)
;; a number between 1 and 9, exwm creates workspaces dynamically so I like starting out with 1
(setq exwm-workspace-number 1)
;; this is a way to declare truly global/always working keybindings
;; this is a nifty way to go back from char mode to line mode without using the mouse
(exwm-input-set-key (kbd "s-r") #'exwm-reset)
(exwm-input-set-key (kbd "s-k") #'exwm-workspace-delete)
(exwm-input-set-key (kbd "s-w") #'exwm-workspace-swap)
;; the next loop will bind s-<number> to switch to the corresponding workspace
(setq exwm-workspace-index-map
(lambda (index) (number-to-string (1+ index))))
(dotimes (i 10)
(exwm-input-set-key (kbd (format "s-%d" i))
`(lambda ()
(interactive)
(exwm-workspace-switch-create (1- ,i)))))
;; the simplest launcher, I keep it in only if dmenu eventually stopped working or something
(exwm-input-set-key (kbd "s-&")
(lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
(exwm-input-set-key (kbd "s-*") #'dmenu)
(exwm-input-set-key
(kbd "M-p")
(lambda ()
(interactive)
(let ((path (concat "~/Documents/Screenshot-" (format-time-string "%Y-%m-%d,%H:%M:%S") ".png")))
(start-process-shell-command
"scrot" nil (concat "scrot -s -f " path))
(message (concat "Screenshot saved to " path))))))
;; an easy way to make keybindings work *only* in line mode
(push ?\C-q exwm-input-prefix-keys)
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
;; simulation keys are keys that exwm will send to the exwm buffer upon inputting a key combination
(setq exwm-input-simulation-keys
'(
;; movement
([?\C-b] . left)
([?\M-b] . C-left)
([?\C-f] . right)
([?\M-f] . C-right)
([?\C-p] . up)
([?\C-n] . down)
([?\C-a] . home)
([?\C-e] . end)
([?\M-v] . prior)
([?\C-v] . next)
([?\C-d] . delete)
([?\C-k] . (S-end delete))
;; cut/paste
([?\C-w] . ?\C-x)
([?\M-w] . ?\C-c)
([?\C-y] . ?\C-v)
;; search
([?\C-s] . ?\C-f)))
;; this little bit will make sure that XF86 keys work in exwm buffers as well
(dolist (k '(XF86AudioLowerVolume
XF86AudioRaiseVolume
XF86PowerOff
XF86AudioMute
XF86AudioPlay
XF86AudioStop
XF86AudioPrev
XF86AudioNext
XF86ScreenSaver
XF68Back
XF86Forward
Scroll_Lock
print))
(cl-pushnew k exwm-input-prefix-keys))
;; this just enables exwm, it started automatically once everything is ready
(exwm-enable))
(use-package dmenu)
(require 'exwm-systemtray)
(exwm-systemtray-enable)
(provide 'my-exwm)
|
x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ;; display time in modeline
(defface egoge-display-time
'((((type x w32 mac))
;; #060525 is the background colour of my default face.
(:foreground "#060525" :inherit bold))
(((type tty))
(:foreground "blue")))
"Face used to display the time in the mode line.")
;; This causes the current time in the mode line to be displayed in
;; `egoge-display-time-face' to make it stand out visually.
(setq display-time-string-forms
'((propertize (concat " " 24-hours ":" minutes " ")
'face 'egoge-display-time)))
(display-time-mode 1)
(provide 'o-modeline)
|
x
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ;; move between windows
(defhydra hydra-window (global-map "C-c m")
"A hydra for moving windows"
("h" windmove-left)
("j" windmove-down)
("k" windmove-up)
("l" windmove-right)
("J" (lambda ()
(interactive)
(split-window-below)
(windmove-down)))
("K" (lambda ()
(interactive)
(split-window-right)
(windmove-right)))
("x" delete-other-windows "one" :color blue)
("t" transpose-frame "'")
("a" ace-window "ace")
("s" ace-swap-window "swap")
("d" ace-delete-window "del")
("m" ace-maximize-window "ace-one" :color blue)
("b" ido-switch-buffer "buf")
("q" nil "cancel"))
(provide 'o-hydras)
|
x
Notes
They are a bit messy, but it serves as a decent start for those trying to make their own modal mode.