【问题标题】:How can I make emacs-jedi use project-specific virtualenvs如何让 emacs-jedi 使用项目特定的 virtualenvs
【发布时间】:2014-01-20 23:26:05
【问题描述】:

我希望 emacs-jedi 能够检测我何时在不同项目中编辑文件,并使用相应的 virtualenv(如果可用)。按照惯例,我的 virtualenvs 与我的项目具有相同的名称。它们位于$HOME/.virtualenvs/

我找到了kenobi.el,但它假设 virtualenvs 位于项目根目录的 bin 目录中。它还有一些我根本不需要的其他功能。

在 kenobi.el 的启发下,我为绝地编写了以下初始化。它工作得很好,但并不完美。

如果我从我的项目中导入库A,并且A 导入B。我可以跳转到A 定义的定义,但是一旦到了那里,我就无法继续跳转到B 的定义。

我的初始化:

(defun project-directory (buffer-name)
  (let ((git-dir (file-name-directory buffer-name)))
    (while (and (not (file-exists-p (concat git-dir ".git")))
                git-dir)
      (setq git-dir
            (if (equal git-dir "/")
                nil
              (file-name-directory (directory-file-name git-dir)))))
    git-dir))

(defun project-name (buffer-name)
  (let ((git-dir (project-directory buffer-name)))
    (if git-dir
        (file-name-nondirectory
         (directory-file-name git-dir))
      nil)))

(defun virtualenv-directory (buffer-name)
  (let ((venv-dir (expand-file-name
                   (concat "~/.virtualenvs/" (project-name buffer-name)))))
    (if (and venv-dir (file-exists-p venv-dir))
        venv-dir
      nil)))    

(defun jedi-setup-args ()
  (let ((venv-dir (virtualenv-directory buffer-file-name)))
    (when venv-dir
      (set (make-local-variable 'jedi:server-args) (list "--virtual-env" venv-dir)))))

(setq jedi:setup-keys t)
(setq jedi:complete-on-dot t)
(add-hook 'python-mode-hook 'jedi-setup-args)
(add-hook 'python-mode-hook 'jedi:setup)

我初始化绝地的方式有什么问题?

【问题讨论】:

    标签: python emacs virtualenv jedi


    【解决方案1】:

    我现在已经确定了一个解决方案,它使用virtualenvwrapper ELPA 包来激活 virtualenvs,允许 emacs-jedi 从 VIRTUAL_ENV 环境变量中获取 virtualenv 路径。

    这是一个完整的、可工作的 emacs-jedi 初始化:

    (defun project-directory (buffer-name)
      "Return the root directory of the project that contain the
    given BUFFER-NAME. Any directory with a .git or .jedi file/directory
    is considered to be a project root."
      (interactive)
      (let ((root-dir (file-name-directory buffer-name)))
        (while (and root-dir
                    (not (file-exists-p (concat root-dir ".git")))
                    (not (file-exists-p (concat root-dir ".jedi"))))
          (setq root-dir
                (if (equal root-dir "/")
                    nil
                  (file-name-directory (directory-file-name root-dir)))))
        root-dir))
    
    (defun project-name (buffer-name)
      "Return the name of the project that contain the given BUFFER-NAME."
      (let ((root-dir (project-directory buffer-name)))
        (if root-dir
            (file-name-nondirectory
             (directory-file-name root-dir))
          nil)))
    
    (defun jedi-setup-venv ()
      "Activates the virtualenv of the current buffer."
      (let ((project-name (project-name buffer-file-name)))
        (when project-name (venv-workon project-name))))
    
    (setq jedi:setup-keys t)
    (setq jedi:complete-on-dot t)
    (add-hook 'python-mode-hook 'jedi-setup-venv)
    (add-hook 'python-mode-hook 'jedi:setup)
    

    记住你必须先安装 virtualenvwrapper。

    阅读virtualenvwrapper documentation 了解自动激活项目虚拟环境的另一种方法。总之你可以在你的项目根目录下创建一个.dir-locals.el文件,内容如下:

    ((python-mode . ((project-venv-name . "myproject-env"))))
    

    "myproject-env" 更改为您的virtualenv 的名称并使用python-mode 挂钩激活虚拟环境:

    (add-hook 'python-mode-hook (lambda ()
                                  (hack-local-variables)
                                  (venv-workon project-venv-name)))
    (add-hook 'python-mode-hook 'jedi:setup)
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多