unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
blob 1ff82f2b81118b33d8a78bd4cfe2c4dddf12ec93 4718 bytes (raw)
name: lisp/pcmpl-git.el 	 # note: path name is non-authoritative(*)

  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
 
;;; pcmpl-git.el --- Completions for Git -*- lexical-binding: t -*-

;; Copyright (C) 2022 Free Software Foundation, Inc.

;; Package: pcomplete

;; This file is part of GNU Emacs.

;; GNU Emacs 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.

;; GNU Emacs 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 GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; This library provides completion rules for the Git program.

;;; Code:

(require 'pcomplete)
(require 'vc-git)

(defun pcmpl-git--expand-flags (args)
  "In the list of ARGS, expand arguments of the form --[no-]flag."
  (mapcan (lambda (arg) (if (string-search "[no-]" arg)
                            (list (string-replace "[no-]" "" arg)
                                  (string-replace "[no-]" "no-" arg))
                          (list arg)))
          args))

(defun pcmpl-git--tracked-file-predicate (&rest args)
  "Return a predicate function determining if a file is tracked by Git.
ARGS are passed to the `git ls-files' command."
  (when-let ((files (mapcar #'expand-file-name
                            (ignore-errors
                              (apply #'process-lines
                                     vc-git-program "ls-files" args)))))
    (lambda (file)
      (setq file (expand-file-name file))
      (if (string-suffix-p "/" file)
          (seq-some (lambda (f) (string-prefix-p file f))
                    files)
        (member file files)))))

(defun pcmpl-git--remote-refs (remote)
  "List the locally known Git revisions from REMOTE."
  (delq nil
        (mapcar
         (let ((re (concat "\\`" (regexp-quote remote) "/\\(.*\\)")))
           (lambda (s) (when (string-match re s) (match-string 1 s))))
         (vc-git-revision-table nil))))

;;;###autoload
(defun pcomplete/git ()
  "Completion for the `git' command."
  (let ((subcmds (pcomplete-from-help `(,vc-git-program "help" "-a")
                                      :margin "^\\( +\\)[a-z]"
                                      :argument "[[:alnum:]-]+")))
    (while (not (member (pcomplete-arg 1) subcmds))
      (pcomplete-here (completion-table-merge
                       subcmds
                       ;; Global switches and their file arguments
                       (pcomplete-from-help `(,vc-git-program "help")
                                            :margin "\\(\\[\\)-"
                                            :separator " | "
                                            :description "\\`")
                       (when (pcomplete-match "\\-")
                         (pcomplete-entries)))))
    (let ((subcmd (pcomplete-arg 1)))
      (while (pcase subcmd
               ((guard (pcomplete-match "\\`-" 0))
                (pcomplete-here
                 (pcmpl-git--expand-flags
                  (pcomplete-from-help `(,vc-git-program "help" ,subcmd)
                                       :argument
                                       "-+\\(?:\\[no-\\]\\)?[a-z-]+=?"))))
               ;; Complete modified tracked files
               ((or "add" "commit" "restore")
                (pcomplete-here
                 (pcomplete-entries nil
                                    (pcmpl-git--tracked-file-predicate "-m"))))
               ;; Complete all tracked files
               ((or "mv" "rm" "grep" "status")
                (pcomplete-here
                 (pcomplete-entries nil (pcmpl-git--tracked-file-predicate))))
               ;; Complete revisions
               ((or "branch" "merge" "rebase" "switch")
                (pcomplete-here (vc-git-revision-table nil)))
               ;; Complete revisions and tracked files
               ;; TODO: diff and log accept revision ranges
               ((or "checkout" "reset" "show" "diff" "log")
                (pcomplete-here
                 (completion-table-in-turn
                  (vc-git-revision-table nil)
                  (pcomplete-entries nil (pcmpl-git--tracked-file-predicate)))))
               ;; Complete remotes and their revisions
               ((or "fetch" "pull" "push")
                (pcomplete-here (process-lines vc-git-program "remote"))
                (pcomplete-here (pcmpl-git--remote-refs (pcomplete-arg 1)))))))))

(provide 'pcmpl-git)
;;; pcmpl-git.el ends here

debug log:

solving 1ff82f2b81 ...
found 1ff82f2b81 in https://yhetil.org/emacs-bugs/87pmg3ef6j.fsf@gmail.com/

applying [1/1] https://yhetil.org/emacs-bugs/87pmg3ef6j.fsf@gmail.com/
diff --git a/lisp/pcmpl-git.el b/lisp/pcmpl-git.el
new file mode 100644
index 0000000000..1ff82f2b81

Checking patch lisp/pcmpl-git.el...
Applied patch lisp/pcmpl-git.el cleanly.

index at:
100644 1ff82f2b81118b33d8a78bd4cfe2c4dddf12ec93	lisp/pcmpl-git.el

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).