mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
Add lang/python module with uv/ruff/pylsp, ANSI colors, and LSP auto-install
- Add lang/python.el: project detection, ruff format-on-save, C-c C-v -> ruff check, optional pylsp with auto-install via uv (asks once per session) - Fix pylsp resolution to check .venv, uv tool path, and PATH - Disable legacy pyls client to avoid spurious warnings - Add ANSI color support in compilation buffers (editor.el) - Remove python-mode/python-ts-mode from global lsp-deferred hooks (lsp.el) - Add ruff, ty, uv packages to desktop group_vars
This commit is contained in:
@@ -6,13 +6,13 @@
|
||||
;; Load modules
|
||||
;;=====================================================================================
|
||||
(fscotto/load-modules
|
||||
;; Core
|
||||
'core/packages
|
||||
'core/ui
|
||||
'core/performance
|
||||
'core/editor
|
||||
'core/keybindings
|
||||
'core/buffer
|
||||
;; Core
|
||||
'core/packages
|
||||
'core/ui
|
||||
'core/performance
|
||||
'core/editor
|
||||
'core/keybindings
|
||||
'core/buffer
|
||||
|
||||
;; Tools
|
||||
'tools/completion
|
||||
@@ -24,28 +24,29 @@
|
||||
'tools/dap
|
||||
'tools/treesitter
|
||||
|
||||
;; Languages
|
||||
'lang/c
|
||||
'lang/docker
|
||||
'lang/golang
|
||||
'lang/json
|
||||
'lang/markdown
|
||||
'lang/org
|
||||
'lang/shell
|
||||
'lang/yaml
|
||||
;; Languages
|
||||
'lang/c
|
||||
'lang/docker
|
||||
'lang/golang
|
||||
'lang/json
|
||||
'lang/markdown
|
||||
'lang/org
|
||||
'lang/python
|
||||
'lang/shell
|
||||
'lang/yaml
|
||||
|
||||
;; Misc
|
||||
'misc/dashboard
|
||||
'misc/custom-functions
|
||||
'misc/doom-modeline
|
||||
'misc/which-key
|
||||
'misc/gptel
|
||||
'misc/email
|
||||
'misc/rss
|
||||
;; Misc
|
||||
'misc/dashboard
|
||||
'misc/custom-functions
|
||||
'misc/doom-modeline
|
||||
'misc/which-key
|
||||
'misc/gptel
|
||||
'misc/email
|
||||
'misc/rss
|
||||
'misc/terminal
|
||||
'misc/vcs
|
||||
'misc/pdf
|
||||
'misc/epub
|
||||
'misc/i3-config)
|
||||
'misc/i3-config)
|
||||
|
||||
(message "...user configuration loaded")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
;;; core-editor
|
||||
|
||||
(require 'ansi-color)
|
||||
|
||||
(setq standard-indent 4)
|
||||
(setq tab-stop-list nil)
|
||||
(setq indent-tabs-mode nil)
|
||||
@@ -9,6 +11,8 @@
|
||||
(prefer-coding-system 'utf-8-unix)
|
||||
(setq custom-file (null-device))
|
||||
|
||||
(add-hook 'compilation-filter-hook #'ansi-color-compilation-filter)
|
||||
|
||||
(provide 'editor)
|
||||
|
||||
;;; editor.el ends here
|
||||
|
||||
135
dotfiles/desktop/.emacs.d/lisp/lang/python.el
Normal file
135
dotfiles/desktop/.emacs.d/lisp/lang/python.el
Normal file
@@ -0,0 +1,135 @@
|
||||
;;; python.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'reformatter)
|
||||
|
||||
(with-eval-after-load 'project
|
||||
(add-to-list 'project-vc-extra-root-markers "pyproject.toml")
|
||||
(add-to-list 'project-vc-extra-root-markers "uv.lock")
|
||||
(add-to-list 'project-vc-extra-root-markers ".venv"))
|
||||
|
||||
(defun fscotto/python-project-root ()
|
||||
"Return project root for Python projects, nil otherwise."
|
||||
(when (and (featurep 'project)
|
||||
(project-current))
|
||||
(let ((root (project-root (project-current))))
|
||||
(when (or (file-exists-p (expand-file-name "pyproject.toml" root))
|
||||
(file-exists-p (expand-file-name "uv.lock" root)))
|
||||
root))))
|
||||
|
||||
(defun fscotto/python-project-has-uv-p ()
|
||||
"Return t if current project uses uv (pyproject.toml or uv.lock)."
|
||||
(when-let ((root (fscotto/python-project-root)))
|
||||
(or (file-exists-p (expand-file-name "uv.lock" root))
|
||||
(file-exists-p (expand-file-name "pyproject.toml" root)))))
|
||||
|
||||
(defun fscotto/python-project-bin (tool)
|
||||
"Return path to TOOL in .venv/bin if it exists, else nil."
|
||||
(when-let ((root (fscotto/python-project-root)))
|
||||
(let ((venv-bin (expand-file-name (concat ".venv/bin/" tool) root)))
|
||||
(when (and (file-exists-p venv-bin)
|
||||
(file-executable-p venv-bin))
|
||||
venv-bin))))
|
||||
|
||||
(defun fscotto/python-activate-project-tools ()
|
||||
"Prefer tools from the project virtualenv when available."
|
||||
(when-let* ((root (fscotto/python-project-root))
|
||||
(venv-bin (expand-file-name ".venv/bin" root))
|
||||
((file-directory-p venv-bin)))
|
||||
(make-local-variable 'exec-path)
|
||||
(add-to-list 'exec-path venv-bin)
|
||||
(setq-local process-environment (copy-sequence process-environment))
|
||||
(setenv "PATH" (concat venv-bin path-separator (getenv "PATH")))))
|
||||
|
||||
(defvar fscotto/python-lsp-install-asked nil
|
||||
"Non-nil if user was already asked about installing pylsp this session.")
|
||||
|
||||
(defun fscotto/resolve-pylsp ()
|
||||
"Return the pylsp binary path if found, else nil.
|
||||
Checks: project .venv, uv tool install path, and PATH."
|
||||
(or (fscotto/python-project-bin "pylsp")
|
||||
(let ((uv-pylsp (expand-file-name "pylsp"
|
||||
(concat (getenv "HOME")
|
||||
"/.local/share/uv/tools/python-lsp-server/bin"))))
|
||||
(when (and (file-exists-p uv-pylsp)
|
||||
(file-executable-p uv-pylsp))
|
||||
uv-pylsp))
|
||||
(executable-find "pylsp")))
|
||||
|
||||
(defun fscotto/python-lsp-server-available-p ()
|
||||
"Return non-nil when a supported Python LSP server is available."
|
||||
(fscotto/resolve-pylsp))
|
||||
|
||||
(defun fscotto/python-ensure-lsp-server ()
|
||||
"Ensure a Python LSP server is installed, prompting the user if needed.
|
||||
If pylsp is already available, start LSP immediately. Otherwise, ask once
|
||||
whether to install it via uv. On confirmation, install python-lsp-server
|
||||
as a uv tool and then start LSP."
|
||||
(unless (fboundp 'lsp-deferred)
|
||||
(message "python: lsp-mode not available")
|
||||
(return-from fscotto/python-ensure-lsp-server))
|
||||
|
||||
(if (fscotto/python-lsp-server-available-p)
|
||||
(progn
|
||||
(setq lsp-pylsp-server-command (fscotto/resolve-pylsp))
|
||||
(lsp-deferred))
|
||||
(when (or fscotto/python-lsp-install-asked
|
||||
(y-or-n-p "python-lsp-server not found. Install it via uv? "))
|
||||
(setq fscotto/python-lsp-install-asked t)
|
||||
(let ((buf (current-buffer)))
|
||||
(message "Installing python-lsp-server via uv in background...")
|
||||
(make-process
|
||||
:name "uv-pylsp-install"
|
||||
:buffer (get-buffer-create " *uv-pylsp-install*")
|
||||
:command '("uv" "tool" "install" "--upgrade" "python-lsp-server")
|
||||
:sentinel
|
||||
(lambda (proc event)
|
||||
(cond
|
||||
((string-match-p "finished" event)
|
||||
(message "python-lsp-server installed.")
|
||||
(setq lsp-pylsp-server-command (fscotto/resolve-pylsp))
|
||||
(with-current-buffer buf
|
||||
(lsp-deferred)))
|
||||
((string-match-p "exited\\|failed" event)
|
||||
(with-current-buffer buf
|
||||
(message "python-lsp-server installation failed. Check *uv-pylsp-install* buffer."))))))))))
|
||||
|
||||
(defun fscotto/python-maybe-start-lsp ()
|
||||
"Start Python LSP, installing pylsp via uv if needed."
|
||||
(fscotto/python-ensure-lsp-server))
|
||||
|
||||
(defun fscotto/python-setup-check-command ()
|
||||
"Use Ruff for the built-in Python check command."
|
||||
(setq-local python-check-command "ruff check"))
|
||||
|
||||
(reformatter-define fscotto/ruff-format
|
||||
:program (or (fscotto/python-project-bin "ruff") (executable-find "ruff"))
|
||||
:args '("format" "-")
|
||||
:lighter " ruff")
|
||||
|
||||
(with-eval-after-load 'python
|
||||
(add-hook 'python-mode-hook #'fscotto/python-activate-project-tools)
|
||||
(add-hook 'python-mode-hook #'fscotto/python-setup-check-command)
|
||||
(add-hook 'python-mode-hook #'fscotto/ruff-format-on-save-mode)
|
||||
(add-hook 'python-mode-hook #'fscotto/python-maybe-start-lsp))
|
||||
|
||||
(with-eval-after-load 'python-ts-mode
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/python-activate-project-tools)
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/python-setup-check-command)
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/ruff-format-on-save-mode)
|
||||
(add-hook 'python-ts-mode-hook #'fscotto/python-maybe-start-lsp))
|
||||
|
||||
(with-eval-after-load 'lsp-mode
|
||||
(add-to-list 'lsp-language-id-configuration '(python-mode . "python"))
|
||||
(add-to-list 'lsp-language-id-configuration '(python-ts-mode . "python"))
|
||||
(setq lsp-pylsp-server-command (fscotto/resolve-pylsp))
|
||||
(setq lsp-pylsp-plugins
|
||||
'((pycodestyle nil)
|
||||
(pyflakes nil)
|
||||
(mccabe nil)
|
||||
(autopep8 nil)
|
||||
(yapf nil)))
|
||||
(add-to-list 'lsp-disabled-clients 'pyls))
|
||||
|
||||
(provide 'lang/python)
|
||||
|
||||
;;; python.el ends here
|
||||
@@ -8,8 +8,6 @@
|
||||
c-ts-mode
|
||||
c++-mode
|
||||
c++-ts-mode
|
||||
python-mode
|
||||
python-ts-mode
|
||||
sh-mode
|
||||
bash-ts-mode) . lsp-deferred)
|
||||
:config
|
||||
|
||||
Reference in New Issue
Block a user