From e5aeae8c81b9eab159b82b119e6a08ede8949554 Mon Sep 17 00:00:00 2001 From: Inhji Date: Wed, 27 Mar 2024 08:26:12 +0100 Subject: [PATCH] add casual, add emacs-conflict --- config/dot_config/doom/config.el | 21 ++- config/dot_config/doom/init.el | 10 +- config/dot_config/doom/lisp/emacs-conflict.el | 160 ++++++++++++++++++ config/dot_config/doom/packages.el | 1 + 4 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 config/dot_config/doom/lisp/emacs-conflict.el diff --git a/config/dot_config/doom/config.el b/config/dot_config/doom/config.el index 977326a..a21fc29 100644 --- a/config/dot_config/doom/config.el +++ b/config/dot_config/doom/config.el @@ -1,5 +1,9 @@ ;;; $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 () "Open org-path in find file" (interactive) @@ -74,6 +78,9 @@ (setq auth-sources '("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")) +(load-directory "~/.config/doom/lisp") + + ;; Default Shell ;; Useful if default system shell is not bash (setq shell-file-name (executable-find "bash")) @@ -101,7 +108,12 @@ (use-package! notmuch :config (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 (use-package! org @@ -249,9 +261,7 @@ ("https://shkspr.mobi/blog/feed/" tech) ("https://smallstar.space/feed/" religion) ("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://tarnkappe.info/feed" tech piracy) ("https://theoatmeal.com/feed/rss" comics) ("https://victoria.dev/atom.xml" tech) ("https://warandpeas.com/feed/" comics) @@ -382,3 +392,8 @@ )) :init (org-super-agenda-mode t)) + +(use-package! casual + :init + (require 'casual) + (define-key calc-mode-map (kbd "C-o") 'casual-main-menu)) diff --git a/config/dot_config/doom/init.el b/config/dot_config/doom/init.el index 1d1d7b8..2a1bbe4 100644 --- a/config/dot_config/doom/init.el +++ b/config/dot_config/doom/init.el @@ -43,20 +43,20 @@ ;;neotree ; a project drawer, like NERDTree for vim ophints ; highlight the region an operation acts on (popup +defaults) ; tame sudden yet inevitable temporary windows - ;;tabs ; a tab bar for Emacs - ;;treemacs ; a project drawer, like neotree but cooler + tabs ; a tab bar for Emacs + treemacs ; a project drawer, like neotree but cooler ;;unicode ; extended unicode support for various languages (vc-gutter +pretty) ; vcs diff in the fringe vi-tilde-fringe ; fringe tildes to mark beyond EOB ;;window-select ; visually switch windows ;;workspaces ; tab emulation, persistence & separate workspaces - ;;zen ; distraction-free coding or writing + zen ; distraction-free coding or writing :editor (evil +everywhere); come to the dark side, we have cookies ;;file-templates ; auto-snippets for empty files ;;fold ; (nigh) universal code folding - ;;(format +onsave) ; automated prettiness + (format +onsave) ; automated prettiness ;;god ; run Emacs commands without modifier keys ;;lispy ; vim for lisp, for people who don't like vim multiple-cursors ; editing in many places at once @@ -178,7 +178,7 @@ ;;zig ; C, but simpler :email - ;;(mu4e +org +gmail) + ;; (mu4e +org +gmail) notmuch ;;(wanderlust +gmail) diff --git a/config/dot_config/doom/lisp/emacs-conflict.el b/config/dot_config/doom/lisp/emacs-conflict.el new file mode 100644 index 0000000..dc71f29 --- /dev/null +++ b/config/dot_config/doom/lisp/emacs-conflict.el @@ -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 +;; 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 . + +;;; 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 diff --git a/config/dot_config/doom/packages.el b/config/dot_config/doom/packages.el index 5301cd8..aaa9464 100644 --- a/config/dot_config/doom/packages.el +++ b/config/dot_config/doom/packages.el @@ -21,6 +21,7 @@ (package! org-noter) (package! org-super-agenda) (package! org-superstar) +(package! casual) ;; To install a package directly from a remote git repo, you must specify a ;; `:recipe'. You'll find documentation on what `:recipe' accepts here: