Compare commits

...

19 commits

Author SHA1 Message Date
f0cc31ea2e
Merge pull request #2 from claytharrison/autoactivate
Some checks failed
melpazoid / build (push) Has been cancelled
naive implementation of autoactivate mode from conda.el
2025-07-05 23:25:39 +03:00
claytharrison
9ecd740ec9 Address changes 2025-03-25 21:38:57 +01:00
claytharrison
f7933808a6 Cache micromamba--buffer-env, check file-remote-p 2025-01-06 19:30:18 +01:00
claytharrison
335804a494 Use add-hook/remove-hook instead of setq/delete 2025-01-06 19:28:43 +01:00
claytharrison
10355eec33 Optimize micromamba--get-name-from-env-yml
1. Use setf and alist-get instead of add-to-list
2. Store only env name for buffer in cache
3. Wrap string-match and match-string in save-match-data
4. Pull the string-matching into its own function
2025-01-06 19:26:10 +01:00
claytharrison
0fe1ed0c63 Add caching for yml contents. 2024-12-21 23:00:36 +01:00
claytharrison
497497537f Only activate if same env not active 2024-12-21 22:23:25 +01:00
claytharrison
359eb819c8 Fix deletion frm window-selection-change-functions 2024-12-21 22:22:43 +01:00
claytharrison
9619d1be5b Formatting 2024-12-21 21:55:00 +01:00
claytharrison
ffbe41a3a4 Remove obsolete code 2024-12-21 21:54:29 +01:00
claytharrison
148e36e326 Remove dependency on f.el 2024-12-21 21:54:02 +01:00
claytharrison
452bd0fe1e Use micromamba-activate on inferred env (duh) 2024-12-21 21:30:45 +01:00
claytharrison
12c9bb366e Fix window-selection-change-functions add 2024-12-21 21:29:35 +01:00
claytharrison
9d2e9fce93 Use fallback environment instead of base 2024-12-21 21:28:58 +01:00
claytharrison
4ffe110f79 advice-add -> window-selection-change-functions 2024-12-21 20:11:12 +01:00
claytharrison
4ae2caa892 if w/o alternate -> when 2024-12-21 19:03:32 +01:00
claytharrison
443736121a Replace (if ... nil) with (when ...) 2024-12-21 16:06:57 +01:00
Clay
56897f586e
Merge branch 'SqrtMinusOne:master' into autoactivate 2024-12-20 15:14:41 +01:00
Clay Harrison
39d2763cb1 naive implementation of autoactivate mode from conda.el 2023-09-22 14:28:00 +02:00

View file

