(msb--choose-menu): Fix error format string.
[bpt/emacs.git] / src / casefiddle.c
CommitLineData
dcfdbac7 1/* GNU Emacs case conversion functions.
3a22ee35 2 Copyright (C) 1985, 1994 Free Software Foundation, Inc.
dcfdbac7
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
7c938215 8the Free Software Foundation; either version 2, or (at your option)
dcfdbac7
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
dcfdbac7
JB
20
21
18160b98 22#include <config.h>
dcfdbac7
JB
23#include "lisp.h"
24#include "buffer.h"
25#include "commands.h"
26#include "syntax.h"
27
28enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
29\f
30Lisp_Object
31casify_object (flag, obj)
32 enum case_action flag;
33 Lisp_Object obj;
34{
35 register int i, c, len;
36 register int inword = flag == CASE_DOWN;
37
38 while (1)
39 {
9d05e3d4 40 if (INTEGERP (obj))
dcfdbac7
JB
41 {
42 c = XINT (obj);
43 if (c >= 0 && c <= 0400)
44 {
45 if (inword)
18e23fd0 46 XSETFASTINT (obj, DOWNCASE (c));
dcfdbac7 47 else if (!UPPERCASEP (c))
18e23fd0 48 XSETFASTINT (obj, UPCASE1 (c));
dcfdbac7
JB
49 }
50 return obj;
51 }
9d05e3d4 52 if (STRINGP (obj))
dcfdbac7
JB
53 {
54 obj = Fcopy_sequence (obj);
55 len = XSTRING (obj)->size;
56 for (i = 0; i < len; i++)
57 {
58 c = XSTRING (obj)->data[i];
96927ba4 59 if (inword && flag != CASE_CAPITALIZE_UP)
dcfdbac7 60 c = DOWNCASE (c);
96927ba4
RS
61 else if (!UPPERCASEP (c)
62 && (!inword || flag != CASE_CAPITALIZE_UP))
dcfdbac7
JB
63 c = UPCASE1 (c);
64 XSTRING (obj)->data[i] = c;
96927ba4 65 if ((int) flag >= (int) CASE_CAPITALIZE)
dcfdbac7
JB
66 inword = SYNTAX (c) == Sword;
67 }
68 return obj;
69 }
b37902c8 70 obj = wrong_type_argument (Qchar_or_string_p, obj);
dcfdbac7
JB
71 }
72}
73
74DEFUN ("upcase", Fupcase, Supcase, 1, 1, 0,
75 "Convert argument to upper case and return that.\n\
76The argument may be a character or string. The result has the same type.\n\
8cef1f78
RS
77The argument object is not altered--the value is a copy.\n\
78See also `capitalize', `downcase' and `upcase-initials'.")
dcfdbac7
JB
79 (obj)
80 Lisp_Object obj;
81{
82 return casify_object (CASE_UP, obj);
83}
84
85DEFUN ("downcase", Fdowncase, Sdowncase, 1, 1, 0,
86 "Convert argument to lower case and return that.\n\
87The argument may be a character or string. The result has the same type.\n\
8cef1f78 88The argument object is not altered--the value is a copy.")
dcfdbac7
JB
89 (obj)
90 Lisp_Object obj;
91{
92 return casify_object (CASE_DOWN, obj);
93}
94
95DEFUN ("capitalize", Fcapitalize, Scapitalize, 1, 1, 0,
96 "Convert argument to capitalized form and return that.\n\
97This means that each word's first character is upper case\n\
98and the rest is lower case.\n\
99The argument may be a character or string. The result has the same type.\n\
8cef1f78 100The argument object is not altered--the value is a copy.")
dcfdbac7
JB
101 (obj)
102 Lisp_Object obj;
103{
104 return casify_object (CASE_CAPITALIZE, obj);
105}
96927ba4 106
2371fad4
KH
107/* Like Fcapitalize but change only the initials. */
108
8cef1f78
RS
109DEFUN ("upcase-initials", Fupcase_initials, Supcase_initials, 1, 1, 0,
110 "Convert the initial of each word in the argument to upper case.\n\
111Do not change the other letters of each word.\n\
112The argument may be a character or string. The result has the same type.\n\
113The argument object is not altered--the value is a copy.")
114 (obj)
115 Lisp_Object obj;
116{
117 return casify_object (CASE_CAPITALIZE_UP, obj);
118}
dcfdbac7
JB
119\f
120/* flag is CASE_UP, CASE_DOWN or CASE_CAPITALIZE or CASE_CAPITALIZE_UP.
121 b and e specify range of buffer to operate on. */
122
123casify_region (flag, b, e)
124 enum case_action flag;
125 Lisp_Object b, e;
126{
127 register int i;
128 register int c;
129 register int inword = flag == CASE_DOWN;
2371fad4 130 int start, end;
dcfdbac7
JB
131
132 if (EQ (b, e))
133 /* Not modifying because nothing marked */
134 return;
135
136 validate_region (&b, &e);
2371fad4
KH
137 start = XFASTINT (b);
138 end = XFASTINT (e);
139 modify_region (current_buffer, start, end);
140 record_change (start, end - start);
dcfdbac7 141
2371fad4 142 for (i = start; i < end; i++)
dcfdbac7
JB
143 {
144 c = FETCH_CHAR (i);
145 if (inword && flag != CASE_CAPITALIZE_UP)
146 c = DOWNCASE (c);
147 else if (!UPPERCASEP (c)
148 && (!inword || flag != CASE_CAPITALIZE_UP))
149 c = UPCASE1 (c);
150 FETCH_CHAR (i) = c;
151 if ((int) flag >= (int) CASE_CAPITALIZE)
152 inword = SYNTAX (c) == Sword;
153 }
154
2371fad4 155 signal_after_change (start, end - start, end - start);
dcfdbac7
JB
156}
157
158DEFUN ("upcase-region", Fupcase_region, Supcase_region, 2, 2, "r",
159 "Convert the region to upper case. In programs, wants two arguments.\n\
160These arguments specify the starting and ending character numbers of\n\
161the region to operate on. When used as a command, the text between\n\
162point and the mark is operated on.\n\
163See also `capitalize-region'.")
8c22d56c
EN
164 (beg, end)
165 Lisp_Object beg, end;
dcfdbac7 166{
8c22d56c 167 casify_region (CASE_UP, beg, end);
dcfdbac7
JB
168 return Qnil;
169}
170
171DEFUN ("downcase-region", Fdowncase_region, Sdowncase_region, 2, 2, "r",
172 "Convert the region to lower case. In programs, wants two arguments.\n\
173These arguments specify the starting and ending character numbers of\n\
174the region to operate on. When used as a command, the text between\n\
175point and the mark is operated on.")
8c22d56c
EN
176 (beg, end)
177 Lisp_Object beg, end;
dcfdbac7 178{
8c22d56c 179 casify_region (CASE_DOWN, beg, end);
dcfdbac7
JB
180 return Qnil;
181}
182
183DEFUN ("capitalize-region", Fcapitalize_region, Scapitalize_region, 2, 2, "r",
184 "Convert the region to capitalized form.\n\
185Capitalized form means each word's first character is upper case\n\
186and the rest of it is lower case.\n\
187In programs, give two arguments, the starting and ending\n\
188character positions to operate on.")
8c22d56c
EN
189 (beg, end)
190 Lisp_Object beg, end;
dcfdbac7 191{
8c22d56c 192 casify_region (CASE_CAPITALIZE, beg, end);
dcfdbac7
JB
193 return Qnil;
194}
195
2371fad4
KH
196/* Like Fcapitalize_region but change only the initials. */
197
8cef1f78
RS
198DEFUN ("upcase-initials-region", Fupcase_initials_region,
199 Supcase_initials_region, 2, 2, "r",
200 "Upcase the initial of each word in the region.\n\
201Subsequent letters of each word are not changed.\n\
202In programs, give two arguments, the starting and ending\n\
203character positions to operate on.")
8c22d56c
EN
204 (beg, end)
205 Lisp_Object beg, end;
8cef1f78 206{
8c22d56c 207 casify_region (CASE_CAPITALIZE_UP, beg, end);
8cef1f78
RS
208 return Qnil;
209}
dcfdbac7
JB
210\f
211Lisp_Object
34628a90 212operate_on_word (arg, newpoint)
dcfdbac7 213 Lisp_Object arg;
34628a90 214 int *newpoint;
dcfdbac7 215{
39fb55ff 216 Lisp_Object val;
34628a90 217 int farend;
2371fad4 218 int iarg;
dcfdbac7
JB
219
220 CHECK_NUMBER (arg, 0);
2371fad4
KH
221 iarg = XINT (arg);
222 farend = scan_words (point, iarg);
dcfdbac7 223 if (!farend)
2371fad4 224 farend = iarg > 0 ? ZV : BEGV;
dcfdbac7 225
34628a90 226 *newpoint = point > farend ? point : farend;
18e23fd0 227 XSETFASTINT (val, farend);
dcfdbac7
JB
228
229 return val;
230}
231
232DEFUN ("upcase-word", Fupcase_word, Supcase_word, 1, 1, "p",
233 "Convert following word (or ARG words) to upper case, moving over.\n\
234With negative argument, convert previous words but do not move.\n\
235See also `capitalize-word'.")
236 (arg)
237 Lisp_Object arg;
238{
34628a90
RS
239 Lisp_Object beg, end;
240 int newpoint;
18e23fd0 241 XSETFASTINT (beg, point);
34628a90
RS
242 end = operate_on_word (arg, &newpoint);
243 casify_region (CASE_UP, beg, end);
244 SET_PT (newpoint);
dcfdbac7
JB
245 return Qnil;
246}
247
248DEFUN ("downcase-word", Fdowncase_word, Sdowncase_word, 1, 1, "p",
249 "Convert following word (or ARG words) to lower case, moving over.\n\
250With negative argument, convert previous words but do not move.")
251 (arg)
252 Lisp_Object arg;
253{
34628a90
RS
254 Lisp_Object beg, end;
255 int newpoint;
18e23fd0 256 XSETFASTINT (beg, point);
34628a90
RS
257 end = operate_on_word (arg, &newpoint);
258 casify_region (CASE_DOWN, beg, end);
259 SET_PT (newpoint);
dcfdbac7
JB
260 return Qnil;
261}
262
263DEFUN ("capitalize-word", Fcapitalize_word, Scapitalize_word, 1, 1, "p",
264 "Capitalize the following word (or ARG words), moving over.\n\
265This gives the word(s) a first character in upper case\n\
266and the rest lower case.\n\
267With negative argument, capitalize previous words but do not move.")
268 (arg)
269 Lisp_Object arg;
270{
34628a90
RS
271 Lisp_Object beg, end;
272 int newpoint;
18e23fd0 273 XSETFASTINT (beg, point);
34628a90
RS
274 end = operate_on_word (arg, &newpoint);
275 casify_region (CASE_CAPITALIZE, beg, end);
276 SET_PT (newpoint);
dcfdbac7
JB
277 return Qnil;
278}
279\f
280syms_of_casefiddle ()
281{
282 defsubr (&Supcase);
283 defsubr (&Sdowncase);
284 defsubr (&Scapitalize);
8cef1f78 285 defsubr (&Supcase_initials);
dcfdbac7
JB
286 defsubr (&Supcase_region);
287 defsubr (&Sdowncase_region);
288 defsubr (&Scapitalize_region);
8cef1f78 289 defsubr (&Supcase_initials_region);
dcfdbac7
JB
290 defsubr (&Supcase_word);
291 defsubr (&Sdowncase_word);
292 defsubr (&Scapitalize_word);
293}
294
295keys_of_casefiddle ()
296{
297 initial_define_key (control_x_map, Ctl('U'), "upcase-region");
d427b66a 298 Fput (intern ("upcase-region"), Qdisabled, Qt);
dcfdbac7 299 initial_define_key (control_x_map, Ctl('L'), "downcase-region");
d427b66a
JB
300 Fput (intern ("downcase-region"), Qdisabled, Qt);
301
dcfdbac7
JB
302 initial_define_key (meta_map, 'u', "upcase-word");
303 initial_define_key (meta_map, 'l', "downcase-word");
304 initial_define_key (meta_map, 'c', "capitalize-word");
305}