(CHECK_FRAME, CHECK_LIVE_FRAME): Remove unused argument `i' in macros.
[bpt/emacs.git] / src / category.c
CommitLineData
4ed46869 1/* GNU Emacs routines to deal with category tables.
75c8c592
RS
2 Copyright (C) 1995, 1997 Electrotechnical Laboratory, JAPAN.
3 Licensed to the Free Software Foundation.
4ed46869
KH
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
369314dc
KH
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
4ed46869
KH
21
22
23/* Here we handle three objects: category, category set, and category
24 table. Read comments in the file category.h to understand them. */
25
26#include <config.h>
27#include <ctype.h>
28#include "lisp.h"
29#include "buffer.h"
30#include "charset.h"
31#include "category.h"
e35f6ff7 32#include "keymap.h"
4ed46869
KH
33
34/* The version number of the latest category table. Each category
35 table has a unique version number. It is assigned a new number
36 also when it is modified. When a regular expression is compiled
37 into the struct re_pattern_buffer, the version number of the
38 category table (of the current buffer) at that moment is also
39 embedded in the structure.
40
41 For the moment, we are not using this feature. */
42static int category_table_version;
43
44Lisp_Object Qcategory_table, Qcategoryp, Qcategorysetp, Qcategory_table_p;
45
46/* Variables to determine word boundary. */
47Lisp_Object Vword_combining_categories, Vword_separating_categories;
48
49/* Temporary internal variable used in macro CHAR_HAS_CATEGORY. */
50Lisp_Object _temp_category_set;
51
52\f
53/* Category set staff. */
54
55DEFUN ("make-category-set", Fmake_category_set, Smake_category_set, 1, 1, 0,
fdb82f93
PJ
56 doc: /* Return a newly created category-set which contains CATEGORIES.
57CATEGORIES is a string of category mnemonics.
58The value is a bool-vector which has t at the indices corresponding to
59those categories. */)
60 (categories)
4ed46869
KH
61 Lisp_Object categories;
62{
63 Lisp_Object val;
64 int len;
65
66 CHECK_STRING (categories, 0);
67 val = MAKE_CATEGORY_SET;
68
115afec3
RS
69 if (STRING_MULTIBYTE (categories))
70 error ("Multibyte string in make-category-set");
71
4ed46869
KH
72 len = XSTRING (categories)->size;
73 while (--len >= 0)
74 {
15c60737 75 Lisp_Object category;
4ed46869 76
15c60737 77 XSETFASTINT (category, XSTRING (categories)->data[len]);
4ed46869
KH
78 CHECK_CATEGORY (category, 0);
79 SET_CATEGORY_SET (val, category, Qt);
80 }
81 return val;
82}
83
84\f
85/* Category staff. */
86
87Lisp_Object check_category_table ();
88
89DEFUN ("define-category", Fdefine_category, Sdefine_category, 2, 3, 0,
fdb82f93
PJ
90 doc: /* Define CHAR as a category which is described by DOCSTRING.
91CHAR should be an ASCII printing character in the range ` ' to `~'.
92DOCSTRING is a documentation string of the category.
93The category is defined only in category table TABLE, which defaults to
94 the current buffer's category table. */)
95 (category, docstring, table)
4ed46869
KH
96 Lisp_Object category, docstring, table;
97{
98 CHECK_CATEGORY (category, 0);
99 CHECK_STRING (docstring, 1);
100 table = check_category_table (table);
101
102 if (!NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
103 error ("Category `%c' is already defined", XFASTINT (category));
104 CATEGORY_DOCSTRING (table, XFASTINT (category)) = docstring;
105
106 return Qnil;
107}
108
109DEFUN ("category-docstring", Fcategory_docstring, Scategory_docstring, 1, 2, 0,
fdb82f93
PJ
110 doc: /* Return the documentation string of CATEGORY, as defined in CATEGORY-TABLE. */)
111 (category, table)
4ed46869
KH
112 Lisp_Object category, table;
113{
4ed46869
KH
114 CHECK_CATEGORY (category, 0);
115 table = check_category_table (table);
116
117 return CATEGORY_DOCSTRING (table, XFASTINT (category));
118}
119
120DEFUN ("get-unused-category", Fget_unused_category, Sget_unused_category,
121 0, 1, 0,
fdb82f93
PJ
122 doc: /* Return a category which is not yet defined in CATEGORY-TABLE. If no
123category remains available, return nil. The optional argument CATEGORY-TABLE
124specifies which category table to modify; it defaults to the current
125buffer's category table. */)
126 (table)
4ed46869
KH
127 Lisp_Object table;
128{
129 int i;
4ed46869
KH
130
131 table = check_category_table (table);
132
133 for (i = ' '; i <= '~'; i++)
134 if (NILP (CATEGORY_DOCSTRING (table, i)))
135 return make_number (i);
136
137 return Qnil;
138}
139
140\f
141/* Category-table staff. */
142
143DEFUN ("category-table-p", Fcategory_table_p, Scategory_table_p, 1, 1, 0,
fdb82f93
PJ
144 doc: /* Return t if ARG is a category table. */)
145 (arg)
4ed46869
KH
146 Lisp_Object arg;
147{
148 if (CHAR_TABLE_P (arg)
ed8ec86d 149 && EQ (XCHAR_TABLE (arg)->purpose, Qcategory_table))
4ed46869
KH
150 return Qt;
151 return Qnil;
152}
153
154/* If TABLE is nil, return the current category table. If TABLE is
155 not nil, check the validity of TABLE as a category table. If
156 valid, return TABLE itself, but if not valid, signal an error of
157 wrong-type-argument. */
158
159Lisp_Object
160check_category_table (table)
161 Lisp_Object table;
162{
163 register Lisp_Object tem;
164 if (NILP (table))
165 return current_buffer->category_table;
166 while (tem = Fcategory_table_p (table), NILP (tem))
167 table = wrong_type_argument (Qcategory_table_p, table);
168 return table;
169}
170
171DEFUN ("category-table", Fcategory_table, Scategory_table, 0, 0, 0,
fdb82f93
PJ
172 doc: /* Return the current category table.
173This is the one specified by the current buffer. */)
174 ()
4ed46869
KH
175{
176 return current_buffer->category_table;
177}
178
179DEFUN ("standard-category-table", Fstandard_category_table,
180 Sstandard_category_table, 0, 0, 0,
fdb82f93
PJ
181 doc: /* Return the standard category table.
182This is the one used for new buffers. */)
183 ()
4ed46869
KH
184{
185 return Vstandard_category_table;
186}
187
188/* Return a copy of category table TABLE. We can't simply use the
189 function copy-sequence because no contents should be shared between
ed8ec86d 190 the original and the copy. This function is called recursively by
9da95d53 191 binding TABLE to a sub char table. */
4ed46869
KH
192
193Lisp_Object
ed8ec86d 194copy_category_table (table)
4ed46869
KH
195 Lisp_Object table;
196{
ed8ec86d
KH
197 Lisp_Object tmp;
198 int i, to;
4ed46869 199
ed8ec86d
KH
200 if (!NILP (XCHAR_TABLE (table)->top))
201 {
202 /* TABLE is a top level char table.
203 At first, make a copy of tree structure of the table. */
204 table = Fcopy_sequence (table);
205
206 /* Then, copy elements for single byte characters one by one. */
207 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
208 if (!NILP (tmp = XCHAR_TABLE (table)->contents[i]))
209 XCHAR_TABLE (table)->contents[i] = Fcopy_sequence (tmp);
210 to = CHAR_TABLE_ORDINARY_SLOTS;
9da95d53
KH
211
212 /* Also copy the first (and sole) extra slot. It is a vector
213 containing docstring of each category. */
214 Fset_char_table_extra_slot
215 (table, make_number (0),
216 Fcopy_sequence (Fchar_table_extra_slot (table, make_number (0))));
ed8ec86d
KH
217 }
218 else
4ed46869 219 {
ed8ec86d
KH
220 i = 32;
221 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
4ed46869
KH
222 }
223
ed8ec86d
KH
224 /* If the table has non-nil default value, copy it. */
225 if (!NILP (tmp = XCHAR_TABLE (table)->defalt))
226 XCHAR_TABLE (table)->defalt = Fcopy_sequence (tmp);
227
228 /* At last, copy the remaining elements while paying attention to a
229 sub char table. */
230 for (; i < to; i++)
231 if (!NILP (tmp = XCHAR_TABLE (table)->contents[i]))
232 XCHAR_TABLE (table)->contents[i]
233 = (SUB_CHAR_TABLE_P (tmp)
234 ? copy_category_table (tmp) : Fcopy_sequence (tmp));
235
4ed46869
KH
236 return table;
237}
238
239DEFUN ("copy-category-table", Fcopy_category_table, Scopy_category_table,
240 0, 1, 0,
fdb82f93
PJ
241 doc: /* Construct a new category table and return it.
242It is a copy of the TABLE, which defaults to the standard category table. */)
243 (table)
4ed46869
KH
244 Lisp_Object table;
245{
246 if (!NILP (table))
247 check_category_table (table);
248 else
249 table = Vstandard_category_table;
250
9da95d53 251 return copy_category_table (table);
4ed46869
KH
252}
253
70414a3d
KH
254DEFUN ("make-category-table", Fmake_category_table, Smake_category_table,
255 0, 0, 0,
fdb82f93
PJ
256 doc: /* Construct a new and empty category table and return it. */)
257 ()
70414a3d
KH
258{
259 Lisp_Object val;
260
261 val = Fmake_char_table (Qcategory_table, Qnil);
262 XCHAR_TABLE (val)->defalt = MAKE_CATEGORY_SET;
263 Fset_char_table_extra_slot (val, make_number (0),
264 Fmake_vector (make_number (95), Qnil));
265 return val;
266}
267
4ed46869 268DEFUN ("set-category-table", Fset_category_table, Sset_category_table, 1, 1, 0,
fdb82f93
PJ
269 doc: /* Specify TABLE as the category table for the current buffer. */)
270 (table)
4ed46869
KH
271 Lisp_Object table;
272{
6f598a6d 273 int idx;
4ed46869
KH
274 table = check_category_table (table);
275 current_buffer->category_table = table;
276 /* Indicate that this buffer now has a specified category table. */
f6cd0527
GM
277 idx = PER_BUFFER_VAR_IDX (category_table);
278 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 1);
4ed46869
KH
279 return table;
280}
281
282\f
283DEFUN ("char-category-set", Fchar_category_set, Schar_category_set, 1, 1, 0,
fdb82f93
PJ
284 doc: /* Return the category set of CHAR. */)
285 (ch)
4ed46869
KH
286 Lisp_Object ch;
287{
4ed46869
KH
288 CHECK_NUMBER (ch, 0);
289 return CATEGORY_SET (XFASTINT (ch));
290}
291
292DEFUN ("category-set-mnemonics", Fcategory_set_mnemonics,
293 Scategory_set_mnemonics, 1, 1, 0,
fdb82f93
PJ
294 doc: /* Return a string containing mnemonics of the categories in CATEGORY-SET.
295CATEGORY-SET is a bool-vector, and the categories \"in\" it are those
296that are indexes where t occurs the bool-vector.
297The return value is a string containing those same categories. */)
298 (category_set)
4ed46869
KH
299 Lisp_Object category_set;
300{
301 int i, j;
302 char str[96];
303
304 CHECK_CATEGORY_SET (category_set, 0);
305
306 j = 0;
307 for (i = 32; i < 127; i++)
308 if (CATEGORY_MEMBER (i, category_set))
309 str[j++] = i;
310 str[j] = '\0';
311
312 return build_string (str);
313}
314
ed8ec86d 315/* Modify all category sets stored under sub char-table TABLE so that
4ed46869
KH
316 they contain (SET_VALUE is t) or don't contain (SET_VALUE is nil)
317 CATEGORY. */
318
319void
320modify_lower_category_set (table, category, set_value)
321 Lisp_Object table, category, set_value;
322{
323 Lisp_Object val;
324 int i;
325
54e67cf7
KH
326 val = XCHAR_TABLE (table)->defalt;
327 if (!CATEGORY_SET_P (val))
328 val = MAKE_CATEGORY_SET;
329 SET_CATEGORY_SET (val, category, set_value);
330 XCHAR_TABLE (table)->defalt = val;
4ed46869 331
ed8ec86d 332 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
4ed46869
KH
333 {
334 val = XCHAR_TABLE (table)->contents[i];
335
336 if (CATEGORY_SET_P (val))
337 SET_CATEGORY_SET (val, category, set_value);
ed8ec86d 338 else if (SUB_CHAR_TABLE_P (val))
4ed46869
KH
339 modify_lower_category_set (val, category, set_value);
340 }
341}
342
343void
344set_category_set (category_set, category, val)
345 Lisp_Object category_set, category, val;
346{
347 do {
348 int idx = XINT (category) / 8;
349 unsigned char bits = 1 << (XINT (category) % 8);
350
351 if (NILP (val))
352 XCATEGORY_SET (category_set)->data[idx] &= ~bits;
353 else
354 XCATEGORY_SET (category_set)->data[idx] |= bits;
355 } while (0);
356}
357
358DEFUN ("modify-category-entry", Fmodify_category_entry,
359 Smodify_category_entry, 2, 4, 0,
fdb82f93
PJ
360 doc: /* Modify the category set of CHARACTER by adding CATEGORY to it.
361The category is changed only for table TABLE, which defaults to
362 the current buffer's category table.
363If optional fourth argument RESET is non-nil,
364then delete CATEGORY from the category set instead of adding it. */)
365 (character, category, table, reset)
ea4943bf 366 Lisp_Object character, category, table, reset;
4ed46869
KH
367{
368 int c, charset, c1, c2;
369 Lisp_Object set_value; /* Actual value to be set in category sets. */
370 Lisp_Object val, category_set;
371
ea4943bf
RS
372 CHECK_NUMBER (character, 0);
373 c = XINT (character);
4ed46869
KH
374 CHECK_CATEGORY (category, 1);
375 table = check_category_table (table);
376
377 if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
378 error ("Undefined category: %c", XFASTINT (category));
379
380 set_value = NILP (reset) ? Qt : Qnil;
381
ed8ec86d 382 if (c < CHAR_TABLE_SINGLE_BYTE_SLOTS)
4ed46869
KH
383 {
384 val = XCHAR_TABLE (table)->contents[c];
385 if (!CATEGORY_SET_P (val))
386 XCHAR_TABLE (table)->contents[c] = (val = MAKE_CATEGORY_SET);
387 SET_CATEGORY_SET (val, category, set_value);
388 return Qnil;
389 }
390
75ec644a 391 SPLIT_CHAR (c, charset, c1, c2);
4ed46869
KH
392
393 /* The top level table. */
cecda314 394 val = XCHAR_TABLE (table)->contents[charset + 128];
ed8ec86d
KH
395 if (CATEGORY_SET_P (val))
396 category_set = val;
397 else if (!SUB_CHAR_TABLE_P (val))
4ed46869 398 {
ed8ec86d 399 category_set = val = MAKE_CATEGORY_SET;
cecda314 400 XCHAR_TABLE (table)->contents[charset + 128] = category_set;
4ed46869 401 }
4ed46869 402
ed8ec86d 403 if (c1 <= 0)
4ed46869
KH
404 {
405 /* Only a charset is specified. */
ed8ec86d
KH
406 if (SUB_CHAR_TABLE_P (val))
407 /* All characters in CHARSET should be the same as for having
408 CATEGORY or not. */
4ed46869
KH
409 modify_lower_category_set (val, category, set_value);
410 else
411 SET_CATEGORY_SET (category_set, category, set_value);
412 return Qnil;
413 }
414
415 /* The second level table. */
ed8ec86d 416 if (!SUB_CHAR_TABLE_P (val))
4ed46869 417 {
ed8ec86d 418 val = make_sub_char_table (Qnil);
cecda314 419 XCHAR_TABLE (table)->contents[charset + 128] = val;
4ed46869
KH
420 /* We must set default category set of CHARSET in `defalt' slot. */
421 XCHAR_TABLE (val)->defalt = category_set;
422 }
423 table = val;
424
425 val = XCHAR_TABLE (table)->contents[c1];
ed8ec86d
KH
426 if (CATEGORY_SET_P (val))
427 category_set = val;
428 else if (!SUB_CHAR_TABLE_P (val))
4ed46869 429 {
ed8ec86d 430 category_set = val = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
4ed46869
KH
431 XCHAR_TABLE (table)->contents[c1] = category_set;
432 }
4ed46869 433
ed8ec86d 434 if (c2 <= 0)
4ed46869 435 {
ed8ec86d 436 if (SUB_CHAR_TABLE_P (val))
4ed46869
KH
437 /* All characters in C1 group of CHARSET should be the same as
438 for CATEGORY. */
439 modify_lower_category_set (val, category, set_value);
440 else
441 SET_CATEGORY_SET (category_set, category, set_value);
442 return Qnil;
443 }
444
445 /* The third (bottom) level table. */
ed8ec86d 446 if (!SUB_CHAR_TABLE_P (val))
4ed46869 447 {
53740deb 448 val = make_sub_char_table (Qnil);
4ed46869
KH
449 XCHAR_TABLE (table)->contents[c1] = val;
450 /* We must set default category set of CHARSET and C1 in
451 `defalt' slot. */
452 XCHAR_TABLE (val)->defalt = category_set;
453 }
454 table = val;
455
456 val = XCHAR_TABLE (table)->contents[c2];
ed8ec86d
KH
457 if (CATEGORY_SET_P (val))
458 category_set = val;
459 else if (!SUB_CHAR_TABLE_P (val))
4ed46869
KH
460 {
461 category_set = Fcopy_sequence (XCHAR_TABLE (table)->defalt);
462 XCHAR_TABLE (table)->contents[c2] = category_set;
463 }
4ed46869
KH
464 else
465 /* This should never happen. */
466 error ("Invalid category table");
467
468 SET_CATEGORY_SET (category_set, category, set_value);
469
470 return Qnil;
471}
472\f
473/* Dump category table to buffer in human-readable format */
474
475static void
476describe_category (value)
477 Lisp_Object value;
478{
479 Lisp_Object mnemonics;
480
481 Findent_to (make_number (16), make_number (1));
482
483 if (NILP (value))
484 {
485 insert_string ("default\n");
486 return;
487 }
488
cfcbf459
RS
489 if (CHAR_TABLE_P (value))
490 {
491 insert_string ("deeper char-table ...\n");
492 return;
493 }
494
4ed46869
KH
495 if (!CATEGORY_SET_P (value))
496 {
497 insert_string ("invalid\n");
498 return;
499 }
500
501 mnemonics = Fcategory_set_mnemonics (value);
115afec3 502 insert_from_string (mnemonics, 0, 0, XSTRING (mnemonics)->size,
fc932ac6 503 STRING_BYTES (XSTRING (mnemonics)), 0);
4ed46869
KH
504 insert_string ("\n");
505 return;
506}
507
508static Lisp_Object
509describe_category_1 (vector)
510 Lisp_Object vector;
511{
512 struct buffer *old = current_buffer;
513 set_buffer_internal (XBUFFER (Vstandard_output));
96439b6a
RS
514 describe_vector (vector, Qnil, describe_category, 0, Qnil, Qnil,
515 (int *)0, 0);
4ed46869
KH
516 {
517 int i;
518 Lisp_Object docs = XCHAR_TABLE (vector)->extras[0];
519 Lisp_Object elt;
520
521 if (!VECTORP (docs) || XVECTOR (docs)->size != 95)
522 {
523 insert_string ("Invalid first extra slot in this char table\n");
524 return Qnil;
525 }
526
527 insert_string ("Meanings of mnemonice characters are:\n");
528 for (i = 0; i < 95; i++)
529 {
530 elt = XVECTOR (docs)->contents[i];
531 if (NILP (elt))
532 continue;
533
534 insert_char (i + 32);
535 insert (": ", 2);
115afec3 536 insert_from_string (elt, 0, 0, XSTRING (elt)->size,
fc932ac6 537 STRING_BYTES (XSTRING (elt)), 0);
4ed46869
KH
538 insert ("\n", 1);
539 }
540 }
541
542 while (! NILP (XCHAR_TABLE (vector)->parent))
543 {
544 vector = XCHAR_TABLE (vector)->parent;
545 insert_string ("\nThe parent category table is:");
96439b6a
RS
546 describe_vector (vector, Qnil, describe_category, 0, Qnil, Qnil,
547 (int *) 0, 0);
4ed46869
KH
548 }
549
550 call0 (intern ("help-mode"));
551 set_buffer_internal (old);
552 return Qnil;
553}
554
ea4943bf 555DEFUN ("describe-categories", Fdescribe_categories, Sdescribe_categories, 0, 0, "",
fdb82f93
PJ
556 doc: /* Describe the category specifications in the current category table.
557The descriptions are inserted in a buffer, which is then displayed. */)
558 ()
4ed46869
KH
559{
560 internal_with_output_to_temp_buffer
561 ("*Help*", describe_category_1, current_buffer->category_table);
562
563 return Qnil;
564}
565\f
566/* Return 1 if there is a word boundary between two word-constituent
567 characters C1 and C2 if they appear in this order, else return 0.
568 Use the macro WORD_BOUNDARY_P instead of calling this function
569 directly. */
570
571int
572word_boundary_p (c1, c2)
573 int c1, c2;
574{
575 Lisp_Object category_set1, category_set2;
576 Lisp_Object tail;
577 int default_result;
578
579 if (CHAR_CHARSET (c1) == CHAR_CHARSET (c2))
580 {
581 tail = Vword_separating_categories;
582 default_result = 0;
583 }
584 else
585 {
586 tail = Vword_combining_categories;
587 default_result = 1;
588 }
589
590 category_set1 = CATEGORY_SET (c1);
591 if (NILP (category_set1))
592 return default_result;
593 category_set2 = CATEGORY_SET (c2);
594 if (NILP (category_set2))
595 return default_result;
596
03699b14 597 for (; CONSP (tail); tail = XCDR (tail))
4ed46869 598 {
03699b14 599 Lisp_Object elt = XCAR (tail);
4ed46869
KH
600
601 if (CONSP (elt)
03699b14
KR
602 && CATEGORYP (XCAR (elt))
603 && CATEGORYP (XCDR (elt))
604 && CATEGORY_MEMBER (XFASTINT (XCAR (elt)), category_set1)
605 && CATEGORY_MEMBER (XFASTINT (XCDR (elt)), category_set2))
4ed46869
KH
606 return !default_result;
607 }
608 return default_result;
609}
610
611\f
dfcf069d 612void
4ed46869
KH
613init_category_once ()
614{
615 /* This has to be done here, before we call Fmake_char_table. */
616 Qcategory_table = intern ("category-table");
617 staticpro (&Qcategory_table);
618
619 /* Intern this now in case it isn't already done.
620 Setting this variable twice is harmless.
621 But don't staticpro it here--that is done in alloc.c. */
622 Qchar_table_extra_slots = intern ("char-table-extra-slots");
623
624 /* Now we are ready to set up this property, so we can
625 create category tables. */
626 Fput (Qcategory_table, Qchar_table_extra_slots, make_number (2));
627
628 Vstandard_category_table = Fmake_char_table (Qcategory_table, Qnil);
629 /* Set a category set which contains nothing to the default. */
630 XCHAR_TABLE (Vstandard_category_table)->defalt = MAKE_CATEGORY_SET;
9da95d53 631 Fset_char_table_extra_slot (Vstandard_category_table, make_number (0),
4ed46869
KH
632 Fmake_vector (make_number (95), Qnil));
633}
634
dfcf069d 635void
4ed46869
KH
636syms_of_category ()
637{
638 Qcategoryp = intern ("categoryp");
639 staticpro (&Qcategoryp);
640 Qcategorysetp = intern ("categorysetp");
641 staticpro (&Qcategorysetp);
642 Qcategory_table_p = intern ("category-table-p");
643 staticpro (&Qcategory_table_p);
644
645 DEFVAR_LISP ("word-combining-categories", &Vword_combining_categories,
fdb82f93
PJ
646 doc: /* List of pair (cons) of categories to determine word boundary.
647
648Emacs treats a sequence of word constituent characters as a single
649word (i.e. finds no word boundary between them) iff they belongs to
650the same charset. But, exceptions are allowed in the following cases.
651
652\(1) The case that characters are in different charsets is controlled
653by the variable `word-combining-categories'.
654
655Emacs finds no word boundary between characters of different charsets
656if they have categories matching some element of this list.
657
658More precisely, if an element of this list is a cons of category CAT1
659and CAT2, and a multibyte character C1 which has CAT1 is followed by
660C2 which has CAT2, there's no word boundary between C1 and C2.
661
662For instance, to tell that ASCII characters and Latin-1 characters can
663form a single word, the element `(?l . ?l)' should be in this list
664because both characters have the category `l' (Latin characters).
665
666\(2) The case that character are in the same charset is controlled by
667the variable `word-separating-categories'.
668
669Emacs find a word boundary between characters of the same charset
670if they have categories matching some element of this list.
671
672More precisely, if an element of this list is a cons of category CAT1
673and CAT2, and a multibyte character C1 which has CAT1 is followed by
674C2 which has CAT2, there's a word boundary between C1 and C2.
675
676For instance, to tell that there's a word boundary between Japanese
677Hiragana and Japanese Kanji (both are in the same charset), the
678element `(?H . ?C) should be in this list. */);
4ed46869
KH
679
680 Vword_combining_categories = Qnil;
681
682 DEFVAR_LISP ("word-separating-categories", &Vword_separating_categories,
fdb82f93
PJ
683 doc: /* List of pair (cons) of categories to determine word boundary.
684See the documentation of the variable `word-combining-categories'. */);
4ed46869
KH
685
686 Vword_separating_categories = Qnil;
687
688 defsubr (&Smake_category_set);
689 defsubr (&Sdefine_category);
690 defsubr (&Scategory_docstring);
691 defsubr (&Sget_unused_category);
692 defsubr (&Scategory_table_p);
693 defsubr (&Scategory_table);
694 defsubr (&Sstandard_category_table);
695 defsubr (&Scopy_category_table);
70414a3d 696 defsubr (&Smake_category_table);
4ed46869
KH
697 defsubr (&Sset_category_table);
698 defsubr (&Schar_category_set);
699 defsubr (&Scategory_set_mnemonics);
700 defsubr (&Smodify_category_entry);
ea4943bf 701 defsubr (&Sdescribe_categories);
4ed46869
KH
702
703 category_table_version = 0;
704}