Skip to content

Commit 9f27c04

Browse files
committed
[Fix #1179] Add support for R projects
1 parent 04ebabb commit 9f27c04

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

lisp/ess-r-mode.el

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ top level functions only."
796796
(add-hook 'completion-at-point-functions #'ess-r-package-completion nil 'local)
797797
(add-hook 'completion-at-point-functions 'ess-filename-completion nil 'local)
798798
(add-hook 'xref-backend-functions #'ess-r-xref-backend nil 'local)
799+
(add-hook 'project-find-functions #'ess-r-project -90 'local)
799800

800801
(if (fboundp 'ess-add-toolbar) (ess-add-toolbar))
801802
;; imenu is needed for `which-function'
@@ -822,6 +823,64 @@ top level functions only."
822823
;;;###autoload
823824
(add-to-list 'auto-mode-alist '("CITATION\\'" . ess-r-mode))
824825

826+
827+
;;;*;;; Project detection
828+
829+
(defvar-local ess-r-project--info-cache nil
830+
"Current package info cache.
831+
See `ess-r-project-info' for its structure.")
832+
833+
(defun ess-r-project (&optional dir)
834+
"Return the current project as an Emacs project instance.
835+
R project is a directory XYZ containing either .Rprofile,
836+
DESCRIPTION or XYZ.Rproj file. Return a list of the form (:name
837+
\"XYZ\" :root \"/path/to/project\"). If DIR is provided, the
838+
project is searched from that directory instead of
839+
`default-directory'."
840+
(let ((info (ess-r-project-info dir)))
841+
(when (car info)
842+
(cons 'ess-r-project (plist-get info :root)))))
843+
844+
;; FIXME: remove when emacs 27 is dropped
845+
(unless (eval-when-compile
846+
(get 'project-roots 'byte-obsolete-info))
847+
(cl-defmethod project-roots ((project (head ess-r-project)))
848+
"Return the project root for ESS R projects."
849+
(list (cdr project))))
850+
851+
(cl-defmethod project-root ((project (head ess-r-project)))
852+
"Return the project root for ESS R projects."
853+
(cdr project))
854+
855+
(defun ess-r-project-info (&optional dir)
856+
"Get the description of the R project in directory DIR.
857+
Return an plist with the keys :name and :root. When not in a
858+
project return '(nil). This value is cached buffer-locally for
859+
efficiency reasons."
860+
(let ((do-cache (null dir)))
861+
(if (and do-cache ess-r-project--info-cache)
862+
ess-r-project--info-cache
863+
(setq dir (or dir (buffer-file-name) default-directory))
864+
(let ((out (or
865+
(unless (file-remote-p dir)
866+
(let ((dir (locate-dominating-file
867+
dir
868+
(lambda (dir)
869+
(or (file-exists-p (expand-file-name ".Rprofile" dir))
870+
(file-exists-p (expand-file-name "DESCRIPTION" dir))
871+
(let ((nm (file-name-nondirectory (directory-file-name dir))))
872+
(file-exists-p (expand-file-name (concat nm ".Rproj") dir))))))))
873+
(when dir
874+
(let ((dir (directory-file-name dir)))
875+
(unless (member dir (list "~" (getenv "HOME")))
876+
(list :name (file-name-nondirectory dir)
877+
:root (expand-file-name dir)))))))
878+
'())))
879+
(when do-cache
880+
(setq ess-r-project--info-cache out))
881+
out))))
882+
883+
825884

826885
;;*;; Miscellaneous
827886

@@ -2405,6 +2464,7 @@ state.")
24052464
(add-hook 'completion-at-point-functions 'ess-r-object-completion nil 'local)
24062465
(add-hook 'completion-at-point-functions 'ess-filename-completion nil 'local)
24072466
(add-hook 'xref-backend-functions #'ess-r-xref-backend nil 'local)
2467+
(add-hook 'project-find-functions #'ess-r-project -90 'local)
24082468
;; eldoc
24092469
(ess--setup-eldoc #'ess-r-eldoc-function)
24102470
;; auto-complete

0 commit comments

Comments
 (0)