al-w3m.el 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. ;;; al-w3m.el --- Additional functionality for w3m
  2. ;; Copyright © 2013-2016 Alex Kost
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ;;; Code:
  14. (require 'cl-lib)
  15. (require 'w3m)
  16. (require 'wget nil t)
  17. (require 'al-buffer)
  18. ;;;###autoload
  19. (defun al/switch-to-w3m ()
  20. "Switch to the `w3m' buffer."
  21. (interactive)
  22. (al/switch-to-buffer-or-funcall
  23. (lambda ()
  24. (if (fboundp 'w3m-alive-p)
  25. (w3m-alive-p)
  26. (error "w3m is not running")))
  27. #'w3m))
  28. ;;; Go to the next/previous link
  29. (defvar al/w3m-search-link-depth 10
  30. "The number of links to search for the next/previous URL.
  31. See `al/w3m-next-url'/`al/w3m-previous-url' for details.")
  32. (defvar al/w3m-search-re "\\<%s\\>"
  33. "Regexp for searching next/previous URL.
  34. The string should contain \"%s\"-expression substituted by a
  35. searched word. ")
  36. (defun al/w3m-search-url (word point fun)
  37. "Search an URL anchor beginning with WORD.
  38. POINT is the start point for searching.
  39. FUN is a function used for going to an anchor (like
  40. `w3m-next-anchor' or `w3m-previous-anchor'). FUN is called
  41. `al/w3m-search-link-depth' times.
  42. Return URL of the found anchor or nil if the link is not found."
  43. (save-excursion
  44. (goto-char point)
  45. (cl-loop for i from 1 to al/w3m-search-link-depth
  46. do (funcall fun)
  47. if (looking-at (format al/w3m-search-re word))
  48. return (w3m-anchor))))
  49. (defmacro al/w3m-define-goto-url (type)
  50. "Define a function for going to the next/previous page.
  51. TYPE should be a string \"next\" or \"previous\".
  52. Defined function has a name `al/w3m-TYPE-url'."
  53. (let ((name (intern (concat "al/w3m-" type "-url")))
  54. (desc (concat "Go to the " type " page.\n"
  55. "If `w3m-" type "-url' is nil, search in the first and last\n"
  56. "`al/w3m-search-link-depth' links for the " type " page URL."))
  57. (type-url (intern (concat "w3m-" type "-url"))))
  58. `(defun ,name ()
  59. ,desc
  60. (interactive)
  61. (let ((url (or ,type-url
  62. (al/w3m-search-url ,type (point-min) 'w3m-next-anchor)
  63. (al/w3m-search-url ,type (point-max) 'w3m-previous-anchor))))
  64. (if url
  65. (let ((w3m-prefer-cache t))
  66. (w3m-history-store-position)
  67. (w3m-goto-url url))
  68. (message ,(concat "No '" type "' link found.")))))))
  69. (al/w3m-define-goto-url "next")
  70. (al/w3m-define-goto-url "previous")
  71. ;;;###autoload (autoload 'al/w3m-next-url "al/w3m" nil t)
  72. ;;;###autoload (autoload 'al/w3m-previous-url "al/w3m" nil t)
  73. ;;;###autoload
  74. (defun al/w3m-wget ()
  75. "Download anchor, image, or current page.
  76. Same as `w3m-wget' but works."
  77. (interactive)
  78. (let ((url (or (w3m-anchor) (w3m-image)))
  79. (wget-current-title w3m-current-title))
  80. (wget-api url w3m-current-url)))
  81. (defun al/w3m-buffer-number-action (function buffer-number)
  82. "Call FUNCTION on a w3m buffer with BUFFER-NUMBER.
  83. Buffers are enumerated from 1."
  84. (let ((buf (nth (- buffer-number 1) (w3m-list-buffers))))
  85. (and buf (funcall function buf))))
  86. ;;;###autoload
  87. (defun al/w3m-switch-to-buffer (arg)
  88. "Switch to a w3m buffer number ARG.
  89. Buffers are enumerated from 1."
  90. (interactive "NSwitch to w3m buffer number: ")
  91. (al/w3m-buffer-number-action #'switch-to-buffer arg))
  92. ;;;###autoload
  93. (defun al/w3m-kill-buffer (arg)
  94. "Kill a w3m buffer number ARG.
  95. Buffers are enumerated from 1."
  96. (interactive "NKill w3m buffer number: ")
  97. (al/w3m-buffer-number-action #'kill-buffer arg))
  98. (defmacro al/w3m-bind-number-keys (fun &optional kbd-prefix)
  99. "Bind number keys (1-9) to a command that takes a numeric argument.
  100. For example to bind <N> keys for switching to w3m buffers (tabs)
  101. and to bind 'k <N>' keys for killing w3m buffers, use:
  102. (al/w3m-bind-number-keys 'al/w3m-switch-to-buffer)
  103. (al/w3m-bind-number-keys 'al/w3m-kill-buffer \"k\")
  104. To bind the keys, `bind-key' function is used."
  105. (let ((numbers (number-sequence 1 9))
  106. (prefix (and kbd-prefix (concat kbd-prefix " "))))
  107. `(progn
  108. ,@(mapcar (lambda (n)
  109. `(al/bind-key ,(concat prefix (number-to-string n))
  110. (lambda () (interactive)
  111. (funcall ,fun ,n))
  112. w3m-mode-map))
  113. numbers))))
  114. (provide 'al-w3m)
  115. ;;; al-w3m.el ends here