;;; git.el --- Magit, minimal Evil -*- lexical-binding: t; -*- ;;; Commentary: ;; Loaded from init.el after evil.el. ;; ;; :git Magit status for the current repo, full frame. ;; q puts your previous window layout back. ;; :git ARGS Run `git ARGS' from the repo root, e.g. :git log --oneline ;; ;; Magit buffers use Evil's emacs state, so every Magit key is native ;; (s stage, u unstage, c c commit, P push, F pull, l log, d diff, b branch, ;; z stash, g refresh, n/p sections, TAB folds, ? lists every command), ;; except j/k, which move by line. That shadows Magit's own j (jump to ;; section) and k (discard): use M-x magit-status-jump / magit-discard. ;; If ESC drops you into normal state, C-z toggles emacs state back. ;; Commit message: opens in insert state; C-c C-c commits, C-c C-k cancels. ;;; Code: (use-package magit :defer t :custom ;; Status takes the whole frame; q restores the previous window layout. (magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1) (magit-bury-buffer-function #'magit-restore-window-configuration)) ;; All Magit buffers derive from magit-mode. (evil-set-initial-state 'magit-mode 'emacs) (with-eval-after-load 'magit-mode (evil-define-key 'emacs magit-mode-map "j" #'next-line "k" #'previous-line)) ;; Commit messages start in insert state. Added after git-commit loads so its ;; default hook functions are kept. (with-eval-after-load 'git-commit (add-hook 'git-commit-setup-hook #'evil-insert-state)) ;; :git opens Magit; :git ARGS runs a git command. (evil-define-command my/git (args) "Open Magit status, or run `git ARGS' from the repository root." (interactive "") (if (and args (string-match-p "[^[:space:]]" args)) (magit-git-command-topdir (concat "git " args)) (magit-status))) (evil-ex-define-cmd "git" #'my/git) ;;; git.el ends here