From 5e5d07543198ccfb7aaf9bbc79470ff8d2097530 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 14 Feb 2018 02:26:16 -0500 Subject: [PATCH] New doom/*-this-file commands; move doom/sudo* to new files library --- core/autoload/editor.el | 15 ---- core/autoload/files.el | 116 +++++++++++++++++++++++++ modules/feature/evil/autoload/files.el | 86 ++---------------- 3 files changed, 124 insertions(+), 93 deletions(-) create mode 100644 core/autoload/files.el diff --git a/core/autoload/editor.el b/core/autoload/editor.el index f26a6d283..5973198c2 100644 --- a/core/autoload/editor.el +++ b/core/autoload/editor.el @@ -1,20 +1,5 @@ ;;; core/autoload/editor.el -*- lexical-binding: t; -*- -;;;###autoload -(defun doom/sudo-find-file (file) - "Open FILE as root." - (interactive - (list (read-file-name "Open as root: "))) - (find-file (if (file-writable-p file) - file - (concat "/sudo:root@localhost:" file)))) - -;;;###autoload -(defun doom/sudo-this-file () - "Open the current file as root." - (interactive) - (doom/sudo-find-file (file-truename buffer-file-name))) - ;;;###autoload (defun doom/backward-to-bol-or-indent () "Jump between the indentation column (first non-whitespace character) and the diff --git a/core/autoload/files.el b/core/autoload/files.el new file mode 100644 index 000000000..b45c66df6 --- /dev/null +++ b/core/autoload/files.el @@ -0,0 +1,116 @@ +;;; core/autoload/files.el -*- lexical-binding: t; -*- + +;;;###autoload +(defun doom/sudo-find-file (file) + "Open FILE as root." + (interactive + (list (read-file-name "Open as root: "))) + (find-file (if (file-writable-p file) + file + (concat "/sudo:root@localhost:" file)))) + +;;;###autoload +(defun doom/sudo-this-file () + "Open the current file as root." + (interactive) + (doom/sudo-find-file (file-truename buffer-file-name))) + + +;; +(defun doom--forget-file (old-path &optional new-path) + "Ensure `recentf', `projectile' and `save-place' forget OLD-PATH." + (when (bound-and-true-p recentf-mode) + (when new-path + (recentf-add-file new-path)) + (recentf-remove-if-non-kept old-path)) + (when (and projectile-mode + (projectile-project-p) + (projectile-file-cached-p old-path (projectile-project-root))) + (projectile-purge-file-from-cache old-path)) + (when (bound-and-true-p save-place-mode) + (save-place-forget-unreadable-files))) + +(defun doom--copy-file (old-path new-path &optional force-p) + (let* ((new-path (expand-file-name new-path)) + (old-path (file-truename old-path)) + (new-path (apply #'expand-file-name + (if (or (directory-name-p new-path) + (file-directory-p new-path)) + (list (file-name-nondirectory old-path) new-path) + (list new-path)))) + (new-path-dir (file-name-directory new-path)) + (project-root (doom-project-root)) + (short-new-name (if (file-in-directory-p new-path project-root) + (file-relative-name new-path project-root) + (abbreviate-file-name new-path)))) + (unless (file-directory-p new-path-dir) + (make-directory new-path-dir t)) + (when (buffer-modified-p) + (save-buffer)) + (cond ((equal (file-truename old-path) + (file-truename new-path)) + (throw 'status 'overwrite-self)) + ((and (file-exists-p new-path) + (not force-p) + (not (y-or-n-p (format "File already exists at %s, overwrite?" short-new-name)))) + (throw 'status 'aborted)) + (t + (copy-file old-path new-path t) + short-new-name)))) + +;;;###autoload +(defun doom/delete-this-file (&optional path force-p) + "Delete FILENAME (defaults to the file associated with current buffer) and +kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)." + (interactive + (list (file-truename (buffer-file-name)) + current-prefix-arg)) + (let* ((fbase (file-name-sans-extension (file-name-nondirectory path))) + (buf (current-buffer))) + (cond ((not (file-exists-p path)) + (error "File doesn't exist: %s" path)) + ((not (or force-p (y-or-n-p (format "Really delete %s?" fbase)))) + (message "Aborted") + nil) + (t + (unwind-protect + (progn (delete-file path) t) + (let ((short-path (file-relative-name path (doom-project-root)))) + (if (file-exists-p path) + (error "Failed to delete %s" short-path) + ;; Ensures that windows displaying this buffer will be switched + ;; to real buffers (`doom-real-buffer-p') + (doom/kill-this-buffer-in-all-windows buf t) + (doom--forget-file path) + (message "Successfully deleted %s" short-path)))))))) + +;;;###autoload +(defun doom/copy-this-file (new-path &optional force-p) + "Copy current buffer's file to NEW-PATH. If FORCE-P, overwrite the destination +file if it exists, without confirmation." + (interactive "F") + (pcase (catch 'status + (when-let* ((dest (doom--copy-file (buffer-file-name) new-path force-p))) + (message "File successfully copied to %s" dest))) + (`overwrite-self (error "Cannot overwrite self")) + (`aborted (message "Aborted")) + (_ t))) + +;;;###autoload +(defun doom/move-this-file (new-path &optional force-p) + "Move current buffer's file to NEW-PATH. If FORCE-P, overwrite the destination +file if it exists, without confirmation." + (interactive "FP") + (pcase (catch 'status + (let ((old-path (buffer-file-name)) + (new-path (expand-file-name new-path))) + (when-let* ((dest (doom--copy-file old-path new-path force-p))) + (delete-file old-path) + (kill-this-buffer) + (find-file new-path) + (doom--forget-file old-path new-path) + (message "File successfully moved to %s" dest)))) + (`overwrite-self (error "Cannot overwrite self")) + (`aborted (message "Aborted")) + (_ t))) + diff --git a/modules/feature/evil/autoload/files.el b/modules/feature/evil/autoload/files.el index c7d293281..d94705021 100644 --- a/modules/feature/evil/autoload/files.el +++ b/modules/feature/evil/autoload/files.el @@ -1,71 +1,13 @@ ;;; feature/evil/autoload/files.el -*- lexical-binding: t; -*- -(defun +evil--forget-file (old-path &optional new-path) - "Ensure `recentf', `projectile' and `save-place' forget OLD-PATH." - (when (bound-and-true-p recentf-mode) - (when new-path - (recentf-add-file new-path)) - (recentf-remove-if-non-kept old-path)) - (when (and projectile-mode - (projectile-project-p) - (projectile-file-cached-p old-path (projectile-project-root))) - (projectile-purge-file-from-cache old-path)) - (when (bound-and-true-p save-place-mode) - (save-place-forget-unreadable-files))) - ;;;###autoload (autoload '+evil:delete-this-file "feature/evil/autoload/files" nil t) (evil-define-command +evil:delete-this-file (&optional filename force-p) "Delete FILENAME (defaults to the file associated with current buffer) and kills the buffer. If FORCE-P, force the deletion (don't ask for confirmation)." :repeat nil (interactive "") - (let* ((fname (file-truename (or filename (buffer-file-name)))) - (fbase (file-name-sans-extension (file-name-nondirectory fname))) - (buf (current-buffer))) - (cond ((not (file-exists-p fname)) - (error "File doesn't exist: %s" fname)) - ((not (or force-p (y-or-n-p (format "Really delete %s?" fbase)))) - (message "Aborted") - nil) - (t - (unwind-protect - (progn (delete-file fname) t) - (let ((short-path (file-relative-name fname (doom-project-root)))) - (if (file-exists-p fname) - (error "Failed to delete %s" short-path) - ;; Ensures that windows displaying this buffer will be switched - ;; to real buffers (`doom-real-buffer-p') - (doom/kill-this-buffer-in-all-windows buf t) - (+evil--forget-file fname) - (message "Successfully deleted %s" short-path)))))))) - -(defun +evil--copy-file (old-path new-path &optional force-p) - (let* ((new-path (expand-file-name new-path)) - (old-path (file-truename old-path)) - (new-path (apply #'expand-file-name - (if (or (directory-name-p new-path) - (file-directory-p new-path)) - (list (file-name-nondirectory old-path) new-path) - (list new-path)))) - (new-path-dir (file-name-directory new-path)) - (project-root (doom-project-root)) - (short-new-name (if (file-in-directory-p new-path project-root) - (file-relative-name new-path project-root) - (abbreviate-file-name new-path)))) - (unless (file-directory-p new-path-dir) - (make-directory new-path-dir t)) - (when (buffer-modified-p) - (save-buffer)) - (cond ((equal (file-truename old-path) - (file-truename new-path)) - (throw 'status 'overwrite-self)) - ((and (file-exists-p new-path) - (not force-p) - (not (y-or-n-p (format "File already exists at %s, overwrite?" short-new-name)))) - (throw 'status 'aborted)) - (t - (copy-file old-path new-path t) - short-new-name)))) + (doom/delete-this-file (or filename (file-truename buffer-file-name)) + force-p)) ;;;###autoload (autoload '+evil:move-this-file "feature/evil/autoload/files" nil t) (evil-define-command +evil:move-this-file (new-path &optional force-p) @@ -74,18 +16,9 @@ filename modifiers (see `+evil*ex-replace-special-filenames'). If FORCE-P, overwrite the destination file if it exists, without confirmation." :repeat nil (interactive "") - (pcase (catch 'status - (let ((old-path (buffer-file-name)) - (new-path (expand-file-name new-path))) - (when-let* ((dest (+evil--copy-file old-path new-path force-p))) - (delete-file old-path) - (kill-this-buffer) - (find-file new-path) - (+evil--forget-file old-path new-path) - (message "File successfully moved to %s" dest)))) - ('overwrite-self (error "Cannot overwrite self")) - ('aborted (message "Aborted")) - (_ t))) + (when (or (not new-path) (string-empty-p new-path)) + (user-error "No new path was specified")) + (doom/move-this-file new-path force-p)) ;;;###autoload (autoload '+evil:copy-this-file "feature/evil/autoload/files" nil nil) (evil-define-command +evil:copy-this-file (new-path &optional force-p) @@ -94,10 +27,7 @@ filename modifiers (see `+evil*ex-replace-special-filenames'). If FORCE-P, overwrite the destination file if it exists, without confirmation." :repeat nil (interactive "") - (pcase (catch 'status - (when-let* ((dest (+evil--copy-file (buffer-file-name) new-path force-p))) - (message "File successfully copied to %s" dest))) - ('overwrite-self (error "Cannot overwrite self")) - ('aborted (message "Aborted")) - (_ t))) + (when (or (not new-path) (string-empty-p new-path)) + (user-error "No new path was specified")) + (doom/copy-this-file new-path force-p))