xwwp-follow-link-ivy.el 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. ;;; xwwp-follow-link-ivy.el --- Link navigation in `xwidget-webkit' sessions using `ivy' -*- lexical-binding: t; -*-
  2. ;; Author: Damien Merenne
  3. ;; URL: https://github.com/canatella/xwwp
  4. ;; Created: 2020-03-11
  5. ;; Keywords: convenience
  6. ;; Version: 0.1
  7. ;; Package-Requires: ((emacs "26.1") (xwwp "0.1"))
  8. ;; Copyright (C) 2020 Damien Merenne <dam@cosinux.org>
  9. ;; This file is NOT part of GNU Emacs.
  10. ;;; License:
  11. ;; This program is free software: you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation, either version 3 of the License, or
  14. ;; (at your option) any later version.
  15. ;; This program is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;; GNU General Public License for more details.
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  21. ;;; Commentary:
  22. ;; Add support for navigating web pages in `xwidget-webkit' sessions using the
  23. ;; `ivy' completion.
  24. ;;; Code:
  25. (require 'xwwp-follow-link)
  26. (require 'ivy)
  27. (defvar xwwp-follow-link-ivy-history
  28. nil
  29. "Stores history for links selected with command `xwwp-follow-link-completion-backend-ivy'.")
  30. (defclass xwwp-follow-link-completion-backend-ivy (xwwp-follow-link-completion-backend) ())
  31. (cl-defmethod xwwp-follow-link-candidates ((_ xwwp-follow-link-completion-backend-ivy))
  32. "Follow a link selected with ivy."
  33. (with-current-buffer (ivy-state-buffer ivy-last)
  34. (let* ((collection (ivy-state-collection ivy-last))
  35. (current (ivy-state-current ivy-last))
  36. (candidates (ivy--filter ivy-text ivy--all-candidates))
  37. (result (cons current candidates)))
  38. (seq-map (lambda (c) (cdr (nth (get-text-property 0 'idx c) collection))) result))))
  39. (cl-defmethod xwwp-follow-link-read ((_ xwwp-follow-link-completion-backend-ivy) prompt collection action update-fn)
  40. "Select a link from COLLECTION a with ivy showing PROMPT using UPDATE-FN to highlight the link in the xwidget session and execute ACTION once a link has been select."
  41. (ivy-read prompt collection
  42. :require-match t
  43. :action (lambda (v) (funcall action (cdr v)))
  44. :update-fn update-fn
  45. :caller 'xwwp-follow-link-read
  46. :history 'xwwp-follow-link-ivy-history))
  47. (defmacro xwwp-follow-link-ivy-ivify-action (v &rest body)
  48. "Wraps BODY as an action for the `xwwp-follow-link-read' `ivy' version.
  49. The text and url of the link is made available through variables `linktext' and
  50. `linkurl' extracted from the selection candidate V. Before the action is
  51. executed, the link highlights are removed from the HTML document shown in
  52. xwidgets."
  53. `(let ((xwidget (xwidget-webkit-current-session))
  54. (linktext (car ,v))
  55. (linkurl (caddr ,v)))
  56. (xwwp-follow-link-cleanup xwidget)
  57. ,body))
  58. (defun xwwp-follow-link-ivy-copy-url-action (v)
  59. "Copy the selected url from candidate V to the `kill-ring'."
  60. (xwwp-follow-link-ivy-ivify-action v
  61. (ignore 'linktext)
  62. (kill-new linkurl)))
  63. (defun xwwp-follow-link-ivy-browse-external-action (v)
  64. "Open the selected url from candidate V in the default browser."
  65. (xwwp-follow-link-ivy-ivify-action v
  66. (ignore 'linktext)
  67. (browse-url linkurl)))
  68. (defun xwwp-follow-link-ivy-get-full-candidate (c)
  69. "Return the full candidate for a text candidate C from xwwp-follow-link-ivy."
  70. (with-current-buffer (ivy-state-buffer ivy-last)
  71. (let* ((collection (ivy-state-collection ivy-last)))
  72. (nth (get-text-property 0 'idx c) collection))))
  73. (defun xwwp-follow-link-ivy-get-candidate-text (v)
  74. "Return the link text for completion candiate V for displaying candidates in `ivy-rich'."
  75. (substring-no-properties (car (xwwp-follow-link-ivy-get-full-candidate v))))
  76. (defun xwwp-follow-link-ivy-get-candidate-url (v)
  77. "Return the url for for a complettion candidate V for displaying candidates in `ivy-rich'."
  78. (caddr (xwwp-follow-link-ivy-get-full-candidate v)))
  79. ;; add ivy actions
  80. (ivy-add-actions
  81. 'xwwp-follow-link-read
  82. '(("w" xwwp-follow-link-ivy-copy-url-action "Copy URL")
  83. ("e" xwwp-follow-link-ivy-browse-external-action "Open in default browser")))
  84. (provide 'xwwp-follow-link-ivy)
  85. ;;; xwwp-follow-link-ivy.el ends here