From: rearman Date: Thu, 2 Oct 2025 19:52:01 +0000 (-0400) Subject: Defuns for files, commenting and killing by defun X-Git-Url: https://git.earman.xyz/?a=commitdiff_plain;h=1c8c1dd919b9c662e522da11505d093b682e37fb;p=emacsinit.git Defuns for files, commenting and killing by defun File Defuns: Move file-related defuns to their own provision, require it in init. Add defuns to copy a file and put its modified date in the filename. Comment/kill by defun: Make comment-defun respect arg for its call to mark-defun. Add a defun to kill by defun, also using mark-defun and its arg. Bind this to C-M-S-K. --- diff --git a/init.el b/init.el index ebeb16c..bfa5539 100644 --- a/init.el +++ b/init.el @@ -12,6 +12,7 @@ (require 're-packages) (require 're-editing-defuns) +(require 're-file-defuns) (require 're-vc-defuns) ;; (require 'acme-mouse) ;; (require 'fully-mono-themes) diff --git a/re/re-bindings.el b/re/re-bindings.el index 9fdf948..fce52dc 100644 --- a/re/re-bindings.el +++ b/re/re-bindings.el @@ -15,6 +15,7 @@ (keymap-global-set "C-w" #'backward-kill-word) (keymap-global-set "C-S-W" #'kill-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) diff --git a/re/re-editing-defuns.el b/re/re-editing-defuns.el index 3c77d51..b0a3f89 100644 --- a/re/re-editing-defuns.el +++ b/re/re-editing-defuns.el @@ -3,24 +3,6 @@ ;;; 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/scratch-only () "Bring up the scratch buffer as the only visible buffer." (interactive) @@ -60,12 +42,20 @@ Stolen from https://depp.brause.cc/dotemacs" (comment-or-uncomment-region (region-beginning) (region-end)) (comment-line))) -(defun re/comment-defun () - "Mark a defun and comment it out." - (interactive) - (save-excursion (mark-defun) +(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 () "Kill region if active, otherwise kill back one word." (interactive) @@ -170,20 +160,6 @@ Stolen from emacsredux.com." (abort-recursive-edit)) (keyboard-quit))) -(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)))) - (defmacro re/open-with-new-frame (frname function) "Run the function in its own named frame." `(progn diff --git a/re/re-file-defuns.el b/re/re-file-defuns.el new file mode 100644 index 0000000..5f3b0c3 --- /dev/null +++ b/re/re-file-defuns.el @@ -0,0 +1,63 @@ +;;; 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