From: rearman Date: Mon, 27 Apr 2026 16:31:04 +0000 (-0400) Subject: Change the structure again X-Git-Url: https://git.earman.xyz/?a=commitdiff_plain;h=21c3bef1c227951954b2ae9c224e15c8941fc8d8;p=emacsinit.git Change the structure again Moving to a flatter structure: only things that can act like packages go in the 're/' directory. Everything else goes in the init in the proper page. The only exceptions for now being files that are used as 'includes' for declarations to use-package. --- diff --git a/init.el b/init.el index 50b613c..5642c24 100644 --- a/init.el +++ b/init.el @@ -8,14 +8,7 @@ (add-to-list 'load-path (concat user-emacs-directory path))) (dolist (requirement '(re-packages - re-editing-defuns - re-file-defuns - re-vc-defuns - re-bindings - re-repl-defuns re-pass-alike - re-dired-defuns - re-skeletons eng-paper-theme)) (require requirement)) @@ -42,8 +35,88 @@ (add-hook 'c-mode-hook (lambda () (require 're-c-style))) -;; Tabs +;; Editing +(defun re/open-line-below (n) + "Creates a new empty line below the current line and moves to it." + (interactive "*p") + (end-of-line) + (open-line n) + (next-line 1) + (indent-for-tab-command)) + +(keymap-global-set "C-o" #'re/open-line-below) + +(defun re/open-line-above (n) + "Creates a new empty line above the current line." + (interactive "*p") + (beginning-of-line) + (open-line n) + (indent-for-tab-command)) + +(keymap-global-set "M-o" #'re/open-line-above) + +(defun re/flush-extra-lines () + "Change all groups of blank lines to 1 blank line." + (interactive) + (save-excursion (mark-whole-buffer) + (replace-regexp "^\n+" + "\n" + nil + (region-beginning) + (region-end)))) + +(defun re/comment-dwim (&optional arg) + "Comment region if active, otherwise comment line. +Stolen from https://depp.brause.cc/dotemacs" + (interactive "P") + (if (use-region-p) + (comment-or-uncomment-region (region-beginning) (region-end)) + (comment-line arg))) + +(keymap-global-set "M-;" #'re/comment-dwim) + +(defun re/comment-defun (&optional arg) + "Mark a defun and comment it out. +Return to initial position after. Arg works on `mark-defun'." + (interactive "P") + (save-excursion (mark-defun arg) + (comment-region (region-beginning) (region-end)))) + +(keymap-global-set "C-M-;" #'re/comment-defun) + +(defun re/kill-defun (&optional arg) + "Mark a defun and kill it. +Arg works on `mark-defun'." + (interactive "P") + (mark-defun arg) + (kill-region (region-beginning) (region-end))) + +(keymap-global-set "C-M-S-K" #'re/kill-defun) + +(defun re/kill-bword-or-region (&optional arg) +"Kill region if active, otherwise kill back one word." +(interactive "p") +(if (use-region-p) + (kill-region (region-beginning) (region-end)) + (backward-kill-word arg))) +(keymap-global-set "C-w" #'re/kill-bword-or-region) + +(keymap-global-set "" nil) ; I keep toggliŋ overwrite-mode haply +(keymap-global-set "C-\\" #'undo-redo) ; issues with C-? sometimes +(keymap-global-set "C-S-K" #'kill-whole-line) +(keymap-global-set "C-u" (lambda () (interactive) (kill-line 0))) ; kill-line backwards +(keymap-global-set "C-S-U" #'universal-argument) ; C-u used above +(keymap-set key-translation-map "C-h" "") ; Rather F1 for help, also C-S-H works +(keymap-global-set "C-S-d" #'delete-pair) +(keymap-global-set "M-j" (lambda () (interactive) (join-line 0))) ; join-line other way +(keymap-global-set "C-z" #'zap-up-to-char) +(keymap-global-set "C-c s" #'sort-lines) +(keymap-global-set " " #'capitalize-dwim) ; M-c +(keymap-global-set " " #'downcase-dwim) ; M-l +(keymap-global-set " " #'upcase-dwim) ; M-u + +;; Tabs (setq-default indent-tabs-mode t tab-width 8 backward-delete-char-untabify-method nil) @@ -57,13 +130,19 @@ (dolist (indent-level '(c-basic-offset cperl-indent-level LaTeX-indent-level)) (defvaralias indent-level 'tab-width)) +(defun Tab (width) + "Give me a function analagous to the Acme `Tab' command" + (interactive) + (setq-local tab-width width)) + +(keymap-global-set "" (lambda () (interactive) (insert "\t"))) ;; Buffer dealiŋ (setq-default indicate-empty-lines t truncate-lines t fill-column 78) -(dolist (hook '(text-mode-hook LaTeX-mode-hook)) +(dolist (hook '(text-mode-hook LaTeX-mode-hook howm-mode-hook)) (lambda () (add-hook hook #'visual-line-mode))) (add-to-list 'display-buffer-alist @@ -91,8 +170,143 @@ "Recenter to page start." (when (called-interactively-p 'any) (recenter 2))) -(advice-add #'backward-page :after #'re/recenter-advice) -(advice-add #'forward-page :after #'re/recenter-advice) +(dolist (binding '(backward-page forward-page)) + (advice-add binding :after #'re/recenter-advice)) + +(keymap-global-set "C-x C-n" #'forward-page) +(keymap-global-set "C-x C-p" #'backward-page) +(keymap-global-set "" #'forward-page) +(keymap-global-set "" #'backward-page) + +(defmacro re/open-with-new-frame (frname function) + "Run the function in its own named frame." + `(progn + (select-frame (make-frame '((name . ,(eval frname))))) + (call-interactively ,function))) + +(keymap-global-set "C-x M-f" #'find-file-at-point) +(keymap-global-set "C-x C-b" #'buffer-menu) +(keymap-global-set "C-x M-b" #'buffer-menu-other-window) +(keymap-global-set "C-x k" #'kill-current-buffer) +(keymap-global-set "C-x K" #'kill-buffer) +(keymap-global-set "C-c d" #'eldoc) ; force eldoc to show in minibuffer +(keymap-global-set "C-c D" #'eldoc-doc-buffer) ; open eldoc buffer when it's getting spammed + +;; Motion +(defun re/scratch-only () + "Bring up the scratch buffer as the only visible buffer." + (interactive) + (scratch-buffer) + (delete-other-windows)) + +(keymap-global-set "" #'scratch-buffer) +(keymap-global-set "S-" #'re/scratch-only) + +(defun re/other-window-or-split-window (&optional window) + "Go to other window or split sensibly." + (interactive) + (if (= (count-windows) 1) + (funcall split-window-preferred-function window) + (other-window 1))) + +(keymap-global-set "C-M-o" #'re/other-window-or-split-window) + +(defun re/smart-beginning-of-line () + "Move point to first non-whitespace character or `beginning-of-visual-line'. +If point was already at that position, call `back-to-indentation'. +Called a third time, move point back to `beginning-of-line'. +If in org-mode, call `org-beginning-of-line' first." + (interactive "^") + (let ((oldpos (point))) + (if (equal major-mode 'org-mode) + (org-beginning-of-line) + (progn + (when visual-line-mode (beginning-of-visual-line 1)) + (skip-syntax-forward " " (line-end-position)) + (backward-prefix-chars))) + (and (= oldpos (point)) + (let ((newpos (point))) + (back-to-indentation) + (and (= newpos (point)) (beginning-of-line)))))) + +(keymap-global-set " " #'re/smart-beginning-of-line) +(keymap-set visual-line-mode-map "C-a" #'re/smart-beginning-of-line) + +(defun re/smart-end-of-line () + "Move point to the end of the visual line. + If point was already at that position, call `move-end-of-line'. +If in org-mode, call `org-end-of-line' first." + (interactive "^") + (let ((oldpos (point))) + (if (equal major-mode 'org-mode) + (org-end-of-line) + (when visual-line-mode + (end-of-visual-line 1))) + (and (= oldpos (point)) (move-end-of-line nil)))) + +(keymap-global-set " " #'re/smart-end-of-line) +(keymap-set visual-line-mode-map "C-e" #'re/smart-end-of-line) + +(defun re/goto-line () + "Show line numbers before going to line, then hide them again." + (interactive) + (display-line-numbers-mode 1) + (call-interactively 'goto-line) + (display-line-numbers-mode -1)) + +(keymap-global-set " " #'re/goto-line) +(keymap-global-set "" #'beginning-of-buffer) +(keymap-global-set "" #'end-of-buffer) +(keymap-global-set "C-." #'next-buffer) +(keymap-global-set "C-," #'previous-buffer) +(keymap-global-set "C-" (lambda () (interactive) (switch-to-buffer nil))) ; toggle last two buffers +(keymap-global-set "" #'previous-buffer) ; Back button +(keymap-global-unset "M-") +(keymap-global-unset "M-") +(keymap-global-unset "M-") +(keymap-global-unset "M-") +(keymap-global-unset "M-") + +;; Search +(defun re/isearch-forward-use-region () + "Search text in region if active, otherwise normal forward search." + (interactive) + (when (use-region-p) + (add-to-history 'search-ring + (buffer-substring (region-beginning) (region-end))) + (deactivate-mark)) + (isearch-forward)) + +(keymap-global-set "C-s" #'re/isearch-forward-use-region) + +(defun re/isearch-backward-use-region () + "Search text in region if active, otherwise normal backward search." + (interactive) + (when (use-region-p) + (add-to-history 'search-ring + (buffer-substring (region-beginning) (region-end))) + (deactivate-mark)) + (isearch-backward)) + +(keymap-global-set "C-r" #'re/isearch-backward-use-region) + +(defun re/exchange-point-and-mark-maybe-activate (arg) + "Call `exchange-point-and-mark' but don't activate the region. +Stolen from https://www.masteringemacs.org/article/fixing-mark-commands-transient-mark-mode" + (interactive "P") + (exchange-point-and-mark (if (and transient-mark-mode (not mark-active)) + (not arg) + arg))) + +(keymap-global-set " " #'re/exchange-point-and-mark-maybe-activate) + +(keymap-global-set "M-s ." #'isearch-forward-thing-at-point) +(keymap-global-set "M-s M-." #'isearch-forward-symbol-at-point) +(keymap-global-set "M-%" #'replace-regexp) +(keymap-global-set "C-%" #'replace-string) +(keymap-global-set "C-M-S-R" #'replace-regexp-as-diff) +(keymap-global-set "C-S-S" #'isearch-forward-regexp) +(keymap-global-set "C-S-R" #'isearch-backward-regexp) ;; Recent Files/Buffers (midnight-mode t) @@ -103,7 +317,118 @@ (save-place-mode 1) (recentf-mode 1) +;; File Handling +(defun re/rename-current-buffer-file nil + "Renames the current buffer and the file it is visiting." + (interactive) + (let ((name (buffer-name)) + (filename (buffer-file-name))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (let ((new-name (read-file-name "New name: " filename))) + (if (get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name) + (rename-file filename new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + (set-buffer-modified-p nil) + (message "File '%s' successfully renamed to '%s'" + name + (file-name-nondirectory new-name))))))) + +(keymap-global-set "C-x C-r" #'re/rename-current-buffer-file) + +(defun re/get-line-from-file (file-path line-number) + "Return the specified LINE-NUMBER from FILE-PATH as a string. +Start from bottom if given a negative line number." + (with-temp-buffer + (insert-file-contents file-path) + (if (< line-number 0) + (progn + (goto-char (point-max)) + (forward-line line-number)) + (progn + (goto-char (point-min)) + (forward-line (1- line-number)))) + (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) + +(defun re/get-file-modified-time (filepath) + (interactive) + (format-time-string "%Y-%m-%d-%H%M" + (file-attribute-modification-time (file-attributes filepath)))) + +(defun re/filename-inject-mod-time (filepath) + (interactive) + (concat (file-name-sans-extension filepath) + "_" + (re/get-file-modified-time filepath) + (file-name-extension filepath t))) + +(defun re/copy-with-mod-time (&optional filepath) + (interactive) + (let ((filepath (if (eq major-mode 'dired-mode) + (dired-get-filename t) + (when (null filepath) + (read-file-name "File to copy with datestring: " + default-directory + nil + t + nil))))) + (copy-file filepath (re/filename-inject-mod-time filepath ) nil t t t))) + ;; Dired +(defun re/dired-new-frame () + "Open dired in a new frame." + (interactive) + (re/open-with-new-frame "DIRED" + #'(lambda () (interactive) (dired default-directory)))) + +(keymap-global-set "" #'re/dired-new-frame) + +(defun re/dired-find-marked-files () + "Open all marked files from `dired'." + (interactive) + (mapc #'find-file (reverse (dired-get-marked-files)))) + +(defun re/dired-sort () + "Change sort order of dired dir." + (interactive) + (let ((smenu '(("name" . "-Ahl") + ("mdate" . "-Ahlt") + ("adate" . "-Ahltu") + ("size" . "-AhlS") + ("dir" . "-Ahl --group-directories-first"))) + ssortBy) + (setq ssortBy (completing-read "Sort by (default name):" + smenu + nil + t + nil + nil + (caar smenu))) + (dired-sort-other (cdr (assoc ssortBy smenu))))) + +(defun re/open-file-external (file) + "Open a file in an external program." + (interactive) + (let ((process-connection-type nil)) + (cond ((eq system-type 'windows-nt) + (w32-shell-execute "open" + (replace-regexp-in-string "/" "\\\\" file t t))) + ((eq system-type 'gnu/linux) + (start-process "" nil "xdg-open" file)) + (t (error "Unable to automatically open this file"))))) + +(defun re/dired-open-externally () + "Open the file at point in an external program." + (interactive) + (re/open-file-external (dired-get-filename))) + +(defun re/dired-open-marked-externally () + "Open all marked files from `dired' in an external program." + (interactive) + (mapc #'re/open-file-external (reverse (dired-get-marked-files)))) + (setq dired-listing-switches "-Ahl" dired-vc-rename-file t dired-auto-revert-buffer t @@ -147,6 +472,8 @@ ;; Bookmarks (setq bookmark-save-flag 1) +(keymap-global-set "" #'recentf-open-files) +(keymap-global-set "C-x r B" #'bookmark-jump-other-window) ;; GUI Settings (load-theme 'eng-paper t) @@ -221,7 +548,84 @@ (add-hook 'before-save-hook #'whitespace-cleanup) (add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p) +;; Control +(defun re/kill-emacs () + "Save all open files and kill emacs." + (interactive) + (save-some-buffers t) + (kill-emacs)) + +(keymap-global-set "C-x M-c" #'re/kill-emacs) + +(defun re/restart-emacs () + "Save all open files and restart emacs." + (interactive) + (save-some-buffers t) + (kill-emacs nil t)) + +(keymap-global-set "C-x M-r" #'re/restart-emacs) + +(defun re/keyboard-quit () + "Smarter version of `keyboard-quit'. +Close the minibuffer if not focused when hit. +Stolen from emacsredux.com." + (interactive) + (if (active-minibuffer-window) + (if (minibufferp) + (minibuffer-keyboard-quit) + (abort-recursive-edit)) + (keyboard-quit))) + +(keymap-global-set " " #'re/keyboard-quit) ; Make C-g better +(keymap-global-set "C-x S" (lambda () (interactive) (save-some-buffers t))) ; don't ask +(keymap-global-set "C-x c" #'delete-frame) ; delete a frame without asking about saving files + ;; Versioning and Backups +(defun re/vc-clone () + "Interactively clone with vc-mode. +Prompt for url and local dir." + (interactive) + (let* ((url (read-string "Repository URL: ")) + (dir (read-string "Local Dir: " (file-name-base url)))) + (vc-git-clone url dir nil))) + +(defun re/vc-show-branches (&optional arg) + "Display all Git branches in a separate buffer. +Remotes as well when arg." + (interactive "P") + (let ((default-directory (if (boundp 'vc-dir-directory) + vc-dir-directory + default-directory))) + (vc-git-command "*git-branches*" + nil + nil + "branch" + "--verbose" + (when arg "--remotes")) + (pop-to-buffer "*git-branches*") + (goto-char (point-min)) + (special-mode))) + +(defun re/vc-fetch (&optional arg) + "Interactively fetch with vc-mode. +Allows separate fetch in addition to pull. Only care about git. +With arg, ask for remote, otherwise fetch all." + (interactive "P") + (let* ((default-directory (if (boundp 'vc-dir-directory) + vc-dir-directory + default-directory))) + (vc-git-command "*vc-fetch*" + nil + nil + "fetch" + (if arg + (read-string "Fetch From: " "origin") + "--all") + "--verbose") + (pop-to-buffer "*vc-fetch*") + (goto-char (point-min)) + (special-mode))) + (setq vc-make-backup-files nil vc-handled-backends '(Git) vc-git-diff-switches '("--patch-with-stat" "--histogram") @@ -249,6 +653,161 @@ delete-old-versions t kept-new-versions 5 kept-old-versions 5) + +(keymap-global-set "C-x v C" #'re/vc-clone) +(keymap-global-set "C-x v b b" #'re/vc-show-branches) +(keymap-global-set "C-x v f" #'re/vc-fetch) + +(add-hook 'vc-dir-mode-hook + (lambda () + (keymap-set vc-dir-mode-map "b b" #'re/vc-show-branches) + (keymap-set vc-dir-mode-map "f" #'re/vc-fetch))) + + +;; Any Lisp Repl +(defmacro re/send-on-close-paren (executor) + "Generalizes sending an execute on close paren. + Interactively call `executor'. For `executor', use whatever + function is called by `' in the applicable REPL. For a + non-repl, use `newline' or similar." + `(lambda (&optional arg) + (interactive "p") + (insert-char 41 arg) + (call-interactively ,executor))) + +(defun re/sexp-drop-paren-p () + "Returns t if sexp needs fewer parens to balance." + (< (car (syntax-ppss)) 0)) + +(defun re/sexp-need-paren-p () + "Returns t if sexp needs more parens to balance." + (> (car (syntax-ppss)) 0)) + +(defun re/sexp-unbalanced-count () + "Returns distance from balanced sexp." + (abs (car (syntax-ppss)))) + +(defun re/balance-sexp () + "Balance the sexp before point. +Either delete, move forward, or add as many ')' as needed." + (let ((distance (re/sexp-unbalanced-count))) + (cond ((re/sexp-need-paren-p) + (if (looking-at ")") + (progn + (forward-char) + (re/balance-sexp)) + (insert-char 41 distance))) + ((re/sexp-drop-paren-p) + (backward-delete-char distance))))) + +(defmacro re/balance-and-eval-sexp (executor) + "Balance the sexp before point, then call `executor'. +Call `re/balance-sexp', then interactively call `executor'. Bind +this to ']' for the interlisp experience. For `executor', use +whatever function is called by `' in the applicable REPL. +For a non-repl, use `newline' or similar." + `(lambda () (interactive) (re/balance-sexp) (call-interactively ,executor))) + +(defvar *re/lisp-mode-hooks* + '(emacs-lisp-mode-hook + lisp-mode-hook + sly-mode-hook + scheme-mode-hook + geiser-mode-hook + lisp-interaction-mode-hook)) + +(dolist (hook *re/lisp-mode-hooks*) + (add-hook hook + (lambda () + (require 'sedit-mouse) + (when (bound-and-true-p acme-mouse-mode) (acme-mouse-mode -1)) + (sedit-mouse-mode 1) + (keymap-set lisp-mode-shared-map "C-M-z" #'eval-region) + (keymap-set lisp-mode-shared-map + "C-M-S-q" + #'sedit-auto-prettify-sexp) + (keymap-set lisp-mode-shared-map + "]" + (re/balance-and-eval-sexp #'sedit-auto-prettify-sexp)) + (keymap-set lisp-interaction-mode-map + "]" + (re/balance-and-eval-sexp #'eval-print-last-sexp))))) + + +;; IELM + +(add-hook 'ielm-mode-hook + (lambda () + (keymap-set inferior-emacs-lisp-mode-map + "C-l" + #'comint-clear-buffer) + (let ((eval-function #'ielm-send-input)) + (keymap-set inferior-emacs-lisp-mode-map + ")" + (re/send-on-close-paren eval-function)) + (keymap-set inferior-emacs-lisp-mode-map + "]" + (re/balance-and-eval-sexp eval-function))))) + +;; Eshell +(keymap-global-set "C-c e" #'eshell) + +(add-hook 'eshell-mode-hook + (lambda () + (keymap-set eshell-mode-map "C-d" #'eshell-quit-or-delete-char) + (let ((eval-function #'eshell-send-input)) + (keymap-set eshell-mode-map + ")" + (re/send-on-close-paren eval-function)) + (keymap-set eshell-mode-map + "]" + (re/balance-and-eval-sexp eval-function))))) + +(defun eshell-quit-or-delete-char (arg) + "Delete char if at one, quit eshell if on empty prompt. +Stolen from https://depp.brause.cc/dotemacs" + (interactive "p") + (if (and (eolp) (looking-back eshell-prompt-regexp 0 t)) + (eshell-life-is-too-much) + (delete-char arg))) + +;; SLY REPL +(add-hook 'sly-mrepl-mode-hook + (lambda () + (keymap-set sly-mrepl-mode-map + ")" + (re/send-on-close-paren #'sly-mrepl-return)) + (keymap-set sly-mrepl-mode-map + "]" + (re/balance-and-eval-sexp #'sly-mrepl-return)) + (keymap-set sly-mrepl-mode-map + "C-c q" + #'re/sly-quit-current-lisp))) + +(defun re/sly-repl-new-frame (&optional arg) + "Start a SLY repl in a new frame." + (interactive "P") + (re/open-with-new-frame "SLY" #'sly)) + +(defun re/sly-quit-current-lisp () + "Quit the current lisp repl connection without prompting." + (interactive) + (sly-quit-lisp nil nil)) + +(defun re/sly-connect-stump (&optional arg) + "Connect to my typical stumpwm instance." + (interactive "P") + (sly-connect "localhost" 4004)) + +;; GEISER REPL +(add-hook 'geiser-repl-mode-hook + (lambda () + (keymap-set geiser-repl-mode-map + ")" + (re/send-on-close-paren #'geiser-repl-maybe-send)) + (keymap-set geiser-repl-mode-map + "]" + (re/balance-and-eval-sexp #'geiser-repl-maybe-send)))) ;; Auto-Revert (global-auto-revert-mode t) @@ -259,7 +818,13 @@ (setq attempt-stack-overflow-recovery nil attempt-orderly-shutdown-on-fatal-signal nil) -;; Abbrev-mode +;; Abbrev-mode and Skeletons +(define-skeleton workorder-link + "part of a link to a workorder, just enter the number." + "" + "https://eservice.r717.net/index.php/PLC_workorders/store/" + _ -) + (setq abbrev-file-name (expand-file-name "abbrev_defs" user-emacs-directory) save-abbrevs 'silently) diff --git a/re/re-bindings.el b/re/re-bindings.el deleted file mode 100644 index a0bca3a..0000000 --- a/re/re-bindings.el +++ /dev/null @@ -1,183 +0,0 @@ -;;; re-bindings.el --- Set Bindiŋs -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs - -;;; Code: - -;; Stopping Emacs & Saving -(keymap-global-set "C-x M-c" #'re/kill-emacs) -(keymap-global-set "C-x M-r" #'re/restart-emacs) -(keymap-global-set "C-x S" (lambda () (interactive) (save-some-buffers t))) ; don't ask -(keymap-global-set "C-x c" #'delete-frame) ; delete a frame without asking about saving files - -;; Editing Bindings -(keymap-global-set "" (lambda () (interactive) (insert "\t"))) -(keymap-global-set "" nil) ; I keep toggliŋ overwrite-mode haply -(keymap-global-set "C-\\" #'undo-redo) ; issues with C-? sometimes -(keymap-global-set "C-S-K" #'kill-whole-line) -(keymap-global-set "C-w" #'re/kill-bword-or-region) -(keymap-global-set "C-u" (lambda () (interactive) (kill-line 0))) ; kill-line backwards -(keymap-global-set "C-M-S-K" #'re/kill-defun) -(keymap-global-set "C-S-U" #'universal-argument) ; C-u used above -(keymap-set key-translation-map "C-h" "") ; Rather F1 for help, also C-S-H works -(keymap-global-set "C-S-d" #'delete-pair) -(keymap-global-set "C-o" #'re/open-line-below) -(keymap-global-set "M-o" #'re/open-line-above) -(keymap-global-set "M-j" (lambda () (interactive) (join-line 0))) ; join-line other way -(keymap-global-set "C-z" #'zap-up-to-char) -(keymap-global-set "C-c s" #'sort-lines) -(keymap-global-set "M-;" #'re/comment-dwim) -(keymap-global-set "C-M-;" #'re/comment-defun) -(keymap-global-set " " #'capitalize-dwim) ; M-c -(keymap-global-set " " #'downcase-dwim) ; M-l -(keymap-global-set " " #'upcase-dwim) ; M-u -(keymap-global-set " " #'re/keyboard-quit) ; Make C-g better -(keymap-global-set " " #'re/exchange-point-and-mark-maybe-activate) - -;; Wayfindiŋ -(keymap-global-set "" #'beginning-of-buffer) -(keymap-global-set "" #'end-of-buffer) -(keymap-global-set "C-." #'next-buffer) -(keymap-global-set "C-," #'previous-buffer) -(keymap-global-set "C-" (lambda () (interactive) (switch-to-buffer nil))) ; toggle last two buffers -(keymap-global-set "" #'previous-buffer) ; Back button -(keymap-global-set "C-M-o" #'re/other-window-or-split-window) -(keymap-global-set " " #'re/smart-beginning-of-line) -(keymap-global-set " " #'re/smart-end-of-line) -(keymap-set visual-line-mode-map "C-a" #'re/smart-beginning-of-line) -(keymap-set visual-line-mode-map "C-e" #'re/smart-end-of-line) -(keymap-global-set " " #'re/goto-line) -(keymap-global-set "C-x C-n" #'forward-page) -(keymap-global-set "C-x C-p" #'backward-page) -(keymap-global-set "" #'forward-page) -(keymap-global-set "" #'backward-page) - -;; Seeking -(keymap-global-set "M-s ." #'isearch-forward-thing-at-point) -(keymap-global-set "M-s M-." #'isearch-forward-symbol-at-point) -(keymap-global-set "M-%" #'replace-regexp) -(keymap-global-set "C-%" #'replace-string) -(keymap-global-set "C-s" #'re/isearch-forward-use-region) -(keymap-global-set "C-r" #'re/isearch-backward-use-region) -(keymap-global-set "C-M-S-R" #'replace-regexp-as-diff) -(keymap-global-set "C-S-S" #'isearch-forward-regexp) -(keymap-global-set "C-S-R" #'isearch-backward-regexp) - -;; Damper/Window Dealing -(keymap-global-set "C-x C-r" #'re/rename-current-buffer-file) -(keymap-global-set "" #'scratch-buffer) -(keymap-global-set "S-" #'re/scratch-only) -(keymap-global-set "C-x M-f" #'find-file-at-point) -(keymap-global-set "C-x C-b" #'buffer-menu) -(keymap-global-set "C-x M-b" #'buffer-menu-other-window) -(keymap-global-set "C-x k" #'kill-current-buffer) -(keymap-global-set "C-x K" #'kill-buffer) -;; (keymap-global-set "C-" #'shrink-window) -;; (keymap-global-set "C-" #'enlarge-window) -;; (keymap-global-set "C-" #'shrink-window-horizontally) -;; (keymap-global-set "C-" #'enlarge-window-horizontally) -(keymap-global-set "C-c d" #'eldoc) ; force eldoc to show in minibuffer -(keymap-global-set "C-c D" #'eldoc-doc-buffer) ; open eldoc buffer when it's getting spammed -(keymap-global-set "" #'re/dired-new-frame) - -;; Mouse -(keymap-global-unset "M-") -(keymap-global-unset "M-") -(keymap-global-unset "M-") -(keymap-global-unset "M-") -(keymap-global-unset "M-") - -;; Late files and Bookmarks -(keymap-global-set "" #'recentf-open-files) -(keymap-global-set "C-x r B" #'bookmark-jump-other-window) - -;; Draftweilding -(keymap-global-set "C-x v C" #'re/vc-clone) -(keymap-global-set "C-x v b b" #'re/vc-show-branches) -(keymap-global-set "C-x v f" #'re/vc-fetch) - -(add-hook 'vc-dir-mode-hook - (lambda () - (keymap-set vc-dir-mode-map "b b" #'re/vc-show-branches) - (keymap-set vc-dir-mode-map "f" #'re/vc-fetch))) - -;; (E)Lisp - -(defvar *re/lisp-mode-hooks* - '(emacs-lisp-mode-hook - lisp-mode-hook - sly-mode-hook - scheme-mode-hook - geiser-mode-hook - lisp-interaction-mode-hook)) - -(dolist (hook *re/lisp-mode-hooks*) - (add-hook hook - (lambda () - (require 'sedit-mouse) - (when (bound-and-true-p acme-mouse-mode) (acme-mouse-mode -1)) - (sedit-mouse-mode 1) - (keymap-set lisp-mode-shared-map "C-M-z" #'eval-region) - (keymap-set lisp-mode-shared-map - "C-M-S-q" - #'sedit-auto-prettify-sexp) - (keymap-set lisp-mode-shared-map - "]" - (re/balance-and-eval-sexp #'sedit-auto-prettify-sexp)) - (keymap-set lisp-interaction-mode-map - "]" - (re/balance-and-eval-sexp #'eval-print-last-sexp))))) - -;; IELM - -(add-hook 'ielm-mode-hook - (lambda () - (keymap-set inferior-emacs-lisp-mode-map - "C-l" - #'comint-clear-buffer) - (let ((eval-function #'ielm-send-input)) - (keymap-set inferior-emacs-lisp-mode-map - ")" - (re/send-on-close-paren eval-function)) - (keymap-set inferior-emacs-lisp-mode-map - "]" - (re/balance-and-eval-sexp eval-function))))) - -;; Eshell -(keymap-global-set "C-c e" #'eshell) - -(add-hook 'eshell-mode-hook - (lambda () - (keymap-set eshell-mode-map "C-d" #'eshell-quit-or-delete-char) - (let ((eval-function #'eshell-send-input)) - (keymap-set eshell-mode-map - ")" - (re/send-on-close-paren eval-function)) - (keymap-set eshell-mode-map - "]" - (re/balance-and-eval-sexp eval-function))))) - -;; SLY REPL -(add-hook 'sly-mrepl-mode-hook - (lambda () - (keymap-set sly-mrepl-mode-map - ")" - (re/send-on-close-paren #'sly-mrepl-return)) - (keymap-set sly-mrepl-mode-map - "]" - (re/balance-and-eval-sexp #'sly-mrepl-return)) - (keymap-set sly-mrepl-mode-map - "C-c q" - #'re/sly-quit-current-lisp))) - -;; GEISER REPL -(add-hook 'geiser-repl-mode-hook - (lambda () - (keymap-set geiser-repl-mode-map - ")" - (re/send-on-close-paren #'geiser-repl-maybe-send)) - (keymap-set geiser-repl-mode-map - "]" - (re/balance-and-eval-sexp #'geiser-repl-maybe-send)))) - -(provide 're-bindings) -;;; re-bindings.el ends here diff --git a/re/re-dired-defuns.el b/re/re-dired-defuns.el deleted file mode 100644 index 60728ef..0000000 --- a/re/re-dired-defuns.el +++ /dev/null @@ -1,53 +0,0 @@ -;;; re-dired-defuns.el -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs. - -;;; Code: - -(defun re/dired-new-frame () - "Open dired in a new frame." - (interactive) - (re/open-with-new-frame "DIRED" - #'(lambda () - (interactive) - (dired default-directory)))) - -(defun re/dired-find-marked-files () - "Open all marked files from `dired'." - (interactive) - (mapc #'find-file (reverse (dired-get-marked-files)))) - -(defun re/dired-sort () - "Change sort order of dired dir." - (interactive) - (let ((smenu '(("name" . "-Ahl") - ("mdate" . "-Ahlt") - ("adate" . "-Ahltu") - ("size" . "-AhlS") - ("dir" . "-Ahl --group-directories-first"))) - ssortBy) - (setq ssortBy (completing-read "Sort by (default name):" smenu nil t nil nil (caar smenu))) - (dired-sort-other (cdr (assoc ssortBy smenu))))) - -(defun re/open-file-external (file) - "Open a file in an external program." - (interactive) - (let ((process-connection-type nil)) - (cond ((eq system-type 'windows-nt) - (w32-shell-execute "open" - (replace-regexp-in-string "/" "\\\\" file t t))) - ((eq system-type 'gnu/linux) - (start-process "" nil "xdg-open" file)) - (t (error "Unable to automatically open this file"))))) - -(defun re/dired-open-externally () - "Open the file at point in an external program." - (interactive) - (re/open-file-external (dired-get-filename))) - -(defun re/dired-open-marked-externally () - "Open all marked files from `dired' in an external program." - (interactive) - (mapc #'re/open-file-external (reverse (dired-get-marked-files)))) - -(provide 're-dired-defuns) -;;; re-dired-defuns.el ends here diff --git a/re/re-editing-defuns.el b/re/re-editing-defuns.el deleted file mode 100644 index b045bb6..0000000 --- a/re/re-editing-defuns.el +++ /dev/null @@ -1,171 +0,0 @@ -;;; re-editing-defuns.el -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs. - -;;; Code: - -(defun re/scratch-only () - "Bring up the scratch buffer as the only visible buffer." - (interactive) - (scratch-buffer) - (delete-other-windows)) - -(defun re/open-line-below (n) - "Creates a new empty line below the current line and moves to it." - (interactive "*p") - (end-of-line) - (open-line n) - (next-line 1) - (indent-for-tab-command)) - -(defun re/open-line-above (n) - "Creates a new empty line above the current line." - (interactive "*p") - (beginning-of-line) - (open-line n) - (indent-for-tab-command)) - -(defun re/flush-extra-lines () - "Change all groups of blank lines to 1 blank line." - (interactive) - (save-excursion (mark-whole-buffer) - (replace-regexp "^\n+" - "\n" - nil - (region-beginning) - (region-end)))) - -(defun re/comment-dwim (&optional arg) - "Comment region if active, otherwise comment line. -Stolen from https://depp.brause.cc/dotemacs" - (interactive "P") - (if (use-region-p) - (comment-or-uncomment-region (region-beginning) (region-end)) - (comment-line arg))) - -(defun re/comment-defun (&optional arg) - "Mark a defun and comment it out. -Return to initial position after. Arg works on `mark-defun'." - (interactive "P") - (save-excursion (mark-defun arg) - (comment-region (region-beginning) (region-end)))) - -(defun re/kill-defun (&optional arg) - "Mark a defun and kill it. -Arg works on `mark-defun'." - (interactive "P") - (mark-defun arg) - (kill-region (region-beginning) (region-end))) - -(defun re/kill-bword-or-region (&optional arg) -"Kill region if active, otherwise kill back one word." -(interactive "p") -(if (use-region-p) - (kill-region (region-beginning) (region-end)) - (backward-kill-word arg))) - -(defun re/smart-beginning-of-line () - "Move point to first non-whitespace character or `beginning-of-visual-line'. -If point was already at that position, call `back-to-indentation'. -Called a third time, move point back to `beginning-of-line'. -If in org-mode, call `org-beginning-of-line' first." - (interactive "^") - (let ((oldpos (point))) - (if (equal major-mode 'org-mode) - (org-beginning-of-line) - (progn - (when visual-line-mode (beginning-of-visual-line 1)) - (skip-syntax-forward " " (line-end-position)) - (backward-prefix-chars))) - (and (= oldpos (point)) - (let ((newpos (point))) - (back-to-indentation) - (and (= newpos (point)) (beginning-of-line)))))) - -(defun re/smart-end-of-line () - "Move point to the end of the visual line. - If point was already at that position, call `move-end-of-line'. -If in org-mode, call `org-end-of-line' first." - (interactive "^") - (let ((oldpos (point))) - (if (equal major-mode 'org-mode) - (org-end-of-line) - (when visual-line-mode - (end-of-visual-line 1))) - (and (= oldpos (point)) (move-end-of-line nil)))) - -(defun re/goto-line () - "Show line numbers before going to line, then hide them again." - (interactive) - (display-line-numbers-mode 1) - (call-interactively 'goto-line) - (display-line-numbers-mode -1)) - -(defun re/other-window-or-split-window (&optional window) - "Go to other window or split sensibly." - (interactive) - (if (= (count-windows) 1) - (funcall split-window-preferred-function window) - (other-window 1))) - -(defun re/isearch-forward-use-region () - "Search text in region if active, otherwise normal forward search." - (interactive) - (when (use-region-p) - (add-to-history 'search-ring - (buffer-substring (region-beginning) (region-end))) - (deactivate-mark)) - (isearch-forward)) - -(defun re/isearch-backward-use-region () - "Search text in region if active, otherwise normal backward search." - (interactive) - (when (use-region-p) - (add-to-history 'search-ring - (buffer-substring (region-beginning) (region-end))) - (deactivate-mark)) - (isearch-backward)) - -(defun Tab (width) - "Give me a function analagous to the Acme `Tab' command" - (interactive) - (setq-local tab-width width)) - -(defun re/kill-emacs () - "Save all open files and kill emacs." - (interactive) - (save-some-buffers t) - (kill-emacs)) - -(defun re/restart-emacs () - "Save all open files and restart emacs." - (interactive) - (save-some-buffers t) - (kill-emacs nil t)) - -(defun re/exchange-point-and-mark-maybe-activate (arg) - "Call `exchange-point-and-mark' but don't activate the region. -Stolen from https://www.masteringemacs.org/article/fixing-mark-commands-transient-mark-mode" - (interactive "P") - (exchange-point-and-mark (if (and transient-mark-mode (not mark-active)) - (not arg) - arg))) - -(defun re/keyboard-quit () - "Smarter version of `keyboard-quit'. -Close the minibuffer if not focused when hit. -Stolen from emacsredux.com." - (interactive) - (if (active-minibuffer-window) - (if (minibufferp) - (minibuffer-keyboard-quit) - (abort-recursive-edit)) - (keyboard-quit))) - -(defmacro re/open-with-new-frame (frname function) - "Run the function in its own named frame." - `(progn - (select-frame (make-frame '((name . ,(eval frname))))) - (call-interactively ,function))) - -(provide 're-editing-defuns) -;;; re-editing-defuns.el ends here diff --git a/re/re-file-defuns.el b/re/re-file-defuns.el deleted file mode 100644 index 5f3b0c3..0000000 --- a/re/re-file-defuns.el +++ /dev/null @@ -1,63 +0,0 @@ -;;; re-file-defuns.el -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs. - -;;; Code: - -(defun re/rename-current-buffer-file nil - "Renames the current buffer and the file it is visiting." - (interactive) - (let ((name (buffer-name)) - (filename (buffer-file-name))) - (if (not (and filename (file-exists-p filename))) - (error "Buffer '%s' is not visiting a file!" name) - (let ((new-name (read-file-name "New name: " filename))) - (if (get-buffer new-name) - (error "A buffer named '%s' already exists!" new-name) - (rename-file filename new-name 1) - (rename-buffer new-name) - (set-visited-file-name new-name) - (set-buffer-modified-p nil) - (message "File '%s' successfully renamed to '%s'" - name - (file-name-nondirectory new-name))))))) - -(defun re/get-line-from-file (file-path line-number) - "Return the specified LINE-NUMBER from FILE-PATH as a string. -Start from bottom if given a negative line number." - (with-temp-buffer - (insert-file-contents file-path) - (if (< line-number 0) - (progn - (goto-char (point-max)) - (forward-line line-number)) - (progn - (goto-char (point-min)) - (forward-line (1- line-number)))) - (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) - -(defun re/get-file-modified-time (filepath) - (interactive) - (format-time-string "%Y-%m-%d-%H%M" - (file-attribute-modification-time (file-attributes filepath)))) - -(defun re/filename-inject-mod-time (filepath) - (interactive) - (concat (file-name-sans-extension filepath) - "_" - (re/get-file-modified-time filepath) - (file-name-extension filepath t))) - -(defun re/copy-with-mod-time (&optional filepath) - (interactive) - (let ((filepath (if (eq major-mode 'dired-mode) - (dired-get-filename t) - (when (null filepath) - (read-file-name "File to copy with datestring: " - default-directory - nil - t - nil))))) - (copy-file filepath (re/filename-inject-mod-time filepath ) nil t t t))) - -(provide 're-file-defuns) -;;; re-file-defuns.el ends here diff --git a/re/re-repl-defuns.el b/re/re-repl-defuns.el deleted file mode 100644 index f0ca5ab..0000000 --- a/re/re-repl-defuns.el +++ /dev/null @@ -1,75 +0,0 @@ -;;; re-repl-defuns.el -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs - -;;; Code: - -;; Any Lisp Repl -(defmacro re/send-on-close-paren (executor) - "Generalizes sending an execute on close paren. - Interactively call `executor'. For `executor', use whatever - function is called by `' in the applicable REPL. For a - non-repl, use `newline' or similar." - `(lambda (&optional arg) - (interactive "p") - (insert-char 41 arg) - (call-interactively ,executor))) - -(defun re/sexp-drop-paren-p () - "Returns t if sexp needs fewer parens to balance." - (< (car (syntax-ppss)) 0)) - -(defun re/sexp-need-paren-p () - "Returns t if sexp needs more parens to balance." - (> (car (syntax-ppss)) 0)) - -(defun re/sexp-unbalanced-count () - "Returns distance from balanced sexp." - (abs (car (syntax-ppss)))) - -(defun re/balance-sexp () - "Balance the sexp before point. -Either delete, move forward, or add as many ')' as needed." - (let ((distance (re/sexp-unbalanced-count))) - (cond ((re/sexp-need-paren-p) - (if (looking-at ")") - (progn - (forward-char) - (re/balance-sexp)) - (insert-char 41 distance))) - ((re/sexp-drop-paren-p) - (backward-delete-char distance))))) - -(defmacro re/balance-and-eval-sexp (executor) - "Balance the sexp before point, then call `executor'. -Call `re/balance-sexp', then interactively call `executor'. Bind -this to ']' for the interlisp experience. For `executor', use -whatever function is called by `' in the applicable REPL. -For a non-repl, use `newline' or similar." - `(lambda () (interactive) (re/balance-sexp) (call-interactively ,executor))) - -;; REPL specific -(defun eshell-quit-or-delete-char (arg) - "Delete char if at one, quit eshell if on empty prompt. -Stolen from https://depp.brause.cc/dotemacs" - (interactive "p") - (if (and (eolp) (looking-back eshell-prompt-regexp 0 t)) - (eshell-life-is-too-much) - (delete-char arg))) - -(defun re/sly-repl-new-frame (&optional arg) - "Start a SLY repl in a new frame." - (interactive "P") - (re/open-with-new-frame "SLY" #'sly)) - -(defun re/sly-quit-current-lisp () - "Quit the current lisp repl connection without prompting." - (interactive) - (sly-quit-lisp nil nil)) - -(defun re/sly-connect-stump (&optional arg) - "Connect to my typical stumpwm instance." - (interactive "P") - (sly-connect "localhost" 4004)) - -(provide 're-repl-defuns) -;;; re-repl-defuns.el ends here diff --git a/re/re-skeletons.el b/re/re-skeletons.el deleted file mode 100644 index f9bd178..0000000 --- a/re/re-skeletons.el +++ /dev/null @@ -1,26 +0,0 @@ -;;; re-skeletons.el -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs - -;;; Code: -(define-skeleton skel-org-block - "Insert an org source code block" - "" - "#+begin_src " - _ - "\n\n" - "#+end_src\n") - -(define-skeleton skel-org-block-elisp - "Insert an org emacs lisp block" - "" - "#+begin_src emacs-lisp\n" - _ - \n - "#+end_src\n") - -(define-skeleton workorder-link - "part of a link to a workorder, just enter the number." - "" - "https://eservice.r717.net/index.php/PLC_workorders/store/" - _ -) - -(provide 're-skeletons) -;;; re-skeletons.el ends here diff --git a/re/re-vc-defuns.el b/re/re-vc-defuns.el deleted file mode 100644 index e72d72b..0000000 --- a/re/re-vc-defuns.el +++ /dev/null @@ -1,52 +0,0 @@ -;;; re-vc-defuns.el -*- lexical-binding: t; -*- -;; This file is not part of GNU Emacs. - -;;; Code: - -(defun re/vc-clone () - "Interactively clone with vc-mode. -Prompt for url and local dir." - (interactive) - (let* ((url (read-string "Repository URL: ")) - (dir (read-string "Local Dir: " (file-name-base url)))) - (vc-git-clone url dir nil))) - -(defun re/vc-show-branches (&optional arg) - "Display all Git branches in a separate buffer. -Remotes as well when arg." - (interactive "P") - (let ((default-directory (if (boundp 'vc-dir-directory) - vc-dir-directory - default-directory))) - (vc-git-command "*git-branches*" - nil - nil - "branch" - "--verbose" - (when arg "--remotes")) - (pop-to-buffer "*git-branches*") - (goto-char (point-min)) - (special-mode))) - -(defun re/vc-fetch (&optional arg) - "Interactively fetch with vc-mode. -Allows separate fetch in addition to pull. Only care about git. -With arg, ask for remote, otherwise fetch all." - (interactive "P") - (let* ((default-directory (if (boundp 'vc-dir-directory) - vc-dir-directory - default-directory))) - (vc-git-command "*vc-fetch*" - nil - nil - "fetch" - (if arg - (read-string "Fetch From: " "origin") - "--all") - "--verbose") - (pop-to-buffer "*vc-fetch*") - (goto-char (point-min)) - (special-mode))) - -(provide 're-vc-defuns) -;;; re-vc-defuns.el ends here