From 1536e1a1ce46455a04aa8dff05e860abdf3aeb2a Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 12:04:27 +0200 Subject: [PATCH 01/24] Disaggregate setqs --- lisp/ess-inf.el | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index f8eb948bd..063d03100 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -130,11 +130,8 @@ Alternatively, it can appear in its own frame if (procname (let ((ntry 0) ;; find the next non-existent process N (*R:N*) (done nil)) (while (not done) - (setq ntry (1+ ntry) - done (not - (get-process (ess-proc-name - ntry - temp-dialect))))) + (setq ntry (1+ ntry)) + (setq done (not (get-process (ess-proc-name ntry temp-dialect))))) (ess-proc-name ntry temp-dialect))) (buf-name-str (funcall ess-gen-proc-buffer-name-function procname)) startdir buf method) @@ -149,33 +146,33 @@ Alternatively, it can appear in its own frame if (eq major-mode 'inferior-ess-mode)) (setq startdir (if ess-ask-for-ess-directory (ess-get-directory defdir temp-dialect procname) - defdir) - buf (current-buffer) - ;; don't change existing buffer name in this case; It is very - ;; commong to restart the process in the same buffer. - buf-name-str (buffer-name) - method 1)) + defdir)) + (setq buf (current-buffer)) + ;; don't change existing buffer name in this case; It is very + ;; commong to restart the process in the same buffer. + (setq buf-name-str (buffer-name)) + (setq method 1)) ;; 2) Take the *R:N* buffer if already exists (and contains dead proc!) ;; fixme: buffer name might have been changed, iterate over all ;; inferior-ess buffers ((get-buffer buf-name-str) - (setq buf (get-buffer buf-name-str) - method 2)) + (setq buf (get-buffer buf-name-str)) + (setq method 2)) ;; 3) Pick up a transcript file or create a new buffer (t (setq startdir (if ess-ask-for-ess-directory - (ess-get-directory defdir temp-dialect procname) - defdir) - buf (if ess-ask-about-transfile - (let ((transfilename (read-file-name "Use transcript file (default none):" - startdir ""))) - (if (string= transfilename "") - (get-buffer-create buf-name-str) - (find-file-noselect (expand-file-name transfilename)))) - (get-buffer-create buf-name-str)) - method 3))) + (ess-get-directory defdir temp-dialect procname) + defdir)) + (setq buf (if ess-ask-about-transfile + (let ((transfilename (read-file-name "Use transcript file (default none):" + startdir ""))) + (if (string= transfilename "") + (get-buffer-create buf-name-str) + (find-file-noselect (expand-file-name transfilename)))) + (get-buffer-create buf-name-str))) + (setq method 3))) (ess-write-to-dribble-buffer (format "(inf-ess 2.0) Method #%d start=%s buf=%s\n" method startdir buf)) From 1079d1fe269c0f503b298850d99e92f4b6f11caf Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 12:15:03 +0200 Subject: [PATCH 02/24] Clean up comments --- lisp/ess-inf.el | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 063d03100..569cb96fc 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -119,15 +119,15 @@ Alternatively, it can appear in its own frame if (defdir (or (and ess-directory-function (funcall ess-directory-function)) ess-directory default-directory)) + ;; Use temp-ess-dialect if not R, R program name otherwise (temp-dialect (if ess-use-inferior-program-name-in-buffer-name ;VS[23-02-2013]: fixme: this should not be here (if (string-equal temp-ess-dialect "R") inferior-ess-r-program-name - temp-ess-dialect) ; use temp-ess-dialect - ; if not R, R program name - ; otherwise. + temp-ess-dialect) temp-ess-dialect)) (temp-lang temp-ess-lang) - (procname (let ((ntry 0) ;; find the next non-existent process N (*R:N*) + ;; Find the next non-existent process N (*R:N*) + (procname (let ((ntry 0) (done nil)) (while (not done) (setq ntry (1+ ntry)) @@ -177,20 +177,15 @@ Alternatively, it can appear in its own frame if (ess-write-to-dribble-buffer (format "(inf-ess 2.0) Method #%d start=%s buf=%s\n" method startdir buf)) - (set-buffer buf) ;; Now that we have the buffer, set buffer-local variables. - (ess-setq-vars-local ess-customize-alist) ; buf) + (set-buffer buf) + (ess-setq-vars-local ess-customize-alist) - ;; Write out debug info (ess-write-to-dribble-buffer (format "(inf-ess 2.1): ess-language=%s, ess-dialect=%s buf=%s \n" ess-language ess-dialect (current-buffer))) - ;; initialize. - (if startdir (setq default-directory startdir)) - - ;; the following was part of ess-multi; - + (when startdir (setq default-directory startdir)) (let* ((ess-directory (or startdir ess-directory)) (infargs (or ess-start-args From 7565e008aaf4eb8989a8e8f0445a93c68a8aa128 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 12:19:54 +0200 Subject: [PATCH 03/24] Refactor loop to proper form --- lisp/ess-inf.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 569cb96fc..d37696dd2 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -127,11 +127,9 @@ Alternatively, it can appear in its own frame if temp-ess-dialect)) (temp-lang temp-ess-lang) ;; Find the next non-existent process N (*R:N*) - (procname (let ((ntry 0) - (done nil)) - (while (not done) - (setq ntry (1+ ntry)) - (setq done (not (get-process (ess-proc-name ntry temp-dialect))))) + (procname (let ((ntry 1)) + (while (get-process (ess-proc-name ntry temp-dialect)) + (setq ntry (1+ ntry))) (ess-proc-name ntry temp-dialect))) (buf-name-str (funcall ess-gen-proc-buffer-name-function procname)) startdir buf method) From db7303455a8c79aed8f3bccd93c354efc58b5052 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 12:26:41 +0200 Subject: [PATCH 04/24] Alias `ess-directory` to `ess-default-directory` --- lisp/ess-custom.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/ess-custom.el b/lisp/ess-custom.el index 0238c98a6..540b3b8c7 100644 --- a/lisp/ess-custom.el +++ b/lisp/ess-custom.el @@ -337,12 +337,13 @@ a workspace." :group 'ess :type '(choice (const nil) function)) -(defcustom ess-directory nil +(defcustom ess-default-directory nil "The directory ESS is run from. It must end in a slash. Provided as a default if `ess-ask-for-ess-directory' is non-nil. A nil value means use the current buffer's default directory." :group 'ess :type '(choice (const nil) directory)) +(defalias 'ess-directory 'ess-default-directory) (defcustom ess-history-directory nil "Directory to pick up `ess-history-file' from. From b78ad411509d5f32cfa285da93b52edd1196b417 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 14:11:14 +0200 Subject: [PATCH 05/24] Refactor ess-get-directory() Separate into: - inferior-ess--default-directory() - inferior-ess--get-directory() --- lisp/ess-inf.el | 50 +++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index d37696dd2..143f1e683 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -116,9 +116,6 @@ Alternatively, it can appear in its own frame if (format "(inf-ess 1): lang=%s, dialect=%s, tmp-dialect=%s, buf=%s\n" ess-language ess-dialect temp-ess-dialect (current-buffer))) (let* ((process-environment process-environment) - (defdir (or (and ess-directory-function (funcall ess-directory-function)) - ess-directory default-directory)) - ;; Use temp-ess-dialect if not R, R program name otherwise (temp-dialect (if ess-use-inferior-program-name-in-buffer-name ;VS[23-02-2013]: fixme: this should not be here (if (string-equal temp-ess-dialect "R") @@ -142,9 +139,7 @@ Alternatively, it can appear in its own frame if ;; 1) try to use current buffer, if inferior-ess-mode but no process ((and (not (comint-check-proc (current-buffer))) (eq major-mode 'inferior-ess-mode)) - (setq startdir (if ess-ask-for-ess-directory - (ess-get-directory defdir temp-dialect procname) - defdir)) + (setq startdir (inferior-ess--get-directory procname temp-dialect)) (setq buf (current-buffer)) ;; don't change existing buffer name in this case; It is very ;; commong to restart the process in the same buffer. @@ -160,9 +155,7 @@ Alternatively, it can appear in its own frame if ;; 3) Pick up a transcript file or create a new buffer (t - (setq startdir (if ess-ask-for-ess-directory - (ess-get-directory defdir temp-dialect procname) - defdir)) + (setq startdir (inferior-ess--get-directory procname temp-dialect)) (setq buf (if ess-ask-about-transfile (let ((transfilename (read-file-name "Use transcript file (default none):" startdir ""))) @@ -581,21 +574,30 @@ This marks the process with a message, at a particular time point." ;;*;; Requester functions called at startup -(defun ess-get-directory (default dialect procname) - (let ((prog-version (cond ((string= dialect "R") - (concat ", " inferior-R-version)) ; notably for the R-X.Y versions - (inferior-ess-program - (concat ", " inferior-ess-program )) - (t "")))) - (ess-prompt-for-directory - (directory-file-name default) - (format "ESS (*%s*%s) starting data directory? " - procname prog-version) - ;; (format "ESS [%s {%s(%s)}: '%s'] starting data directory? " - ;; ;;FIXME: maybe rather tmp-dialect (+ evt drop ess-language?)? - ;; procname ess-language ess-dialect prog-version) - ))) - +;; FIXME EMACS 25.1: +;; Deprecate `ess-directory-function' in favour of `project-find-functions'? +(defun inferior-ess--default-directory () + (let ((dir (or (and ess-directory-function + (funcall ess-directory-function)) + ess-default-directory + default-directory))) + (directory-file-name dir))) + +(defun inferior-ess--get-directory (procname dialect) + "This returns the directory of the current project" + (let ((default-dir (inferior-ess--default-directory))) + (if (not ess-ask-for-ess-directory) + default-dir + (let* ((prog (cond ((string= dialect "R") + ;; Includes R-X.Y versions + (concat ", " inferior-R-version)) + (inferior-ess-program + (concat ", " inferior-ess-program )) + (t ""))) + (prompt (format "ESS (*%s*%s) starting data directory? " + procname + prog))) + (ess-prompt-for-directory default-dir prompt))))) (defun ess-prompt-for-directory (default prompt) "`prompt' for a directory, using `default' as the usual." From 2dd3d2336c128ebccf747a94e50897e3ebe83c82 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 14:12:48 +0200 Subject: [PATCH 06/24] Reduce noise in directory prompt --- lisp/ess-inf.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 143f1e683..4a7db0308 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -594,7 +594,7 @@ This marks the process with a message, at a particular time point." (inferior-ess-program (concat ", " inferior-ess-program )) (t ""))) - (prompt (format "ESS (*%s*%s) starting data directory? " + (prompt (format "%s starting project directory? " procname prog))) (ess-prompt-for-directory default-dir prompt))))) From 3f22ff4cf1ed6b4694443d1002ef50e9b0ef4e1c Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 14:14:04 +0200 Subject: [PATCH 07/24] Integrate `ess-r-package-mode` with Emacs projects --- lisp/ess-r-package.el | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index f8e843597..98f99ca66 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -87,6 +87,11 @@ whether the current file is part of a package, or the value of (with-ess-process-buffer t ess-r-package-info))) +(defun ess-r-package-project (dir) + (let ((info (ess-r-package--package-dir-info dir))) + (when (car info) + info))) + (defun ess-r-package--all-source-dirs (dir) (when (file-exists-p dir) (cl-loop for f in (directory-files-and-attributes dir t "^[^.]") @@ -180,19 +185,25 @@ return all physically present directories." "Parses DESCRIPTION file in PATH (R specific so far). PATH defaults to the value returned by `ess-r-package--find-package-path'." - (let ((pkg-path (ess-r-package--find-package-path))) - (setq ess-r-package-info - (if pkg-path - (cons (ess-r-package--find-package-name pkg-path) pkg-path) - ;; cache non-package files as well - '(nil))))) - -(defun ess-r-package--find-package-path () + ;; Cache info for better performance on remotes + (setq ess-r-package-info (ess-r-package--package-dir-info))) + +(defun ess-r-package--package-dir-info (&optional dir) + (let ((pkg-path (ess-r-package--find-package-path dir))) + (if pkg-path + (cons (ess-r-package--find-package-name pkg-path) pkg-path) + ;; Ensures that non-package files are cached as well + '(nil)))) + +(defun ess-r-package--find-package-path (&optional dir) "Get the root of R package that contains current directory. Root is determined by locating `ess-r-package-root-file'." - (let* ((path (if (buffer-file-name) - (file-name-directory (buffer-file-name)) - default-directory)) + (let* ((path (cond + (dir) + ((buffer-file-name) + (file-name-directory (buffer-file-name))) + (t + default-directory))) (pkg-path (when path (or @@ -406,8 +417,10 @@ disable the mode line entirely." :lighter ess-r-package-mode-line (cond (ess-r-package-mode + (add-hook 'project-find-functions #'ess-r-package-project) (run-hooks 'ess-r-package-enter-hook)) (t + (remove-hook 'project-find-functions #'ess-r-package-project) (run-hooks 'ess-r-package-exit-hook)))) (add-hook 'after-change-major-mode-hook 'ess-r-package-auto-activate) From 01e1b3cac6efc3ffc6d4f0c62300f83e9e37f564 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 14:14:50 +0200 Subject: [PATCH 08/24] Use project-current() for checking default directory Now that R packages are registered as projects this will return their root directory as default. Eventually we might want to deprecate `ess-directory-function` in favour of projects once Emacs 25.1 becomes the oldest supported version. --- lisp/ess-inf.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 4a7db0308..9a668720f 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -577,7 +577,9 @@ This marks the process with a message, at a particular time point." ;; FIXME EMACS 25.1: ;; Deprecate `ess-directory-function' in favour of `project-find-functions'? (defun inferior-ess--default-directory () - (let ((dir (or (and ess-directory-function + (let ((dir (or (and (fboundp 'project-current) + (cdr (project-current))) + (and ess-directory-function (funcall ess-directory-function)) ess-default-directory default-directory))) From 36dbbd2f6a8d81236972768ab88b5801007d4592 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 14:26:17 +0200 Subject: [PATCH 09/24] Restore directory silently on reloading --- lisp/ess-inf.el | 19 +++++++++++-------- lisp/ess-r-mode.el | 13 ++----------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 9a668720f..c42987374 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -2578,14 +2578,17 @@ before you quit. It is run automatically by \\[ess-quit]." ;; Interrupt early so we can get working directory (ess-interrupt) (save-window-excursion - (:override - (let ((dir (ess-get-working-directory)) - (ess-ask-for-ess-directory nil) - (proc (ess-get-proc))) - (ess-quit 'no-save) - (inferior-ess--wait-for-exit proc) - (error "Unimplemented for this dialect") - (ess-set-working-directory dir))))) + ;; Make sure we don't ask for directory again + (let ((project-find-functions nil) + (ess-directory-function nil) + (ess-default-directory nil) + ;; Use current working directory as default before restarting + (ess-ask-for-ess-directory nil) + (default-dir (ess-get-working-directory))) + (ess-quit 'no-save) + (inferior-ess--wait-for-exit (ess-get-process)) + (:override + (error "Unimplemented for this dialect"))))) (defun inferior-ess--wait-for-exit (proc) "Wait for process exit. diff --git a/lisp/ess-r-mode.el b/lisp/ess-r-mode.el index ac07f6c5f..b24d9572c 100644 --- a/lisp/ess-r-mode.el +++ b/lisp/ess-r-mode.el @@ -1386,17 +1386,8 @@ we flush the cache.") :group 'ess-R) (ess-defmethod R inferior-ess-reload (&optional start-args) - (let ((dir (ess-get-working-directory)) - (ess-ask-for-ess-directory nil) - (proc (ess-get-process))) - (with-ess-process-buffer nil - (ess-quit 'no-save) - (inferior-ess--wait-for-exit proc) - (R start-args) - (run-hooks 'inferior-ess-r-reload-hook)) - ;; If we are in a package the working directory is already set - (unless (cdr ess-r-package-info) - (ess-set-working-directory dir)))) + (R start-args) + (run-hooks 'inferior-ess-r-reload-hook)) (defun inferior-ess-r-force (&optional prompt force no-autostart ask-if-1) (setq ess-dialect "R") From 9907220ab78d8b35077ae8ce0ea101c9e6267e66 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 7 Oct 2017 18:12:22 +0200 Subject: [PATCH 10/24] Use `ess-default-directory` instead of `default-directory` `default-directory` is unset by the time the inferior is restarted --- lisp/ess-inf.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index c42987374..65d4fd54d 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -2579,12 +2579,11 @@ before you quit. It is run automatically by \\[ess-quit]." (ess-interrupt) (save-window-excursion ;; Make sure we don't ask for directory again + ;; Use current working directory as default (let ((project-find-functions nil) (ess-directory-function nil) - (ess-default-directory nil) - ;; Use current working directory as default before restarting - (ess-ask-for-ess-directory nil) - (default-dir (ess-get-working-directory))) + (ess-default-directory (ess-get-working-directory)) + (ess-ask-for-ess-directory nil)) (ess-quit 'no-save) (inferior-ess--wait-for-exit (ess-get-process)) (:override From 581ed386ef5332a848eeb44a60b06b4c647b08b8 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sun, 8 Oct 2017 18:13:43 +0200 Subject: [PATCH 11/24] Better names for directory helpers Renamed inferior-ess--get-directory() to inferior-ess--maybe-prompt-startup-directory() Renamed inferior-ess--default-directory() to inferior-ess--get-startup-directory() --- lisp/ess-inf.el | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 65d4fd54d..6610b00a8 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -139,7 +139,7 @@ Alternatively, it can appear in its own frame if ;; 1) try to use current buffer, if inferior-ess-mode but no process ((and (not (comint-check-proc (current-buffer))) (eq major-mode 'inferior-ess-mode)) - (setq startdir (inferior-ess--get-directory procname temp-dialect)) + (setq startdir (inferior-ess--maybe-prompt-startup-directory procname temp-dialect)) (setq buf (current-buffer)) ;; don't change existing buffer name in this case; It is very ;; commong to restart the process in the same buffer. @@ -155,7 +155,7 @@ Alternatively, it can appear in its own frame if ;; 3) Pick up a transcript file or create a new buffer (t - (setq startdir (inferior-ess--get-directory procname temp-dialect)) + (setq startdir (inferior-ess--maybe-prompt-startup-directory procname temp-dialect)) (setq buf (if ess-ask-about-transfile (let ((transfilename (read-file-name "Use transcript file (default none):" startdir ""))) @@ -576,7 +576,7 @@ This marks the process with a message, at a particular time point." ;; FIXME EMACS 25.1: ;; Deprecate `ess-directory-function' in favour of `project-find-functions'? -(defun inferior-ess--default-directory () +(defun inferior-ess--get-startup-directory () (let ((dir (or (and (fboundp 'project-current) (cdr (project-current))) (and ess-directory-function @@ -585,21 +585,20 @@ This marks the process with a message, at a particular time point." default-directory))) (directory-file-name dir))) -(defun inferior-ess--get-directory (procname dialect) - "This returns the directory of the current project" - (let ((default-dir (inferior-ess--default-directory))) - (if (not ess-ask-for-ess-directory) - default-dir - (let* ((prog (cond ((string= dialect "R") - ;; Includes R-X.Y versions - (concat ", " inferior-R-version)) - (inferior-ess-program - (concat ", " inferior-ess-program )) - (t ""))) - (prompt (format "%s starting project directory? " - procname - prog))) - (ess-prompt-for-directory default-dir prompt))))) +(defun inferior-ess--maybe-prompt-startup-directory (procname dialect) + (let ((default-dir (inferior-ess--get-startup-directory))) + (if ess-ask-for-ess-directory + (let* ((prog (cond ((string= dialect "R") + ;; Includes R-X.Y versions + (concat ", " inferior-R-version)) + (inferior-ess-program + (concat ", " inferior-ess-program )) + (t ""))) + (prompt (format "%s starting project directory? " + procname + prog))) + (ess-prompt-for-directory default-dir prompt)) + default-dir))) (defun ess-prompt-for-directory (default prompt) "`prompt' for a directory, using `default' as the usual." From eb46c8dd0d68a51174b6ac9aba282c4638fcb824 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sun, 8 Oct 2017 18:15:38 +0200 Subject: [PATCH 12/24] Rename `ess-default-directory` to `ess-startup-directory` --- lisp/ess-custom.el | 4 ++-- lisp/ess-inf.el | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lisp/ess-custom.el b/lisp/ess-custom.el index 540b3b8c7..cbea51fbe 100644 --- a/lisp/ess-custom.el +++ b/lisp/ess-custom.el @@ -337,13 +337,13 @@ a workspace." :group 'ess :type '(choice (const nil) function)) -(defcustom ess-default-directory nil +(defcustom ess-startup-directory nil "The directory ESS is run from. It must end in a slash. Provided as a default if `ess-ask-for-ess-directory' is non-nil. A nil value means use the current buffer's default directory." :group 'ess :type '(choice (const nil) directory)) -(defalias 'ess-directory 'ess-default-directory) +(defalias 'ess-directory 'ess-startup-directory) (defcustom ess-history-directory nil "Directory to pick up `ess-history-file' from. diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 6610b00a8..099706e7b 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -581,7 +581,7 @@ This marks the process with a message, at a particular time point." (cdr (project-current))) (and ess-directory-function (funcall ess-directory-function)) - ess-default-directory + ess-startup-directory default-directory))) (directory-file-name dir))) @@ -2581,7 +2581,7 @@ before you quit. It is run automatically by \\[ess-quit]." ;; Use current working directory as default (let ((project-find-functions nil) (ess-directory-function nil) - (ess-default-directory (ess-get-working-directory)) + (ess-startup-directory (ess-get-working-directory)) (ess-ask-for-ess-directory nil)) (ess-quit 'no-save) (inferior-ess--wait-for-exit (ess-get-process)) From 463aeb745081526f3c5dc2786e6436a996704e75 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Tue, 10 Oct 2017 09:53:42 +0200 Subject: [PATCH 13/24] Proper `defvaralias` --- lisp/ess-custom.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/ess-custom.el b/lisp/ess-custom.el index cbea51fbe..aca49c3a6 100644 --- a/lisp/ess-custom.el +++ b/lisp/ess-custom.el @@ -343,7 +343,7 @@ Provided as a default if `ess-ask-for-ess-directory' is non-nil. A nil value means use the current buffer's default directory." :group 'ess :type '(choice (const nil) directory)) -(defalias 'ess-directory 'ess-startup-directory) +(defvaralias 'ess-directory 'ess-startup-directory) (defcustom ess-history-directory nil "Directory to pick up `ess-history-file' from. From 115f86cbf218dae960e9a01d951037675ba72935 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 11:18:35 +0200 Subject: [PATCH 14/24] Move ess--parent-dir() to ess-utils.el --- lisp/ess-r-package.el | 11 ----------- lisp/ess-utils.el | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index 98f99ca66..c189ceaa8 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -224,17 +224,6 @@ Root is determined by locating `ess-r-package-root-file'." (when pkg-path (directory-file-name pkg-path)))) -(defun ess--parent-dir (path n) - "Return Nth parent of PATH." - (let ((opath path)) - (while (and path (> n 0)) - (setq path (file-name-directory (directory-file-name opath))) - (if (equal path opath) - (setq path nil) - (setq opath path - n (1- n)))) - path)) - (defun ess-r-package--find-package-name (path) (let ((file (expand-file-name ess-r-package-root-file path)) (case-fold-search t)) diff --git a/lisp/ess-utils.el b/lisp/ess-utils.el index 2a4784f6c..268503efb 100644 --- a/lisp/ess-utils.el +++ b/lisp/ess-utils.el @@ -394,6 +394,17 @@ Search for the executables in ESS-EXEC-DIR (which defaults to "Drop all entries that do not \"look like\" directories." (ess-flatten-list (mapcar 'file-name-directory file-strings))) +(defun ess--parent-dir (path n) + "Return Nth parent of PATH." + (let ((opath path)) + (while (and path (> n 0)) + (setq path (file-name-directory (directory-file-name opath))) + (if (equal path opath) + (setq path nil) + (setq opath path + n (1- n)))) + path)) + ;;*;; Interaction with inferiors From 5a67ea53de27bc02c5e95bb431dfabb0b4f0e361 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 11:51:01 +0200 Subject: [PATCH 15/24] Remove wd setter in ESSR startup as it has moved to inferior startup --- lisp/ess-r-mode.el | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lisp/ess-r-mode.el b/lisp/ess-r-mode.el index b24d9572c..6b116bd2f 100644 --- a/lisp/ess-r-mode.el +++ b/lisp/ess-r-mode.el @@ -595,10 +595,6 @@ Executed in process buffer." (when inferior-ess-language-start (ess-eval-linewise inferior-ess-language-start nil nil nil 'wait-prompt)) - ;; FIXME Emacs 25.1: Use `when-let' - (let ((pkg-path (cdr (ess-r-package-get-info)))) - (when pkg-path - (ess-set-working-directory pkg-path))) (with-ess-process-buffer nil (add-hook 'ess-presend-filter-functions 'ess-R-scan-for-library-call nil 'local) (run-mode-hooks 'ess-r-post-run-hook))) From b736d63a98423be7277c4161dfcce1483bde8e69 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 12:21:52 +0200 Subject: [PATCH 16/24] Use ess-r-package-project() to get project info --- lisp/ess-r-mode.el | 2 +- lisp/ess-r-package.el | 18 +++++++++++------- lisp/ess-tracebug.el | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lisp/ess-r-mode.el b/lisp/ess-r-mode.el index 6b116bd2f..0877f0222 100644 --- a/lisp/ess-r-mode.el +++ b/lisp/ess-r-mode.el @@ -1164,7 +1164,7 @@ attached packages." '(:eval (let ((env (ess-r-get-evaluation-env))) (if env (format " %s" - (propertize (if (equal env (car (ess-r-package-get-info))) + (propertize (if (equal env (car (ess-r-package-project))) "pkg" env) 'face 'mode-line-emphasis)) diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index c189ceaa8..e657977f9 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -103,7 +103,8 @@ whether the current file is part of a package, or the value of Return nil if not in a package. Search sub-directories listed in `ess-r-package-source-roots' are searched recursively and return all physically present directories." - (let ((pkg-root (cdr (ess-r-package-get-info)))) + ;; FIXME Emacs 25.1: Use `when-let' + (let ((pkg-root (cdr (ess-r-package-project)))) (when pkg-root (let ((files (directory-files-and-attributes pkg-root t "^[^.]"))) (cl-loop for f in files @@ -116,7 +117,7 @@ return all physically present directories." (defun ess-r-package-use-dir () "Set process directory to current package directory." (interactive) - (let ((dir (cdr (ess-r-package-get-info)))) + (let ((dir (cdr (ess-r-package-project)))) (ess-use-dir dir))) (defun ess-r-package-set-package () @@ -141,7 +142,7 @@ return all physically present directories." (let ((pkgs (ess-get-words-from-vector (format "print(.packages(%s), max = 1e6)\n" (if ess-r-prompt-for-attached-pkgs-only "FALSE" "TRUE")))) - (current-pkg (car (ess-r-package-get-info)))) + (current-pkg (car (ess-r-package-project)))) (let ((env (ess-r-get-evaluation-env))) (when env (setq pkgs (append '("*none*") pkgs)) @@ -151,7 +152,8 @@ return all physically present directories." (defun ess-r-package-set-namespaced-evaluation () (when ess-r-package-auto-set-evaluation-env - (let ((pkg (car (ess-r-package-get-info)))) + ;; FIXME Emacs 25.1: Use `when-let' + (let ((pkg (car (ess-r-package-project)))) (when pkg (ess-r-set-evaluation-env pkg))))) @@ -159,7 +161,7 @@ return all physically present directories." (defun ess-r-package-send-process (command &optional msg alt default-alt) (inferior-ess-r-force) - (let* ((pkg-info (or (ess-r-package-get-info) + (let* ((pkg-info (or (ess-r-package-project) (ess-r-package-set-package))) (name (car pkg-info)) (path (concat "'" (cdr pkg-info) "'")) @@ -383,7 +385,8 @@ When called with prefix, also asks for additional arguments." :type 'hook) (defcustom ess-r-package-mode-line - '(:eval (let* ((pkg-name (car (ess-r-package-get-info)))) + ;; FIXME Emacs 25.1: Use `when-let' + '(:eval (let ((pkg-name (car (ess-r-package-project)))) (when pkg-name (format " [pkg:%s]" pkg-name)))) "Mode line for ESS developer. Set this variable to nil to @@ -420,7 +423,8 @@ disable the mode line entirely." (not (memq major-mode '(minibuffer-inactive-mode fundamental-mode))) (or (buffer-file-name) default-directory)) - (let ((pkg-info (ess-r-package-get-info))) + ;; FIXME Emacs 25.1: Use `when-let' + (let ((pkg-info (car (ess-r-package-project)))) (when (car pkg-info) (ess-r-package-mode 1))))) diff --git a/lisp/ess-tracebug.el b/lisp/ess-tracebug.el index bdb97d271..57e08bce0 100644 --- a/lisp/ess-tracebug.el +++ b/lisp/ess-tracebug.el @@ -2685,7 +2685,7 @@ for signature and trace it with browser tracer." (interactive) (ess-force-buffer-current "Process to use: ") (let* ((tbuffer (get-buffer-create " *ess-command-output*")) ;; output buffer name is hard-coded in ess-inf.el - (pkg (car (ess-r-package-get-info))) + (pkg (car (ess-r-package-project))) (all-functions (ess-get-words-from-vector (if pkg (format ".ess_all_functions(c('%s'))\n" pkg) From 00a490ac3c023ed1b19fe2ea4cf46ab04b1b2cb7 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 12:22:53 +0200 Subject: [PATCH 17/24] Rename `ess-r-package-info` to `ess-r-package--project-cache` --- lisp/ess-r-package.el | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index e657977f9..690e3ef15 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -38,7 +38,7 @@ See also `ess-r-set-evaluation-env' and `ess-r-evaluation-env'." :group 'ess-r-package :type 'boolean) -(defvar-local ess-r-package-info nil +(defvar-local ess-r-package--project-cache nil "Current package info cache. Cons cell of two strings. CAR is the package name active in the @@ -79,13 +79,13 @@ all source dirs recursively within the current package.") "Get current package info. Return a cons cell of two strings whose CAR is a package name and CDR is a package directory. The package is determined by (in this -order) the buffer-local value of `ess-r-package-info', +order) the buffer-local value of `ess-r-package--project-cache', whether the current file is part of a package, or the value of -`ess-r-package-info' in the attached process buffer." - (or ess-r-package-info +`ess-r-package--project-cache' in the attached process buffer." + (or ess-r-package--project-cache (ess-r-package--local-package-info) (with-ess-process-buffer t - ess-r-package-info))) + ess-r-package--project-cache))) (defun ess-r-package-project (dir) (let ((info (ess-r-package--package-dir-info dir))) @@ -134,8 +134,8 @@ return all physically present directories." (error "Not a valid package. No '%s' found in `%s'." ess-r-package-root-file pkg-path)) (message (format "%s selected and added to file-local variables" pkg-name)) (save-excursion - (add-file-local-variable 'ess-r-package-info pkg-info)) - (setq ess-r-package-info pkg-info))) + (add-file-local-variable 'ess-r-package--project-cache pkg-info)) + (setq ess-r-package--project-cache pkg-info))) (defun ess-r--select-package-name () (inferior-ess-r-force) @@ -168,7 +168,7 @@ return all physically present directories." (args (ess-r-command--process-alt-args alt default-alt))) (message msg name) (with-ess-process-buffer nil - (setq ess-r-package-info pkg-info)) + (setq ess-r-package--project-cache pkg-info)) (ess-eval-linewise (format command (concat path args))))) (defun ess-r-command--process-alt-args (alt &optional default-alt) @@ -188,7 +188,7 @@ return all physically present directories." defaults to the value returned by `ess-r-package--find-package-path'." ;; Cache info for better performance on remotes - (setq ess-r-package-info (ess-r-package--package-dir-info))) + (setq ess-r-package--project-cache (ess-r-package--package-dir-info))) (defun ess-r-package--package-dir-info (&optional dir) (let ((pkg-path (ess-r-package--find-package-path dir))) From fa595224177ef8a8267924f6928736b92de2dd4d Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 12:29:15 +0200 Subject: [PATCH 18/24] Simplify package finding functions --- lisp/ess-r-package.el | 51 +++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index 690e3ef15..55d8b8cb8 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -75,22 +75,29 @@ all source dirs recursively within the current package.") ;;;*;;; Package UI +(defun ess-r-package-project (&optional dir) + "Return the current package as an Emacs project instance. +A project instance is a cons cell of the project name as symbol +and the project path as string. If DIR is provided, the package +is searched from that directory instead of `default-directory'." + (if (car ess-r-package--project-cache) + ess-r-package--project-cache + (let* ((pkg-path (ess-r-package--find-package-path (or dir default-directory))) + (project (when pkg-path + (cons (ess-r-package--find-package-name pkg-path) pkg-path)))) + ;; Cache info for better performance on remotes + (setq-local ess-r-package--project-cache (or project (list nil))) + (when (car project) + project)))) + (defun ess-r-package-get-info () - "Get current package info. -Return a cons cell of two strings whose CAR is a package name and -CDR is a package directory. The package is determined by (in this -order) the buffer-local value of `ess-r-package--project-cache', -whether the current file is part of a package, or the value of -`ess-r-package--project-cache' in the attached process buffer." - (or ess-r-package--project-cache - (ess-r-package--local-package-info) - (with-ess-process-buffer t - ess-r-package--project-cache))) - -(defun ess-r-package-project (dir) - (let ((info (ess-r-package--package-dir-info dir))) - (when (car info) - info))) + "Deprecated function to get package info. +Please use `ess-r-package-project' instead." + (let ((project (ess-r-package-project))) + (if project + (cons (symbol-name (car project)) (cdr project)) + (list nil)))) +(make-obsolete 'ess-r-package-get-info 'ess-r-package-project "17.11") (defun ess-r-package--all-source-dirs (dir) (when (file-exists-p dir) @@ -183,20 +190,6 @@ return all physically present directories." ;;;*;;; Package Detection -(defun ess-r-package--local-package-info () - "Parses DESCRIPTION file in PATH (R specific so far). PATH -defaults to the value returned by -`ess-r-package--find-package-path'." - ;; Cache info for better performance on remotes - (setq ess-r-package--project-cache (ess-r-package--package-dir-info))) - -(defun ess-r-package--package-dir-info (&optional dir) - (let ((pkg-path (ess-r-package--find-package-path dir))) - (if pkg-path - (cons (ess-r-package--find-package-name pkg-path) pkg-path) - ;; Ensures that non-package files are cached as well - '(nil)))) - (defun ess-r-package--find-package-path (&optional dir) "Get the root of R package that contains current directory. Root is determined by locating `ess-r-package-root-file'." From 924ddaa6f2db7abdffae9fdd7ce934905a5a08a8 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 13:08:23 +0200 Subject: [PATCH 19/24] Add ess-r-package-name() --- lisp/ess-r-mode.el | 2 +- lisp/ess-r-package.el | 21 ++++++++++++++------- lisp/ess-tracebug.el | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lisp/ess-r-mode.el b/lisp/ess-r-mode.el index 0877f0222..b9a56babd 100644 --- a/lisp/ess-r-mode.el +++ b/lisp/ess-r-mode.el @@ -1164,7 +1164,7 @@ attached packages." '(:eval (let ((env (ess-r-get-evaluation-env))) (if env (format " %s" - (propertize (if (equal env (car (ess-r-package-project))) + (propertize (if (equal env (ess-r-package-name)) "pkg" env) 'face 'mode-line-emphasis)) diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index 55d8b8cb8..9cf3e3794 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -90,6 +90,13 @@ is searched from that directory instead of `default-directory'." (when (car project) project)))) +(defun ess-r-package-name (&optional dir) + "Return the name of the current package as a string." + ;; FIXME Emacs 25.1: Use `when-let' + (let ((project (ess-r-package-project dir))) + (when project + (symbol-name (car project))))) + (defun ess-r-package-get-info () "Deprecated function to get package info. Please use `ess-r-package-project' instead." @@ -149,7 +156,7 @@ return all physically present directories." (let ((pkgs (ess-get-words-from-vector (format "print(.packages(%s), max = 1e6)\n" (if ess-r-prompt-for-attached-pkgs-only "FALSE" "TRUE")))) - (current-pkg (car (ess-r-package-project)))) + (current-pkg (ess-r-package-name))) (let ((env (ess-r-get-evaluation-env))) (when env (setq pkgs (append '("*none*") pkgs)) @@ -160,7 +167,7 @@ return all physically present directories." (defun ess-r-package-set-namespaced-evaluation () (when ess-r-package-auto-set-evaluation-env ;; FIXME Emacs 25.1: Use `when-let' - (let ((pkg (car (ess-r-package-project)))) + (let ((pkg (ess-r-package-name))) (when pkg (ess-r-set-evaluation-env pkg))))) @@ -170,7 +177,7 @@ return all physically present directories." (inferior-ess-r-force) (let* ((pkg-info (or (ess-r-package-project) (ess-r-package-set-package))) - (name (car pkg-info)) + (name (symbol-name (car pkg-info))) (path (concat "'" (cdr pkg-info) "'")) (args (ess-r-command--process-alt-args alt default-alt))) (message msg name) @@ -227,7 +234,7 @@ Root is determined by locating `ess-r-package-root-file'." (insert-file-contents file) (goto-char (point-min)) (when (re-search-forward "package: \\(.*\\)" nil t) - (match-string 1)))))) + (intern (match-string 1))))))) ;;;*;;; Devtools Integration @@ -379,7 +386,7 @@ When called with prefix, also asks for additional arguments." (defcustom ess-r-package-mode-line ;; FIXME Emacs 25.1: Use `when-let' - '(:eval (let ((pkg-name (car (ess-r-package-project)))) + '(:eval (let ((pkg-name (ess-r-package-name))) (when pkg-name (format " [pkg:%s]" pkg-name)))) "Mode line for ESS developer. Set this variable to nil to @@ -417,8 +424,8 @@ disable the mode line entirely." (or (buffer-file-name) default-directory)) ;; FIXME Emacs 25.1: Use `when-let' - (let ((pkg-info (car (ess-r-package-project)))) - (when (car pkg-info) + (let ((pkg-info (ess-r-package-project))) + (when pkg-info (ess-r-package-mode 1))))) diff --git a/lisp/ess-tracebug.el b/lisp/ess-tracebug.el index 57e08bce0..c79e7a2b2 100644 --- a/lisp/ess-tracebug.el +++ b/lisp/ess-tracebug.el @@ -2685,7 +2685,7 @@ for signature and trace it with browser tracer." (interactive) (ess-force-buffer-current "Process to use: ") (let* ((tbuffer (get-buffer-create " *ess-command-output*")) ;; output buffer name is hard-coded in ess-inf.el - (pkg (car (ess-r-package-project))) + (pkg (ess-r-package-name)) (all-functions (ess-get-words-from-vector (if pkg (format ".ess_all_functions(c('%s'))\n" pkg) From a7277b31be13f3e8ffbda06ca46b3d91eef3bd3b Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 13:15:52 +0200 Subject: [PATCH 20/24] Move news item about source dirs to R features --- doc/newfeat.texi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/newfeat.texi b/doc/newfeat.texi index 496d1bf23..523918005 100644 --- a/doc/newfeat.texi +++ b/doc/newfeat.texi @@ -4,12 +4,6 @@ Changes and New Features in 17.05: @itemize @bullet -@item Lookup for references in inferior buffers has been improved. -New variable @code{ess-r-package-source-roots} contains package -sub-directories which are searched recursively during the file lookup -point. Directories in @code{ess-tracebug-search-path} are now also -searched recursively. - @item The ESS initialisation process has been streamlined. You can now load the R and Stata modes independently from the rest of ESS. Just put @code{(require 'ess-r-mode)} or @code{(require 'ess-stata-mode)} in your @@ -33,6 +27,12 @@ the working directory to the package path. You can now launch R from files within @code{R/} or @code{src/} without worrying about the wd. @end itemize +@item Lookup for references in inferior buffers has been improved. +New variable @code{ess-r-package-source-roots} contains package +sub-directories which are searched recursively during the file lookup +point. Directories in @code{ess-tracebug-search-path} are now also +searched recursively. + Changes and New Features in 16.10: @itemize @bullet From 63d07c20e8f5f17cc38677ac312b888b0871a201 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 13:24:52 +0200 Subject: [PATCH 21/24] Document new project features in news file --- doc/newfeat.texi | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/doc/newfeat.texi b/doc/newfeat.texi index 523918005..505b0282d 100644 --- a/doc/newfeat.texi +++ b/doc/newfeat.texi @@ -22,9 +22,28 @@ from capturing the cursor. @item @ESS{[R]}: New command @code{ess-r-package-use-dir}. It sets the working directory of the current process to the current package directory. -@item @ESS{[R]}: Launching or reloading R from a package file now sets -the working directory to the package path. You can now launch R from -files within @code{R/} or @code{src/} without worrying about the wd. +@item @ESS{[R]}: Launching R from a package file now recognises the package +root as the likely startup directory for R. If +@code{ess-ask-for-ess-directory} is non-nil, ESS prompts with the +package root as default selection. Otherwise the working directory is +automatically set to the package root. + +The mechanism is a bit more general if you are using Emacs 25.1 or +older. On those recent Emacsen R packages are now recognised as Emacs +projects and ESS queries Emacs projects to get the default startup +directory. This means that any git or subversion directory will be +recognised as project root even if it is not an R package. + +In light of these developments, @code{ess-r-package-get-info} is +deprecated in favour of @code{ess-r-package-project}. This function +returns an Emacs project instance, e.g. a cons cell of the project name +as symbol and the package directory as string. In addition +@code{ess-r-package-name} returns the current package name as a string +(rather than a symbol as in the project instance). + +In the future (long term), we will thus deprecate +@code{ess-directory-function} in favour of the Emacs wide hook +@code{project-find-functions}. @end itemize @item Lookup for references in inferior buffers has been improved. From 292476220eee0f5f8b99d8d42fe60374c9d1a42f Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sat, 21 Oct 2017 19:55:57 +0200 Subject: [PATCH 22/24] Emacs projects' car contains project type not project name --- doc/newfeat.texi | 3 +-- lisp/ess-r-package.el | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/doc/newfeat.texi b/doc/newfeat.texi index 505b0282d..0ca5f8868 100644 --- a/doc/newfeat.texi +++ b/doc/newfeat.texi @@ -38,8 +38,7 @@ In light of these developments, @code{ess-r-package-get-info} is deprecated in favour of @code{ess-r-package-project}. This function returns an Emacs project instance, e.g. a cons cell of the project name as symbol and the package directory as string. In addition -@code{ess-r-package-name} returns the current package name as a string -(rather than a symbol as in the project instance). +@code{ess-r-package-name} returns the current package name as a string. In the future (long term), we will thus deprecate @code{ess-directory-function} in favour of the Emacs wide hook diff --git a/lisp/ess-r-package.el b/lisp/ess-r-package.el index 9cf3e3794..b14e567cd 100644 --- a/lisp/ess-r-package.el +++ b/lisp/ess-r-package.el @@ -88,21 +88,21 @@ is searched from that directory instead of `default-directory'." ;; Cache info for better performance on remotes (setq-local ess-r-package--project-cache (or project (list nil))) (when (car project) - project)))) + (cons 'r-package (cdr project)))))) (defun ess-r-package-name (&optional dir) "Return the name of the current package as a string." ;; FIXME Emacs 25.1: Use `when-let' (let ((project (ess-r-package-project dir))) (when project - (symbol-name (car project))))) + (symbol-name (car ess-r-package--project-cache))))) (defun ess-r-package-get-info () "Deprecated function to get package info. Please use `ess-r-package-project' instead." (let ((project (ess-r-package-project))) (if project - (cons (symbol-name (car project)) (cdr project)) + (cons (ess-r-package-name) (cdr project)) (list nil)))) (make-obsolete 'ess-r-package-get-info 'ess-r-package-project "17.11") @@ -177,12 +177,12 @@ return all physically present directories." (inferior-ess-r-force) (let* ((pkg-info (or (ess-r-package-project) (ess-r-package-set-package))) - (name (symbol-name (car pkg-info))) + (name (ess-r-package-name)) (path (concat "'" (cdr pkg-info) "'")) (args (ess-r-command--process-alt-args alt default-alt))) (message msg name) (with-ess-process-buffer nil - (setq ess-r-package--project-cache pkg-info)) + (setq ess-r-package--project-cache ess-r-package--project-cache)) (ess-eval-linewise (format command (concat path args))))) (defun ess-r-command--process-alt-args (alt &optional default-alt) From 4b2e38e0c1aacc7881f1b935cfe0c151365bb075 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sun, 29 Oct 2017 11:42:48 +0100 Subject: [PATCH 23/24] Remove superfluous items from newfeat --- doc/newfeat.texi | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/doc/newfeat.texi b/doc/newfeat.texi index 0ca5f8868..150ec3228 100644 --- a/doc/newfeat.texi +++ b/doc/newfeat.texi @@ -34,22 +34,13 @@ projects and ESS queries Emacs projects to get the default startup directory. This means that any git or subversion directory will be recognised as project root even if it is not an R package. -In light of these developments, @code{ess-r-package-get-info} is -deprecated in favour of @code{ess-r-package-project}. This function -returns an Emacs project instance, e.g. a cons cell of the project name -as symbol and the package directory as string. In addition -@code{ess-r-package-name} returns the current package name as a string. - -In the future (long term), we will thus deprecate -@code{ess-directory-function} in favour of the Emacs wide hook -@code{project-find-functions}. -@end itemize +@item @ESS{[R]} Lookup for references in inferior buffers has been +improved. New variable @code{ess-r-package-source-roots} contains +package sub-directories which are searched recursively during the file +lookup point. Directories in @code{ess-tracebug-search-path} are now +also searched recursively. -@item Lookup for references in inferior buffers has been improved. -New variable @code{ess-r-package-source-roots} contains package -sub-directories which are searched recursively during the file lookup -point. Directories in @code{ess-tracebug-search-path} are now also -searched recursively. +@end itemize Changes and New Features in 16.10: From 5a7fb1cbf2d13de8f5a4e820c9318891e59970bc Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Sun, 29 Oct 2017 12:12:00 +0100 Subject: [PATCH 24/24] Prefer the `tests` directory over package roots cc @vspinu. This is currently a bit ugly, we'll need to move all the dialect-specific stuff out of `ess-inf.el` at some point. --- doc/newfeat.texi | 16 +++++++++++----- lisp/ess-inf.el | 19 ++++++++++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/doc/newfeat.texi b/doc/newfeat.texi index 150ec3228..04a38e12d 100644 --- a/doc/newfeat.texi +++ b/doc/newfeat.texi @@ -28,11 +28,17 @@ root as the likely startup directory for R. If package root as default selection. Otherwise the working directory is automatically set to the package root. -The mechanism is a bit more general if you are using Emacs 25.1 or -older. On those recent Emacsen R packages are now recognised as Emacs -projects and ESS queries Emacs projects to get the default startup -directory. This means that any git or subversion directory will be -recognised as project root even if it is not an R package. +An exception is made when you are opening a new process from the +@code{tests} folder. Since @code{R CMD check} sets the working directory +to that folder when executing test files, this folder is preferred over +the package root. + +The mechanism for selecting a directory is a bit more general if you are +using Emacs 25.1 or older. On those recent Emacsen R packages are now +recognised as Emacs projects and ESS queries Emacs projects to get the +default startup directory. This means that any git or subversion +directory will be recognised as project root even if it is not an R +package (and in fact regardless of language or dialect). @item @ESS{[R]} Lookup for references in inferior buffers has been improved. New variable @code{ess-r-package-source-roots} contains diff --git a/lisp/ess-inf.el b/lisp/ess-inf.el index 099706e7b..6bf8bbb1b 100644 --- a/lisp/ess-inf.el +++ b/lisp/ess-inf.el @@ -585,8 +585,25 @@ This marks the process with a message, at a particular time point." default-directory))) (directory-file-name dir))) +;; FIXME: Move all that R stuff elsewhere +(defun inferior-ess-r--adjust-startup-directory (dir dialect) + (if (string= dialect "R") + (let* ((project-dir (cdr (ess-r-package-project))) + (tests-dir (expand-file-name (file-name-as-directory "tests") + project-dir))) + ;; Prefer the `tests' directory but only if the package + ;; directory was selected in the first place + (if (and project-dir + (string= project-dir dir) + (string= default-directory tests-dir)) + tests-dir + dir)) + dir)) + (defun inferior-ess--maybe-prompt-startup-directory (procname dialect) - (let ((default-dir (inferior-ess--get-startup-directory))) + (let ((default-dir (inferior-ess-r--adjust-startup-directory + (inferior-ess--get-startup-directory) + dialect))) (if ess-ask-for-ess-directory (let* ((prog (cond ((string= dialect "R") ;; Includes R-X.Y versions