PageRenderTime 45ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/lisp/fringe.el

https://gitlab.com/RobertCochran/emacs
Emacs Lisp | 314 lines | 233 code | 42 blank | 39 comment | 9 complexity | 63bd13886d0ad740da752d25ad00de98 MD5 | raw file
  1. ;;; fringe.el --- fringe setup and control -*- lexical-binding:t -*-
  2. ;; Copyright (C) 2002-2019 Free Software Foundation, Inc.
  3. ;; Author: Simon Josefsson <simon@josefsson.org>
  4. ;; Maintainer: emacs-devel@gnu.org
  5. ;; Keywords: frames
  6. ;; Package: emacs
  7. ;; This file is part of GNU Emacs.
  8. ;; GNU Emacs is free software: you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation, either version 3 of the License, or
  11. ;; (at your option) any later version.
  12. ;; GNU Emacs is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;; GNU General Public License for more details.
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
  18. ;;; Commentary:
  19. ;; This file contains code to initialize the built-in fringe bitmaps
  20. ;; as well as helpful functions for customizing the appearance of the
  21. ;; fringe.
  22. ;; The code is influenced by scroll-bar.el and avoid.el. The author
  23. ;; gratefully acknowledge comments and suggestions made by Miles
  24. ;; Bader, Eli Zaretskii, Richard Stallman, Pavel Janík and others which
  25. ;; improved this package.
  26. ;;; Code:
  27. (defgroup fringe nil
  28. "Window fringes."
  29. :version "22.1"
  30. :group 'frames)
  31. ;; Define the built-in fringe bitmaps and setup default mappings
  32. (when (boundp 'fringe-bitmaps)
  33. (let ((bitmaps '(question-mark exclamation-mark
  34. left-arrow right-arrow up-arrow down-arrow
  35. left-curly-arrow right-curly-arrow
  36. left-triangle right-triangle
  37. top-left-angle top-right-angle
  38. bottom-left-angle bottom-right-angle
  39. left-bracket right-bracket
  40. filled-rectangle hollow-rectangle
  41. filled-square hollow-square
  42. vertical-bar horizontal-bar
  43. empty-line))
  44. (bn 1))
  45. (while bitmaps
  46. (push (car bitmaps) fringe-bitmaps)
  47. (put (car bitmaps) 'fringe bn)
  48. (setq bitmaps (cdr bitmaps)
  49. bn (1+ bn))))
  50. (setq-default fringe-indicator-alist
  51. '((truncation . (left-arrow right-arrow))
  52. (continuation . (left-curly-arrow right-curly-arrow))
  53. (overlay-arrow . right-triangle)
  54. (up . up-arrow)
  55. (down . down-arrow)
  56. (top . (top-left-angle top-right-angle))
  57. (bottom . (bottom-left-angle bottom-right-angle
  58. top-right-angle top-left-angle))
  59. (top-bottom . (left-bracket right-bracket
  60. top-right-angle top-left-angle))
  61. (empty-line . empty-line)
  62. (unknown . question-mark)))
  63. (setq-default fringe-cursor-alist
  64. '((box . filled-rectangle)
  65. (hollow . hollow-rectangle)
  66. (bar . vertical-bar)
  67. (hbar . horizontal-bar)
  68. (hollow-small . hollow-square))))
  69. (defun fringe-bitmap-p (symbol)
  70. "Return non-nil if SYMBOL is a fringe bitmap."
  71. (get symbol 'fringe))
  72. ;; Control presence of fringes
  73. (defvar fringe-mode)
  74. (defvar fringe-mode-explicit nil
  75. "Non-nil means `set-fringe-mode' should really do something.
  76. This is nil while loading `fringe.el', and t afterward.")
  77. (defun set-fringe-mode-1 (_ignore value)
  78. "Call `set-fringe-mode' with VALUE.
  79. See `fringe-mode' for valid values and their effect.
  80. This is usually invoked when setting `fringe-mode' via customize."
  81. (set-fringe-mode value))
  82. (defun set-fringe-mode (value)
  83. "Set `fringe-mode' to VALUE and put the new value into effect.
  84. See `fringe-mode' for possible values and their effect."
  85. (fringe--check-style value)
  86. (setq fringe-mode value)
  87. (when fringe-mode-explicit
  88. (modify-all-frames-parameters
  89. (list (cons 'left-fringe (if (consp fringe-mode)
  90. (car fringe-mode)
  91. fringe-mode))
  92. (cons 'right-fringe (if (consp fringe-mode)
  93. (cdr fringe-mode)
  94. fringe-mode))))))
  95. (defun fringe--check-style (style)
  96. (or (null style)
  97. (integerp style)
  98. (and (consp style)
  99. (or (null (car style)) (integerp (car style)))
  100. (or (null (cdr style)) (integerp (cdr style))))
  101. (error "Invalid fringe style `%s'" style)))
  102. ;; For initialization of fringe-mode, take account of changes
  103. ;; made explicitly to default-frame-alist.
  104. (defun fringe-mode-initialize (symbol value)
  105. (let* ((left-pair (assq 'left-fringe default-frame-alist))
  106. (right-pair (assq 'right-fringe default-frame-alist))
  107. (left (cdr left-pair))
  108. (right (cdr right-pair)))
  109. (if (or left-pair right-pair)
  110. ;; If there's something in default-frame-alist for fringes,
  111. ;; don't change it, but reflect that into the value of fringe-mode.
  112. (progn
  113. (setq fringe-mode (cons left right))
  114. (if (equal fringe-mode '(nil . nil))
  115. (setq fringe-mode nil))
  116. (if (equal fringe-mode '(0 . 0))
  117. (setq fringe-mode 0)))
  118. ;; Otherwise impose the user-specified value of fringe-mode.
  119. (custom-initialize-reset symbol value))))
  120. (defconst fringe-styles
  121. '(("default" . nil)
  122. ("no-fringes" . 0)
  123. ("right-only" . (0 . nil))
  124. ("left-only" . (nil . 0))
  125. ("half-width" . (4 . 4))
  126. ("minimal" . (1 . 1)))
  127. "Alist mapping fringe mode names to fringe widths.
  128. Each list element has the form (NAME . WIDTH), where NAME is a
  129. mnemonic fringe mode name and WIDTH is one of the following:
  130. - nil, which means the default width (8 pixels).
  131. - a cons cell (LEFT . RIGHT), where LEFT and RIGHT are
  132. respectively the left and right fringe widths in pixels, or
  133. nil (meaning the default width).
  134. - a single integer, which specifies the pixel widths of both
  135. fringes.")
  136. (defcustom fringe-mode nil
  137. "Default appearance of fringes on all frames.
  138. The Lisp value should be one of the following:
  139. - nil, which means the default width (8 pixels).
  140. - a cons cell (LEFT . RIGHT), where LEFT and RIGHT are
  141. respectively the left and right fringe widths in pixels, or
  142. nil (meaning the default width).
  143. - a single integer, which specifies the pixel widths of both
  144. fringes.
  145. Note that the actual width may be rounded up to ensure that the
  146. sum of the width of the left and right fringes is a multiple of
  147. the frame's character width. However, a fringe width of 0 is
  148. never rounded.
  149. When setting this variable from Customize, the user can choose
  150. from the mnemonic fringe mode names defined in `fringe-styles'.
  151. When setting this variable in a Lisp program, call
  152. `set-fringe-mode' afterward to make it take real effect.
  153. To modify the appearance of the fringe in a specific frame, use
  154. the interactive function `set-fringe-style'."
  155. :type `(choice
  156. ,@ (mapcar (lambda (style)
  157. (let ((name
  158. (replace-regexp-in-string "-" " " (car style))))
  159. `(const :tag
  160. ,(concat (capitalize (substring name 0 1))
  161. (substring name 1))
  162. ,(cdr style))))
  163. fringe-styles)
  164. (integer :tag "Specific width")
  165. (cons :tag "Different left/right sizes"
  166. (integer :tag "Left width")
  167. (integer :tag "Right width")))
  168. :group 'fringe
  169. :require 'fringe
  170. :initialize 'fringe-mode-initialize
  171. :set 'set-fringe-mode-1)
  172. ;; We just set fringe-mode, but that was the default.
  173. ;; If it is set again, that is for real.
  174. (setq fringe-mode-explicit t)
  175. (defun fringe-query-style (&optional all-frames)
  176. "Query user for fringe style.
  177. Returns values suitable for left-fringe and right-fringe frame parameters.
  178. If ALL-FRAMES, the negation of the fringe values in
  179. `default-frame-alist' is used when user enters the empty string.
  180. Otherwise the negation of the fringe value in the currently selected
  181. frame parameter is used."
  182. (let* ((mode (completing-read
  183. (concat
  184. "Select fringe mode for "
  185. (if all-frames "all frames" "selected frame")
  186. ": ")
  187. fringe-styles nil t))
  188. (style (assoc (downcase mode) fringe-styles)))
  189. (cond
  190. (style
  191. (cdr style))
  192. ((not (eq 0 (cdr (assq 'left-fringe
  193. (if all-frames
  194. default-frame-alist
  195. (frame-parameters))))))
  196. 0))))
  197. (defun fringe-mode (&optional mode)
  198. "Set the default appearance of fringes on all frames.
  199. When called interactively, query the user for MODE; valid values
  200. are `no-fringes', `default', `left-only', `right-only', `minimal'
  201. and `half-width'. See `fringe-styles'.
  202. When used in a Lisp program, MODE should be one of these:
  203. - nil, which means the default width (8 pixels).
  204. - a cons cell (LEFT . RIGHT), where LEFT and RIGHT are
  205. respectively the left and right fringe widths in pixels, or
  206. nil (meaning the default width).
  207. - a single integer, which specifies the pixel widths of both
  208. fringes.
  209. This command may round up the left and right width specifications
  210. to ensure that their sum is a multiple of the character width of
  211. a frame. It never rounds up a fringe width of 0.
  212. Fringe widths set by `set-window-fringes' override the default
  213. fringe widths set by this command. This command applies to all
  214. frames that exist and frames to be created in the future. If you
  215. want to set the default appearance of fringes on the selected
  216. frame only, see the command `set-fringe-style'."
  217. (interactive (list (fringe-query-style 'all-frames)))
  218. (set-fringe-mode mode))
  219. (defun set-fringe-style (&optional mode)
  220. "Set the default appearance of fringes on the selected frame.
  221. When called interactively, query the user for MODE; valid values
  222. are `no-fringes', `default', `left-only', `right-only', `minimal'
  223. and `half-width'. See `fringe-styles'.
  224. When used in a Lisp program, MODE should be one of these:
  225. - nil, which means the default width (8 pixels).
  226. - a cons cell (LEFT . RIGHT), where LEFT and RIGHT are
  227. respectively the left and right fringe widths in pixels, or
  228. nil (meaning the default width).
  229. - a single integer, which specifies the pixel widths of both
  230. fringes.
  231. This command may round up the left and right width specifications
  232. to ensure that their sum is a multiple of the character width of
  233. a frame. It never rounds up a fringe width of 0.
  234. Fringe widths set by `set-window-fringes' override the default
  235. fringe widths set by this command. If you want to set the
  236. default appearance of fringes on all frames, see the command
  237. `fringe-mode'."
  238. (interactive (list (fringe-query-style)))
  239. (fringe--check-style mode)
  240. (modify-frame-parameters
  241. (selected-frame)
  242. (list (cons 'left-fringe (if (consp mode) (car mode) mode))
  243. (cons 'right-fringe (if (consp mode) (cdr mode) mode)))))
  244. (defsubst fringe-columns (side &optional real)
  245. "Return the width, measured in columns, of the fringe area on SIDE.
  246. If optional argument REAL is non-nil, return a real floating point
  247. number instead of a rounded integer value.
  248. SIDE must be the symbol `left' or `right'."
  249. (funcall (if real '/ 'ceiling)
  250. (or (funcall (if (eq side 'left) 'car 'cadr)
  251. (window-fringes))
  252. 0)
  253. (float (frame-char-width))))
  254. ;;;###autoload
  255. (unless (fboundp 'define-fringe-bitmap)
  256. (defun define-fringe-bitmap (_bitmap _bits &optional _height _width _align)
  257. "Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH.
  258. BITMAP is a symbol identifying the new fringe bitmap.
  259. BITS is either a string or a vector of integers.
  260. HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
  261. WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
  262. Optional fifth arg ALIGN may be one of top, center, or bottom,
  263. indicating the positioning of the bitmap relative to the rows where it
  264. is used; the default is to center the bitmap. Fifth arg may also be a
  265. list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap
  266. should be repeated.
  267. If BITMAP already exists, the existing definition is replaced."
  268. ;; This is a fallback for non-GUI builds.
  269. ;; The real implementation is in src/fringe.c.
  270. ))
  271. (provide 'fringe)
  272. ;;; fringe.el ends here