/[slime]/slime/contrib/slime-editing-commands.el
ViewVC logotype

Contents of /slime/contrib/slime-editing-commands.el

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (show annotations)
Wed Mar 9 20:30:37 2011 UTC (3 years, 1 month ago) by heller
Branch: MAIN
CVS Tags: SLIME-2-3, FAIRLY-STABLE, byte-stream, SLIME-2-2, HEAD
Changes since 1.12: +2 -1 lines
* slime-editing-commands.el (slime-beginning-of-defun): Call
beginning-of-defun with call-interactively so that the mark gets
pushed.
1
2 (define-slime-contrib slime-editing-commands
3 "Editing commands without server interaction."
4 (:authors "Thomas F. Burdick <tfb@OCF.Berkeley.EDU>"
5 "Luke Gorrie <luke@synap.se>"
6 "Bill Clementson <billclem@gmail.com>"
7 "Tobias C. Rittweiler <tcr@freebits.de>")
8 (:license "GPL")
9 (:on-load
10 (define-key slime-mode-map "\M-\C-a" 'slime-beginning-of-defun)
11 (define-key slime-mode-map "\M-\C-e" 'slime-end-of-defun)
12 (define-key slime-mode-map "\C-c\M-q" 'slime-reindent-defun)
13 (define-key slime-mode-map "\C-c\C-]" 'slime-close-all-parens-in-sexp)))
14
15 (defun slime-beginning-of-defun ()
16 (interactive)
17 (if (and (boundp 'slime-repl-input-start-mark)
18 slime-repl-input-start-mark)
19 (slime-repl-beginning-of-defun)
20 (let ((this-command 'beginning-of-defun)) ; needed for push-mark
21 (call-interactively 'beginning-of-defun))))
22
23 (defun slime-end-of-defun ()
24 (interactive)
25 (if (eq major-mode 'slime-repl-mode)
26 (slime-repl-end-of-defun)
27 (end-of-defun)))
28
29 (defvar slime-comment-start-regexp
30 "\\(\\(^\\|[^\n\\\\]\\)\\([\\\\][\\\\]\\)*\\);+[ \t]*"
31 "Regexp to match the start of a comment.")
32
33 (defun slime-beginning-of-comment ()
34 "Move point to beginning of comment.
35 If point is inside a comment move to beginning of comment and return point.
36 Otherwise leave point unchanged and return NIL."
37 (let ((boundary (point)))
38 (beginning-of-line)
39 (cond ((re-search-forward slime-comment-start-regexp boundary t)
40 (point))
41 (t (goto-char boundary)
42 nil))))
43
44 (defun slime-close-all-parens-in-sexp (&optional region)
45 "Balance parentheses of open s-expressions at point.
46 Insert enough right parentheses to balance unmatched left parentheses.
47 Delete extra left parentheses. Reformat trailing parentheses
48 Lisp-stylishly.
49
50 If REGION is true, operate on the region. Otherwise operate on
51 the top-level sexp before point."
52 (interactive "P")
53 (let ((sexp-level 0)
54 point)
55 (save-excursion
56 (save-restriction
57 (when region
58 (narrow-to-region (region-beginning) (region-end))
59 (goto-char (point-max)))
60 ;; skip over closing parens, but not into comment
61 (skip-chars-backward ") \t\n")
62 (when (slime-beginning-of-comment)
63 (forward-line)
64 (skip-chars-forward " \t"))
65 (setq point (point))
66 ;; count sexps until either '(' or comment is found at first column
67 (while (and (not (looking-at "^[(;]"))
68 (ignore-errors (backward-up-list 1) t))
69 (incf sexp-level))))
70 (when (> sexp-level 0)
71 ;; insert correct number of right parens
72 (goto-char point)
73 (dotimes (i sexp-level) (insert ")"))
74 ;; delete extra right parens
75 (setq point (point))
76 (skip-chars-forward " \t\n)")
77 (skip-chars-backward " \t\n")
78 (let* ((deleted-region (slime-delete-and-extract-region point (point)))
79 (deleted-text (substring-no-properties deleted-region))
80 (prior-parens-count (count ?\) deleted-text)))
81 ;; Remember: we always insert as many parentheses as necessary
82 ;; and only afterwards delete the superfluously-added parens.
83 (when slime-close-parens-limit
84 (let ((missing-parens (- sexp-level prior-parens-count
85 slime-close-parens-limit)))
86 (dotimes (i (max 0 missing-parens))
87 (delete-char -1))))))))
88
89 (defvar slime-close-parens-limit nil
90 "Maxmimum parens for `slime-close-all-sexp' to insert. NIL
91 means to insert as many parentheses as necessary to correctly
92 close the form.")
93
94 (defun slime-insert-balanced-comments (arg)
95 "Insert a set of balanced comments around the s-expression
96 containing the point. If this command is invoked repeatedly
97 \(without any other command occurring between invocations), the
98 comment progressively moves outward over enclosing expressions.
99 If invoked with a positive prefix argument, the s-expression arg
100 expressions out is enclosed in a set of balanced comments."
101 (interactive "*p")
102 (save-excursion
103 (when (eq last-command this-command)
104 (when (search-backward "#|" nil t)
105 (save-excursion
106 (delete-char 2)
107 (while (and (< (point) (point-max)) (not (looking-at " *|#")))
108 (forward-sexp))
109 (replace-match ""))))
110 (while (> arg 0)
111 (backward-char 1)
112 (cond ((looking-at ")") (incf arg))
113 ((looking-at "(") (decf arg))))
114 (insert "#|")
115 (forward-sexp)
116 (insert "|#")))
117
118 (defun slime-remove-balanced-comments ()
119 "Remove a set of balanced comments enclosing point."
120 (interactive "*")
121 (save-excursion
122 (when (search-backward "#|" nil t)
123 (delete-char 2)
124 (while (and (< (point) (point-max)) (not (looking-at " *|#")))
125 (forward-sexp))
126 (replace-match ""))))
127
128
129 ;; SLIME-CLOSE-PARENS-AT-POINT is obsolete:
130
131 ;; It doesn't work correctly on the REPL, because there
132 ;; BEGINNING-OF-DEFUN-FUNCTION and END-OF-DEFUN-FUNCTION is bound to
133 ;; SLIME-REPL-MODE-BEGINNING-OF-DEFUN (and
134 ;; SLIME-REPL-MODE-END-OF-DEFUN respectively) which compromises the
135 ;; way how they're expect to work (i.e. END-OF-DEFUN does not signal
136 ;; an UNBOUND-PARENTHESES error.)
137
138 ;; Use SLIME-CLOSE-ALL-PARENS-IN-SEXP instead.
139
140 ;; (defun slime-close-parens-at-point ()
141 ;; "Close parenthesis at point to complete the top-level-form. Simply
142 ;; inserts ')' characters at point until `beginning-of-defun' and
143 ;; `end-of-defun' execute without errors, or `slime-close-parens-limit'
144 ;; is exceeded."
145 ;; (interactive)
146 ;; (loop for i from 1 to slime-close-parens-limit
147 ;; until (save-excursion
148 ;; (slime-beginning-of-defun)
149 ;; (ignore-errors (slime-end-of-defun) t))
150 ;; do (insert ")")))
151
152 (defun slime-reindent-defun (&optional force-text-fill)
153 "Reindent the current defun, or refill the current paragraph.
154 If point is inside a comment block, the text around point will be
155 treated as a paragraph and will be filled with `fill-paragraph'.
156 Otherwise, it will be treated as Lisp code, and the current defun
157 will be reindented. If the current defun has unbalanced parens,
158 an attempt will be made to fix it before reindenting.
159
160 When given a prefix argument, the text around point will always
161 be treated as a paragraph. This is useful for filling docstrings."
162 (interactive "P")
163 (save-excursion
164 (if (or force-text-fill (slime-beginning-of-comment))
165 (fill-paragraph nil)
166 (let ((start (progn (unless (or (and (zerop (current-column))
167 (eq ?\( (char-after)))
168 (and slime-repl-input-start-mark
169 (slime-repl-at-prompt-start-p)))
170 (slime-beginning-of-defun))
171 (point)))
172 (end (ignore-errors (slime-end-of-defun) (point))))
173 (unless end
174 (forward-paragraph)
175 (slime-close-all-parens-in-sexp)
176 (slime-end-of-defun)
177 (setf end (point)))
178 (indent-region start end nil)))))
179
180 (provide 'slime-editing-commands)

  ViewVC Help
Powered by ViewVC 1.1.5