   :general
   (:keymaps 'grep-mode-map "C-c w" #'wgrep-change-to-wgrep-mode))
 
-(use-package projectile
-  :after evil
-  :demand t     ; required because use-package-always-defer is t
-  :custom
-  (projectile-completion-system 'ivy)
-  (projectile-globally-ignored-files #'( "TAGS" "GTAGS" "GRTAGS" "GPATH" ))
-  (projectile-globally-ignored-file-suffixes #'( ".o" ".so" ".a" ".ko" ".jar" ".bc" ".class"))
-  ;; we mainly want projects defined by a few markers and we always want to take the top-most marker.
-  ;; Reorder so other cases are secondary
-  (projectile-project-root-files-functions #'(projectile-root-top-down
-                                              projectile-root-bottom-up
-                                              projectile-root-local))
-  (projectile-project-root-files #'( ".projectile" ))
-  (projectile-use-git-grep t)
-  (projectile-indexing-method 'hybrid)      ;; default indexing method is total crap
-  (projectile-enable-caching t)
-  :general
-  (:keymaps 'projectile-mode-map "<f7>" 'projectile-command-map )  ; all projectile built in bindings off f7
-  ("<f7> N"     #'projectile-clear-known-projects)
-  ("<f7> n"     #'projectile-add-known-project)
-  (:prefix "<f7>" "4"  '(:ignore t :which-key "Find→" ))
-  (:prefix "<f7>" "5"  '(:ignore t :which-key "Find→" ))
-  (:prefix "<f7>" "x"  '(:ignore t :which-key "Run→" ))
-  (:prefix "<f7>" "s"  '(:ignore t :which-key "Search→" ))
-  (:prefix "<f7> s" :keymaps 'projectile-mode-map
-           "a" #'me:counsel-ag-project
-           "r" nil  ;; unbind projectile-ripgrep
-           "s" #'me:counsel-rg-project)
-  ;; For reasons I don't understand, if projectile's map
-  ;; has ESC in its map, this prevents the binding
-  ;; <f7> <f7> for persp-projectile, but only in "emacs -nw" mode!
-  ;; So getting rid of it here.
-  (:prefix "<f7>" :keymaps 'projectile-mode-map
-           "ESC" nil
-           "c" nil)
-;;  (:prefix "<f7>" "c" #'counsel-compile)
-
-  :init
-  (setq
-   projectile-project-root-files #'( ".projectile" )
-   projectile-project-compilation-cmd "")     ;; workaround for stupid projectile bug
-  :config
-  ;; We really only want to top-down recognize projects that are marked
-  ;; with .projectile. Anything else is brain-damage.
-  ;; Projectile has a nifty "feature" where it sets up projectile-project-root-files
-  ;; to be umpteen different project marker files which goes against having
-  ;; a super-project, which of course many people have. Fuck projectile.
-  (setq projectile-project-root-files #'( ".projectile" ))
-  (defun me:counsel-ag-project ()
-    "Search using ag in project"
-    (interactive)
-    (if (and (fboundp 'projectile-project-p) (projectile-project-p))
-        (counsel-ag (thing-at-point 'symbol) (projectile-project-root))
-      (message "Not in a project")))
+;; built-in project.el
+(use-package project
+  :demand t
+  :general
+  ;; TODO: This duplicates project-prefix-map; should find a way to use that
+  (:prefix "<f7>"
+           "<f7>" 'me:counsel-rg-project
+           "!" 'project-shell-command
+           "&" 'project-async-shell-command
+           "f" 'project-find-file
+           "F" 'project-or-external-find-file
+           "b" 'project-switch-to-buffer
+           "s" 'project-shell
+           "d" 'project-find-dir
+           "D" 'project-dired
+           "v" 'project-vc-dir
+           ;; N.B. f7-c runs counsel-compile
+           "C" 'project-compile
+           "e" 'project-eshell
+           "k" 'project-kill-buffers
+           "p" 'project-switch-project
+           "g" 'project-find-regexp
+           "G" 'project-or-external-find-regexp
+           "r" 'project-query-replace-regexp
+           "x" 'project-execute-extended-command)
+  :config
   (defun me:counsel-rg-project ()
     "Search using ripgrep in project"
     (interactive)
-    (if (and (fboundp 'projectile-project-p) (projectile-project-p))
-        (counsel-rg (thing-at-point 'symbol) (projectile-project-root))
+    (if-let ((root (me:project-path)))
+        (counsel-rg (thing-at-point 'symbol) root)
       (message "Not in a project")))
-
+  ;; Add project relative org templates
   (defun me:add-project-templates ()
-    (add-to-list 'org-capture-templates `("pn" "Project Notes" entry (file+headline ,(me:project-path "Notes/notes.org") "Notes")))
-    (add-to-list 'org-capture-templates `("pd" "Project Tasks" entry (file+headline ,(me:project-path "Notes/notes.org") "TODOs")
-                                          "* TODO %?\n  %i\n  %a")))
+    (when (project-current)
+      (add-to-list 'org-capture-templates
+                   `("pn" "Project Notes" entry (file+headline ,(me:project-path "Notes/notes.org") "Notes")))
+      (add-to-list 'org-capture-templates
+                   `("pd" "Project Tasks" entry (file+headline ,(me:project-path "Notes/notes.org") "TODOs")
+                     "* TODO %?\n  %i\n  %a"))))
+  ;; Return path relative to project or nil if no project
   (defun me:project-path ( &optional path)
-    (if path
-        (expand-file-name path (projectile-project-root))
-      (projectile-project-root)))
-  (projectile-mode 1))
-
-(use-package persp-projectile
-  :after projectile
-  :general
-  (:prefix "<f7>" "<f7>"  #'projectile-persp-switch-project)
-  :demand)
-
-(use-package perspective
-  :after persp-projectile
-  :general
-  ("<f7> r"     #'persp-rename)
-  ("M-<right>"  #'persp-next)
-  ("M-<left>"   #'persp-prev)
-  (:prefix "C-x"
-           "x"  '(:ignore t :which-key "Perspective→" ))
-  :config
-  (persp-mode))
+    (if-let* ((proj (project-current))
+              (root (project-root proj)))
+        (if path
+            (expand-file-name path root)
+          root)))
+  (defun me:project-mode-line-info()
+    (if-let* ((path (me:project-path))
+              (name (file-name-nondirectory (directory-file-name path))))
+        (concat " [" name "] ")))
+  (add-to-list 'mode-line-misc-info `(:eval (me:project-mode-line-info)))
+  :ensure nil)
 
 (use-package rainbow-delimiters
   :hook ((emacs-lisp-mode) . rainbow-delimiters-mode ))

        magit-section-initial-visibility-alist '(( stashes . hide ))
        magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1
        magit-repository-directories `((,(expand-file-name "dev" "~") . 1)))
  ;; fullscreen magit and restore configuration when done. This and other
  ;; things stolen from:
  ;; https://jakemccrary.com/blog/2020/11/14/speeding-up-magit/
  (defadvice magit-status (around magit-fullscreen activate)
    (window-configuration-to-register :magit-fullscreen)
    ad-do-it
    (delete-other-windows))
  (defadvice magit-quit-window (after magit-restore-screen activate)
    (jump-to-register :magit-fullscreen))
  :general
  ("<f9> a"     #'magit-commit-amend)
  ("<f9> b"     #'magit-blame)

        (magit-find-file-other-window rev (buffer-file-name))
      (magit-find-file rev (buffer-file-name)))))

;; git configuration file editting
(use-package git-modes)

(use-package git-timemachine
