10sr 5 лет назад
Родитель
Сommit
67c582141c
Подписано: 10sr Идентификатор GPG ключа: 7BEC428194130EB2
1 измененных файлов: 3 добавлений и 128 удалений
  1. +3
    -128
      emacs.el

+ 3
- 128
emacs.el Просмотреть файл

@@ -963,6 +963,9 @@ found, otherwise returns nil."
)
(set-variable 'flycheck-python-pycompile-executable "python3")
(set-variable 'python-indent-guess-indent-offset nil)
(with-eval-after-load 'blacken
(with-venv-advice-add 'blacken-call-bin))


;; http://fukuyama.co/foreign-regexp
'(and (safe-require-or-eval 'foreign-regexp)
@@ -2012,134 +2015,6 @@ initializing."
(tabulated-list-init-header)
(tabulated-list-print nil nil))


;;;;;;;;;;;;;;;;;;;;;;;
;; with-venv

(defvar-local with-venv-venv-dir
nil
"Venv directory path.

This variable is intended to be explicitly set by user.
When nil, `with-venv' tries to find suitable venv dir.
When this variable is set , use this value without checking if it is a valid
python environment.")

(defmacro with-venv-dir (dir &rest body)
"Set python environment to DIR and execute BODY.

This macro does not check if DIR is a valid python environemnt.
If dir is nil, execute BODY as usual."
`(let ((--with-venv-process-environment-orig (cl-copy-list process-environment))
(--with-venv-exec-path-orig (cl-copy-list exec-path)))
(unwind-protect
(progn
(when ,dir
(let* ((dir (file-name-as-directory ,dir))
(bin (expand-file-name "bin" dir)))
;; Do the same thing that bin/activate does
(setq exec-path
(cons bin
exec-path))
(setenv "VIRTUAL_ENV" dir)
(setenv "PATH" (concat bin ":" (or (getenv "PATH") "")))
(setenv "PYTHONHOME")))
,@body)
(setq process-environment
--with-venv-process-environment-orig)
(setq exec-path
--with-venv-exec-path-orig))))


(defvar-local with-venv-previously-used nil
"Previously used venv dir path.")
(defmacro with-venv (&rest body)
"Execute BODY with venv enabled.

This function tries to find suitable venv dir, or run BODY as usual when no
suitable environment was found."
`(with-venv-dir
;; If set explicitly use it
(or with-venv-venv-dir
;; Check previously used directory
(with-venv-check-exists with-venv-previously-used)
(setq with-venv-previously-used (with-venv-find-venv-dir)))
,@body))

(defun with-venv-find-venv-dir (&optional dir)
"Try to find venv dir for DIR.
If none found return nil."
(with-temp-buffer
(when dir
(cd dir))
(or
;; Check pipenv
(with-venv-check-exists (with-venv--find-venv-dir-pipenv))
;; Check poetry
(with-venv-check-exists (with-venv--find-venv-dir-poetry))
;; Search for .venv dir
(with-venv-check-exists (with-venv--find-venv-dir-by-name)))))

(defun with-venv--find-venv-dir-pipenv ()
"Try to find venv dir via pipenv."
(with-temp-buffer
(let ((status (call-process "pipenv" nil t nil "--venv")))
(when (eq status 0)
(goto-char (point-min))
(buffer-substring-no-properties (point-at-bol)
(point-at-eol))))))

(defun with-venv--find-venv-dir-poetry ()
"Try to find venv dir via poetry."
(with-temp-buffer
;; TODO: Use poetry env info --path
(let ((status (call-process "poetry" nil t nil "debug:info")))
(when (eq status 0)
(goto-char (point-min))
(save-match-data
(when (re-search-forward "^ \\* Path: *\\(.*\\)$")
(match-string 1)))))))

(defun with-venv--find-venv-dir-by-name ()
"Try to find venv dir by its name."
(let ((dir (locate-dominating-file default-directory
".venv")))
(when dir
;; TODO: check with -check-exists
(expand-file-name ".venv"
dir))))

(defun with-venv-check-exists (dir)
"Return DIR as is if \"bin\" directory was found under DIR."
(and dir
(file-directory-p (expand-file-name "bin"
dir))
dir))

(defun with-venv-advice-add (func)
"Setup advice so that FUNC uses `with-env' macro when executing."
(advice-add func
:around
'with-venv--advice-around))

(defun with-venv-advice-remove (func)
"Remove advice added by `with-venv-advice-add'."
(advice-remove func
'with-venv--advice-around))

(defun with-venv--advice-around (orig-func &rest args)
"Function to be used to advice functions with `with-venv-advice-add'.
When a function is adviced with this function, it is wrapped with `with-venv'."
(with-venv
(apply orig-func args)))

(with-eval-after-load 'blacken
(with-venv-advice-add 'blacken-call-bin))


;; (with-venv (:dir default-directory) (message "a"))
;; (with-venv () (message "a"))

;; Local Variables:
;; flycheck-disabled-checkers: (emacs-lisp-checkdoc)
;; flycheck-checker: emacs-lisp


Загрузка…
Отмена
Сохранить