-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbanner-comment.el
116 lines (98 loc) · 4.04 KB
/
banner-comment.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
;;; banner-comment.el --- For producing banner comments. -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2018 James Ferguson
;;
;; Author: James Ferguson <[email protected]>
;; URL: https://github.com/WJCFerguson/banner-comment
;; Package-Requires: ((emacs "24.4"))
;; Version: 2.8.1
;; Keywords: convenience
;; This file is not part of GNU Emacs.
;;; License:
;; Licensed under the same terms as Emacs.
;;; Commentary:
;; Quick start:
;;
;; Bind the following commands:
;; banner-comment
;;
;; Code to format a line into a banner comment
;;
;; ;; ================================ like so ================================
;;
;; or in a language with comment-end, like C:
;;
;; /* =============================== like so ============================== */
;;
;;; Code:
(defgroup banner-comment nil
"Turning comments into banners."
:group 'convenience)
(defcustom banner-comment-char ?=
"Character to be used for comment banners."
:type 'character)
(defcustom banner-comment-char-match "[[:space:];#/*~=-]*"
"Regexp to match old comment-banner prefix/suffix text to be destroyed."
:type 'regexp)
(defcustom banner-comment-width nil
"Default final column for banner comment if not specified by prefix arg.
If nil, use (or `comment-fill-column' `fill-column')."
:type '(choice (const :tag "(or comment-fill-column fill-column)" nil)
integer))
(defcustom banner-comment-start nil
"String to override `comment-start' for the banner, if non-nil."
:type '(choice (const :tag "use `comment-start'" nil)
string))
(defcustom banner-comment-end nil
"String to override `comment-end' for the banner, if non-nil."
:type '(choice (const :tag "use `comment-end'" nil)
string))
(require 'subr-x) ;; for string-trim
;;;###autoload
(defun banner-comment (&optional end-column)
"Turn line at point into a banner comment.
Called on an existing banner comment, will reformat it.
Final column will be (or END-COLUMN comment-fill-column fill-column)."
(interactive "P")
(save-excursion
(save-restriction
(beginning-of-line)
(forward-to-indentation 0)
(let ((banner-width (- (or end-column
banner-comment-width
comment-fill-column
fill-column)
(current-column)))
(comment-start (or banner-comment-start comment-start))
(comment-end (or banner-comment-end comment-end)))
;; narrow to btw indentation column and end of line
(narrow-to-region (point) (line-end-position))
;; re search to extract existing text, ignoring existing comments &
;; banners, into subexp 98
(if (re-search-forward
(format
"\\(^\\(%s\\|\\)%s\\)\\(?98:.*?\\)\\(%s\\(%s\\|%s\\|\\)\\)$"
(or comment-start-skip (regexp-quote (string-trim comment-start)))
banner-comment-char-match
banner-comment-char-match
(regexp-quote (string-trim comment-start))
(or comment-end-skip (regexp-quote (string-trim comment-start)))))
(let* ((banner-text (if (string-empty-p (match-string 98))
""
(concat " " (match-string 98) " ")))
(remaining-width (- banner-width
(length comment-start)
(length banner-text)
(length comment-end))))
(if (< remaining-width 0)
(error "Text too wide for banner comment"))
(replace-match ;; replace everything with prefix-text-suffix
(concat
comment-start
(make-string (+ (/ remaining-width 2) (% remaining-width 2))
banner-comment-char)
banner-text
(make-string (/ remaining-width 2) banner-comment-char)
comment-end))))))))
(provide 'banner-comment)
;;; banner-comment.el ends here