0
|
1 ;;; -*- Mode: Emacs-Lisp -*-
|
|
2
|
|
3 ;;; ilisp-mov.el --
|
|
4
|
|
5 ;;; This file is part of ILISP.
|
4
|
6 ;;; Version: 5.8
|
0
|
7 ;;;
|
|
8 ;;; Copyright (C) 1990, 1991, 1992, 1993 Chris McConnell
|
|
9 ;;; 1993, 1994 Ivan Vasquez
|
4
|
10 ;;; 1994, 1995, 1996 Marco Antoniotti and Rick Busdiecker
|
|
11 ;;; 1996 Marco Antoniotti and Rick Campbell
|
0
|
12 ;;;
|
|
13 ;;; Other authors' names for which this Copyright notice also holds
|
|
14 ;;; may appear later in this file.
|
|
15 ;;;
|
4
|
16 ;;; Send mail to 'ilisp-request@naggum.no' to be included in the
|
|
17 ;;; ILISP mailing list. 'ilisp@naggum.no' is the general ILISP
|
0
|
18 ;;; mailing list were bugs and improvements are discussed.
|
|
19 ;;;
|
|
20 ;;; ILISP is freely redistributable under the terms found in the file
|
|
21 ;;; COPYING.
|
|
22
|
|
23
|
|
24
|
|
25 ;;;%%Movement
|
|
26 (defun bol-ilisp (arg)
|
|
27 "Goes to the beginning of line, then skips past the prompt, if any.
|
|
28 If a prefix argument is given (\\[universal-argument]), then no prompt skip
|
|
29 -- go straight to column 0.
|
|
30
|
|
31 The prompt skip is done by skipping text matching the regular expression
|
|
32 comint-prompt-regexp or ilisp-other-prompt, both buffer local variables."
|
|
33 (interactive "P")
|
|
34 (beginning-of-line)
|
|
35 (if (null arg)
|
|
36 (or (comint-skip-prompt)
|
|
37 (if ilisp-other-prompt
|
|
38 (let ((comint-prompt-regexp ilisp-other-prompt))
|
|
39 (comint-skip-prompt))))))
|
|
40
|
|
41 ;;;
|
|
42 (defun beginning-of-defun-lisp (&optional stay)
|
|
43 "Go to the next left paren that starts at the left margin or after a
|
|
44 prompt in an ILISP buffer. If optional STAY, then do not move to
|
|
45 prior defun if at the start of one in an ilisp mode."
|
|
46 (interactive)
|
|
47 (if (memq major-mode ilisp-modes)
|
|
48 (let ((point (point)))
|
|
49 (if (and (not stay) (= point (lisp-input-start)))
|
|
50 (progn (forward-line -1) (lisp-input-start))))
|
|
51 (beginning-of-defun)))
|
|
52
|
|
53 ;;;
|
|
54 (defun end-of-defun-lisp ()
|
|
55 "Go to the next left paren that starts at the left margin or after a
|
|
56 prompt in an ILISP buffer and go to the end of the expression."
|
|
57 (interactive)
|
|
58 (let ((point (point)))
|
|
59 (if (memq major-mode ilisp-modes)
|
|
60 (beginning-of-defun-lisp t)
|
|
61 (if (or (lisp-in-string)
|
|
62 (progn (beginning-of-line)
|
|
63 (re-search-forward "^[ \t\n]*[^; \t\n]" nil t)
|
|
64 (back-to-indentation)
|
|
65 (not (bolp))))
|
|
66 (beginning-of-defun-lisp t)))
|
|
67 (lisp-end-defun-text t)
|
|
68 (if (= point (point)) ;Already at end so move to next end
|
|
69 (progn
|
|
70 (if (memq major-mode ilisp-modes)
|
|
71 (re-search-forward comint-prompt-regexp (point-max) t)
|
|
72 (lisp-skip (point-max)))
|
|
73 (if (not (or (eobp)
|
|
74 (= (char-after (point)) ?\n)))
|
|
75 (lisp-end-defun-text t))))))
|
|
76
|
|
77 ;;;
|
|
78 (defun lisp-defun-begin ()
|
|
79 "Go to the start of the containing defun and return point."
|
|
80 (let (begin)
|
|
81 (if (memq major-mode ilisp-modes)
|
|
82 (lisp-input-start)
|
|
83 (if (or (eobp) (not (and (bolp) (= (char-after (point)) ?\())))
|
|
84 (beginning-of-defun))
|
|
85 (point))))
|
|
86
|
|
87 ;;;
|
|
88 (defun lisp-defun-end (&optional no-errorp at-beginp)
|
|
89 "Go to the end of the containing defun and return point or nil if
|
|
90 there is no end."
|
|
91 (if (not at-beginp) (lisp-defun-begin))
|
|
92 (condition-case ()
|
|
93 (progn
|
|
94 (lisp-skip (point-max)) ;To skip comments on defun-end
|
|
95 (forward-sexp)
|
|
96 (point))
|
|
97 (error (if no-errorp nil (error "Unbalanced parentheses")))))
|
|
98
|
|
99 ;;;
|
|
100 (defun lisp-find-next-start ()
|
|
101 "Find the start of the next line at the left margin that starts with
|
|
102 a character besides whitespace, a \) or ;;; and return the
|
|
103 point."
|
|
104 (if (eobp)
|
|
105 (point-max)
|
|
106 (save-excursion
|
|
107 (forward-char)
|
|
108 (if (re-search-forward "^\\(\\(;;;\\)\\|\\([^ \t\n\);]\\)\\)" nil t)
|
|
109 (match-beginning 0)
|
|
110 (point-max)))))
|
|
111
|
|
112 ;;;
|
|
113 (defun lisp-end-defun-text (&optional at-start)
|
|
114 "Go the end of the text associated with the current defun and return
|
|
115 point. The end is the last character before whitespace leading to
|
|
116 a left paren or ;;; at the left margin unless it is in a string."
|
|
117 (if (not at-start) (lisp-defun-begin))
|
|
118 (let ((point (point))
|
|
119 (boundary (lisp-find-next-start))
|
|
120 (final (save-excursion
|
|
121 (condition-case ()
|
|
122 (progn (forward-sexp) (point))
|
|
123 (error (point-max))))))
|
|
124 ;; Find the next line starting at the left margin and then check
|
|
125 ;; to see if it is in a string.
|
|
126 (while (progn
|
|
127 (skip-chars-forward "^\"" boundary) ;To the next string
|
|
128 (if (= (point) boundary)
|
|
129 nil ;No quote found and at limit
|
|
130 (let ((string-boundary ;Start of next defun
|
|
131 (save-excursion
|
|
132 (if (re-search-forward "^\(\\|^;;;" nil t)
|
|
133 (match-beginning 0)
|
|
134 (point-max)))))
|
|
135 (if (condition-case ()
|
|
136 (progn (forward-sexp) t)
|
|
137 (error (goto-char string-boundary) nil))
|
|
138 (if (>= (point) boundary)
|
|
139 ;; Boundary was in string
|
|
140 (if (> (point) string-boundary)
|
|
141 (progn ;String ended in next defun
|
|
142 (goto-char string-boundary)
|
|
143 nil)
|
|
144 (if (> (setq boundary
|
|
145 (lisp-find-next-start))
|
|
146 final)
|
|
147 ;; Normal defun
|
|
148 (progn (goto-char final) nil)
|
|
149 t))
|
|
150 t)
|
|
151 ;; Unclosed string
|
|
152 nil)))))
|
|
153 (re-search-backward "^[^; \t\n]\\|^[^;\n][ \t]*[^ \t\n]" point t)
|
|
154 (end-of-line)
|
|
155 (skip-chars-backward " \t")
|
|
156 (if (< (point) point)
|
|
157 (goto-char point)
|
|
158 (if (save-excursion
|
|
159 (let ((point (point)))
|
|
160 (beginning-of-line)
|
|
161 (if comment-start (search-forward comment-start point t))))
|
|
162 (progn (next-line 1) (indent-line-ilisp)))
|
|
163 (point))))
|
|
164
|
|
165 ;;;
|
|
166 (defun lisp-in-comment (test)
|
|
167 "Return T if you are in a comment."
|
|
168 (beginning-of-line)
|
|
169 (and (looking-at test)
|
|
170 (not (= (match-end 0)
|
|
171 (progn (end-of-line) (point))))))
|
|
172
|
|
173 ;;;
|
|
174 (defun lisp-in-string (&optional begin end)
|
|
175 "Return the string region that immediately follows/precedes point or
|
|
176 that contains point in optional region BEGIN to END. If point is in
|
|
177 region, T will be returned as well."
|
|
178 (save-excursion
|
|
179 (if (not begin)
|
|
180 (save-excursion
|
|
181 (setq end (lisp-end-defun-text)
|
|
182 begin (lisp-defun-begin))))
|
|
183 (let* ((point (progn (skip-chars-forward " \t") (point)))
|
|
184 (done nil))
|
|
185 (goto-char begin)
|
|
186 (while (and (< (point) end) (not done))
|
|
187 (skip-chars-forward "^\"" end)
|
|
188 (setq begin (point))
|
|
189 (if (< begin end)
|
|
190 (if (and (not (bobp)) (= (char-after (1- begin)) ??))
|
|
191 (forward-char)
|
|
192 (if (condition-case () (progn (forward-sexp) (<= (point) end))
|
|
193 (error nil))
|
|
194 (progn ;After string
|
|
195 (skip-chars-forward " \t")
|
|
196 (if (or (= begin point) (= point (point)))
|
|
197 (setq done (list begin (point) nil))
|
|
198 (if (and (< begin point) (< point (point)))
|
|
199 (setq done (list begin (point) t)))))
|
|
200 ;; In string at end of buffer
|
|
201 (setq done (list begin end t))))))
|
|
202 done)))
|