Switch to using `oglot'

This commit is contained in:
Gerard Vermeulen 2024-02-24 19:57:37 +01:00
parent c81a45820e
commit cb0f863e24
1 changed files with 7 additions and 222 deletions

View File

@ -2986,41 +2986,6 @@ to add =HTML+CSS+JS= for ~mhtml-mode~:
:CUSTOM_ID: sec:buffer-properties
:END:
#+caption[Buffer properties]:
#+caption: Buffer properties.
#+name: lst:buffer-properties-XXX
#+begin_src emacs-lisp -n :results silent :tangle no
(with-eval-after-load 'org
(defconst prop-comments-link-re
"\\( :comments link$\\)\\|\\( *$\\)"
"Regexp to find \"#+property:\" \":comments link\".")
(defconst prop-ha-re-template
(format "\\(?:^[[:blank:]]*#\\+%s:[[:blank:]]+%s:%s\\+*\\)+"
"property" "header-args" "%s")
"Regexp template to find `#+property:' header-args:any-language.")
(defconst prop-emacs-lisp-ha-re
(format prop-ha-re-template "emacs-lisp")
"Regexp to find `#+property:' Emacs Lisp header arguments.")
(defconst prop-python-ha-re
(format prop-ha-re-template "python")
"Regexp to find `#+property:' Python header arguments.")
(defun prop-python-comments-link-toggle ()
(interactive)
(save-excursion
(goto-char (point-min))
(if (re-search-forward prop-python-ha-re nil 'noerror)
(when (re-search-forward prop-comments-link-re nil t)
(if (match-string 1)
(replace-match " ")
(replace-match " :comments link"))
(org-ctrl-c-ctrl-c))
(user-error "Found no python header arguments property")))))
#+end_src
#+caption[Buffer properties]:
#+caption: Buffer properties.
#+name: lst:buffer-properties
@ -4754,14 +4719,8 @@ out of your way. [[info:eglot#Top][Eglot (info)]] is a builtin since Emacs-29.1
listings contribute to a programming language mode independent [[https://github.com/joaotavora/eglot][Eglot]]
configuration:
1. Listing [[lst:minimal-eglot-setup][minimal Eglot setup]] adds key bindings to =eglot-mode-keymap=.
2. Listing [[lst:help-setup-org-src-mode-for-eglot-1]],
[[lst:help-setup-org-src-mode-for-eglot-2]],
[[lst:help-setup-org-src-mode-for-eglot-3]], and
[[lst:setup-python-org-src-mode-for-eglot]] try to prepare any =org-src-mode=
buffers for use with [[https://github.com/joaotavora/eglot][Eglot]]. They are a refactored implementation of the post
[[https://www.reddit.com/r/emacs/comments/w4f4u3/using_rustic_eglot_and_orgbabel_for_literate/][Using rustic, eglot, and org-babel with LSP support in Emacs]] for my use with
Python. Listing [[lst:help-setup-org-src-mode-for-eglot-1]] is bad practice,
because it signals ~user-errors~.
2. Listing [[lst:setup-oglot]] uses [[https://github.com/gav451/oglot#][oglot]] to enable using [[https://github.com/joaotavora/eglot][Eglot]] in =org-src-mode=
Python buffers.
3. 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
file [[info:emacs#Directory Variables][.dir-locals.el]] in the root directory of any project using proper
@ -4779,186 +4738,12 @@ configuration:
(keymap-set eglot-mode-map "C-c r" 'eglot-rename))
#+end_src
#+caption[1st help to setup any =org-src-mode= buffers for =eglot=]:
#+caption: 1st help to setup any =org-src-mode= buffers for =eglot=.
#+caption: Bad practice.
#+name: lst:help-setup-org-src-mode-for-eglot-1
#+begin_src emacs-lisp -n :results silent :tangle no
;;; Begin: Eglot and Org Babel source blocks
;; https://www.reddit.com/r/emacs/comments/w4f4u3
;; /using_rustic_eglot_and_orgbabel_for_literate/
;;
;; One should not signal `user-error's in `org-babel-edit-prep:LANG'
;; functions.
(defun eglot-org-babel-edit-prep-user-error (info)
"Try to setup an `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'."
(unless (bound-and-true-p org-src-mode)
(user-error "Buffer %s is no `org-src-mode' buffer" (buffer-name)))
(let ((point (point))
(body (nth 1 info))
(filename (cdr (assq :tangle (nth 2 info)))))
(when (string= filename "no")
(user-error "Org source block has no tangled file"))
(setq filename (expand-file-name filename))
(unless (file-readable-p filename)
(user-error "Tangled file %s is not readable" 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)
(search-forward body)
;; The next line preserves point in the `org-src-mode' buffer.
(goto-char (+ (match-beginning 0) point -1))
(narrow-to-region (match-beginning 0) (match-end 0))
(eglot-ensure)))
#+end_src
#+caption[2nd help to setup any =org-src-mode= buffers for =eglot=]:
#+caption: 2nd help to setup any =org-src-mode= buffers for =eglot=.
#+caption: Best practice.
#+name: lst:help-setup-org-src-mode-for-eglot-2
#+begin_src emacs-lisp -n :results silent :tangle no
;; https://www.reddit.com/r/emacs/comments/w4f4u3
;; /using_rustic_eglot_and_orgbabel_for_literate/
(defun eglot-org-babel-edit-prep (info)
"Try to setup an `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'."
(when-let ((ok (bound-and-true-p org-src-mode))
(point (point))
(body (nth 1 info))
(filename (cdr (assq :tangle (nth 2 info)))))
(when (string= filename "no")
(setq ok nil)
(message "Org source block has no tangled file"))
(when ok
(setq filename (expand-file-name filename))
(unless (file-readable-p filename)
(setq ok nil)
(message "Tangled file %s is not readable" filename)))
(when ok
(with-temp-buffer
(insert-file-contents filename 'visit nil nil 'replace)
(unless (search-forward body nil 'noerror)
(setq ok nil)
(message "Org source block does not occur in tangled file %s"
filename))
(when (search-forward body nil 'noerror)
(setq ok nil)
(message
"Org source block occurs twice or more in tangled file %s"
filename))))
(when ok
(goto-char (point-min))
(insert-file-contents filename 'visit nil nil 'replace)
(search-forward body)
;; The next line preserves point in the `org-src-mode' buffer.
(goto-char (+ (match-beginning 0) point -1))
(narrow-to-region (match-beginning 0) (match-end 0))
(eglot-ensure))))
#+end_src
#+caption[3rd help to setup any =org-src-mode= buffers for =eglot=]:
#+caption: 3rd help to setup any =org-src-mode= buffers for =eglot=.
#+caption: Good practice.
#+name: lst:help-setup-org-src-mode-for-eglot-3
#+begin_src emacs-lisp -n :results silent :tangle no
;; https://www.reddit.com/r/emacs/comments/w4f4u3
;; /using_rustic_eglot_and_orgbabel_for_literate/
(defun eglot-org-babel-edit-prep-if-let (info)
"Try to setup an `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'."
(if-let ((ok (bound-and-true-p org-src-mode))
(point (point))
(body (nth 1 info))
(filename (cdr (assq :tangle (nth 2 info)))))
(progn
(when (string= filename "no")
(setq ok nil)
(message "Org source block has no tangled file"))
(when ok
(setq filename (expand-file-name filename))
(unless (file-readable-p filename)
(setq ok nil)
(message "Tangled file %s is not readable" filename)))
(when ok
(with-temp-buffer
(insert-file-contents filename 'visit nil nil 'replace)
(unless (search-forward body nil 'noerror)
(setq ok nil)
(message "Org source block does not occur in tangled file %s"
filename))
(when (search-forward body nil 'noerror)
(setq ok nil)
(message
"Org source block occurs twice or more in tangled file %s"
filename))))
(when ok
(goto-char (point-min))
(insert-file-contents filename 'visit nil nil 'replace)
(search-forward body)
;; The next line preserves point in the `org-src-mode' buffer.
(goto-char (+ (match-beginning 0) point -1))
(narrow-to-region (match-beginning 0) (match-end 0))
(eglot-ensure)))
(message "Buffer %s is not `eglot' ready" (buffer-name))))
#+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 -n :results silent :tangle no
;; https://www.reddit.com/r/emacs/comments/w4f4u3
;; /using_rustic_eglot_and_orgbabel_for_literate/
(defun org-babel-edit-prep:python (info)
(eglot-org-babel-edit-prep info))
(defcustom eglot-maybe-ensure-modes '(python-mode)
"Modes where calling `eglot-ensure' may have occurred.
This may be in the case of proper directory local variables or in
the case of proper `org-src-mode' buffers.")
(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 (bound-and-true-p org-src-mode)
(buffer-file-name)
(apply #'derived-mode-p eglot-maybe-ensure-modes))
(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: Eglot and Org Babel source blocks
#+end_src
#+caption: Setup ~oglot~ for ~python-mode~.
#+name: lst:setup-oglot
#+begin_src emacs-lisp -n :results silent
(when (package-installed-p 'oglot)
(require 'oglot))
(when (and (package-installed-p 'oglot)
(require 'oglot nil 'noerror))
(setopt oglot-maybe-ensure-modes '(python-mode)))
#+end_src
#+caption[Start =eglot= in case of a proper =dir-local-variables-alist=]: