X-Git-Url: https://git.distorted.org.uk/~mdw/stgit/blobdiff_plain/37cb5766267f6bca518dee62eaa95556303a5fbd..306b37a63112bf26cac29474116490376537f04f:/contrib/stgit.el diff --git a/contrib/stgit.el b/contrib/stgit.el index b47dbae..c4ed958 100644 --- a/contrib/stgit.el +++ b/contrib/stgit.el @@ -164,6 +164,17 @@ Returns nil if there was no output." "Returns non-nil if the index contains no changes from HEAD." (zerop (stgit-run-git-silent "diff-index" "--cached" "--quiet" "HEAD"))) +(defvar stgit-index-node nil) +(defvar stgit-worktree-node nil) + +(defun stgit-refresh-index () + (when stgit-index-node + (ewoc-invalidate (car stgit-index-node) (cdr stgit-index-node)))) + +(defun stgit-refresh-worktree () + (when stgit-worktree-node + (ewoc-invalidate (car stgit-worktree-node) (cdr stgit-worktree-node)))) + (defun stgit-run-series (ewoc) (let ((first-line t)) (with-temp-buffer @@ -191,19 +202,21 @@ Returns nil if there was no output." :desc (match-string 5) :empty (string= (match-string 1) "0")))) (setq first-line nil) - (forward-line 1)) - (ewoc-enter-last ewoc - (make-stgit-patch - :status 'index - :name :index - :desc nil - :empty nil)) - (ewoc-enter-last ewoc - (make-stgit-patch - :status 'work - :name :work - :desc nil - :empty nil))))))) + (forward-line 1))))) + (if stgit-show-worktree + (setq stgit-index-node (cons ewoc (ewoc-enter-last ewoc + (make-stgit-patch + :status 'index + :name :index + :desc nil + :empty nil))) + stgit-worktree-node (cons ewoc (ewoc-enter-last ewoc + (make-stgit-patch + :status 'work + :name :work + :desc nil + :empty nil)))) + (setq stgit-worktree-node nil)))) (defun stgit-reload () @@ -221,7 +234,12 @@ Returns nil if there was no output." (buffer-substring (point-min) (1- (point-max)))) 'face 'bold) "\n") - "--") + (if stgit-show-worktree + "--" + (propertize + (substitute-command-keys "--\n\"\\[stgit-toggle-worktree]\"\ + shows the working tree\n") + 'face 'stgit-description-face))) (stgit-run-series stgit-ewoc) (if curpatch (stgit-goto-patch curpatch) @@ -417,11 +435,8 @@ Cf. `stgit-file-type-change-string'." 'file-data file)))) (defun stgit-insert-patch-files (patch) - "Expand (show modification of) the patch with name PATCHSYM (a -symbol) after the line at point. -`stgit-expand-find-copies-harder' controls how hard to try to -find copied files." - (insert "\n") + "Expand (show modification of) the patch PATCH after the line +at point." (let* ((patchsym (stgit-patch-name patch)) (end (progn (insert "#") (prog1 (point-marker) (forward-char -1)))) (args (list "-z" (if stgit-expand-find-copies-harder @@ -564,47 +579,52 @@ find copied files." "Keymap for StGit major mode.") (unless stgit-mode-map - (setq stgit-mode-map (make-keymap)) - (suppress-keymap stgit-mode-map) - (mapc (lambda (arg) (define-key stgit-mode-map (car arg) (cdr arg))) - '((" " . stgit-mark) - ("m" . stgit-mark) - ("\d" . stgit-unmark-up) - ("u" . stgit-unmark-down) - ("?" . stgit-help) - ("h" . stgit-help) - ("\C-p" . stgit-previous-line) - ("\C-n" . stgit-next-line) - ([up] . stgit-previous-line) - ([down] . stgit-next-line) - ("p" . stgit-previous-patch) - ("n" . stgit-next-patch) - ("\M-{" . stgit-previous-patch) - ("\M-}" . stgit-next-patch) - ("s" . stgit-git-status) - ("g" . stgit-reload) - ("r" . stgit-refresh) - ("\C-c\C-r" . stgit-rename) - ("e" . stgit-edit) - ("M" . stgit-move-patches) - ("S" . stgit-squash) - ("N" . stgit-new) - ("R" . stgit-repair) - ("C" . stgit-commit) - ("U" . stgit-uncommit) - ("\r" . stgit-select) - ("o" . stgit-find-file-other-window) - ("i" . stgit-file-toggle-index) - (">" . stgit-push-next) - ("<" . stgit-pop-next) - ("P" . stgit-push-or-pop) - ("G" . stgit-goto) - ("=" . stgit-show) - ("D" . stgit-delete) - ([(control ?/)] . stgit-undo) - ("\C-_" . stgit-undo) - ("B" . stgit-branch) - ("q" . stgit-quit)))) + (let ((toggle-map (make-keymap))) + (suppress-keymap toggle-map) + (mapc (lambda (arg) (define-key toggle-map (car arg) (cdr arg))) + '(("t" . stgit-toggle-worktree))) + (setq stgit-mode-map (make-keymap)) + (suppress-keymap stgit-mode-map) + (mapc (lambda (arg) (define-key stgit-mode-map (car arg) (cdr arg))) + `((" " . stgit-mark) + ("m" . stgit-mark) + ("\d" . stgit-unmark-up) + ("u" . stgit-unmark-down) + ("?" . stgit-help) + ("h" . stgit-help) + ("\C-p" . stgit-previous-line) + ("\C-n" . stgit-next-line) + ([up] . stgit-previous-line) + ([down] . stgit-next-line) + ("p" . stgit-previous-patch) + ("n" . stgit-next-patch) + ("\M-{" . stgit-previous-patch) + ("\M-}" . stgit-next-patch) + ("s" . stgit-git-status) + ("g" . stgit-reload) + ("r" . stgit-refresh) + ("\C-c\C-r" . stgit-rename) + ("e" . stgit-edit) + ("M" . stgit-move-patches) + ("S" . stgit-squash) + ("N" . stgit-new) + ("R" . stgit-repair) + ("C" . stgit-commit) + ("U" . stgit-uncommit) + ("\r" . stgit-select) + ("o" . stgit-find-file-other-window) + ("i" . stgit-file-toggle-index) + (">" . stgit-push-next) + ("<" . stgit-pop-next) + ("P" . stgit-push-or-pop) + ("G" . stgit-goto) + ("=" . stgit-show) + ("D" . stgit-delete) + ([(control ?/)] . stgit-undo) + ("\C-_" . stgit-undo) + ("B" . stgit-branch) + ("t" . ,toggle-map) + ("q" . stgit-quit))))) (defun stgit-mode () "Major mode for interacting with StGit. @@ -619,6 +639,7 @@ Commands: (set (make-local-variable 'list-buffers-directory) default-directory) (set (make-local-variable 'stgit-marked-patches) nil) (set (make-local-variable 'stgit-expanded-patches) nil) + (set (make-local-variable 'stgit-show-worktree) stgit-default-show-worktree) (set-variable 'truncate-lines 't) (add-hook 'after-save-hook 'stgit-update-saved-file) (run-hooks 'stgit-mode-hook)) @@ -631,8 +652,7 @@ Commands: (buffer (and gitdir (stgit-find-buffer gitdir)))) (when buffer (with-current-buffer buffer - ;; FIXME: just invalidate ewoc node - (stgit-reload))))) + (stgit-refresh-worktree))))) (defun stgit-add-mark (patchsym) "Mark the patch PATCHSYM." @@ -856,13 +876,14 @@ If PATCHSYM is a keyword, returns PATCHSYM unmodified." (goto-char (point-min)) (diff-mode)))) -(defun stgit-move-change-to-index (file status) +(defun stgit-move-change-to-index (file) "Copies the workspace state of FILE to index, using git add or git rm" - (let ((op (if (file-exists-p file) "add" "rm"))) + (let ((op (if (or (file-exists-p file) (file-symlink-p file)) + '("add") '("rm" "-q")))) (stgit-capture-output "*git output*" - (stgit-run-git op "--" file)))) + (apply 'stgit-run-git (append op '("--") (list file)))))) -(defun stgit-remove-change-from-index (file status) +(defun stgit-remove-change-from-index (file) "Unstages the change in FILE from the index" (stgit-capture-output "*git output*" (stgit-run-git "reset" "-q" "--" file))) @@ -875,15 +896,13 @@ If PATCHSYM is a keyword, returns PATCHSYM unmodified." (error "No file on the current line")) (let ((patch-name (stgit-patch-name-at-point))) (cond ((eq patch-name :work) - (stgit-move-change-to-index (stgit-file-file patched-file) - (stgit-file-status patched-file))) + (stgit-move-change-to-index (stgit-file-file patched-file))) ((eq patch-name :index) - (stgit-remove-change-from-index (stgit-file-file patched-file) - (stgit-file-status patched-file))) + (stgit-remove-change-from-index (stgit-file-file patched-file))) (t (error "Can only move files in the working tree to index"))))) - ;; FIXME: invalidate ewoc - (stgit-reload)) + (stgit-refresh-worktree) + (stgit-refresh-index)) (defun stgit-edit () "Edit the patch on the current line." @@ -1117,4 +1136,29 @@ With prefix argument, refresh the marked patch or the patch under point." (stgit-refresh-git-status)) (stgit-reload)) +(defcustom stgit-default-show-worktree + nil + "Set to non-nil to by default show the working tree in a new stgit buffer. + +This value is used as the default value for `stgit-show-worktree'." + :type 'boolean + :group 'stgit) + +(defvar stgit-show-worktree nil + "Show work tree and index in the stgit buffer. + +See `stgit-default-show-worktree' for its default value.") + +(defun stgit-toggle-worktree (&optional arg) + "Toggle the visibility of the work tree. +With arg, show the work tree if arg is positive. + +Its initial setting is controlled by `stgit-default-show-worktree'." + (interactive) + (setq stgit-show-worktree + (if (numberp arg) + (> arg 0) + (not stgit-show-worktree))) + (stgit-reload)) + (provide 'stgit)