diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index af2146a..620217d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,7 +12,6 @@ jobs: fail-fast: false matrix: emacs_version: - - '26.3' - '27.1' - '27.2' - '28.1' diff --git a/README.org b/README.org index bd61a4c..6ae447b 100644 --- a/README.org +++ b/README.org @@ -94,6 +94,25 @@ It will run =latexmk -C= in the project. This command replaces enviroment name to NEW-NAME in current position. This edits most-inner environment containing the current position. +** =lsp-latex-cancel-build= +This command cancel build of texlab. + +** =lsp-latex-find-environments= + +*** =lsp-latex-complete-environment= +This function reads environment name from minibuffer and returns =lsp-latex-environment-location= instance. + +It takes three arguments, =BUFFER=, =POINT=, =PROMPT=. +=PROMPT= is used as prompt for =consult--read=, which is wrapper of =completing-read=. +=BUFFER= and =POINT= specify basis to find environments. + +* Commands with =lsp-latex-complete-environment= +** =lsp-latex-goto-environment= +Go to selected environment containing the current point. + +** =lsp-latex-select-and-change-environment= +Change name of selected environment to NEW-NAME. + * Forward/inverse search Forward search and inverse search are available. See also [[https://github.com/latex-lsp/texlab/wiki/Previewing][texlab official wiki]]. diff --git a/lsp-latex.el b/lsp-latex.el index 089d7e1..f6e41d3 100644 --- a/lsp-latex.el +++ b/lsp-latex.el @@ -5,9 +5,9 @@ ;; Author: ROCKTAKEY ;; Keywords: languages, tex -;; Version: 3.5.0 +;; Version: 3.6.0 -;; Package-Requires: ((emacs "26.3") (lsp-mode "6.0")) +;; Package-Requires: ((emacs "27.1") (lsp-mode "6.0") (consult "0.35")) ;; URL: https://github.com/ROCKTAKEY/lsp-latex ;; This program is free software; you can redistribute it and/or modify @@ -40,7 +40,13 @@ ;; .. 1. `lsp-latex-clean-auxiliary' ;; .. 2. `lsp-latex-clean-artifacts' ;; .. 3. `lsp-latex-change-environment' -;; 6. Forward/inverse search +;; .. 4. `lsp-latex-cancel-build' +;; .. 5. `lsp-latex-find-environments' +;; ..... 1. `lsp-latex-complete-environment' +;; 6. Commands with `lsp-latex-complete-environment' +;; .. 1. `lsp-latex-goto-environment' +;; .. 2. `lsp-latex-select-and-change-environment' +;; 7. Forward/inverse search ;; .. 1. Forward search ;; .. 2. Inverse search ;; .. 3. Examples @@ -51,7 +57,7 @@ ;; ..... 5. qpdfview ;; ..... 6. Skim ;; ..... 7. `pdf-tools' integration -;; 7. License +;; 8. License ;; [https://img.shields.io/github/tag/ROCKTAKEY/lsp-latex.svg?style=flat-square] @@ -218,7 +224,43 @@ ;; This edits most-inner environment containing the current position. -;; 6 Forward/inverse search +;; 5.4 `lsp-latex-cancel-build' +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +;; This command cancel build of texlab. + + +;; 5.5 `lsp-latex-find-environments' +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +;; 5.5.1 `lsp-latex-complete-environment' +;; -------------------------------------- + +;; This function reads environment name from minibuffer and returns +;; `lsp-latex-environment-location' instance. + +;; It takes three arguments, `BUFFER', `POINT', `PROMPT'. `PROMPT' is +;; used as prompt for `consult--read', which is wrapper of +;; `completing-read'. `BUFFER' and `POINT' specify basis to find +;; environments. + + +;; 6 Commands with `lsp-latex-complete-environment' +;; ================================================ + +;; 6.1 `lsp-latex-goto-environment' +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +;; Go to selected environment containing the current point. + + +;; 6.2 `lsp-latex-select-and-change-environment' +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +;; Change name of selected environment to NEW-NAME. + + +;; 7 Forward/inverse search ;; ======================== ;; Forward search and inverse search are available. See also [texlab @@ -228,7 +270,7 @@ ;; [texlab official wiki] ;; -;; 6.1 Forward search +;; 7.1 Forward search ;; ~~~~~~~~~~~~~~~~~~ ;; You can move from Emacs to current position on pdf viewer by the @@ -292,7 +334,7 @@ ;; -;; 6.2 Inverse search +;; 7.2 Inverse search ;; ~~~~~~~~~~~~~~~~~~ ;; You can go to the current position on Emacs from pdf viewer. Whatever @@ -324,7 +366,7 @@ ;; -;; 6.3 Examples +;; 7.3 Examples ;; ~~~~~~~~~~~~ ;; These examples are according to [texlab official wiki]. Especially, @@ -335,7 +377,7 @@ ;; [texlab official wiki] ;; -;; 6.3.1 SumatraPDF +;; 7.3.1 SumatraPDF ;; ---------------- ;; We highly recommend SumatraPDF on Windows because Adobe @@ -343,7 +385,7 @@ ;; prevent further builds. -;; * 6.3.1.1 Forward search +;; * 7.3.1.1 Forward search ;; Write to init.el: ;; ,---- @@ -352,7 +394,7 @@ ;; `---- -;; * 6.3.1.2 Inverse Search +;; * 7.3.1.2 Inverse Search ;; Add the following line to your [SumatraPDF] settings file ;; (Menu -> Settings -> Advanced Options): @@ -366,7 +408,7 @@ ;; [SumatraPDF] -;; 6.3.2 Evince +;; 7.3.2 Evince ;; ------------ ;; The SyncTeX feature of [Evince] requires communication via @@ -378,7 +420,7 @@ ;; [evince-synctex] -;; * 6.3.2.1 Forward search +;; * 7.3.2.1 Forward search ;; Write to init.el: ;; ,---- @@ -387,17 +429,17 @@ ;; `---- -;; * 6.3.2.2 Inverse search +;; * 7.3.2.2 Inverse search ;; The inverse search feature is already configured if you ;; use `evince-synctex'. You can execute the search by ;; pressing `Ctrl+Click' in the PDF document. -;; 6.3.3 Okular +;; 7.3.3 Okular ;; ------------ -;; * 6.3.3.1 Forward search +;; * 7.3.3.1 Forward search ;; Write to init.el: ;; ,---- @@ -406,7 +448,7 @@ ;; `---- -;; * 6.3.3.2 Inverse search +;; * 7.3.3.2 Inverse search ;; Change the editor of Okular (Settings -> Configure ;; Okular... -> Editor) to "Custom Text Editor" and set the @@ -418,10 +460,10 @@ ;; document. -;; 6.3.4 Zathura +;; 7.3.4 Zathura ;; ------------- -;; * 6.3.4.1 Forward search +;; * 7.3.4.1 Forward search ;; Write to init.el: ;; ,---- @@ -430,7 +472,7 @@ ;; `---- -;; * 6.3.4.2 Inverse search +;; * 7.3.4.2 Inverse search ;; Add the following lines to your ;; `~/.config/zathura/zathurarc' file: @@ -442,10 +484,10 @@ ;; PDF document. -;; 6.3.5 qpdfview +;; 7.3.5 qpdfview ;; -------------- -;; * 6.3.5.1 Forward search +;; * 7.3.5.1 Forward search ;; Write to init.el: ;; ,---- @@ -454,7 +496,7 @@ ;; `---- -;; * 6.3.5.2 Inverse search +;; * 7.3.5.2 Inverse search ;; Change the source editor setting (Edit -> Settings... -> ;; Behavior -> Source editor) to: @@ -467,7 +509,7 @@ ;; pressing Modifier+Click in the PDF document. -;; 6.3.6 Skim +;; 7.3.6 Skim ;; ---------- ;; We recommend [Skim] on macOS since it is the only native @@ -478,7 +520,7 @@ ;; [Skim] -;; * 6.3.6.1 Forward search +;; * 7.3.6.1 Forward search ;; Write to init.el: ;; ,---- @@ -490,14 +532,14 @@ ;; `lsp-latex-forward-search-args'. -;; * 6.3.6.2 Inverse search +;; * 7.3.6.2 Inverse search ;; Select Emacs preset "in the Skim preferences (Skim -> Preferences -> ;; Sync -> PDF-TeX Sync support). You can execute the search by pressing ;; `Shift+⌘+Click' in the PDF document." -;; 6.3.7 `pdf-tools' integration +;; 7.3.7 `pdf-tools' integration ;; ----------------------------- ;; If you want to use forward search with `pdf-tools', follow the @@ -521,7 +563,7 @@ ;; `pdf-sync-backward-search-mouse'. -;; 7 License +;; 8 License ;; ========= ;; This package is licensed by GPLv3. See [LICENSE]. @@ -530,9 +572,11 @@ ;; [LICENSE] ;;; Code: -(require 'lsp-mode) (require 'cl-lib) +(require 'lsp-mode) +(require 'consult) + (defgroup lsp-latex nil "Language Server Protocol client for LaTeX." :group 'lsp-mode) @@ -904,6 +948,14 @@ PARAMS progress report notification data." (lambda () (setq-local lsp-completion-sort-initial-results lsp-latex-completion-sort-in-emacs)))) + + +;;; Interface +(eval-when-compile + (lsp-interface + (texlab:EnvironmentLocation + (:name :fullRange) nil))) + ;;; Build @@ -1031,23 +1083,25 @@ When called interactively, TEXT-DOCUMENT-IDENTIFIER is provided by (lsp-workspace-command-execute "texlab.cleanArtifacts" (vector text-document-identifier))) -(defun lsp-latex-change-environment (text-document-identifier - point - new-name) +(defun lsp-latex-change-environment-most-inner (text-document-identifier + position + new-name) "Change environment name to NEW-NAME in current position. -This will change most-inner environment containing the POINT position +This will change most-inner environment containing the POSITION the file specified by TEXT-DOCUMENT-IDENTIFIER." (interactive (list (lsp-text-document-identifier) - (point) + (lsp-point-to-position (point)) (read-string "New environment name: "))) (lsp-workspace-command-execute "texlab.changeEnvironment" (vector (list :textDocument text-document-identifier - :position (lsp-point-to-position point) + :position position :newName new-name)))) +(defalias 'lsp-latex-change-environment #'lsp-latex-change-environment-most-inner) + (declare-function graphviz-dot-mode "ext:graphviz-dot-mode") (defun lsp-latex-show-dependency-graph () "Show dependency graph written by DOT format. @@ -1065,5 +1119,134 @@ or a graphical image." (read-only-mode +1)) (pop-to-buffer buffer))) +(defun lsp-latex-cancel-build () + "Cancel builds by texlab." + (lsp-workspace-command-execute "texlab.cancelBuild")) + +;;;; Find environments + +(cl-defstruct lsp-latex-environment-location + "Structure for \"EnvironmentLocation\" on texlab. + +NAME is string which is name of environment, like \"equation\" or \"document\". +NAME-REGION and FULL-REGION are cons cells (BEG END). BEG and END are points. +NAME-REGION is region including the environment name. +FULL-REGION is region including the whole environment." + (name nil :type string) + (name-region nil :type cons) + (full-region nil :type cons)) + +(defun lsp-latex--create-enviroment-location (source) + "Create `lsp-latex-environment-location' structure from SOURCE. +SOURCE should be LSP object `texlab:EnvironmentLocation' +defined by `lsp-interface'." + (-let* (((&texlab:EnvironmentLocation + :name + :full-range) + source) + (name-text (lsp-get name :text)) + (name-range (lsp-get name :range)) + (name-region (lsp--range-to-region name-range)) + (full-region (lsp--range-to-region full-range))) + (make-lsp-latex-environment-location + :name name-text + :name-region name-region + :full-region full-region))) + +(defun lsp-latex-find-environments (text-document-identifier position) + "Get name of environment containing the POSITION. +The POINT means point in the file specified by TEXT-DOCUMENT-IDENTIFIER." + (mapcar + #'lsp-latex--create-enviroment-location + (lsp-workspace-command-execute "texlab.findEnvironments" + (vector (lsp--text-document-position-params + text-document-identifier position))))) + + +;;;;; Commands with `lsp-latex-find-environments' + +(defun lsp-latex--consult-mark-with-prompt (prompt markers) + "Jump to a marker in MARKERS. + +Same as `consult-mark' except PROMPT is used as prompt for `consult--read'." + (consult--read + (consult--mark-candidates markers) + :prompt prompt + :annotate (consult--line-prefix) + :category 'consult-location + :sort nil + :require-match t + :lookup #'consult--lookup-location + :history '(:input consult--line-history) + :add-history (thing-at-point 'symbol) + :state (consult--jump-state))) + +(defun lsp-latex--consult-mark-return (prompt markers) + "Get marker in MARKERS. + +Similar to `consult-mark', but there are some differences: +- PROMPT is used as prompt for `consult--read' +- Return a marker instead of jumping to a marker" + (save-current-buffer + (save-excursion + (lsp-latex--consult-mark-with-prompt prompt markers) + (point-marker)))) + +(defun lsp-latex-complete-environment (buffer point prompt) + "Complition environment containing POINT in BUFFER with previewing. + +PROMPT is used as prompt for `consult--read'." + (let* ((text-document-identifier (with-current-buffer buffer + (lsp-text-document-identifier))) + (position (lsp-point-to-position point)) + (environment-location-list + (lsp-latex-find-environments text-document-identifier position)) + (markers + (with-current-buffer buffer + (save-excursion + (mapcar + (lambda (environment-location) + (goto-char (car (lsp-latex-environment-location-name-region environment-location))) + (point-marker)) + environment-location-list)))) + (markers-alist + (cl-mapcar #'cons markers environment-location-list)) + (selected-marker + (lsp-latex--consult-mark-return prompt markers))) + (cdr (assoc selected-marker markers-alist)))) + +(defun lsp-latex-goto-environment (buffer environment-location) + "Jump to environment expressed by ENVIRONMENT-LOCATION in BUFFER. + +In interactive use, jump to selected environment containing current point." + (interactive + (list + (current-buffer) + (let* ((text-document-identifier (lsp-text-document-identifier)) + (position (lsp--point-to-position (point))) + (environment-location + (lsp-latex-complete-environment text-document-identifier position + "Goto environment: "))) + environment-location))) + (switch-to-buffer buffer) + (goto-char (car (lsp-latex-environment-location-full-region environment-location)))) + +(defun lsp-latex-select-and-change-environment (text-document-identifier environment-location new-name) + "Change to NEW-NAME name of environment expressed by ENVIRONMENT-LOCATION. +TEXT-DOCUMENT-IDENTIFIER expresses a buffer containing the environment." + (interactive + (list + (lsp-text-document-identifier) + (lsp-latex-complete-environment + (current-buffer) + (point) + "Change environment: ") + (read-string "New environment name: "))) + (lsp-latex-change-environment-most-inner + text-document-identifier + (lsp-point-to-position + (car (lsp-latex-environment-location-name-region environment-location))) + new-name)) + (provide 'lsp-latex) ;;; lsp-latex.el ends here