summaryrefslogtreecommitdiff
path: root/.config/emacs/site-lisp/surround.el
blob: 8fdf44390f1b2feeadc736b538393dd7a91b0ae9 (plain) (blame)
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
117
118
119
120
121
122
;;; surround.el --- Surround a region with delimeters  -*- lexical-binding: t; -*-

(require 'cl-macs)

(defgroup surround nil
  "Customization group for `surround'."
  :group 'convenience)

(defcustom surround-with-paired-bracket-p t
  "Surround text with paired brackets.
If non-nil surrounding text with a character (assuming that character is
not configured in `surround-pairs-alist') will attempt to surround the
text with the supplied character and its paired bracket.

As an example, if `surround-with-paired-bracket-p' is non-nil and the
user attempts to surround the word “foo” with the character “「” the
result would be “「foo」”.

Whether or not an opening- or closing bracket is provided is not
important; the opening bracket will always be placed at the front of the
region and the closing bracket at the end of the region (assuming
left-to-right writing).

In more technical terms this function surrounds text with both the
provided character and the characters corresponding Bidi_Paired_Bracket
Unicode property."
  :type 'boolean
  :package-version '(surround . "1.0.0")
  :group 'surround)

(defcustom surround-with-mirror-p t
  "Surround text with mirrored characters.
If non-nil surrounding text with a character (assuming that character is
not configured in `surround-pairs-alist') will attempt to surround the
text with the supplied character and its mirror.

As an example, if `surround-with-mirror-p' is non-nil and the user
attempts to surround the word “foo” with the character “«” the result
would be “«foo»”.

Note that unlike `surround-with-paired-bracket-p', because there is no
concept of an “opening” or “closing” bracket — because this option
doesn't work in terms of brackets — ordering matters.  This means that
surrounding “Ελλάδα” with “«” will result in “«Ελλάδα»” while
surrounding “Österreich” with “»” will result in “»Österreich«”.

In more technical terms this function surrounds text with both the
provided character and the characters corresponding Bidi_Mirroring_Glyph
Unicode property."
  :type 'boolean
  :package-version '(surround . "1.0.0")
  :group 'surround)

(defvar surround-pairs-alist '((emacs-lisp-mode
                                . ((?` ("`" . "'")))))
  "TODO")

(defun surround--get-pair-from-alist (char)
  (declare (ftype (function (char) (cons string string)))
           (side-effect-free t))
  (catch 'surround--break
    (let ((char-as-string (char-to-string char)))
      (dolist (pair surround-pairs-alist)
        (let ((mode-or-t (car pair))
              (pairs     (cdr pair)))
          (when (or (derived-mode-p mode-or-t)
                    (eq t mode-or-t))
            (dolist (pair pairs)
              (let ((open-or-trigger (car pair))
                    (closing-or-pair (cdr pair)))
                (if (numberp open-or-trigger) ; Implies trigger
                    (when (= char open-or-trigger)
                      (throw 'surround--break (car closing-or-pair)))
                  (when (string= char-as-string open-or-trigger)
                    (throw 'surround--break pair)))))))))))

(defun surround--get-pair (char)
  (declare (ftype (function (char) (cons string string)))
           (side-effect-free t))
  (or (surround--get-pair-from-alist char)
      (let ((char (char-to-string char))
            (other (char-to-string
                    (or (when surround-with-paired-bracket-p
                          (get-char-code-property char 'paired-bracket))
                        (when surround-with-mirror-p
                          (get-char-code-property char 'mirroring))
                        char)))
            (bracket-type (get-char-code-property char 'bracket-type)))
        (pcase bracket-type
          ((or 'c 'n) (cons other char))
          ('o         (cons char other))))))

(defun suprround--region (pair beginning end)
  (save-excursion
    (goto-char beginning)
    (insert (car pair))
    (goto-char end)
    (insert (cdr pair))))

(defun surround-region (char)
  (interactive
   (list (read-char-from-minibuffer
          (format-prompt "Surround with" nil))))
  (when-let ((pair (surround--get-pair char)))
    (dolist (bounds (cl-loop for (beginning . end) in (region-bounds)
                             collect (cons (set-marker (make-marker) beginning)
                                           (set-marker (make-marker) end))))
      (surround--region pair (car bounds) (cdr bounds)))))

(defun surround-padded-region (char)
  (interactive
   (list (read-char-from-minibuffer
          (format-prompt "Surround with" nil))))
  (when-let ((pair (surround--get-pair char))
             (pair (cons (concat (car pair) " ")
                         (concat " " (cdr pair)))))
    (dolist (bounds (cl-loop for (beginning . end) in (region-bounds)
                             collect (cons (set-marker (make-marker) beginning)
                                           (set-marker (make-marker) end))))
      (surround--region pair (car bounds) (cdr bounds)))))

(provide 'surround)