add casual, add emacs-conflict
This commit is contained in:
parent
e3a5b6e2a0
commit
e5aeae8c81
|
@ -1,5 +1,9 @@
|
||||||
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(defun load-directory (dir)
|
||||||
|
(let ((load-it (lambda (f) (load-file (concat (file-name-as-directory dir) f)))))
|
||||||
|
(mapc load-it (directory-files dir nil "\\.el$"))))
|
||||||
|
|
||||||
(defun org-path-find-file ()
|
(defun org-path-find-file ()
|
||||||
"Open org-path in find file"
|
"Open org-path in find file"
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -74,6 +78,9 @@
|
||||||
(setq auth-sources
|
(setq auth-sources
|
||||||
'("~/.authinfo" "~/.authinfo.gpg" "~/.netrc"))
|
'("~/.authinfo" "~/.authinfo.gpg" "~/.netrc"))
|
||||||
|
|
||||||
|
(load-directory "~/.config/doom/lisp")
|
||||||
|
|
||||||
|
|
||||||
;; Default Shell
|
;; Default Shell
|
||||||
;; Useful if default system shell is not bash
|
;; Useful if default system shell is not bash
|
||||||
(setq shell-file-name (executable-find "bash"))
|
(setq shell-file-name (executable-find "bash"))
|
||||||
|
@ -101,7 +108,12 @@
|
||||||
(use-package! notmuch
|
(use-package! notmuch
|
||||||
:config
|
:config
|
||||||
(setq +notmuch-sync-backend 'offlineimap
|
(setq +notmuch-sync-backend 'offlineimap
|
||||||
+notmuch-home-function (lambda () (notmuch-search "tag:inbox"))))
|
+notmuch-home-function (lambda () (notmuch-search "tag:inbox"))
|
||||||
|
message-send-mail-function 'smtpmail-send-it
|
||||||
|
smtpmail-default-smtp-server "posteo.de"
|
||||||
|
smtpmail-stream-type 'ssl
|
||||||
|
smtpmail-smtp-service 465))
|
||||||
|
|
||||||
|
|
||||||
;; Org Mode
|
;; Org Mode
|
||||||
(use-package! org
|
(use-package! org
|
||||||
|
@ -249,9 +261,7 @@
|
||||||
("https://shkspr.mobi/blog/feed/" tech)
|
("https://shkspr.mobi/blog/feed/" tech)
|
||||||
("https://smallstar.space/feed/" religion)
|
("https://smallstar.space/feed/" religion)
|
||||||
("https://snikket.org/blog/index.xml" tech release)
|
("https://snikket.org/blog/index.xml" tech release)
|
||||||
("https://social.prepedia.org/@FediNINA_Giessen.rss" alerts)
|
|
||||||
("https://solar.lowtechmagazine.com/posts/index.xml" tech sustainability)
|
("https://solar.lowtechmagazine.com/posts/index.xml" tech sustainability)
|
||||||
("https://tarnkappe.info/feed" tech piracy)
|
|
||||||
("https://theoatmeal.com/feed/rss" comics)
|
("https://theoatmeal.com/feed/rss" comics)
|
||||||
("https://victoria.dev/atom.xml" tech)
|
("https://victoria.dev/atom.xml" tech)
|
||||||
("https://warandpeas.com/feed/" comics)
|
("https://warandpeas.com/feed/" comics)
|
||||||
|
@ -382,3 +392,8 @@
|
||||||
))
|
))
|
||||||
:init
|
:init
|
||||||
(org-super-agenda-mode t))
|
(org-super-agenda-mode t))
|
||||||
|
|
||||||
|
(use-package! casual
|
||||||
|
:init
|
||||||
|
(require 'casual)
|
||||||
|
(define-key calc-mode-map (kbd "C-o") 'casual-main-menu))
|
||||||
|
|
|
@ -43,20 +43,20 @@
|
||||||
;;neotree ; a project drawer, like NERDTree for vim
|
;;neotree ; a project drawer, like NERDTree for vim
|
||||||
ophints ; highlight the region an operation acts on
|
ophints ; highlight the region an operation acts on
|
||||||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||||||
;;tabs ; a tab bar for Emacs
|
tabs ; a tab bar for Emacs
|
||||||
;;treemacs ; a project drawer, like neotree but cooler
|
treemacs ; a project drawer, like neotree but cooler
|
||||||
;;unicode ; extended unicode support for various languages
|
;;unicode ; extended unicode support for various languages
|
||||||
(vc-gutter +pretty) ; vcs diff in the fringe
|
(vc-gutter +pretty) ; vcs diff in the fringe
|
||||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||||
;;window-select ; visually switch windows
|
;;window-select ; visually switch windows
|
||||||
;;workspaces ; tab emulation, persistence & separate workspaces
|
;;workspaces ; tab emulation, persistence & separate workspaces
|
||||||
;;zen ; distraction-free coding or writing
|
zen ; distraction-free coding or writing
|
||||||
|
|
||||||
:editor
|
:editor
|
||||||
(evil +everywhere); come to the dark side, we have cookies
|
(evil +everywhere); come to the dark side, we have cookies
|
||||||
;;file-templates ; auto-snippets for empty files
|
;;file-templates ; auto-snippets for empty files
|
||||||
;;fold ; (nigh) universal code folding
|
;;fold ; (nigh) universal code folding
|
||||||
;;(format +onsave) ; automated prettiness
|
(format +onsave) ; automated prettiness
|
||||||
;;god ; run Emacs commands without modifier keys
|
;;god ; run Emacs commands without modifier keys
|
||||||
;;lispy ; vim for lisp, for people who don't like vim
|
;;lispy ; vim for lisp, for people who don't like vim
|
||||||
multiple-cursors ; editing in many places at once
|
multiple-cursors ; editing in many places at once
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
;;zig ; C, but simpler
|
;;zig ; C, but simpler
|
||||||
|
|
||||||
:email
|
:email
|
||||||
;;(mu4e +org +gmail)
|
;; (mu4e +org +gmail)
|
||||||
notmuch
|
notmuch
|
||||||
;;(wanderlust +gmail)
|
;;(wanderlust +gmail)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
;;; emacs-conflict.el --- quickly find and resolve conflicts in external tools like Syncthing -*- lexical-binding:t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2019 Pierre Penninckx
|
||||||
|
|
||||||
|
;; Author: Pierre Penninckx <ibizapeanut@gmail.com>
|
||||||
|
;; URL: https://github.com/ibizaman/emacs-conflicts
|
||||||
|
;; Version: 0.1.0
|
||||||
|
|
||||||
|
;; This file is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published
|
||||||
|
;; by the Free Software Foundation, either version 3 of the License,
|
||||||
|
;; or (at your option) any later version.
|
||||||
|
|
||||||
|
;; This file is distributed in the hope that it will be useful, but
|
||||||
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;; General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this file. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; `emacs-conflict' is used to quickly find and resolve conflicts in
|
||||||
|
;; external tools like Syncthing, Nextcloud or Pacman.
|
||||||
|
;;
|
||||||
|
;; `emacs-conflict-resolve-conflicts' searches a given directory for
|
||||||
|
;; all conflict files and provides a list of all of them. The
|
||||||
|
;; inconvenience is this function works synchronously so it will block
|
||||||
|
;; Emacs.
|
||||||
|
;;
|
||||||
|
;; `emacs-conflict-show-conflicts-dired' is the asynchronous version
|
||||||
|
;; where the results are presented in a `dired' buffer thanks to
|
||||||
|
;; `find-name-dired'. In the `dired' buffer, hover a conflict file
|
||||||
|
;; then call `emacs-conflict-resolve-conflict-dired'.
|
||||||
|
;;
|
||||||
|
;; In both cases, the conflict will be resolved using an `ediff'
|
||||||
|
;; session.
|
||||||
|
;;
|
||||||
|
;; The tool supports `Syncthing' [1], 'Nextcloud' [2] and 'Pacman' [3]
|
||||||
|
;; for now.
|
||||||
|
;;
|
||||||
|
;; [1] https://docs.syncthing.net/users/faq.html#what-if-there-is-a-conflict
|
||||||
|
;; [2] https://docs.nextcloud.com/desktop/2.6/conflicts.html
|
||||||
|
;; [3] https://wiki.archlinux.org/title/Pacman/Pacnew_and_Pacsave
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
|
||||||
|
(require 'dired)
|
||||||
|
(require 'dired-aux)
|
||||||
|
(require 'ediff)
|
||||||
|
|
||||||
|
|
||||||
|
(defgroup conflict nil
|
||||||
|
"Find conflicting files"
|
||||||
|
:group 'files
|
||||||
|
:prefix "emacs-conflict")
|
||||||
|
|
||||||
|
(defcustom emacs-conflict-find-regexes
|
||||||
|
'(("syncthing" "\\.sync-conflict-.*\\(\\.\\)" "\\1")
|
||||||
|
("nextcloud" " (conflicted copy .*)\\(\\.\\)" "\\1")
|
||||||
|
("pacman" "\\(?:\\.\\)pacnew$" ""))
|
||||||
|
"Regexes to identify a file as a conflict."
|
||||||
|
:type '(alist :key-type string :value-type (list regexp regexp))
|
||||||
|
:group 'conflict)
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict--find-regexes ()
|
||||||
|
"Merge all regexes into one."
|
||||||
|
(mapconcat (lambda (ls) (nth 1 ls)) emacs-conflict-find-regexes "\\|"))
|
||||||
|
|
||||||
|
(defun emacs-conflict-resolve-conflicts (directory)
|
||||||
|
"Resolve all conflicts under given DIRECTORY."
|
||||||
|
(interactive "D")
|
||||||
|
(let* ((all (emacs-conflict--get-sync-conflicts directory))
|
||||||
|
(chosen (emacs-conflict--pick-a-conflict all)))
|
||||||
|
(emacs-conflict--resolve-conflict chosen)))
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict-show-conflicts-dired (directory)
|
||||||
|
"Open dired buffer at DIRECTORY showing all syncthing conflicts."
|
||||||
|
(interactive "D")
|
||||||
|
(find-lisp-find-dired directory (emacs-conflict--find-regexes)))
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict-resolve-conflict-dired (&optional arg)
|
||||||
|
"Resolve conflict of first marked file in dired or close to point with ARG."
|
||||||
|
(interactive "P")
|
||||||
|
(let* ((chosen (car (dired-get-marked-files nil arg))))
|
||||||
|
(emacs-conflict--resolve-conflict chosen)))
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict--resolve-conflict (conflict)
|
||||||
|
"Resolve CONFLICT file using ediff."
|
||||||
|
(let* ((normal (emacs-conflict--get-normal-filename conflict)))
|
||||||
|
(emacs-conflict--resolve-ediff
|
||||||
|
(list conflict normal)
|
||||||
|
`(lambda ()
|
||||||
|
(when (y-or-n-p "Delete conflict file? ")
|
||||||
|
(kill-buffer (get-file-buffer ,conflict))
|
||||||
|
(delete-file ,conflict))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict--get-sync-conflicts (directory)
|
||||||
|
"Return a list of all sync conflict files in a DIRECTORY."
|
||||||
|
(directory-files-recursively directory (emacs-conflict--find-regexes)))
|
||||||
|
|
||||||
|
|
||||||
|
(defvar emacs-conflict--conflict-history nil
|
||||||
|
"Completion conflict history.")
|
||||||
|
|
||||||
|
(defun emacs-conflict--pick-a-conflict (conflicts)
|
||||||
|
"Let user choose the next conflict from CONFLICTS to investigate."
|
||||||
|
(completing-read "Choose the conflict to investigate: " conflicts
|
||||||
|
nil t nil 'emacs-conflict--conflict-history))
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict--get-normal-filename (conflict)
|
||||||
|
"Get non-conflict filename matching the given CONFLICT."
|
||||||
|
(let (normal-filename)
|
||||||
|
(dolist (r emacs-conflict-find-regexes normal-filename)
|
||||||
|
(let ((regex (nth 1 r))
|
||||||
|
(replacement (nth 2 r)))
|
||||||
|
(when (and
|
||||||
|
(null normal-filename)
|
||||||
|
(not (null (string-match-p regex conflict))))
|
||||||
|
(setq normal-filename
|
||||||
|
(replace-regexp-in-string regex replacement conflict)))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun emacs-conflict--resolve-ediff (&optional files quit-hook)
|
||||||
|
"Resolve conflict between files using `ediff'.
|
||||||
|
|
||||||
|
If FILES is nil, conflict resolution will be done between the two
|
||||||
|
marked files in `dired'.
|
||||||
|
|
||||||
|
QUIT-HOOK, if given is called ."
|
||||||
|
(let ((files (or files (dired-get-marked-files)))
|
||||||
|
(quit-hook quit-hook)
|
||||||
|
(wnd (current-window-configuration)))
|
||||||
|
(if (<= (length files) 2)
|
||||||
|
(let ((file1 (car files))
|
||||||
|
(file2 (if (cdr files)
|
||||||
|
(cadr files)
|
||||||
|
(read-file-name
|
||||||
|
"file: "
|
||||||
|
(dired-dwim-target-directory)))))
|
||||||
|
(if (file-newer-than-file-p file1 file2)
|
||||||
|
(ediff-files file2 file1)
|
||||||
|
(ediff-files file1 file2))
|
||||||
|
(add-hook 'ediff-after-quit-hook-internal
|
||||||
|
(lambda ()
|
||||||
|
(setq ediff-after-quit-hook-internal nil)
|
||||||
|
(when quit-hook (funcall quit-hook))
|
||||||
|
(set-window-configuration wnd))))
|
||||||
|
(error "No more than 2 files should be marked"))))
|
||||||
|
|
||||||
|
(provide 'emacs-conflict)
|
||||||
|
;;; emacs-conflict.el ends here
|
|
@ -21,6 +21,7 @@
|
||||||
(package! org-noter)
|
(package! org-noter)
|
||||||
(package! org-super-agenda)
|
(package! org-super-agenda)
|
||||||
(package! org-superstar)
|
(package! org-superstar)
|
||||||
|
(package! casual)
|
||||||
|
|
||||||
;; To install a package directly from a remote git repo, you must specify a
|
;; To install a package directly from a remote git repo, you must specify a
|
||||||
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
|
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
|
||||||
|
|
Loading…
Reference in New Issue