diff options
Diffstat (limited to '.config/emacs/modules/mm-editing.el')
| -rw-r--r-- | .config/emacs/modules/mm-editing.el | 449 |
1 files changed, 0 insertions, 449 deletions
diff --git a/.config/emacs/modules/mm-editing.el b/.config/emacs/modules/mm-editing.el deleted file mode 100644 index 24aa7ea..0000000 --- a/.config/emacs/modules/mm-editing.el +++ /dev/null @@ -1,449 +0,0 @@ -;;; mm-editing.el --- Text editing configuation -*- lexical-binding: t; -*- - -;;; Delete Region When Typing - -(use-package delsel - :hook (after-init . delete-selection-mode)) - - -;;; Capitalize ‘ß’ into ‘ẞ’ - -;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2024-11/msg00030.html -(set-case-syntax-pair ?ẞ ?ß (standard-case-table)) -(put-char-code-property ?ß 'special-uppercase nil) - - -;;; Force Spaces For Alignment - -(defun mm-editing-force-space-indentation (function &rest arguments) - "Call FUNCTION with ARGUMENTS in an environment in which -`indent-tabs-mode' is nil." - (let (indent-tabs-mode) - (apply function arguments))) - -(dolist (command #'(align-region - c-backslash-region - comment-dwim - makefile-backslash-region - sh-backslash-region)) - (advice-add command :around #'mm-editing-force-space-indentation)) - - -;;; Recenter The Screen When Jumping - -(mm-comment - (dolist (command #'(backward-page - backward-paragraph - forward-page - forward-paragraph - pop-global-mark)) - (advice-add command :around #'mm-do-and-center))) - - -;;; Indentation Settings - -(setq-default - tab-width 4 - indent-tabs-mode (not mm-humanwave-p)) - -(defvar mm-editing-indentation-settings-alist - '((awk-ts-mode . (:extras awk-ts-mode-indent-level)) - (c-mode . (:extras c-basic-offset)) - (c-ts-mode . (:extras c-ts-mode-indent-offset)) - (css-mode . (:extras css-indent-offset)) - (elixir-ts-mode . (:width 2 :extras elixir-ts-indent-offset)) - (emacs-lisp-mode . (:width 8 :spaces t)) ; GNU code uses 8-column tabs - (go-mod-ts-mode . (:extras go-ts-mode-indent-offset)) - (go-ts-mode . (:extras go-ts-mode-indent-offset)) - (gsp-ts-mode . (:width 2 :extras gsp-ts-mode-indent-rules)) - (helpful-mode . (:width 8)) ; GNU code uses 8-column tabs - (json-ts-mode . (:extras json-ts-mode-indent-offset)) - (latex-mode . (:width 2)) - (lisp-data-mode . (:spaces t)) - (lisp-interaction-mode . (:spaces t)) - (lisp-mode . (:spaces t)) - (mhtml-mode . (:extras sgml-basic-offset)) - (org-mode . (:width 8 :spaces t)) - (python-mode . (:extras python-indent-offset)) - (python-ts-mode . (:extras python-indent-offset)) - (sgml-mode . (:extras sgml-basic-offset)) - (sh-mode . (:extras sh-basic-offset)) - (sql-mode . (:extras sqlind-basic-offset)) - (tex-mode . (:width 2)) - (typescript-ts-mode . (:extras typescript-ts-mode-indent-offset)) - (vimscript-ts-mode . (:extras vimscript-ts-mode-indent-level)) - (vue-ts-mode . (:extras (typescript-ts-mode-indent-offset - vue-ts-mode-indent-offset)))) - "Alist of indentation settings. -Each pair in this alist is of the form (MODE . SETTINGS) where MODE -specifies the mode for which the given SETTINGS should apply. - -SETTINGS is a plist of one-or-more of the following keys: - - `:spaces' -- If nil force tabs for indentation, if non-nil for spaces - for indentation. If this key is not provided then the - value of `indent-tabs-mode' is used. - `:width' -- Specifies a non-negative number to be used as the tab - width and indentation offset. If this key is not - provided then the default value of `tab-width' is used. - `:extras' -- A list of mode-specific variables which control - indentation settings that need to be set for - configurations to properly be applied.") - -(defun mm-editing-set-indentation-settings () - "Set indentation settings for the current major mode. -The indentation settings are set based on the configured values in -`mm-editing-indentation-settings-alist'." - (let* ((plist (alist-get major-mode mm-editing-indentation-settings-alist)) - (spaces (plist-member plist :spaces)) - (width (plist-member plist :width)) - (extras (plist-member plist :extras))) - ;; Some modes like ‘python-mode’ explicitly set ‘tab-width’ and - ;; ‘indent-tabs-mode’ so we must override them explicitly. - (setq-local indent-tabs-mode (if spaces (not (cadr spaces)) - (default-value 'indent-tabs-mode)) - tab-width (or (cadr width) (default-value 'tab-width))) - (when extras - (setq extras (cadr extras)) - (when (symbolp extras) - (setq extras (list extras))) - (dolist (extra extras) - (set extra tab-width))))) - -(add-hook 'after-change-major-mode-hook #'mm-editing-set-indentation-settings) - -(defun mm-editing-set-tabsize () - "Set the tabsize for the current buffer. -If the current buffer’s major mode requires setting additional variables, -those should be listed in `mm-editing-indentation-settings'." - (interactive) - (let* ((prompt-default (default-value 'tab-width)) - (prompt (format-prompt "Tabsize" prompt-default)) - (tabsize (mm-as-number (read-string prompt nil nil prompt-default)))) - (setq-local tab-width tabsize) - (when-let* ((plist (alist-get major-mode mm-editing-indentation-settings)) - (extras (plist-get plist :extras))) - (dolist (extra (if (symbolp extras) - (list extras) - extras)) - (set (make-local-variable extra) tabsize))))) - -(use-package sh-mode - :custom - (sh-indent-for-case-label 0) - (sh-indent-for-case-alt #'+)) - - -;;; Code Commenting - -(defun mm-newcomment-c-config () - (setq-local comment-continue " ")) - -(defun mm-newcomment-html-config () - (setq-local comment-continue " ")) - -(defun mm-newcomment-rust-config () - (setq-local comment-start "/* " - comment-end " */" - comment-continue " * " ; rustfmt doesn’t play nice - comment-quote-nested nil)) - -(use-package newcomment - :custom - (comment-style 'multi-line) - :config - (dolist (mode '(c-mode c++-mode)) - (add-hook (mm-mode-to-hook mode) #'mm-newcomment-c-config) - (when-let ((ts-mode (mm-mode-to-ts-mode mode)) - ((fboundp ts-mode))) - (add-hook (mm-mode-to-hook ts-mode) #'mm-newcomment-c-config))) - (add-hook 'mhtml-mode-hook #'mm-newcomment-html-config) - (add-hook 'rust-ts-mode-hook #'mm-newcomment-rust-config)) - - -;;; Multiple Cursors - -(defmacro mm--define-mc-marking-command (name search-function noun) - (let ((noun-symbol (intern noun))) - `(defun ,name (beg end ,noun-symbol) - ,(format "Mark all occurances of %s between BEG and END. -If called interactively with an active region then all matches in the -region are marked, otherwise all matches in the buffer are marked." - (upcase noun)) - (interactive - (list (or (use-region-beginning) (point-min)) - (or (use-region-end) (point-max)) - (read-string - (format-prompt ,(concat "Match " noun) nil)))) - (if (string-empty-p ,noun-symbol) - (message "Command aborted") - (catch 'mm--no-match - (mc/remove-fake-cursors) - (goto-char beg) - (let (did-match-p) - (while (,search-function ,noun-symbol end :noerror) - (setq did-match-p t) - (push-mark (match-beginning 0)) - (exchange-point-and-mark) - (mc/create-fake-cursor-at-point) - (goto-char (mark))) - (unless did-match-p - (message "No match for `%s'" ,noun-symbol) - (throw 'mm--no-match nil))) - (when-let ((first (mc/furthest-cursor-before-point))) - (mc/pop-state-from-overlay first)) - (if (> (mc/num-cursors) 1) - (multiple-cursors-mode 1) - (multiple-cursors-mode 0))))))) - -(mm--define-mc-marking-command - mm-mark-all-in-region search-forward "string") -(mm--define-mc-marking-command - mm-mark-all-in-region-regexp re-search-forward "regexp") - -(mm-comment - (defun mm-silent-mc-load (args) - "Advice to `load' to force it to be silent. -The `multiple-cursors' package loads an `.mc-lists.el' file without -passing `:nomessage' which causes messages to be sent in the minibuffer -and *Messages* buffer. This forces that to not happen." - (when (and (boundp 'mc/list-file) - (string= (file-truename (car args)) - (file-truename mc/list-file))) - (pcase (length args) - (1 (setq args (list (car args) nil :nomessage))) - (2 (add-to-list 'args :nomessage :append)) - (_ (setf (caddr args) :nomessage))) - (advice-remove #'load #'mm-silent-mc-load)) - args)) - -(use-package multiple-cursors - :ensure t - :demand t - :bind (("C->" . #'mc/mark-next-like-this) - ("C-<" . #'mc/mark-previous-like-this) - ("C-M-<" . #'mc/mark-all-like-this-dwim) - ("C-M->" . #'mc/edit-lines) - :map search-map - ("$" . #'mm-mark-all-in-region) - ("M-$" . #'mm-mark-all-in-region-regexp)) - :commands ( mm-mark-all-in-region mm-mark-all-in-region-regexp - mm-add-cursor-to-next-thing mm-transpose-cursor-regions) - :init - (mm-comment - (advice-add #'load :filter-args #'mm-silent-mc-load) - (with-eval-after-load 'multiple-cursors-core - (dolist (command #'(backward-delete-char - capitalize-dwim - delete-backward-char - delete-forward-char - downcase-dwim - upcase-dwim)) - (add-to-list 'mc/cmds-to-run-for-all command)) - (dolist (command #'(helpful-callable - helpful-key - helpful-symbol - helpful-variable)) - (add-to-list 'mc/cmds-to-run-once command)))) - (with-eval-after-load 'multiple-cursors-core - (keymap-unset mc/keymap "<return>" :remove))) - - -;;; Increment Numbers - -(use-package increment - :bind (("C-c i i" . #'increment-number-at-point) - ("C-c i d" . #'decrement-number-at-point)) - :commands (increment-number-at-point decrement-number-at-point)) - - -;;; Move Line or Region - -(defun mm-move-text-indent (&rest _) - (let ((deactivate deactivate-mark)) - (if (region-active-p) - (indent-region (region-beginning) (region-end)) - (indent-region (line-beginning-position) (line-end-position))) - (setq deactivate-mark deactivate))) - -(use-package move-text - :ensure t - :bind (("M-n" . move-text-down) - ("M-p" . move-text-up)) - :config - (dolist (command #'(move-text-up move-text-down)) - (advice-add command :after #'mm-move-text-indent))) - - -;;; Surround With Delimeters - -(defun mm-editing-surround-with-spaces (char) - "Surrounds region or current symbol with a pair defined by CHAR. -This is the same as `surround-insert' except it pads the contents of the -surround with spaces." - (interactive - (list (char-to-string (read-char "Character: ")))) - (let* ((pair (surround--make-pair char)) - (left (car pair)) - (right (cdr pair)) - (bounds (surround--infer-bounds t))) - (save-excursion - (goto-char (cdr bounds)) - (insert " " right) - (goto-char (car bounds)) - (insert left " ")) - (when (eq (car bounds) (point)) - (forward-char)))) - -;; TODO: Implement this manually -(use-package surround - :ensure t - :bind-keymap ("M-'" . surround-keymap) - :bind (:map surround-keymap - ("S" . #'mm-editing-surround-with-spaces)) - :config - (dolist (pair '(("‘" . "’") - ("“" . "”") - ("»" . "«") - ("⟮" . "⟯"))) - (push pair surround-pairs)) - (make-variable-buffer-local 'surround-pairs) - (add-hook 'emacs-lisp-mode-hook - (defun mm-editing-add-elisp-quotes-pair () - (push '("`" . "'") surround-pairs)))) - - -;;; Insert Webpage Contents - -(defun mm-insert-from-url (url) - "Insert the contents of URL at point." - (interactive - (let ((url-at-point (thing-at-point 'url))) - (list (read-string - (format-prompt "URL" url-at-point) - nil nil url-at-point)))) - (call-process "curl" nil '(t nil) nil url)) - - -;;; Emmet Mode - -(defun mm-editing-emmet-dwim (arg) - "Do-What-I-Mean Emmet expansion. -If the region is active then the region will be surrounded by an emmet -expansion read from the minibuffer. Otherwise the emmet expression -before point is expanded. When provided a prefix argument the behaviour -is as described by `emmet-expand-line'." - (interactive "P") - (if (region-active-p) - (call-interactively #'emmet-wrap-with-markup) - (emmet-expand-line arg))) - -(use-package emmet-mode - :ensure t - :bind ("C-," . mm-editing-emmet-dwim) - :custom - (emmet-self-closing-tag-style "")) - - -;;; JQ Manipulation in JSON Mode - -(defun mm-jq-filter (query &optional beg end) - "TODO" - (interactive - (list - (read-string (format-prompt "Query" nil)) - (when (use-region-p) (region-beginning)) - (when (use-region-p) (region-end)))) - (let* ((beg (or beg (point-min))) - (end (or end (point-max))) - (temp-buffer (generate-new-buffer "* jq temp*")) - (exit-code (call-process-region beg end "jq" nil temp-buffer nil - "--tab" query)) - (output (with-current-buffer temp-buffer (buffer-string)))) - (if (zerop exit-code) - (atomic-change-group - (delete-region beg end) - (insert output) - (indent-region beg (point))) - (message "%s" output)) - (kill-buffer temp-buffer))) - -(use-package json-ts-mode - :bind ( :map json-ts-mode-map - ("C-|" . #'mm-jq-filter)) - :config - (require 'live-jq)) - - -;;; Number Formatting - -(use-package number-format-mode - :commands ( number-format-buffer number-format-region - number-unformat-buffer number-unformat-region - number-format-mode)) - - -;;; Additional Major Modes - -(use-package awk-ts-mode :ensure t) -(use-package cmake-mode :ensure t) -(use-package git-modes :ensure t) -(use-package kdl-mode :ensure t) -(use-package po-mode :ensure t) -(use-package sed-mode :ensure t) - -(use-package csv-mode - :ensure t - :custom - (csv-align-style 'auto) - (csv-align-padding 2)) - -(use-package xcompose-mode - :vc ( :url "https://git.thomasvoss.com/xcompose-mode" - :branch "master" - :rev :newest - :vc-backend Git) - :ensure t) - -(use-package yaml-pro - :hook ((yaml-mode . yaml-pro-mode) - (yaml-ts-mode . yaml-pro-ts-mode))) - - -;;; Mode-Specific Configurations - -(use-package make-mode - :custom - (makefile-backslash-column 80)) - -(use-package python-mode - :custom - (python-indent-def-block-scale 1) - (python-indent-guess-indent-offset-verbose nil)) - - -;;; Add Missing Extensions - -(dolist (pattern '("\\.tmac\\'" "\\.mom\\'")) - (add-to-list 'auto-mode-alist (cons pattern #'nroff-mode))) - - -;;; Subword Navigation - -(use-package subword - :hook prog-mode) - - -;;; Edit Files via Doas/Sudo - -(defvar mm-root-editing-program - (if (string= (system-name) "mangobox") "doas" "sudo")) - -(defun mm-edit-root-protected-file-buffer () - (interactive) - (when (and buffer-file-name (not (file-writable-p buffer-file-name))) - (find-alternate-file (format "/%s:root@localhost:%s" - mm-root-editing-program - buffer-file-name)))) - -(provide 'mm-editing) |