Browse Source

Add some refactors

master
10sr 5 years ago
parent
commit
3aa065cf1a
Signed by: 10sr GPG Key ID: 7BEC428194130EB2
1 changed files with 49 additions and 54 deletions
  1. +49
    -54
      emacs.el

+ 49
- 54
emacs.el View File

@@ -2263,12 +2263,6 @@ use for the buffer. It defaults to \"*recetf-show*\"."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; git walktree ;; git walktree


;; TODO: Fix variable names
;; commit-sha1 for commit sha1 (allow abbreviated)
;; commit-full-sha1 for commit sha1 in 40 chars
;; object-full-sha1 for object sha1 in 40 chars
;; Do not use something like "-id" in name

(defgroup git-walktree nil (defgroup git-walktree nil
"Git Walktree." "Git Walktree."
:tag "GitWalktree" :tag "GitWalktree"
@@ -2288,9 +2282,8 @@ This path is always relative to repository root.")
"Psudo filename of current buffer.") "Psudo filename of current buffer.")
(make-variable-buffer-local 'git-walktree-buffer-file-name) (make-variable-buffer-local 'git-walktree-buffer-file-name)


;; TODO: -> object-full-sha1
(defvar git-walktree-object-full-sha1 nil (defvar git-walktree-object-full-sha1 nil
"Object id of current buffer.")
"Object name in full sha1 format of current buffer.")
(make-variable-buffer-local 'git-walktree-object-full-sha1) (make-variable-buffer-local 'git-walktree-object-full-sha1)


(defvar git-walktree-repository-root nil (defvar git-walktree-repository-root nil
@@ -2325,7 +2318,7 @@ TYPE is target object type."
(string= type "tree")) (string= type "tree"))
(with-current-buffer (or git-walktree-tree-buffer-for-reuse (with-current-buffer (or git-walktree-tree-buffer-for-reuse
(setq git-walktree-tree-buffer-for-reuse (setq git-walktree-tree-buffer-for-reuse
(get-buffer-create "*gitwalktree*")))
(generate-new-buffer "gitwalktreebuf")))
(setq git-walktree-repository-root root) (setq git-walktree-repository-root root)
(rename-buffer name t) (rename-buffer name t)
(current-buffer)) (current-buffer))
@@ -2349,6 +2342,7 @@ It also copy text overlays."
(with-current-buffer target (with-current-buffer target
(replace-buffer-contents src))) (replace-buffer-contents src)))


;; Copy color overlays
(let ((overlays (overlays-in (point-min) (point-max)))) (let ((overlays (overlays-in (point-min) (point-max))))
(dolist (o overlays) (dolist (o overlays)
(let ((beg (overlay-start o)) (let ((beg (overlay-start o))
@@ -2360,7 +2354,9 @@ It also copy text overlays."


(require 'ansi-color) (require 'ansi-color)
(defun git-walktree--open-treeish (committish path treeish) (defun git-walktree--open-treeish (committish path treeish)
"Open git tree buffer of TREEISH."
"Open git tree buffer of COMMITISH:PATH.

TREEISH should be a tree-ish object full-sha1 of COMMITISH:PATH."
(cl-assert path) (cl-assert path)
(cl-assert treeish) (cl-assert treeish)
(let* (point-tree-start (let* (point-tree-start
@@ -2374,10 +2370,10 @@ It also copy text overlays."
(with-current-buffer buf (with-current-buffer buf
(unless (and (string= treeish (unless (and (string= treeish
git-walktree-object-full-sha1) git-walktree-object-full-sha1)
(or (string= committish
git-walktree-current-committish)
(eq committish
git-walktree-current-committish)))
(or (eq committish
git-walktree-current-committish)
(string= committish
git-walktree-current-committish)))
(buffer-disable-undo) (buffer-disable-undo)
;; For running git command go back to repository root ;; For running git command go back to repository root
(cd git-walktree-repository-root) (cd git-walktree-repository-root)
@@ -2425,7 +2421,7 @@ It also copy text overlays."
(cd dir))) (cd dir)))
(when (= (point) (point-min)) (when (= (point) (point-min))
(goto-char point-tree-start) (goto-char point-tree-start)
(git-walktree-mode--goto-file)
(git-walktree-mode--move-to-file)
) )
)) ))
buf)) buf))
@@ -2446,7 +2442,8 @@ Result will be inserted into current buffer."
args)))) args))))
?w ?w
(defun git-walktree--open-blob (committish path blob) (defun git-walktree--open-blob (committish path blob)
"Open BLOB object."
"Open blob object of COMMITISH:PATH.
BLOB should be a object full sha1 of COMMITISH:PATH."
(cl-assert committish) (cl-assert committish)
(cl-assert path) (cl-assert path)
(cl-assert blob) (cl-assert blob)
@@ -2505,8 +2502,8 @@ When PATH is omitted or nil, it is calculated from current file or directory."
(git-walktree--path-in-repository (or buffer-file-name (git-walktree--path-in-repository (or buffer-file-name
default-directory)))) default-directory))))
;; PATH must not start with and end with slashes ;; PATH must not start with and end with slashes
(cl-assert (not (string-match "\\`/" path)))
(cl-assert (not (string-match "/\\'" path)))
(cl-assert (not (string-match-p "\\`/" path)))
(cl-assert (not (string-match-p "/\\'" path)))


