Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Python project root in Emacs?

emacs-for-python (based on python.el) provides nice capability to start Python process and send buffer there right from Emacs (normally you do it with C-c C-c). However, this way new process is created for every buffer, and Python's working directory is set to the directory of corresponding file.

Instead, I'd like to have single Python process with working directory set to the root of the project. Or maybe even several processes, but started at the root directory, not the directory of the module.


Why do I need it? It's all about imports. Imagine following project structure:

myproject
   package1
      __init__.py
      mod1.py
   package2
      __init__.py
      mod2.py

If I start Python process on file mod1.py, Emacs will automatically set working directory to myproject/package1 so that I will be restricted to importing modules from the same package only. No imports from other packages. No absolute imports. Pain.

Currently I use a trick with sys.path, something like:

import sys, os
sys.path.insert(0, os.path.join(os.path.abspath(__file__), '..', '..'))

at the beginning of each module. But this is really, really, really ugly and inconvenient.

So does anybody have any tips or tricks to set up Python's project root for inferior process in Emacs?

like image 378
ffriend Avatar asked Nov 20 '25 03:11

ffriend


2 Answers

OK this should get you started

(defvar my-python-shell-dir-setup-code 
  "import os
home = os.path.expanduser('~')
while os.path.isfile('__init__.py') and (os.getcwd() != home):
    os.chdir('..')
del os")

(defun my-python-shell-dir-setup ()
  (let ((process (get-buffer-process (current-buffer))))
    (python-shell-send-string my-python-shell-dir-setup-code process)
    (message "Setup project path")))

(add-hook 'inferior-python-mode-hook 'my-python-shell-dir-setup)

Here is what we are doing my-python-shell-dir-setup-code is simple python code to find project-dir and set it (it quick and dirty you may want to modify it according to your needs). Then we add a inferior-python-mode-hook (i.e. my-shell-dir-setup) to execute the python code in out inferior shell whenever the shell is created.

I'm not familiar with emacs-for-python, but finding the path to the root of your project is straightforward.

Projectile provides a function projectile-project-root. You could call this in your mod1.py buffer, and it will return "/path/to/myproject". This assumes that projectile can recognise your project root, which will be fine if you've using some sort of VCS.

like image 37
Wilfred Hughes Avatar answered Nov 22 '25 19:11

Wilfred Hughes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!