magit-transient.el (7617B)
1 ;;; magit-transient.el --- support for transients -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2008-2021 The Magit Project Contributors 4 ;; 5 ;; You should have received a copy of the AUTHORS.md file which 6 ;; lists all contributors. If not, see http://magit.vc/authors. 7 8 ;; Author: Jonas Bernoulli <jonas@bernoul.li> 9 ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li> 10 11 ;; SPDX-License-Identifier: GPL-3.0-or-later 12 13 ;; Magit is free software; you can redistribute it and/or modify it 14 ;; under the terms of the GNU General Public License as published by 15 ;; the Free Software Foundation; either version 3, or (at your option) 16 ;; any later version. 17 ;; 18 ;; Magit is distributed in the hope that it will be useful, but WITHOUT 19 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 20 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 21 ;; License for more details. 22 ;; 23 ;; You should have received a copy of the GNU General Public License 24 ;; along with Magit. If not, see http://www.gnu.org/licenses. 25 26 ;;; Commentary: 27 28 ;; This library implements Magit-specific prefix and suffix classes, 29 ;; and their methods. 30 31 ;;; Code: 32 33 (require 'magit-git) 34 (require 'magit-mode) 35 (require 'magit-process) 36 37 (require 'transient) 38 39 ;;; Classes 40 41 (defclass magit--git-variable (transient-variable) 42 ((scope :initarg :scope))) 43 44 (defclass magit--git-variable:choices (magit--git-variable) 45 ((choices :initarg :choices) 46 (fallback :initarg :fallback :initform nil) 47 (default :initarg :default :initform nil))) 48 49 (defclass magit--git-variable:urls (magit--git-variable) 50 ((seturl-arg :initarg :seturl-arg :initform nil))) 51 52 ;;; Methods 53 ;;;; Init 54 55 (cl-defmethod transient-init-scope ((obj magit--git-variable)) 56 (oset obj scope 57 (cond (transient--prefix 58 (oref transient--prefix scope)) 59 ((slot-boundp obj 'scope) 60 (funcall (oref obj scope) obj))))) 61 62 (cl-defmethod transient-init-value ((obj magit--git-variable)) 63 (let ((variable (format (oref obj variable) 64 (oref obj scope)))) 65 (oset obj variable variable) 66 (oset obj value 67 (cond ((oref obj multi-value) 68 (magit-get-all variable)) 69 (t 70 (magit-git-string "config" "--local" variable)))))) 71 72 ;;;; Read 73 74 (cl-defmethod transient-infix-read :around ((obj magit--git-variable:urls)) 75 (mapcar (lambda (url) 76 (if (string-prefix-p "~" url) 77 (expand-file-name url) 78 url)) 79 (cl-call-next-method obj))) 80 81 (cl-defmethod transient-infix-read ((obj magit--git-variable:choices)) 82 (let ((choices (oref obj choices))) 83 (when (functionp choices) 84 (setq choices (funcall choices))) 85 (if-let ((value (oref obj value))) 86 (cadr (member value choices)) 87 (car choices)))) 88 89 ;;;; Readers 90 91 (defun magit-transient-read-person (prompt initial-input history) 92 (magit-completing-read 93 prompt 94 (mapcar (lambda (line) 95 (save-excursion 96 (and (string-match "\\`[\s\t]+[0-9]+\t" line) 97 (list (substring line (match-end 0)))))) 98 (magit-git-lines "shortlog" "-n" "-s" "-e" "HEAD")) 99 nil nil initial-input history)) 100 101 (defun magit-transient-read-revision (prompt initial-input history) 102 (or (magit-completing-read prompt (cons "HEAD" (magit-list-refnames)) 103 nil nil initial-input history 104 (or (magit-branch-or-commit-at-point) 105 (magit-get-current-branch))) 106 (user-error "Nothing selected"))) 107 108 ;;;; Set 109 110 (cl-defmethod transient-infix-set ((obj magit--git-variable) value) 111 (let ((variable (oref obj variable))) 112 (oset obj value value) 113 (if (oref obj multi-value) 114 (magit-set-all value variable) 115 (magit-set value variable)) 116 (magit-refresh) 117 (unless (or value transient--prefix) 118 (message "Unset %s" variable)))) 119 120 (cl-defmethod transient-infix-set ((obj magit--git-variable:urls) values) 121 (let ((previous (oref obj value)) 122 (seturl (oref obj seturl-arg)) 123 (remote (oref transient--prefix scope))) 124 (oset obj value values) 125 (dolist (v (-difference values previous)) 126 (magit-call-git "remote" "set-url" seturl "--add" remote v)) 127 (dolist (v (-difference previous values)) 128 (magit-call-git "remote" "set-url" seturl "--delete" remote 129 (concat "^" (regexp-quote v) "$"))) 130 (magit-refresh))) 131 132 ;;;; Draw 133 134 (cl-defmethod transient-format-description ((obj magit--git-variable)) 135 (or (oref obj description) 136 (oref obj variable))) 137 138 (cl-defmethod transient-format-value ((obj magit--git-variable)) 139 (if-let ((value (oref obj value))) 140 (if (oref obj multi-value) 141 (if (cdr value) 142 (mapconcat (lambda (v) 143 (concat "\n " 144 (propertize v 'face 'transient-value))) 145 value "") 146 (propertize (car value) 'face 'transient-value)) 147 (propertize (car (split-string value "\n")) 148 'face 'transient-value)) 149 (propertize "unset" 'face 'transient-inactive-value))) 150 151 (cl-defmethod transient-format-value ((obj magit--git-variable:choices)) 152 (let* ((variable (oref obj variable)) 153 (choices (oref obj choices)) 154 (local (magit-git-string "config" "--local" variable)) 155 (global (magit-git-string "config" "--global" variable)) 156 (default (oref obj default)) 157 (fallback (oref obj fallback)) 158 (fallback (and fallback 159 (when-let ((val (magit-get fallback))) 160 (concat fallback ":" val))))) 161 (when (functionp choices) 162 (setq choices (funcall choices))) 163 (concat 164 (propertize "[" 'face 'transient-inactive-value) 165 (mapconcat (lambda (choice) 166 (propertize choice 'face (if (equal choice local) 167 (if (member choice choices) 168 'transient-value 169 'font-lock-warning-face) 170 'transient-inactive-value))) 171 (if (and local (not (member local choices))) 172 (cons local choices) 173 choices) 174 (propertize "|" 'face 'transient-inactive-value)) 175 (and (or global fallback default) 176 (concat 177 (propertize "|" 'face 'transient-inactive-value) 178 (cond (global 179 (propertize (concat "global:" global) 180 'face (cond (local 181 'transient-inactive-value) 182 ((member global choices) 183 'transient-value) 184 (t 185 'font-lock-warning-face)))) 186 (fallback 187 (propertize fallback 188 'face (if local 189 'transient-inactive-value 190 'transient-value))) 191 (default 192 (propertize (concat "default:" default) 193 'face (if local 194 'transient-inactive-value 195 'transient-value)))))) 196 (propertize "]" 'face 'transient-inactive-value)))) 197 198 ;;; _ 199 (provide 'magit-transient) 200 ;;; magit-transient.el ends here