(let ((obj (git-walktree--resolve-object committish path))) (let ((obj (git-walktree--resolve-object committish path)))
(while (not obj) (while (not obj)
@@ -2520,9 +2517,9 @@ When PATH is omitted or nil, it is calculated from current file or directory."


;; TODO: Store view history ;; TODO: Store view history
(defun git-walktree--open-noselect (committish path object) (defun git-walktree--open-noselect (committish path object)
"Open git tree buffer of COMMITTISH.
"Open buffer to view git object of COMMITTISH:PATH.
When PATH was given and non-nil open that, otherwise open root tree. When PATH was given and non-nil open that, otherwise open root tree.
When OBJECT was given and non-nil, assume that is the full sha1 object id of
When OBJECT was given and non-nil, assume that is the object full sha1 of
COMMITTISH:PATH without checking it." COMMITTISH:PATH without checking it."
(cl-assert committish) (cl-assert committish)
(let ((type (git-walktree--git-plumbing "cat-file" (let ((type (git-walktree--git-plumbing "cat-file"
@@ -2533,8 +2530,8 @@ COMMITTISH:PATH without checking it."
(setq path (or path (setq path (or path
".")) "."))
;; PATH must not start with and end with slashes ;; PATH must not start with and end with slashes
(cl-assert (not (string-match "\\`/" path)))
(cl-assert (not (string-match "/\\'" path)))
(cl-assert (not (string-match-p "\\`/" path)))
(cl-assert (not (string-match-p "/\\'" path)))


(setq object (or object (setq object (or object
(git-walktree--resolve-object committish path))) (git-walktree--resolve-object committish path)))
@@ -2554,11 +2551,13 @@ COMMITTISH:PATH without checking it."
(error "Type cannot handle: %s" type))))) (error "Type cannot handle: %s" type)))))


(defun git-walktree--resolve-object (committish path) (defun git-walktree--resolve-object (committish path)
"Return object id of COMMITISIH:PATH.
If path is equal to \".\" return COMMITTISH's tree object
"Return object full sha1 name of COMMITISIH:PATH.
If path is equal to \".\" return COMMITTISH's root tree object.
PATH will be always treated as relative to repository root." PATH will be always treated as relative to repository root."
(cl-assert committish) (cl-assert committish)
(cl-assert path) (cl-assert path)
(cl-assert (not (string-match-p "\\`/" path)))
(cl-assert (not (string-match-p "/\\'" path)))
(if (string= path ".") (if (string= path ".")
(git-walktree--git-plumbing "show" (git-walktree--git-plumbing "show"
"--no-patch" "--no-patch"
@@ -2570,13 +2569,12 @@ PATH will be always treated as relative to repository root."
path)))) path))))
(plist-get info :object)))) (plist-get info :object))))


(defun git-walktree-open (committish &optional path object)
(defun git-walktree-open (committish &optional path)
"Open git tree buffer of COMMITTISH. "Open git tree buffer of COMMITTISH.
When PATH was given and non-nil open that, otherwise open root tree.
When OBJECT was given and non-nil, assume that is the object of COMMITTISH:PATH without
checking it."
When PATH was given and non-nil open that, otherwise try to open current path.
If target path is not found in COMMITISH tree, go up path and try again until found."
(interactive (list (magit-read-branch-or-commit "Revision: "))) (interactive (list (magit-read-branch-or-commit "Revision: ")))
(switch-to-buffer (git-walktree--open-noselect committish path object)))
(switch-to-buffer (git-walktree--open-noselect-safe-path committish path)))
(defalias 'git-walktree 'git-walktree-open) (defalias 'git-walktree 'git-walktree-open)


(defun git-walktree--path-in-repository (path) (defun git-walktree--path-in-repository (path)
@@ -2596,7 +2594,7 @@ checking it."


(defcustom git-walktree-try-cd t (defcustom git-walktree-try-cd t
"Try to cd if directory exists in current working directory if non-nil. "Try to cd if directory exists in current working directory if non-nil.
Otherwise buffer's `default-directory' is always repository root."
Otherwise use repository root for gitwalktree buffer's `default-directory'."
:type 'boolean :type 'boolean
:group 'git-walktree) :group 'git-walktree)


@@ -2605,10 +2603,8 @@ Otherwise buffer's `default-directory' is always repository root."
:type 'boolean :type 'boolean
:group 'git-walktree) :group 'git-walktree)


(defcustom git-walktree-tree-buffer-for-reuse nil
"Buffer to use when `git-walktree-reuse-tree-buffer' is non-nil."
:type 'string
:group 'git-walktree)
(defvar git-walktree-tree-buffer-for-reuse nil
"Buffer to use when `git-walktree-reuse-tree-buffer' is non-nil.")


(defun git-walktree--git-plumbing (&rest args) (defun git-walktree--git-plumbing (&rest args)
"Run git plubming command with ARGS. "Run git plubming command with ARGS.
@@ -2630,6 +2626,7 @@ Returns first line of output without newline."
(progn (progn
(goto-char (point-min)) (goto-char (point-min))
(point-at-eol)))))) (point-at-eol))))))

(defconst git-walktree-ls-tree-line-regexp (defconst git-walktree-ls-tree-line-regexp
"^\\([0-9]\\{6\\}\\) \\(\\w+\\) \\([0-9a-f]+\\)\t\\(.*\\)$" "^\\([0-9]\\{6\\}\\) \\(\\w+\\) \\([0-9a-f]+\\)\t\\(.*\\)$"
"Regexp for one line of output of git ls-tree.") "Regexp for one line of output of git ls-tree.")
@@ -2661,7 +2658,7 @@ Returns property list like (:mode MODE :type TYPE :object OBJECT :file FILE)."
:file (match-string 4))))))) :file (match-string 4)))))))


(defun git-walktree-mode-open-this () (defun git-walktree-mode-open-this ()
"Open current object."
"Open git object of current line."
(interactive) (interactive)
(let ((info (git-walktree--parse-lstree-line (buffer-substring-no-properties (point-at-bol) (let ((info (git-walktree--parse-lstree-line (buffer-substring-no-properties (point-at-bol)
(point-at-eol))))) (point-at-eol)))))
@@ -2721,8 +2718,7 @@ If not given, value of current buffer will be used."
nil)) nil))
(message "Cannot find parent directory for current tree.")))) (message "Cannot find parent directory for current tree."))))


;; TODO: -> -move-to
(defun git-walktree-mode--goto-file ()
(defun git-walktree-mode--move-to-file ()
"Move point to file field of ls-tree output in current line. "Move point to file field of ls-tree output in current line.


This function do nothing when current line is not ls-tree output." This function do nothing when current line is not ls-tree output."
@@ -2739,7 +2735,7 @@ This function do nothing when current line is not ls-tree output."
(interactive "^p\np") (interactive "^p\np")
(or arg (setq arg 1)) (or arg (setq arg 1))
(line-move arg nil nil try-vscroll) (line-move arg nil nil try-vscroll)
(git-walktree-mode--goto-file)
(git-walktree-mode--move-to-file)
) )


(defun git-walktree-mode-previous-line (&optional arg try-vscroll) (defun git-walktree-mode-previous-line (&optional arg try-vscroll)
@@ -2747,7 +2743,7 @@ This function do nothing when current line is not ls-tree output."
(interactive "^p\np") (interactive "^p\np")
(or arg (setq arg 1)) (or arg (setq arg 1))
(line-move (- arg) nil nil try-vscroll) (line-move (- arg) nil nil try-vscroll)
(git-walktree-mode--goto-file)
(git-walktree-mode--move-to-file)
) )


