summaryrefslogtreecommitdiffstats
path: root/lisp/init-project.el
blob: 6ff22a741465f2549e2f9dccee87b243cdae36b2 (plain) (blame)
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
;;; init-project.el --- configure project integration  -*- lexical-binding:t -*-
;;; Commentary:
;;; Code:

(defun mpolden/project-try-go (dir)
  "Find root directory of a nested modules-based Go project from DIR."
  ;; this speeds up working with a go project nested inside a large repository
  (let* ((module-root (locate-dominating-file dir "go.mod"))
         (is-vc-root (file-directory-p (expand-file-name ".git" module-root))))
    (when (and module-root (not is-vc-root))
      (cons 'transient module-root))))

(defun mpolden/project-vterm ()
  "Start Vterm in the current project's root directory.
If a buffer already exists for any directory in the current
project, switch to it.

With \\[universal-argument] prefix arg, always create a new
buffer even if one already exists for the current project, or if
there is no project in `default-directory'."
  (interactive)
  (let* ((project (project-current (not current-prefix-arg)))
         (default-directory (if project
                                (project-root project)
                              default-directory))
         ;; find a vterm buffer which has its current directory in the project
         ;; root or any sub-directory of the root
         (vterm-buf
          (car (seq-filter
                (lambda (buf)
                  (let* ((buf-prefix "vterm: ")
                         (buf-name (buffer-name buf))
                         (buf-dir (string-remove-prefix buf-prefix buf-name)))
                    (and (string-prefix-p buf-prefix buf-name)
                         (file-in-directory-p buf-dir default-directory))))
                (buffer-list)))))
    (if (and vterm-buf (not current-prefix-arg))
        (pop-to-buffer vterm-buf)
      (vterm-other-window))))

(use-package project
  :init
  ;; commands to show when switching projects
  (setq project-switch-commands '((project-find-file "Find file" ?f)
                                  (project-dired "Dired" ?d)
                                  (mpolden/grep "Grep" ?g)
                                  (magit-project-status "Magit" ?m)
                                  (mpolden/project-vterm "Vterm" ?v)))
  ;; configure how projects are detected
  (setq project-find-functions '(mpolden/project-try-go project-try-vc))
  :bind (;; C-x f finds file in project
         ("C-x f" . project-find-file)
         ;; C-c p switches project
         ("C-c p" . project-switch-project)
         ;; C-c v starts vterm in project
         ("C-c v" . mpolden/project-vterm)))

(provide 'init-project)

;;; init-project.el ends here