bui-button.el 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. ;;; bui-button.el --- Text buttons and faces -*- lexical-binding: t -*-
  2. ;; Copyright © 2014-2016 Alex Kost <alezost@gmail.com>
  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. ;;
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Commentary:
  16. ;; This file provides general faces and some code to display buttons and
  17. ;; to work with them.
  18. ;;; Code:
  19. (require 'cus-edit) ; for faces
  20. (require 'dash)
  21. (require 'bui-utils)
  22. (defface bui-time
  23. '((t :inherit font-lock-constant-face))
  24. "Face used for timestamps."
  25. :group 'bui-faces)
  26. (defface bui-file-name
  27. '((t :inherit link))
  28. "Face used for file name buttons."
  29. :group 'bui-faces)
  30. (defface bui-url
  31. '((t :inherit link))
  32. "Face used for URL buttons."
  33. :group 'bui-faces)
  34. (defface bui-action-button
  35. '((t :inherit custom-button))
  36. "Face used for action buttons."
  37. :group 'bui-faces)
  38. (defface bui-action-button-mouse
  39. '((t :inherit custom-button-mouse))
  40. "Mouse face used for action buttons."
  41. :group 'bui-faces)
  42. (defvar bui-button-map
  43. (let ((map (make-sparse-keymap)))
  44. (set-keymap-parent map button-map)
  45. (define-key map (kbd "c") 'bui-button-copy-label)
  46. map)
  47. "Keymap for BUI buttons.")
  48. (define-button-type 'bui
  49. 'keymap bui-button-map
  50. 'follow-link t)
  51. (define-button-type 'bui-action
  52. :supertype 'bui
  53. 'face 'bui-action-button
  54. 'mouse-face 'bui-action-button-mouse)
  55. (define-button-type 'bui-file
  56. :supertype 'bui
  57. 'face 'bui-file-name
  58. 'help-echo "Find file"
  59. 'action (lambda (btn)
  60. (bui-find-file (or (button-get btn 'file)
  61. (button-label btn)))))
  62. (define-button-type 'bui-url
  63. :supertype 'bui
  64. 'face 'bui-url
  65. 'help-echo "Browse URL"
  66. 'action (lambda (btn)
  67. (browse-url (or (button-get btn 'url)
  68. (button-label btn)))))
  69. (defun bui-button-copy-label (&optional position)
  70. "Copy a label of the button at POSITION into kill ring.
  71. If POSITION is nil, use the current point position."
  72. (interactive)
  73. (--when-let (button-at (or position (point)))
  74. (bui-copy-as-kill (button-label it))))
  75. (defun bui-button-type? (symbol)
  76. "Return non-nil, if SYMBOL is a button type."
  77. (and symbol
  78. (get symbol 'button-category-symbol)))
  79. (defun bui-insert-button (label &optional type &rest properties)
  80. "Make button of TYPE with LABEL and insert it at point.
  81. See `insert-text-button' for the meaning of PROPERTIES."
  82. (apply #'insert-text-button label
  83. :type (or type 'button)
  84. properties))
  85. (defun bui-insert-action-button (label action &optional message
  86. &rest properties)
  87. "Make action button with LABEL and insert it at point.
  88. ACTION is a function called when the button is pressed. It
  89. should accept button as the argument.
  90. MESSAGE is a button message.
  91. See `insert-text-button' for the meaning of PROPERTIES."
  92. (apply #'bui-insert-button
  93. label 'bui-action
  94. 'action action
  95. 'help-echo message
  96. properties))
  97. (defun bui-buttonize (value button-type separator &rest properties)
  98. "Make BUTTON-TYPE button(s) from VALUE.
  99. Return a string with button(s).
  100. VALUE can be nil, a button name (string or symbol) or a list of
  101. button names. If it is a list, buttons are separated with
  102. SEPARATOR string.
  103. PROPERTIES are passed to `bui-insert-button'."
  104. (bui-get-non-nil value
  105. (with-temp-buffer
  106. (let ((labels (if (listp value) value (list value))))
  107. (bui-mapinsert (lambda (label)
  108. (apply #'bui-insert-button
  109. (if (symbolp label)
  110. (symbol-name label)
  111. label)
  112. button-type properties))
  113. labels
  114. separator))
  115. (buffer-substring (point-min) (point-max)))))
  116. (provide 'bui-button)
  117. ;;; bui-button.el ends here