Barebones python project with a virtual environment in Emacs Lisp

March 23, 2024
emacs elisp python programming

A lot of the time I find myself wanting to have a directory with a basic Python virtual environment initialized in it, so I wrote the following Emacs Lisp script to do that, you can use it as an interactive function in emacs or as a script that you call from a shell.

Remember to change the path and the keybinding to your liking

#! emacs --script

;;; Code:
(defun setup-python-project-in-directory (project-name)
  "Setup a Python project at PROJECT-NAME with a virtual environment."
  (interactive (list (read-string "Enter the project name: "
  (let* ((project-dir (concat (expand-file-name "~") "/personal/python-playground/" project-name))
         (venv-cmd (format "python3 -m venv %s/.venv --prompt %s" project-dir project-dir))
         (exists (file-exists-p project-dir)))

    (when exists
      (if (y-or-n-p (format "Directory %s exists.  Delete and recreate? " project-dir))
          (delete-directory project-dir t)
        (user-error "Process cancelled by the user")))

    (unless exists (make-directory project-dir t))
    (message "Setting up virtual environment...")
    (shell-command venv-cmd)
    (message (format "To activate your virtual environment, run: \n\n source %s/.venv/bin/activate" project-dir))))

(when noninteractive
  (let ((project-name (car command-line-args-left)))
    (if (or (null project-name) (string= project-name ""))
        (error "No project name provided. Usage: script %s <project-name>" load-file-name)
      (setup-python-project-in-directory project-name))))

(global-set-key (kbd "C-x p y") 'setup-python-project-in-directory)

(provide 'setup-python-project-in-directory)

I haven’t bothered to make a proper shebang but check this out if you’re interested in doing that.