dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

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