Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Add Asciidoctor integration for previewing and exporting documents, reachable from the new `adoc-asciidoctor-menu` transient on `C-c C-c` (and the AsciiDoc menu). `adoc-preview` renders the current buffer with `asciidoctor` and shows the HTML in a side pane - an xwidget WebKit widget when available, otherwise `eww`, configurable via `adoc-preview-backend` - and `adoc-live-preview-mode` re-renders on every save. The preview feeds the buffer to `asciidoctor` through its standard input, so unsaved edits and relative `include::` / image paths both keep working. Export commands `adoc-export-html`, `adoc-export-docbook`, `adoc-export-pdf`, and `adoc-export-epub` run through `compile`, so Asciidoctor's warnings and errors are navigable.
- Add context-aware completion via `completion-at-point` (kbd:[M-TAB], or any of corfu/company/built-in completion). Inside `<<` or `xref:` it completes cross-reference ids from the explicit anchors defined in the buffer (`[[id]]`, `[#id]`, `[[[biblio]]]`); inside `{` it completes attribute names (the ones defined with `:name:` plus a set of common built-ins); after `include::` it completes file paths; and inside `[source,` it completes source-block language names. It stays out of the way in plain prose.
- Add a Flymake backend (`adoc-flymake`) that runs the buffer through Asciidoctor and reports its parser errors and warnings inline. It's registered automatically, so enabling `flymake-mode` is enough. The check feeds the buffer to Asciidoctor over its standard input, so it works on unsaved edits.
- Make references clickable. Cross-references (`<<id>>`, `xref:id[]`), links and URLs (`link:`, `https:`, `mailto:`, ...), and `include::` macros now highlight on hover and follow with a `mouse-1` (or `mouse-2`) click - the same action as `C-c C-o` / `M-.`. As part of this, `adoc-follow-thing-at-point` now also follows `link:` macros (opening a local target or a URL) and no longer passes the `[label]` along when opening a URL macro.
- Make references clickable. Cross-references (`<<id>>`, `xref:id[]`), links and URLs (`link:`, `https:`, `mailto:`, ...), and `include::` macros now highlight and underline on hover (via the new `adoc-link-mouse-face`) and follow with a `mouse-1` (or `mouse-2`) click - the same action as `C-c C-o` / `M-.`. As part of this, `adoc-follow-thing-at-point` now also follows `link:` macros (opening a local target or a URL) and no longer passes the `[label]` along when opening a URL macro.
- Add an `xref` backend over AsciiDoc anchors. In an `adoc-mode` buffer, `M-?` (`xref-find-references`) lists every cross-reference to the anchor at point, and the standard xref machinery (the marker stack, the completion-read prompt, `consult-xref`, ...) now works for AsciiDoc ids. Definitions are anchors (`[[id]]`, `[#id]`, `[[[biblio]]]`) and references are `<<id>>` / `xref:id[]` usages, resolved within the current buffer. `M-.` keeps following URLs and `include::` too, via `adoc-follow-thing-at-point`.
- Follow Antora cross-file cross-references. In a file inside an Antora component (one with an `antora.yml` above it), following an `xref:` that targets a page - e.g. `xref:basics/install.adoc[]` or `xref:other.adoc#a-section[]`, including a `module:` prefix - now opens the resolved page (under the target module's `pages/` directory) and jumps to the `#fragment` section. Works from `C-c C-o` / `M-.` and a mouse click, and `M-,` (`xref-go-back`) returns. Resolution is limited to the current component.
- Complete Antora `xref:` targets. Inside an `xref:` in an Antora component, completion offers the component's pages as targets (pages in other modules prefixed with `module:`), and after a `#` it offers the target page's section ids and anchors. A same-page `xref:#` completes against the current buffer.
Expand Down
19 changes: 12 additions & 7 deletions adoc-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,11 @@ For example the URL part of `http://example.com[foo]', or a raw
"Face for reference link titles."
:group 'adoc-faces)

(defface adoc-link-mouse-face
'((t (:inherit highlight :underline t)))
"Face used to highlight a link, URL or anchor under the mouse pointer."
:group 'adoc-faces)

(defface adoc-comment-face
'((t (:inherit font-lock-comment-face)))
"Face for HTML comments."
Expand Down Expand Up @@ -2090,7 +2095,7 @@ TEXTPROPS is an additional plist with textproperties."
(let ((cmd-name (regexp-opt '("http" "https" "ftp" "file" "irc" "mailto" "callto" "link"))))
(list
`(lambda (end) (adoc-kwf-std end ,(adoc-re-inline-macro cmd-name) '(0) '(0)))
'(0 '(face nil keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: visit this link")) ; clickable
'(0 '(face nil keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: visit this link")) ; clickable
`(1 '(face adoc-url-face adoc-reserved t adoc-flyspell-ignore t) t) ; cmd-name
`(2 '(face adoc-url-face adoc-reserved t) t) ; :
`(3 '(face adoc-url-face adoc-reserved t adoc-flyspell-ignore t) t) ; target
Expand All @@ -2102,7 +2107,7 @@ TEXTPROPS is an additional plist with textproperties."
(let ((cmd-name (regexp-opt '("http" "https" "ftp" "file" "irc" "mailto" "callto" "link"))))
(list
`(lambda (end) (adoc-kwf-std end ,(adoc-re-inline-macro cmd-name nil nil 'empty) '(0) '(0)))
'(0 '(face nil keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: visit this link")) ; clickable
'(0 '(face nil keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: visit this link")) ; clickable
'(1 '(face adoc-url-face adoc-reserved t adoc-flyspell-ignore t) append) ; cmd-name
'(2 '(face adoc-url-face adoc-reserved t) append) ; :
'(3 '(face adoc-url-face adoc-reserved t adoc-flyspell-ignore t) append) ; target
Expand Down Expand Up @@ -2146,7 +2151,7 @@ TEXTPROPS is an additional plist with textproperties."
(both (concat "\\(?:" url "\\)\\|\\(?:" url<> "\\)\\|\\(?:" email "\\)")))
(list
`(lambda (end) (adoc-kwf-std end ,both '(0) '(0)))
'(0 '(face adoc-url-face adoc-reserved t adoc-flyspell-ignore t keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: visit this URL") append t))))
'(0 '(face adoc-url-face adoc-reserved t adoc-flyspell-ignore t keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: visit this URL") append t))))

;; bug: escapes are not handled yet
;; TODO: give the inserted character a specific face. But I fear that is not
Expand Down Expand Up @@ -2500,7 +2505,7 @@ for multiline constructs to be matched."
'(4 '(face adoc-meta-hide-face adoc-reserved block-del))) ; ]
;; include
(list "^\\(\\(include1?::\\)\\([^ \t\n]*?\\)\\(\\[\\)\\(.*?\\)\\(\\]\\)\\)[ \t]*$"
'(1 '(face nil adoc-reserved block-del keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: open this include")) ; the whole match
'(1 '(face nil adoc-reserved block-del keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: open this include")) ; the whole match
'(2 '(face adoc-preprocessor-face adoc-flyspell-ignore t)) ; macro name
'(3 '(face adoc-meta-face adoc-flyspell-ignore t)) ; file name
'(4 'adoc-meta-hide-face) ; [
Expand Down Expand Up @@ -2790,7 +2795,7 @@ for multiline constructs to be matched."
(adoc-kw-inline-macro "anchor" nil nil nil 'adoc-anchor-face t '("xreflabel"))
(adoc-kw-inline-macro "xref" nil nil nil '(adoc-reference-face adoc-internal-reference-face) t
'(("caption") (("caption" . adoc-reference-face)))
'(keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: jump to this anchor"))
'(keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: jump to this anchor"))
(adoc-kw-inline-macro "footnote" t nil 'adoc-footnote-marker-face nil nil 'adoc-footnote-text-face)
(adoc-kw-inline-macro "footnoteref" t 'single-attribute 'adoc-footnote-marker-face nil nil
'(("id") (("id" . adoc-internal-reference-face))))
Expand Down Expand Up @@ -2835,7 +2840,7 @@ for multiline constructs to be matched."
(list (adoc-re-xref 'inline-special-with-caption t)
;; clickable, but not inside code/literal blocks (those set adoc-reserved)
'(0 (unless (get-text-property (match-beginning 0) 'adoc-reserved)
'(face nil keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: jump to this anchor")))
'(face nil keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: jump to this anchor")))
'(1 'adoc-meta-hide-face) ; <<
'(2 'adoc-meta-face) ; anchor-id
'(3 'adoc-meta-hide-face) ; ,
Expand All @@ -2844,7 +2849,7 @@ for multiline constructs to be matched."
;; reference without caption
(list (adoc-re-xref 'inline-special-no-caption t)
'(0 (unless (get-text-property (match-beginning 0) 'adoc-reserved)
'(face nil keymap adoc-link-keymap mouse-face highlight help-echo "mouse-1: jump to this anchor")))
'(face nil keymap adoc-link-keymap mouse-face adoc-link-mouse-face help-echo "mouse-1: jump to this anchor")))
'(1 'adoc-meta-hide-face) ; <<
'(2 'adoc-reference-face) ; link text = anchor id
'(3 'adoc-meta-hide-face)) ; >>
Expand Down
5 changes: 4 additions & 1 deletion test/adoc-mode-navigation-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,12 @@
"https://example.com[site]" "bare.example.com"
"include::other.adoc[]"))
(expect (adoc-test--prop-at doc needle 'keymap) :to-be 'adoc-link-keymap)
(expect (adoc-test--prop-at doc needle 'mouse-face) :to-be 'highlight)
(expect (adoc-test--prop-at doc needle 'mouse-face) :to-be 'adoc-link-mouse-face)
(expect (adoc-test--prop-at doc needle 'help-echo) :to-be-truthy))))

(it "underlines references under the mouse pointer"
(expect (face-attribute 'adoc-link-mouse-face :underline nil t) :to-be-truthy))

(it "leaves plain prose unclickable"
(expect (adoc-test--prop-at "just some ordinary prose\n" "ordinary" 'keymap)
:to-be nil))
Expand Down