branch: elpa/opam-switch-mode commit 2961d8669ac68efe89bb3ef348fe6819105a711f Author: Erik Martin-Dorel <erik.martin-do...@irit.fr> Commit: Erik Martin-Dorel <erik.martin-do...@irit.fr>
fix: opam-switch-mode support for local switches - (opam-switch--get-current-switch) returned "_opam" for local switches - (opam-switch--set-env) raised "No opam-root directory in PATH" for local switches Close #12 --- NEWS.md | 2 ++ opam-switch-mode.el | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/NEWS.md b/NEWS.md index ae241b87b0..04976b88a4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - **README.md**: Markdown badges - (opam-switch--reset-env) unexpectedly cleared exec-path, closes [#13](https://github.com/ProofGeneral/opam-switch-mode/issues/13) +- (opam-switch--get-current-switch) returned "_opam" for local switches +- (opam-switch--set-env) raised "No opam-root directory in PATH" for local switches, closes [#12](https://github.com/ProofGeneral/opam-switch-mode/issues/12) ### Changed diff --git a/opam-switch-mode.el b/opam-switch-mode.el index 9ec49d7f94..ba210348c4 100644 --- a/opam-switch-mode.el +++ b/opam-switch-mode.el @@ -208,28 +208,32 @@ The variable `exec-path' is saved in addition to environment variables." (mapcar (lambda (x) (list (car x) (getenv (car x)))) opam-env)) (setq opam-switch--saved-exec-path exec-path)) -(defun opam-switch--set-env (opam-env) +(defun opam-switch--set-env (opam-env previous-prefix) "Set a new opam environment. Environment variables in OPAM-ENV are put into the environment of the current Emacs session. The variable `exec-path' is changed to match the environment PATH. -It is unclear which value in variable `exec-path' corresponds to a -previously set opam switch and also which entry in the PATH +It's not that clear which value in variable `exec-path' corresponds to +a previously set opam switch and also which entry in the PATH environment variable in OPAM-ENV corresponds to the new switch. -Therefore this function uses the following heuristic. First all -entries in variable `exec-path' that match `(opam-switch--root)' are deleted. -Then, the first entry for PATH that maches `(opam-switch--root)' is added at the -front of variable `exec-path'." +Therefore this function uses the following heuristic. +First, all entries in variable `exec-path' that match +PREVIOUS-PREFIX or `(opam-switch--root)' are deleted. +Then, the first entry for PATH that matches the new switch prefix +is added at the front of variable `exec-path'." (let ((new-bin-dir (seq-find - (lambda (dir) (string-prefix-p (opam-switch--root) dir)) + (lambda (dir) (string-prefix-p (opam-switch--get-current-switch-prefix-from opam-env) dir)) (parse-colon-path (cadr (assoc "PATH" opam-env)))))) (unless new-bin-dir - (error "No opam-root directory in PATH")) + (error "No OPAM_SWITCH_PREFIX directory in PATH")) (mapc (lambda (x) (setenv (car x) (cadr x))) opam-env) (setq exec-path - (seq-remove (lambda (dir) (string-prefix-p (opam-switch--root) dir)) exec-path)) + (seq-remove + (lambda (dir) (or (string-prefix-p (opam-switch--root) dir) + (and previous-prefix (string-prefix-p previous-prefix dir)))) + exec-path)) (push new-bin-dir exec-path))) (defun opam-switch--reset-env () @@ -246,11 +250,22 @@ switch overwrote them." (setq opam-switch--saved-env nil) (setq opam-switch--saved-exec-path nil)) +(defun opam-switch--get-current-switch-prefix () + "Return prefix of current switch or nil." + (getenv "OPAM_SWITCH_PREFIX")) + +(defun opam-switch--get-current-switch-prefix-from (opam-env) + "Return prefix of next switch from `opam-env'." + (cadr (assoc "OPAM_SWITCH_PREFIX" opam-env))) + (defun opam-switch--get-current-switch () "Return name of current switch or \"<none>\"." - (let ((current-switch (getenv "OPAM_SWITCH_PREFIX"))) + (let ((current-switch (opam-switch--get-current-switch-prefix))) (if current-switch - (file-name-nondirectory current-switch) + (if (string-prefix-p (opam-switch--root) current-switch) + (file-name-nondirectory current-switch) + ;; else current-switch is local + (directory-file-name (file-name-directory current-switch))) "<none>"))) ;;;###autoload @@ -291,15 +306,16 @@ not any other shells outside Emacs." (if (equal switch-name "") (opam-switch--reset-env) (let ((output-string (opam-switch--command-as-string "env" switch-name t)) + (prefix (opam-switch--get-current-switch-prefix)) opam-env) (unless output-string (error - "Command 'opam env %s' failed - probably because of invalid opam switch \"%s\"" + "Command 'opam env --switch=%s' failed - probably because of invalid opam switch \"%s\"" switch-name switch-name)) (setq opam-env (car (read-from-string output-string))) (unless opam-switch--saved-env (opam-switch--save-current-env opam-env)) - (opam-switch--set-env opam-env))) + (opam-switch--set-env opam-env prefix))) (run-hooks 'opam-switch-change-opam-switch-hook)) (define-obsolete-function-alias 'opam-switch--set-switch