PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/configs/semacs.d/elisp/vline.el

https://github.com/manniche/dot-files
Emacs Lisp | 389 lines | 246 code | 48 blank | 95 comment | 6 complexity | 1d11404d2271dd807a572601824f181f MD5 | raw file
  1. ;;; vline.el --- show vertical line (column highlighting) mode.
  2. ;; Copyright (C) 2002, 2008-2012 by Taiki SUGAWARA <buzz.taiki@gmail.com>
  3. ;; Author: Taiki SUGAWARA <buzz.taiki@gmail.com>
  4. ;; Maintainer: Taiki SUGAWARA <buzz.taiki@gmail.com>
  5. ;; Keywords: faces, editing, emulating
  6. ;; Version: 1.11
  7. ;; Time-stamp: <2012-01-08 12:40:18 UTC taiki>
  8. ;; URL: http://www.emacswiki.org/cgi-bin/wiki/vline.el
  9. ;; URL: http://bitbucket.org/buzztaiki/elisp/src/tip/vline.el
  10. ;; This file is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation; either version 2, or (at your option)
  13. ;; any later version.
  14. ;; This file is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;; GNU General Public License for more details.
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with GNU Emacs; see the file COPYING. If not, write to
  20. ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. ;; Boston, MA 02110-1301, USA.
  22. ;;; Commentary:
  23. ;; put followings your .emacs
  24. ;; (require 'vline)
  25. ;;
  26. ;; if you display a vertical line, type M-x vline-mode. `vline-mode' doesn't
  27. ;; effect other buffers, because it is a buffer local minor mode. if you hide
  28. ;; a vertical line, type M-x vline-mode again.
  29. ;;
  30. ;; if you display a vertical line in all buffers, type M-x vline-global-mode.
  31. ;;
  32. ;; `vline-style' provides a display style of vertical line. see
  33. ;; `vline-style' docstring.
  34. ;;
  35. ;; if you don't want to visual line highlighting (ex. for performance
  36. ;; issue), please to set `vline-visual' to nil.
  37. ;;
  38. ;; if you don't want to use timer (ex. you want to highlight column
  39. ;; during moving cursors), please to set `vline-use-timer' to nil.
  40. ;;; Change Log:
  41. ;; 2012-01-08 taiki
  42. ;; fix for the Lint warnings.
  43. ;; 2010-02-02 taiki
  44. ;; improve performance.
  45. ;; 2009-08-26 taiki
  46. ;; support org-mode, outline-mode
  47. ;; 2009-08-18 taiki
  48. ;; add autoload cookies.
  49. ;; 2009-08-18 taiki
  50. ;; fix last line highlighting probrem.
  51. ;; 2009-08-18 taiki
  52. ;; support visual line highlighting.
  53. ;; - Added face vline-visual.
  54. ;; - Added defcustom vline-visual-face.
  55. ;; - Added defcustom vline-visual.
  56. ;;
  57. ;; 2009-08-17 taiki
  58. ;; fix continuas line problem.
  59. ;; - Don't display vline when cursor into fringe
  60. ;; - Don't expand eol more than window width.
  61. ;;
  62. ;; 2008-10-22 taiki
  63. ;; fix coding-system problem.
  64. ;; - Added vline-multiwidth-space-list
  65. ;; - Use ucs code-point for japanese fullwidth space.
  66. ;;
  67. ;; 2008-01-22 taiki
  68. ;; applied patch from Lennart Borgman
  69. ;; - Added :group 'vline
  70. ;; - Added defcustom vline-current-window-only
  71. ;; - Added header items to simplify for users
  72. ;;; TODO:
  73. ;; - track window-scroll-functions, window-size-change-functions.
  74. ;; - consider other minor modes (using {after,before}-string overlay).
  75. ;; - don't use {post,after}-command-hook for performance??
  76. ;;; Code:
  77. (defvar vline-overlay-table-size 200)
  78. (defvar vline-overlay-table (make-vector vline-overlay-table-size nil))
  79. (defvar vline-line-char ?|)
  80. (defvar vline-multiwidth-space-list
  81. (list
  82. ?\t
  83. (decode-char 'ucs #x3000) ; japanese fullwidth space
  84. ))
  85. (defvar vline-timer nil)
  86. (defcustom vline-style 'face
  87. "This variable holds vertical line display style.
  88. Available values are followings:
  89. `face' : use face.
  90. `compose' : use composit char.
  91. `mixed' : use face and composit char."
  92. :type '(radio
  93. (const face)
  94. (const compose)
  95. (const mixed))
  96. :group 'vline)
  97. (defface vline
  98. '((t (:background "light steel blue")))
  99. "A default face for vertical line highlighting."
  100. :group 'vline)
  101. (defface vline-visual
  102. '((t (:background "gray90")))
  103. "A default face for vertical line highlighting in visual lines."
  104. :group 'vline)
  105. (defcustom vline-face 'vline
  106. "A face for vertical line highlighting."
  107. :type 'face
  108. :group 'vline)
  109. (defcustom vline-visual-face 'vline-visual
  110. "A face for vertical line highlighting in visual lines."
  111. :type 'face
  112. :group 'vline)
  113. (defcustom vline-current-window-only nil
  114. "If non-nil then highlight column in current window only.
  115. If the buffer is shown in several windows then highlight column only
  116. in the currently selected window."
  117. :type 'boolean
  118. :group 'vline)
  119. (defcustom vline-visual t
  120. "If non-nil then highlight column in visual lines.
  121. If you specified `force' then use force visual line highlighting even
  122. if `truncate-lines' is non-nil."
  123. :type '(radio
  124. (const nil)
  125. (const t)
  126. (const force))
  127. :group 'vline)
  128. (defcustom vline-use-timer t
  129. "If non-nil, use idle timer instead of (post|after)-command-hook."
  130. :type 'boolean
  131. :group 'vline)
  132. (defcustom vline-idle-time 0.02
  133. "Idle time for highlighting column."
  134. :type 'number
  135. :group 'vline)
  136. ;;;###autoload
  137. (define-minor-mode vline-mode
  138. "Display vertical line mode."
  139. :global nil
  140. :lighter " VL"
  141. :group 'vline
  142. (if vline-mode
  143. (progn
  144. (add-hook 'pre-command-hook 'vline-pre-command-hook nil t)
  145. (if vline-use-timer
  146. (vline-set-timer)
  147. (add-hook 'post-command-hook 'vline-post-command-hook nil t)))
  148. (vline-cancel-timer)
  149. (vline-clear)
  150. (remove-hook 'pre-command-hook 'vline-pre-command-hook t)
  151. (remove-hook 'post-command-hook 'vline-post-command-hook t)))
  152. ;;;###autoload
  153. (define-global-minor-mode vline-global-mode
  154. vline-mode
  155. (lambda ()
  156. (unless (minibufferp)
  157. (vline-mode 1)))
  158. :group 'vline)
  159. (defun vline-pre-command-hook ()
  160. (when (and vline-mode (not (minibufferp)))
  161. (vline-clear)))
  162. (defun vline-post-command-hook ()
  163. (when (and vline-mode (not (minibufferp)))
  164. (vline-show)))
  165. (defun vline-set-timer ()
  166. (setq vline-timer
  167. (run-with-idle-timer
  168. vline-idle-time t 'vline-timer-callback)))
  169. (defun vline-cancel-timer ()
  170. (when (timerp vline-timer)
  171. (cancel-timer vline-timer)))
  172. (defun vline-timer-callback ()
  173. (when (and vline-mode (not (minibufferp)))
  174. (vline-show)))
  175. (defun vline-clear ()
  176. (mapcar (lambda (ovr)
  177. (and ovr (delete-overlay ovr)))
  178. vline-overlay-table))
  179. (defsubst vline-into-fringe-p ()
  180. (eq (nth 1 (posn-at-point)) 'right-fringe))
  181. (defsubst vline-visual-p ()
  182. (or (eq vline-visual 'force)
  183. (and (not truncate-lines)
  184. vline-visual)))
  185. (defsubst vline-current-column ()
  186. (if (or (not (vline-visual-p))
  187. ;; margin for full-width char
  188. (< (1+ (current-column)) (window-width)))
  189. (current-column)
  190. ;; hmm.. posn-at-point is not consider tab width.
  191. (- (current-column)
  192. (save-excursion
  193. (vertical-motion 0)
  194. (current-column)))))
  195. (defsubst vline-move-to-column (col &optional bol-p)
  196. (if (or (not (vline-visual-p))
  197. ;; margin for full-width char
  198. (< (1+ (current-column)) (window-width)))
  199. (move-to-column col)
  200. (unless bol-p
  201. (vertical-motion 0))
  202. (let ((bol-col (current-column)))
  203. (- (move-to-column (+ bol-col col))
  204. bol-col))))
  205. (defsubst vline-invisible-p (pos)
  206. (let ((inv (get-char-property pos 'invisible)))
  207. (and inv
  208. (or (eq buffer-invisibility-spec t)
  209. (memq inv buffer-invisibility-spec)
  210. (assq inv buffer-invisibility-spec)))))
  211. (defsubst vline-forward (n)
  212. (unless (memq n '(-1 0 1))
  213. (error "n(%s) must be 0 or 1" n))
  214. (if (not (vline-visual-p))
  215. (progn
  216. (forward-line n)
  217. ;; take care of org-mode, outline-mode
  218. (when (and (not (bobp))
  219. (vline-invisible-p (1- (point))))
  220. (goto-char (1- (point))))
  221. (when (vline-invisible-p (point))
  222. (if (< n 0)
  223. (while (and (not (bobp)) (vline-invisible-p (point)))
  224. (goto-char (previous-char-property-change (point))))
  225. (while (and (not (bobp)) (vline-invisible-p (point)))
  226. (goto-char (next-char-property-change (point))))
  227. (forward-line 1))))
  228. (vertical-motion n)))
  229. (defun vline-face (visual-p)
  230. (if visual-p
  231. vline-visual-face
  232. vline-face))
  233. (defun vline-show (&optional point)
  234. (vline-clear)
  235. (save-window-excursion
  236. (save-excursion
  237. (if point
  238. (goto-char point)
  239. (setq point (point)))
  240. (let* ((column (vline-current-column))
  241. (lcolumn (current-column))
  242. (i 0)
  243. (compose-p (memq vline-style '(compose mixed)))
  244. (face-p (memq vline-style '(face mixed)))
  245. (line-char (if compose-p vline-line-char ? ))
  246. (line-str (make-string 1 line-char))
  247. (visual-line-str line-str)
  248. (in-fringe-p (vline-into-fringe-p)))
  249. (when face-p
  250. (setq line-str (propertize line-str 'face (vline-face nil)))
  251. (setq visual-line-str (propertize visual-line-str 'face (vline-face t))))
  252. (goto-char (window-end nil t))
  253. (vline-forward 0)
  254. (while (and (not in-fringe-p)
  255. (< i (window-height))
  256. (< i (length vline-overlay-table))
  257. (not (bobp)))
  258. (let ((cur-column (vline-move-to-column column t))
  259. (cur-lcolumn (current-column)))
  260. ;; non-cursor line only (workaround of eol probrem.
  261. (unless (= (point) point)
  262. ;; if column over the cursor's column (when tab or wide char is appered.
  263. (when (> cur-column column)
  264. (let ((lcol (current-column)))
  265. (backward-char)
  266. (setq cur-column (- cur-column (- lcol (current-column))))))
  267. (let* ((ovr (aref vline-overlay-table i))
  268. (visual-p (or (< lcolumn (current-column))
  269. (> lcolumn (+ (current-column)
  270. (- column cur-column)))))
  271. ;; consider a newline, tab and wide char.
  272. (str (concat (make-string (- column cur-column) ? )
  273. (if visual-p visual-line-str line-str)))
  274. (char (char-after)))
  275. ;; create overlay if not found.
  276. (unless ovr
  277. (setq ovr (make-overlay 0 0))
  278. (overlay-put ovr 'rear-nonsticky t)
  279. (aset vline-overlay-table i ovr))
  280. ;; initialize overlay.
  281. (overlay-put ovr 'face nil)
  282. (overlay-put ovr 'before-string nil)
  283. (overlay-put ovr 'after-string nil)
  284. (overlay-put ovr 'invisible nil)
  285. (overlay-put ovr 'window
  286. (if vline-current-window-only
  287. (selected-window)
  288. nil))
  289. (cond
  290. ;; multiwidth space
  291. ((memq char vline-multiwidth-space-list)
  292. (setq str
  293. (concat str
  294. (make-string (- (save-excursion (forward-char)
  295. (current-column))
  296. (current-column)
  297. (string-width str))
  298. ? )))
  299. (move-overlay ovr (point) (1+ (point)))
  300. (overlay-put ovr 'invisible t)
  301. (overlay-put ovr 'after-string str))
  302. ;; eol
  303. ((eolp)
  304. (move-overlay ovr (point) (point))
  305. (overlay-put ovr 'after-string str)
  306. ;; don't expand eol more than window width
  307. (when (and (not truncate-lines)
  308. (>= (1+ column) (window-width))
  309. (>= column (vline-current-column))
  310. (not (vline-into-fringe-p)))
  311. (delete-overlay ovr)))
  312. (t
  313. (cond
  314. (compose-p
  315. (let (str)
  316. (when char
  317. (setq str (compose-chars
  318. char
  319. (cond ((= (char-width char) 1)
  320. '(tc . tc))
  321. ((= cur-column column)
  322. '(tc . tr))
  323. (t
  324. '(tc . tl)))
  325. line-char))
  326. (when face-p
  327. (setq str (propertize str 'face (vline-face visual-p))))
  328. (move-overlay ovr (point) (1+ (point)))
  329. (overlay-put ovr 'invisible t)
  330. (overlay-put ovr 'after-string str))))
  331. (face-p
  332. (move-overlay ovr (point) (1+ (point)))
  333. (overlay-put ovr 'face (vline-face visual-p))))))))
  334. (setq i (1+ i))
  335. (vline-forward -1)))))))
  336. (provide 'vline)
  337. ;;; Local Variables:
  338. ;;; time-stamp-format: "%:y-%02m-%02d %02H:%02M:%02S %Z %u"
  339. ;;; time-stamp-line-limit: 16
  340. ;;; End:
  341. ;;; vline.el ends here