-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathmajutsu-diffedit.el
More file actions
144 lines (122 loc) · 5.08 KB
/
Copy pathmajutsu-diffedit.el
File metadata and controls
144 lines (122 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
;;; majutsu-diffedit.el --- Diffedit helpers for Majutsu -*- lexical-binding: t; -*-
;; Copyright (C) 2026 0WD0
;; Author: 0WD0 <wd.1105848296@gmail.com>
;; Maintainer: 0WD0 <wd.1105848296@gmail.com>
;; Keywords: tools, vc
;; URL: https://github.com/0WD0/majutsu
;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Commentary:
;; Shared helpers for `jj diffedit' workflows.
;;; Code:
(require 'majutsu-jj)
(require 'majutsu-core)
(require 'majutsu-process)
(require 'seq)
(require 'server)
(require 'with-editor)
(defvar majutsu-buffer-blob-path)
(defvar majutsu-buffer-diff-range)
(defcustom majutsu-diffedit-finish-on-save t
"When non-nil, finish diffedit session on save."
:group 'majutsu
:type 'boolean)
(defun majutsu-diffedit--finish-on-save ()
"Finish a with-editor session after saving a diffedit file."
(when (and majutsu-diffedit-finish-on-save
(bound-and-true-p with-editor-mode)
(bound-and-true-p server-buffer-clients))
(with-editor-finish nil)))
(define-minor-mode majutsu-diffedit-mode
"Minor mode for jj diffedit buffers."
:lighter " DiffEdit"
(if majutsu-diffedit-mode
(progn
(with-editor-mode 1)
(when majutsu-diffedit-finish-on-save
(add-hook 'after-save-hook #'majutsu-diffedit--finish-on-save nil t)))
(remove-hook 'after-save-hook #'majutsu-diffedit--finish-on-save t)))
(defun majutsu-diffedit--maybe-enable-mode ()
"Enable `majutsu-diffedit-mode' in jj diffedit temp buffers."
(when-let* ((file buffer-file-name))
(when (locate-dominating-file
(file-name-directory file)
(lambda (directory)
(file-regular-p
(expand-file-name "JJ-INSTRUCTIONS" directory))))
(majutsu-diffedit-mode 1))))
(add-hook 'find-file-hook #'majutsu-diffedit--maybe-enable-mode)
(defun majutsu-diffedit--range (args)
"Return (FROM . TO) range for diffedit from ARGS or context."
(or (majutsu-jj--parse-diff-range args)
(and (derived-mode-p 'majutsu-diff-mode)
(majutsu-jj--parse-diff-range majutsu-buffer-diff-range))
(when-let* ((rev (majutsu-revision-at-point)))
(cons (concat rev "-") rev))
(cons "@-" "@")))
(defun majutsu-diffedit--revision-arg (args)
"Return the revision selector in ARGS, if ARGS uses revision syntax."
(seq-some (lambda (arg)
(or (transient-arg-value "--revisions=" (list arg))
(transient-arg-value "--revision=" (list arg))
(and (string-prefix-p "-r" arg)
(> (length arg) 2)
(substring arg 2))))
args))
(defun majutsu-diffedit--command-args (args)
"Return `jj diffedit' option arguments from ARGS or buffer context."
(let ((source-args (or args
(and (derived-mode-p 'majutsu-diff-mode)
majutsu-buffer-diff-range))))
(if-let* ((rev (majutsu-diffedit--revision-arg source-args)))
(list "-r" rev)
(pcase-let ((`(,from . ,to) (majutsu-diffedit--range args)))
(cond
((and from to)
(list "--from" from "--to" to))
(to
(list "-r" to))
(from
(list "-r" from))
(t
(list "-r" "@")))))))
(defun majutsu-diffedit--read-file (from to)
"Return diffedit target file from context or prompt."
(or (and (bound-and-true-p majutsu-blob-mode)
majutsu-buffer-blob-path)
(majutsu-file-at-point)
(majutsu-jj-read-diff-file from to)))
(defun majutsu-diffedit--normalize-file (file root)
"Return FILE normalized to repository-relative path under ROOT."
(if (file-name-absolute-p file)
(let* ((abs-root (file-name-as-directory (expand-file-name root)))
(abs-file (expand-file-name file)))
(if (string-prefix-p abs-root abs-file)
(file-relative-name abs-file abs-root)
(user-error "Diffedit target outside repository: %s" file)))
file))
(defun majutsu-diffedit-run (args file diff-editor)
"Run jj diffedit with option ARGS, FILE and DIFF-EDITOR config.
DIFF-EDITOR may be a config string, or a function called with the normalized
repository-relative file path."
(unless file
(user-error "Diffedit requires a file target"))
(let* ((root (majutsu--toplevel-safe default-directory))
(default-directory root)
(file (majutsu-diffedit--normalize-file file root))
(diff-editor-cmd (if (functionp diff-editor)
(funcall diff-editor file)
diff-editor))
(fileset (majutsu-jj-fileset-quote file))
(jj-args (majutsu-jj-append-filesets args (list fileset))))
(apply #'majutsu-run-jj-async "diffedit" "--config" diff-editor-cmd jj-args)))
(defun majutsu-diffedit-run-with-editor (args file)
"Run jj diffedit with option ARGS and FILE through with-editor."
(majutsu-with-editor
(majutsu-diffedit-run
args file
(lambda (file)
(majutsu-jj--editor-command-config "ui.diff-editor"
(concat "$right/" file))))))
;;; _
(provide 'majutsu-diffedit)
;;; majutsu-diffedit.el ends here