From b415dbef07bcdc3af8c6cec82b408bbec6be5778 Mon Sep 17 00:00:00 2001 From: Gerard Vermeulen Date: Tue, 26 Jul 2022 19:56:24 +0200 Subject: [PATCH] Try to make Python org-src-mode buffers working with eglot --- README.org | 89 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 13 deletions(-) diff --git a/README.org b/README.org index dc16d57..9aec935 100644 --- a/README.org +++ b/README.org @@ -2910,11 +2910,17 @@ Listing [[lst:configure-writegood-mode]] configures [[https://github.com/bnbeckw :END: [[https://github.com/joaotavora/eglot#readme][Emacs polyGLOT (eglot)]] is an Emacs language-server-protocol client that stays -out of the way. Listing [[lst:ensure-eglot-installation]] ensures installation of -[[https://github.com/joaotavora/eglot][eglot]] with minimal configuration and listing [[lst:eglot-maybe-ensure]] starts [[https://github.com/joaotavora/eglot][eglot]] -in case of proper programming modes and proper directory local variables -(meaning in presence of a proper [[info:emacs#Directory Variables][.dir-locals.el]] file in the root directory of -any project using proper programming modes). +out of the way. Three listings provide a programming language mode independent +[[https://github.com/joaotavora/eglot][eglot]] configuration: +1. Listing [[lst:ensure-eglot-installation]] ensures installation of [[https://github.com/joaotavora/eglot][eglot]] with + minimal configuration. +2. Listing [[lst:eglot-maybe-ensure]] starts [[https://github.com/joaotavora/eglot][eglot]] in case of proper programming + modes and proper directory local variables (meaning in presence of a proper + [[info:emacs#Directory + Variables][.dir-locals.el]] file in the root directory of any project using proper + programming modes). +3. Listing [[lst:setup-python-org-src-mode-for-eglot]] tries to prepare Python + =org-src-mode= buffers for use with [[https://github.com/joaotavora/eglot][eglot]]. #+caption[Ensure =eglot= installation]: #+caption: Ensure =eglot= installation. @@ -2935,17 +2941,74 @@ any project using proper programming modes). #+name: lst:eglot-maybe-ensure #+begin_src emacs-lisp (when (fboundp 'eglot-ensure) - (defcustom eglot-maybe-derived-modes '(python-mode) - "Modes to call `eglot-ensure' in case of proper directory local variables.") + (defcustom eglot-maybe-ensure-modes '(python-mode) + "Modes where maybe `eglot-ensure' should be or has been called. + This may be in the case of proper directory local variables or in + the case of proper `org-src-mode' buffers.") + + (defun eglot-maybe-ensure () + (when (and (apply #'derived-mode-p eglot-maybe-ensure-modes) + (assoc 'eglot-workspace-configuration dir-local-variables-alist)) + (eglot-ensure))) + ;; The two hooks `after-change-major-mode-hook' and ;; `hack-local-variables-hook' are OK, but language mode hooks like ;; `python-mode-hook' are not. - (add-hook 'after-change-major-mode-hook - (defun eglot-maybe-ensure () - (when (and (apply #'derived-mode-p eglot-maybe-derived-modes) - (assoc 'eglot-workspace-configuration - dir-local-variables-alist)) - (eglot-ensure))))) + (add-hook 'after-change-major-mode-hook #'eglot-maybe-ensure)) +#+end_src + +#+caption[Setup Python =org-src-mode= buffers for =eglot=]: +#+caption: Setup Python =org-src-mode= buffers for =eglot=. +#+name: lst:setup-python-org-src-mode-for-eglot +#+begin_src emacs-lisp + (when (fboundp 'eglot-ensure) + ;; https://www.reddit.com/r/emacs/comments/w4f4u3 + ;; /using_rustic_eglot_and_orgbabel_for_literate/ + (defun org-babel-edit-prep:python (info) + "Try to setup the `org-mode-src' buffer to make `eglot-ensure' succeed. + INFO has a form similar to the return value of + `org-babel-get-src-block-info'. Try to load the tangled file + into the `org-src-mode' buffer as well as to narrow the region to + the Org-mode source block code before calling `eglot-ensure'." + (let ((mark (point)) + (body (nth 1 info)) + (filename (expand-file-name (cdr (assq :tangle (nth 2 info)))))) + (unless (file-readable-p filename) + (user-error "Tangled file %s is not readible" filename)) + (with-temp-buffer + (insert-file-contents filename 'visit nil nil 'replace) + (unless (search-forward body nil 'noerror) + (user-error "Org source block does not occur in tangled file %s" + filename)) + (when (search-forward body nil 'noerror) + (user-error "Org source block occurs twice or more in tangled file %s" + filename))) + (goto-char (point-min)) + (insert-file-contents filename 'visit nil nil 'replace) + (let ((max-point (search-forward body)) + (min-point (search-backward body))) + (narrow-to-region min-point max-point)) + (goto-char mark) + (eglot-ensure))) + + (defun undo-eglot-org-babel-edit-prep() + "Undo the `eglot' setup by deleting the text hidden by narrowing. + This is to advice `org-edit-src-exit' and `org-edit-src-save'." + (when (and (apply #'derived-mode-p eglot-maybe-ensure-modes) + (bound-and-true-p org-src-mode) + (buffer-file-name)) + (save-excursion + (goto-char (point-min)) + (save-restriction + (widen) + (delete-region (point-min) (point))) + (goto-char (point-max)) + (save-restriction + (widen) + (delete-region (point) (point-max)))))) + + (advice-add 'org-edit-src-exit :before #'undo-eglot-org-babel-edit-prep) + (advice-add 'org-edit-src-save :before #'undo-eglot-org-babel-edit-prep)) #+end_src ** [[https://github.com/lassik/emacs-format-all-the-code#readme][Format-all]]