Mercurial > hg > xemacs-beta
comparison src/abbrev.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 859a2309aef8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 /* Primitives for word-abbrev mode. | |
2 Copyright (C) 1985, 1986, 1992, 1993 Free Software Foundation, Inc. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 Boston, MA 02111-1307, USA. */ | |
20 | |
21 /* Synched up with: FSF 19.30. Note that there are many more functions in | |
22 FSF's abbrev.c. These have been moved into Lisp in XEmacs. */ | |
23 | |
24 /* Authorship: | |
25 | |
26 FSF: Original version; a long time ago. | |
27 JWZ or Mly: Mostly moved into Lisp; maybe 1992. | |
28 Ben Wing: Some changes for Mule for 19.12. | |
29 */ | |
30 | |
31 /* This file has been Mule-ized. */ | |
32 | |
33 #include <config.h> | |
34 #include "lisp.h" | |
35 | |
36 #include "buffer.h" | |
37 #include "commands.h" | |
38 #include "insdel.h" | |
39 #include "syntax.h" | |
40 #include "window.h" | |
41 | |
42 /* An abbrev table is an obarray. | |
43 Each defined abbrev is represented by a symbol in that obarray | |
44 whose print name is the abbreviation. | |
45 The symbol's value is a string which is the expansion. | |
46 If its function definition is non-nil, it is called | |
47 after the expansion is done. | |
48 The plist slot of the abbrev symbol is its usage count. */ | |
49 | |
50 /* The table of global abbrevs. These are in effect | |
51 in any buffer in which abbrev mode is turned on. */ | |
52 Lisp_Object Vglobal_abbrev_table; | |
53 | |
54 int abbrev_all_caps; | |
55 | |
56 /* Non-nil => use this location as the start of abbrev to expand | |
57 (rather than taking the word before point as the abbrev) */ | |
58 Lisp_Object Vabbrev_start_location; | |
59 | |
60 /* Buffer that Vabbrev_start_location applies to */ | |
61 Lisp_Object Vabbrev_start_location_buffer; | |
62 | |
63 /* The symbol representing the abbrev most recently expanded */ | |
64 Lisp_Object Vlast_abbrev; | |
65 | |
66 /* A string for the actual text of the abbrev most recently expanded. | |
67 This has more info than Vlast_abbrev since case is significant. */ | |
68 Lisp_Object Vlast_abbrev_text; | |
69 | |
70 /* Character address of start of last abbrev expanded */ | |
71 int last_abbrev_point; | |
72 | |
73 /* Hook to run before expanding any abbrev. */ | |
74 Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook; | |
75 | |
76 | |
77 /* Expand the word before point, if it is an abbrev. | |
78 Returns Qt if an expansion is done. */ | |
79 | |
80 DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "" /* | |
81 Expand the abbrev before point, if there is an abbrev there. | |
82 Effective when explicitly called even when `abbrev-mode' is nil. | |
83 Returns t if expansion took place. | |
84 */ ) | |
85 () | |
86 { | |
87 /* This function can GC */ | |
88 REGISTER Bufbyte *buffer, *p; | |
89 REGISTER Bufpos wordstart, wordend, idx; | |
90 Charcount whitecnt; | |
91 Charcount uccount = 0, lccount = 0; | |
92 REGISTER Lisp_Object sym; | |
93 Lisp_Object expansion, hook, value; | |
94 struct buffer *buf = current_buffer; | |
95 Lisp_Object lbuf; | |
96 int oldmodiff = BUF_MODIFF (buf); | |
97 | |
98 XSETBUFFER (lbuf, buf); | |
99 run_hook (Qpre_abbrev_expand_hook); | |
100 /* If the hook changes the buffer, treat that as having "done an | |
101 expansion". */ | |
102 value = (BUF_MODIFF (buf) != oldmodiff ? Qt : Qnil); | |
103 | |
104 wordstart = 0; | |
105 if (!BUFFERP (Vabbrev_start_location_buffer) || | |
106 XBUFFER (Vabbrev_start_location_buffer) != buf) | |
107 Vabbrev_start_location = Qnil; | |
108 if (!NILP (Vabbrev_start_location)) | |
109 { | |
110 wordstart = get_buffer_pos_char (buf, Vabbrev_start_location, GB_COERCE_RANGE); | |
111 Vabbrev_start_location = Qnil; | |
112 if (wordstart < BUF_BEGV (buf) || wordstart > BUF_ZV (buf)) | |
113 wordstart = 0; | |
114 if (wordstart && wordstart != BUF_ZV (buf) && | |
115 BUF_FETCH_CHAR (buf, wordstart) == '-') | |
116 buffer_delete_range (buf, wordstart, wordstart + 1, 0); | |
117 } | |
118 if (!wordstart) | |
119 wordstart = scan_words (buf, BUF_PT (buf), -1); | |
120 | |
121 if (!wordstart) | |
122 return value; | |
123 | |
124 wordend = scan_words (buf, wordstart, 1); | |
125 if (!wordend) | |
126 return value; | |
127 | |
128 if (wordend > BUF_PT (buf)) | |
129 wordend = BUF_PT (buf); | |
130 whitecnt = BUF_PT (buf) - wordend; | |
131 if (wordend <= wordstart) | |
132 return value; | |
133 | |
134 p = buffer = (Bufbyte *) alloca (MAX_EMCHAR_LEN*(wordend - wordstart)); | |
135 | |
136 for (idx = wordstart; idx < wordend; idx++) | |
137 { | |
138 REGISTER Emchar c = BUF_FETCH_CHAR (buf, idx); | |
139 if (UPPERCASEP (buf, c)) | |
140 c = DOWNCASE (buf, c), uccount++; | |
141 else if (! NOCASEP (buf, c)) | |
142 lccount++; | |
143 p += set_charptr_emchar (p, c); | |
144 } | |
145 | |
146 if (VECTORP (buf->abbrev_table)) | |
147 sym = oblookup (buf->abbrev_table, | |
148 buffer, | |
149 p - buffer); | |
150 else | |
151 sym = Qzero; | |
152 if (INTP (sym) || NILP (XSYMBOL (sym)->value)) | |
153 sym = oblookup (Vglobal_abbrev_table, | |
154 buffer, | |
155 p - buffer); | |
156 if (INTP (sym) || NILP (XSYMBOL (sym)->value)) | |
157 return value; | |
158 | |
159 if (INTERACTIVE && !EQ (minibuf_window, Fselected_window (Qnil))) | |
160 { | |
161 /* Add an undo boundary, in case we are doing this for | |
162 a self-inserting command which has avoided making one so far. */ | |
163 BUF_SET_PT (buf, wordend); | |
164 Fundo_boundary (); | |
165 } | |
166 BUF_SET_PT (buf, wordstart); | |
167 Vlast_abbrev_text = | |
168 make_string_from_buffer (buf, wordstart, wordend - wordstart); | |
169 buffer_delete_range (buf, wordstart, wordend, 0); | |
170 | |
171 /* Now sym is the abbrev symbol. */ | |
172 Vlast_abbrev = sym; | |
173 last_abbrev_point = wordstart; | |
174 | |
175 if (INTP (XSYMBOL (sym)->plist)) | |
176 XSETINT (XSYMBOL (sym)->plist, | |
177 XINT (XSYMBOL (sym)->plist) + 1); /* Increment use count */ | |
178 | |
179 expansion = XSYMBOL (sym)->value; | |
180 buffer_insert_lisp_string (buf, expansion); | |
181 BUF_SET_PT (buf, BUF_PT (buf) + whitecnt); | |
182 | |
183 if (uccount && !lccount) | |
184 { | |
185 /* Abbrev was all caps */ | |
186 /* If expansion is multiple words, normally capitalize each word */ | |
187 /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase | |
188 but Megatest 68000 compiler can't handle that */ | |
189 if (!abbrev_all_caps) | |
190 if (scan_words (buf, BUF_PT (buf), -1) > | |
191 scan_words (buf, wordstart, 1)) | |
192 { | |
193 Fupcase_initials_region (make_int (wordstart), | |
194 make_int (BUF_PT (buf)), | |
195 lbuf); | |
196 goto caped; | |
197 } | |
198 /* If expansion is one word, or if user says so, upcase it all. */ | |
199 Fupcase_region (make_int (wordstart), make_int (BUF_PT (buf)), | |
200 lbuf); | |
201 caped: ; | |
202 } | |
203 else if (uccount) | |
204 { | |
205 /* Abbrev included some caps. Cap first initial of expansion */ | |
206 Bufpos pos = wordstart; | |
207 | |
208 /* Find the initial. */ | |
209 while (pos < BUF_PT (buf) | |
210 && !WORD_SYNTAX_P (buf->syntax_table, BUF_FETCH_CHAR (buf, pos))) | |
211 pos++; | |
212 | |
213 /* Change just that. */ | |
214 Fupcase_initials_region (make_int (pos), make_int (pos + 1), lbuf); | |
215 } | |
216 | |
217 hook = XSYMBOL (sym)->function; | |
218 if (!NILP (hook) && !UNBOUNDP (hook)) | |
219 call0 (hook); | |
220 | |
221 return Qt; | |
222 } | |
223 | |
224 void | |
225 syms_of_abbrev (void) | |
226 { | |
227 defsymbol (&Qpre_abbrev_expand_hook, "pre-abbrev-expand-hook"); | |
228 defsubr (&Sexpand_abbrev); | |
229 } | |
230 | |
231 void | |
232 vars_of_abbrev (void) | |
233 { | |
234 DEFVAR_LISP ("global-abbrev-table", &Vglobal_abbrev_table /* | |
235 The abbrev table whose abbrevs affect all buffers. | |
236 Each buffer may also have a local abbrev table. | |
237 If it does, the local table overrides the global one | |
238 for any particular abbrev defined in both. | |
239 */ ); | |
240 Vglobal_abbrev_table = Qnil; /* setup by Lisp code */ | |
241 | |
242 DEFVAR_LISP ("last-abbrev", &Vlast_abbrev /* | |
243 The abbrev-symbol of the last abbrev expanded. | |
244 See the function `abbrev-symbol'. | |
245 */ ); | |
246 | |
247 DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text /* | |
248 The exact text of the last abbrev expanded. | |
249 nil if the abbrev has already been unexpanded. | |
250 */ ); | |
251 | |
252 DEFVAR_INT ("last-abbrev-location", &last_abbrev_point /* | |
253 The location of the start of the last abbrev expanded. | |
254 */ ); | |
255 | |
256 Vlast_abbrev = Qnil; | |
257 Vlast_abbrev_text = Qnil; | |
258 last_abbrev_point = 0; | |
259 | |
260 DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location /* | |
261 Buffer position for `expand-abbrev' to use as the start of the abbrev. | |
262 nil means use the word before point as the abbrev. | |
263 Calling `expand-abbrev' sets this to nil. | |
264 */ ); | |
265 Vabbrev_start_location = Qnil; | |
266 | |
267 DEFVAR_LISP ("abbrev-start-location-buffer", &Vabbrev_start_location_buffer /* | |
268 Buffer that `abbrev-start-location' has been set for. | |
269 Trying to expand an abbrev in any other buffer clears `abbrev-start-location'. | |
270 */ ); | |
271 Vabbrev_start_location_buffer = Qnil; | |
272 | |
273 DEFVAR_BOOL ("abbrev-all-caps", &abbrev_all_caps /* | |
274 *Set non-nil means expand multi-word abbrevs all caps if abbrev was so. | |
275 */ ); | |
276 abbrev_all_caps = 0; | |
277 | |
278 DEFVAR_LISP ("pre-abbrev-expand-hook", &Vpre_abbrev_expand_hook /* | |
279 Function or functions to be called before abbrev expansion is done. | |
280 This is the first thing that `expand-abbrev' does, and so this may change | |
281 the current abbrev table before abbrev lookup happens. | |
282 */ ); | |
283 Vpre_abbrev_expand_hook = Qnil; | |
284 } |