(defgroup git-walktree-faces nil (defgroup git-walktree-faces nil
@@ -2767,11 +2763,12 @@ This function do nothing when current line is not ls-tree output."
:group 'git-walktree-faces) :group 'git-walktree-faces)


(defvar git-walktree-known-child-revisions (make-hash-table :test 'equal) (defvar git-walktree-known-child-revisions (make-hash-table :test 'equal)
"Hash of already known pair of commitid -> list of child commitid.")
"Hash of already known pair of commitid -> list of child commitid.
Both values should be object full sha1 names.")


(defun git-walktree--put-child (parent child) (defun git-walktree--put-child (parent child)
"Register PARENT and CHILD relationship. "Register PARENT and CHILD relationship.
PARENT should be a full SHA-1 object name."
PARENT should be a full sha1 object name."
;; Any way to check if PARENT is a full SHA-1 object name? ;; Any way to check if PARENT is a full SHA-1 object name?
(let ((current (gethash parent git-walktree-known-child-revisions))) (let ((current (gethash parent git-walktree-known-child-revisions)))
(unless (member child current) (unless (member child current)
@@ -2781,12 +2778,12 @@ PARENT should be a full SHA-1 object name."
git-walktree-known-child-revisions)))) git-walktree-known-child-revisions))))


;; TODO: Add aggressive search mode ;; TODO: Add aggressive search mode
;; https://stackoverflow.com/a/9870218
;; git log --reverse --pretty=format:%H -n 1 --ancestry-path <PARENT>..HEAD
(defun git-walktree--get-children (parent) (defun git-walktree--get-children (parent)
"Get known children list of PARENT commit. "Get known children list of PARENT commit.
PARENT should be a full SHA-1 object name."
PARENT should be a full sha1 object name."
(gethash parent git-walktree-known-child-revisions)) (gethash parent git-walktree-known-child-revisions))
;; https://stackoverflow.com/a/9870218
;; git log --reverse --pretty=format:%H -n 1 --ancestry-path <PARENT>..HEAD


(defun git-walktree--choose-committish (prompt-format collection) (defun git-walktree--choose-committish (prompt-format collection)
"Emit PROMPT-FORMAT and ask user to which committish of COLLECTION to use. "Emit PROMPT-FORMAT and ask user to which committish of COLLECTION to use.
@@ -2807,12 +2804,12 @@ When collection has just one element, return the first element without asking."
If current path was not found in the parent revision try to go up path." If current path was not found in the parent revision try to go up path."
(interactive) (interactive)
(cl-assert git-walktree-current-committish) (cl-assert git-walktree-current-committish)
(let* ((commitid (git-walktree--git-plumbing "rev-parse"
git-walktree-current-committish))
(parents (git-walktree--parent-commitid commitid)))
(let* ((commit-full-sha1 (git-walktree--git-plumbing "rev-parse"
git-walktree-current-committish))
(parents (git-walktree--parent-full-sha1 commit-full-sha1)))
(dolist (parent parents) (dolist (parent parents)
(git-walktree--put-child parent (git-walktree--put-child parent
commitid))
commit-full-sha1))
(if (< (length parents) (if (< (length parents)
1) 1)
(message "This revision has no parent revision") (message "This revision has no parent revision")
@@ -2823,7 +2820,7 @@ If current path was not found in the parent revision try to go up path."
(switch-to-buffer (git-walktree--open-noselect-safe-path parent (switch-to-buffer (git-walktree--open-noselect-safe-path parent
path)))))) path))))))


(defun git-walktree--parent-commitid (committish)
(defun git-walktree--parent-full-sha1 (committish)
"Return list of parent commits of COMMITTISH in sha1 string." "Return list of parent commits of COMMITTISH in sha1 string."
(let ((type (git-walktree--git-plumbing "cat-file" (let ((type (git-walktree--git-plumbing "cat-file"
"-t" "-t"
@@ -2834,15 +2831,13 @@ If current path was not found in the parent revision try to go up path."
"--pretty=format:%P" "--pretty=format:%P"
committish))) committish)))
(split-string parents))) (split-string parents)))
;; (git-walktree--parent-sha1 "HEAD")
;; (git-walktree--parent-sha1 "ae4b80f")


(defun git-walktree-known-child-revision () (defun git-walktree-known-child-revision ()
"Open known revision of current path." "Open known revision of current path."
(interactive) (interactive)
(let* ((commitid (git-walktree--git-plumbing "rev-parse"
git-walktree-current-committish))
(children (git-walktree--get-children commitid)))
(let* ((commit-full-sha1 (git-walktree--git-plumbing "rev-parse"
git-walktree-current-committish))
(children (git-walktree--get-children commit-full-sha1)))
(if (< (length children) (if (< (length children)
1) 1)
(message "There are no known child revision") (message "There are no known child revision")


Loading…
Cancel
Save