@ -54,6 +54,11 @@
:type 'string :type 'string
:group 'micromamba) :group 'micromamba)
(defcustom micromamba-fallback-environment nil
"An environment that micromamba.el activates by default."
:type 'string
:group 'micromamba)
(defcustom micromamba-preactivate-hook nil (defcustom micromamba-preactivate-hook nil
"Hook run before a micromamba environment is activated." "Hook run before a micromamba environment is activated."
:type 'hook :type 'hook
@ -77,6 +82,9 @@
(defvar micromamba-env-current-prefix nil (defvar micromamba-env-current-prefix nil
"Current activated micromamba environment.") "Current activated micromamba environment.")
(defvar micromamba--yml-cache nil
"Stores contents of yaml files.")
(defvar eshell-path-env) (defvar eshell-path-env)
(defun micromamba--call-json (&rest args) (defun micromamba--call-json (&rest args)
@ -158,6 +166,62 @@ Returns an alist with the following keys:
(vars-export . ,vars-export) (vars-export . ,vars-export)
(scripts . ,scripts)))) (scripts . ,scripts))))
(defun micromamba--find-env-yml (dir) ;; adapted from conda.el
"Find an environment.yml or .yaml in DIR or its parent directories."
(let ((containing-path (locate-dominating-file dir
(lambda (parent)
(directory-files parent nil "environment.[yml|yaml]")))))
(when containing-path
(let ((yml-candidate
(concat (file-name-as-directory containing-path) "environment.yml"))
(yaml-candidate
(concat (file-name-as-directory containing-path) "environment.yaml")))
(or (when (file-readable-p yml-candidate) yml-candidate)
(when (file-readable-p yaml-candidate) yaml-candidate))))))
(defun micromamba--read-file-into-string (filename)
"Read the contents of FILENAME into a string."
(with-temp-buffer
(let ((coding-system-for-read 'utf-8))
(insert-file-contents filename)
(buffer-string))))
(defun micromamba--get-name-from-env-yml-contents (env-yml-contents)
"Pull the `name` property out of a stringified YAML file"
(save-match-data
(when (string-match "name:[ ]*\\([A-z0-9-_.]+\\)[ ]*$" env-yml-contents)
(match-string 1 env-yml-contents))))
(defun micromamba--get-name-from-env-yml (filename) ;; adapted from conda.el
"Pull the `name` property out of the YAML file at FILENAME."
(when filename
(let ((filename (file-truename filename)))
(or (unless (file-has-changed-p filename)
(cdr (assoc filename micromamba--yml-cache)))
(setf (alist-get filename micromamba--yml-cache nil nil #'equal)
(micromamba--get-name-from-env-yml-contents
(micromamba--read-file-into-string filename)))))))
(defvar-local micromamba--buffer-env nil
"The environment to autoactivate for the buffer.")
(defun micromamba--infer-env-from-buffer () ;; adapted from conda.el
"Search up the project tree for an `environment.yml` defining a conda env.
Return `micromamba-fallback-environment' if not found."
(if (file-remote-p buffer-file-name)
micromamba-fallback-environment
(or micromamba--buffer-env
(setq micromamba--buffer-env
(let* ((filename (buffer-file-name))
(working-dir (if filename
(file-name-directory filename)
default-directory)))
(when working-dir
(or
(micromamba--get-name-from-env-yml (micromamba--find-env-yml working-dir))
micromamba-fallback-environment)))))))
(defun micromamba--get-activation-parameters (prefix) (defun micromamba--get-activation-parameters (prefix)
"Get activation parameters for the environment PREFIX. "Get activation parameters for the environment PREFIX.
@ -195,6 +259,12 @@ The parameters value is an alist as defined by
(setenv (car var) (cdr var))) (setenv (car var) (cdr var)))
(setq eshell-path-env (getenv "PATH"))) (setq eshell-path-env (getenv "PATH")))
(defun micromamba--env-name-to-prefix (name)
"Get the prefix of an environment with NAME."
(let ((envs (micromamba-envs)))
(alist-get name envs nil nil #'equal)))
;; "public" functions
;;;###autoload ;;;###autoload
(defun micromamba-activate (prefix) (defun micromamba-activate (prefix)
"Switch to environment with PREFIX (path). Prompt if called interactively. "Switch to environment with PREFIX (path). Prompt if called interactively.
@ -209,8 +279,7 @@ full paths."
envs nil nil #'equal)))) envs nil nil #'equal))))
;; To allow calling the function with env name as well ;; To allow calling the function with env name as well
(unless (string-match-p (rx bos "/") prefix) (unless (string-match-p (rx bos "/") prefix)
(let ((envs (micromamba-envs))) (setq prefix (micromamba--env-name-to-prefix prefix))
(setq prefix (alist-get prefix envs nil nil #'equal)))
(unless prefix (unless prefix
(user-error "Environment %s not found" prefix))) (user-error "Environment %s not found" prefix)))
(micromamba-deactivate) (micromamba-deactivate)
@ -236,5 +305,47 @@ full paths."
(setq micromamba-env-current-prefix nil) (setq micromamba-env-current-prefix nil)
(run-hooks 'micromamba-postdeactivate-hook))) (run-hooks 'micromamba-postdeactivate-hook)))
;;;###autoload
(defun micromamba-env-activate-for-buffer ()
"Activate the conda environment implied by the current buffer.
This can be set by a buffer-local or project-local variable (e.g. a
`.dir-locals.el` that defines `conda-project-env-path`), or inferred from an
`environment.yml` or similar at the project level."
(interactive)
(let ((inferred-env (micromamba--infer-env-from-buffer)))
(when (and inferred-env
(not (string= micromamba-env-current-prefix
(micromamba--env-name-to-prefix inferred-env))))
(micromamba-activate inferred-env))))
(defun micromamba--switch-buffer-auto-activate (&rest args)
"Add Conda environment activation if a buffer has a file, handling ARGS."
(let ((filename (buffer-file-name)))
(when filename
(with-demoted-errors "Error: %S"
(micromamba-env-activate-for-buffer)))))
;;;###autoload
(define-minor-mode micromamba-env-autoactivate-mode
"Toggle conda-env-autoactivate mode.
This mode automatically tries to activate a conda environment for the current
buffer."
;; The initial value.
:init-value nil
;; The indicator for the mode line.
:lighter nil
;; The minor mode bindings.
:keymap nil
;; Kwargs
:group 'micromamba
:global t
;; Forms
(if micromamba-env-autoactivate-mode ;; already on, now switching off
(add-hook 'window-selection-change-functions
#'micromamba--switch-buffer-auto-activate)
(remove-hook 'window-selection-change-functions #'micromamba--switch-buffer-auto-activate)))
(provide 'micromamba) (provide 'micromamba)
;;; micromamba.el ends here ;;; micromamba.el ends here