refactor: Move user config into modules/
This commit is contained in:
161
modules/home/users/crumb/emacs/lib/syd-file.el
Normal file
161
modules/home/users/crumb/emacs/lib/syd-file.el
Normal file
@@ -0,0 +1,161 @@
|
||||
;;; syd-file.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'syd-prelude)
|
||||
(require 'syd-buffers)
|
||||
(require 'cl-lib)
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
(eval-when-compile (require 'tramp))
|
||||
|
||||
(syd-define-stub
|
||||
syd/copy-this-file
|
||||
:desc "Copy current file. See `doom/copy-this-file'."
|
||||
:interactive t)
|
||||
|
||||
(defun syd-files--update-refs (&rest files)
|
||||
"Ensure FILES are updated in `recentf', `magit' and `save-place'."
|
||||
(let (toplevels)
|
||||
(dolist (file files)
|
||||
(when (featurep 'vc)
|
||||
(vc-file-clearprops file)
|
||||
(when-let (buffer (get-file-buffer file))
|
||||
(with-current-buffer buffer
|
||||
(vc-refresh-state))))
|
||||
(when (featurep 'magit)
|
||||
(when-let (default-directory
|
||||
(magit-toplevel (file-name-directory file)))
|
||||
(cl-pushnew default-directory toplevels)))
|
||||
(unless (file-readable-p file)
|
||||
(when (bound-and-true-p recentf-mode)
|
||||
(recentf-remove-if-non-kept file))
|
||||
(dolist (default-directory toplevels)
|
||||
(magit-refresh))
|
||||
(when (bound-and-true-p save-place-mode)
|
||||
(save-place-forget-unreadable-files))))))
|
||||
|
||||
(defun syd/delete-this-file (&optional path force-p)
|
||||
"Delete PATH, kill its buffers and expunge it from vc/magit cache.
|
||||
|
||||
If PATH is not specified, default to the current buffer's file.
|
||||
|
||||
If FORCE-P, delete without confirmation."
|
||||
(interactive (list (buffer-file-name (buffer-base-buffer))
|
||||
current-prefix-arg))
|
||||
(let* ((path (or path (buffer-file-name (buffer-base-buffer))))
|
||||
(short-path (and path (abbreviate-file-name path))))
|
||||
(unless path
|
||||
(user-error "Buffer is not visiting any file"))
|
||||
(unless (file-exists-p path)
|
||||
(error "File doesn't exist: %s" path))
|
||||
(unless (or force-p (y-or-n-p (format "Really delete %S?" short-path)))
|
||||
(user-error "Aborted"))
|
||||
(let ((buf (current-buffer)))
|
||||
(unwind-protect
|
||||
(progn (delete-file path t) t))
|
||||
(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')
|
||||
(syd/kill-this-buffer-in-all-windows buf t)
|
||||
(syd-files--update-refs path)
|
||||
(message "Deleted %S" short-path)))))
|
||||
|
||||
(syd-define-stub
|
||||
syd/move-this-file
|
||||
:desc "Move current file. See `doom/move-this-file'."
|
||||
:interactive t)
|
||||
|
||||
(defun syd-find-file-in (root)
|
||||
(interactive (list (read-directory-name
|
||||
"Find file in: " default-directory nil t)))
|
||||
;; HACK: To avoid reimplementation, we pretend `root' is a project and
|
||||
;; delegate the work to project.el.
|
||||
(syd-with-project-root root
|
||||
(project-find-file)))
|
||||
|
||||
(syd-define-stub
|
||||
syd/yank-buffer-path
|
||||
:desc "Yank buffer path."
|
||||
:interactive t)
|
||||
|
||||
(defun syd/find-file-in-emacs-user-directory ()
|
||||
(interactive)
|
||||
(unless (file-directory-p user-emacs-directory)
|
||||
(user-error "`user-emacs-directory' doesn't exist! (%s)"
|
||||
(abbreviate-file-name user-emacs-directory)))
|
||||
(let ((default-directory user-emacs-directory))
|
||||
(call-interactively #'find-file)))
|
||||
|
||||
(defun syd-switch-to-emacs-user-directory ()
|
||||
"Switch project to `user-emacs-directory' via `project-switch-project'."
|
||||
(interactive)
|
||||
(require 'syd-project)
|
||||
(if (file-directory-p user-emacs-directory)
|
||||
(syd-with-project-root user-emacs-directory
|
||||
(project-switch-project user-emacs-directory))
|
||||
(user-error "`user-emacs-directory' (%s) does not exist or is not a directory!"
|
||||
(abbreviate-file-name user-emacs-directory))))
|
||||
|
||||
(syd-define-stub
|
||||
syd/open-this-file-as-root
|
||||
:desc "Open current file as root. See `doom/sudo-this-file'."
|
||||
:interactive t)
|
||||
|
||||
(syd-define-stub
|
||||
syd/find-file-as-root
|
||||
:desc "Open current file as root. See `doom/sudo-this-file'."
|
||||
:interactive t)
|
||||
|
||||
(defun syd--make-syncthing-merge-finalise-hook (file-name conflict-file-name)
|
||||
(lambda ()
|
||||
(let ((merge-result-file (read-file-name
|
||||
(format "Write merge to (default: %s):"
|
||||
file-name)
|
||||
nil file-name))
|
||||
(delete-conflict-p (yes-or-no-p (format "Delete conflict file? (%s)"
|
||||
conflict-file-name)))))
|
||||
(when merge-result-file
|
||||
(with-current-buffer ediff-buffer-C
|
||||
(set-visited-file-name merge-result-file)
|
||||
(save-buffer))
|
||||
(kill-buffer ediff-buffer-C))
|
||||
(when delete-conflict-p
|
||||
(kill-buffer (find-buffer-visiting conflict-file-name))
|
||||
(delete-file conflict-file-name))))
|
||||
|
||||
(defun syd--read-syncthing-conflict-file (&optional directory)
|
||||
(let ((conflict-files (directory-files-recursively
|
||||
(or directory default-directory)
|
||||
(rx ".sync-conflict-"))))
|
||||
(completing-read "Conflict file: " conflict-files nil t)))
|
||||
|
||||
(defun syd--syncthing-conflict-file-base-name (conflict-file)
|
||||
(replace-regexp-in-string (rx ".sync-conflict-" (* (not ?.)))
|
||||
""
|
||||
conflict-file))
|
||||
|
||||
(defun syd-resolve-syncthing-conflict (conflict-file)
|
||||
(interactive (list (syd--read-syncthing-conflict-file)))
|
||||
(require 'ediff)
|
||||
(let* ((base-file (syd--syncthing-conflict-file-base-name conflict-file))
|
||||
(ediff-after-quit-hook-internal
|
||||
;; Override Ediff's "save and quit" hook with our own.
|
||||
(cons (syd--make-syncthing-merge-finalise-hook base-file conflict-file)
|
||||
(remq #'ediff-write-merge-buffer-and-maybe-kill
|
||||
(ensure-list ediff-quit-merge-hook)))))
|
||||
(ediff-merge-files
|
||||
base-file
|
||||
conflict-file)))
|
||||
|
||||
;;;###autoload
|
||||
(defun syd-split-tramp-file-name (file-name)
|
||||
"Split FILE-NAME into (TRAMP-PREFIX . LOCAL-NAME). Returns (nil . FILE-NAME)
|
||||
if FILE-NAME has no TRAMP prefix."
|
||||
(if (tramp-tramp-file-p file-name)
|
||||
(let* ((dissected (tramp-dissect-file-name file-name t))
|
||||
(localname (tramp-file-name-localname dissected)))
|
||||
(setf (tramp-file-name-localname dissected) nil)
|
||||
(cons (tramp-make-tramp-file-name dissected)
|
||||
localname))
|
||||
(cons nil file-name)))
|
||||
|
||||
(provide 'syd-file)
|
||||
Reference in New Issue
Block a user