diff options
| author | Gerd Moellmann | 1999-10-17 12:55:00 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-10-17 12:55:00 +0000 |
| commit | 0daf6e8d79c654bba1e0232be4d802f4087c0ded (patch) | |
| tree | c91ab8c073428b74e20f6e35a771794527422bfc /src/editfns.c | |
| parent | 7b9e346c81aa90f097fa16091865e6c131c163f3 (diff) | |
| download | emacs-0daf6e8d79c654bba1e0232be4d802f4087c0ded.tar.gz emacs-0daf6e8d79c654bba1e0232be4d802f4087c0ded.zip | |
(Fconstrain_to_field): Make sure we don't violate the
argument preconditions of find_before_next_newline in the case
where both ONLY_IN_LINE and ESCAPE_FROM_EDGE are set and OLD_POS
was indeed at the edge.
(text_property_eq, text_property_stickiness): Don't
use initializers for auto variables of type Lisp_Object.
(find_field): Likewise. Use braces around nested ifs.
(Fline_end_position): Store the raw eol in a variable, so that the
final expression doesn't look so ugly.
(Fconstrain_to_field): Doc fix.
(preceding_pos): Renamed from `preceeding_pos'.
(text_property_stickiness, find_field): Call preceding_pos,
not preceeding_pos.
(Ffield_string_no_properties): New function.
(text_property_stickiness, preceeding_pos): New functions.
(Ffield_string): Remove PROPS parameter.
(find_field): Add MERGE_AT_BOUNDARY parameter.
Rewrite to use stickiness of `field' property to resolve
ambiguous cases.
(Ffield_beginning, Ffield_end): Add ESCAPE_FROM_EDGE parameter.
(Fconstrain_to_field): Likewise.
(syms_of_editfns): Init Sfield_string_no_properties.
(Ffield_string, Ferase_field, Ffield_end):
Supply new MERGE_AT_BOUNDARY argument to find_field.
(Fline_beginning_position, Fline_end_position): Supply new
ESCAPE_FROM_EDGE parameter to Fconstrain_to_field.
Pass a value of Qt for the ONLY_IN_LINE argument to
Fconstrain_to_field (only matters if N != 1).
(Fconstrain_to_field): Add get/set-current-point
behavior when NEW_POS is nil.
(find_field): Use XSETFASTINT instead of make_number.
(Qfield): New variable.
(find_field, Ferase_field, Ffield_string,
Ffield_beginning, Ffield_end, Fconstrain_to_field): New functions.
(Fline_beginning_position, Fline_end_position): Constrain to any field.
(make_buffer_string_both): Remove minibuffer-prompt hack.
(syms_of_editfns): Initialize Qfield, and subr entries for
field functions above.
Diffstat (limited to 'src/editfns.c')
| -rw-r--r-- | src/editfns.c | 340 |
1 files changed, 322 insertions, 18 deletions
diff --git a/src/editfns.c b/src/editfns.c index 7b3e5d446c6..a9c2b5f5855 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Lisp functions pertaining to editing. | 1 | /* Lisp functions pertaining to editing. |
| 2 | Copyright (C) 1985,86,87,89,93,94,95,96,97,98 Free Software Foundation, Inc. | 2 | Copyright (C) 1985,86,87,89,93,94,95,96,97,98, 1999 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -276,6 +276,307 @@ If you set the marker not to point anywhere, the buffer will have no mark.") | |||
| 276 | return current_buffer->mark; | 276 | return current_buffer->mark; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | /* Returns the position before POS in the current buffer. POS must not | ||
| 280 | be at the beginning of the buffer. */ | ||
| 281 | static Lisp_Object | ||
| 282 | preceding_pos (int pos) | ||
| 283 | { | ||
| 284 | int pos_byte = CHAR_TO_BYTE (pos); | ||
| 285 | |||
| 286 | /* Decrement POS_BYTE (is all this cruft really necessary?). */ | ||
| 287 | if (NILP (current_buffer->enable_multibyte_characters)) | ||
| 288 | pos_byte--; | ||
| 289 | else | ||
| 290 | DEC_POS (pos_byte); | ||
| 291 | |||
| 292 | return make_number (BYTE_TO_CHAR (pos_byte)); | ||
| 293 | } | ||
| 294 | |||
| 295 | /* Returns true if POS1 and POS2 have the same value for text property PROP. */ | ||
| 296 | static int | ||
| 297 | text_property_eq (prop, pos1, pos2) | ||
| 298 | Lisp_Object prop; | ||
| 299 | Lisp_Object pos1, pos2; | ||
| 300 | { | ||
| 301 | Lisp_Object pval1, pval2; | ||
| 302 | |||
| 303 | pval1 = Fget_text_property (pos1, prop, Qnil); | ||
| 304 | pval2 = Fget_text_property (pos2, prop, Qnil); | ||
| 305 | |||
| 306 | return EQ (pval1, pval2); | ||
| 307 | } | ||
| 308 | |||
| 309 | /* Returns the direction that the text-property PROP would be inherited | ||
| 310 | by any new text inserted at POS: 1 if it would be inherited from POS, | ||
| 311 | -1 if it would be inherited from POS-1, and 0 if from neither. */ | ||
| 312 | static int | ||
| 313 | text_property_stickiness (prop, pos) | ||
| 314 | Lisp_Object prop; | ||
| 315 | Lisp_Object pos; | ||
| 316 | { | ||
| 317 | Lisp_Object front_sticky; | ||
| 318 | |||
| 319 | if (PT > BEGV) | ||
| 320 | /* Consider previous position. */ | ||
| 321 | { | ||
| 322 | Lisp_Object prev_pos, rear_non_sticky; | ||
| 323 | |||
| 324 | prev_pos = preceding_pos (pos); | ||
| 325 | rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil); | ||
| 326 | |||
| 327 | if (EQ (rear_non_sticky, Qnil) | ||
| 328 | || (CONSP (rear_non_sticky) | ||
| 329 | && !Fmemq (prop, rear_non_sticky))) | ||
| 330 | /* PROP is not rear-non-sticky, and since this takes precedence over | ||
| 331 | any front-stickiness, that must be the answer. */ | ||
| 332 | return -1; | ||
| 333 | } | ||
| 334 | |||
| 335 | /* Consider current position. */ | ||
| 336 | front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil); | ||
| 337 | |||
| 338 | if (EQ (front_sticky, Qt) | ||
| 339 | || (CONSP (front_sticky) | ||
| 340 | && Fmemq (prop, front_sticky))) | ||
| 341 | /* PROP is front-sticky. */ | ||
| 342 | return 1; | ||
| 343 | |||
| 344 | /* PROP is not sticky at all. */ | ||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 348 | /* Name for the text property we use to distinguish fields. */ | ||
| 349 | Lisp_Object Qfield; | ||
| 350 | |||
| 351 | /* Returns the field surrounding POS in *BEG and *END; an | ||
| 352 | `field' is a region of text with the same `field' property. | ||
| 353 | If POS is nil, the position of the current buffer's point is used. | ||
| 354 | If MERGE_AT_BOUNDARY is true, then if POS is at the very first | ||
| 355 | position of a field, then the beginning of the previous field | ||
| 356 | is returned instead of the beginning of POS's field (since the end of | ||
| 357 | a field is actually also the beginning of the next input | ||
| 358 | field, this behavior is sometimes useful). BEG or END may be 0, in | ||
| 359 | which case the corresponding value is not returned. */ | ||
| 360 | void | ||
| 361 | find_field (pos, merge_at_boundary, beg, end) | ||
| 362 | Lisp_Object pos; | ||
| 363 | Lisp_Object merge_at_boundary; | ||
| 364 | int *beg, *end; | ||
| 365 | { | ||
| 366 | /* If POS is at the edge of a field, then -1 or 1 depending on | ||
| 367 | whether it should be considered as the beginning of the following | ||
| 368 | field, or the end of the previous field, respectively. If POS is | ||
| 369 | not at a field-boundary, then STICKINESS is 0. */ | ||
| 370 | int stickiness = 0; | ||
| 371 | |||
| 372 | if (NILP (pos)) | ||
| 373 | XSETFASTINT (pos, PT); | ||
| 374 | else | ||
| 375 | CHECK_NUMBER_COERCE_MARKER (pos, 0); | ||
| 376 | |||
| 377 | if (NILP (merge_at_boundary) && XFASTINT (pos) > BEGV) | ||
| 378 | /* See if we need to handle the case where POS is at beginning of a | ||
| 379 | field, which can also be interpreted as the end of the previous | ||
| 380 | field. We decide which one by seeing which field the `field' | ||
| 381 | property sticks to. The case where if MERGE_AT_BOUNDARY is | ||
| 382 | non-nil (see function comment) is actually the more natural one; | ||
| 383 | then we avoid treating the beginning of a field specially. */ | ||
| 384 | { | ||
| 385 | /* First see if POS is actually *at* a boundary. */ | ||
| 386 | Lisp_Object after_field, before_field; | ||
| 387 | |||
| 388 | after_field = Fget_text_property (pos, Qfield, Qnil); | ||
| 389 | before_field = Fget_text_property (preceding_pos (pos), Qfield, Qnil); | ||
| 390 | |||
| 391 | if (! EQ (after_field, before_field)) | ||
| 392 | /* We are at a boundary, see which direction is inclusive. */ | ||
| 393 | { | ||
| 394 | stickiness = text_property_stickiness (Qfield, pos); | ||
| 395 | |||
| 396 | if (stickiness == 0) | ||
| 397 | /* STICKINESS == 0 means that any inserted text will get a | ||
| 398 | `field' text-property of nil, so check to see if that | ||
| 399 | matches either of the adjacent characters (this being a | ||
| 400 | kind of `stickiness by default'). */ | ||
| 401 | { | ||
| 402 | if (NILP (before_field)) | ||
| 403 | stickiness = -1; /* Sticks to the left. */ | ||
| 404 | else if (NILP (after_field)) | ||
| 405 | stickiness = 1; /* Sticks to the right. */ | ||
| 406 | } | ||
| 407 | } | ||
| 408 | } | ||
| 409 | |||
| 410 | if (beg) | ||
| 411 | { | ||
| 412 | if (stickiness > 0) | ||
| 413 | /* POS is at the edge of a field, and we should consider it as | ||
| 414 | the beginning of the following field. */ | ||
| 415 | *beg = XFASTINT (pos); | ||
| 416 | else | ||
| 417 | /* Find the previous field boundary. */ | ||
| 418 | { | ||
| 419 | Lisp_Object prev; | ||
| 420 | prev = Fprevious_single_property_change (pos, Qfield, Qnil, Qnil); | ||
| 421 | *beg = NILP(prev) ? BEGV : XFASTINT (prev); | ||
| 422 | } | ||
| 423 | } | ||
| 424 | |||
| 425 | if (end) | ||
| 426 | { | ||
| 427 | if (stickiness < 0) | ||
| 428 | /* POS is at the edge of a field, and we should consider it as | ||
| 429 | the end of the previous field. */ | ||
| 430 | *end = XFASTINT (pos); | ||
| 431 | else | ||
| 432 | /* Find the next field boundary. */ | ||
| 433 | { | ||
| 434 | Lisp_Object next; | ||
| 435 | next = Fnext_single_property_change (pos, Qfield, Qnil, Qnil); | ||
| 436 | *end = NILP(next) ? ZV : XFASTINT (next); | ||
| 437 | } | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | DEFUN ("erase-field", Ferase_field, Serase_field, 0, 1, "d", | ||
| 442 | "Erases the field surrounding POS.\n\ | ||
| 443 | A field is a region of text with the same `field' property.\n\ | ||
| 444 | If POS is nil, the position of the current buffer's point is used.") | ||
| 445 | (pos) | ||
| 446 | Lisp_Object pos; | ||
| 447 | { | ||
| 448 | int beg, end; | ||
| 449 | find_field (pos, Qnil, &beg, &end); | ||
| 450 | if (beg != end) | ||
| 451 | del_range (beg, end); | ||
| 452 | } | ||
| 453 | |||
| 454 | DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0, | ||
| 455 | "Return the contents of the field surrounding POS as a string.\n\ | ||
| 456 | A field is a region of text with the same `field' property.\n\ | ||
| 457 | If POS is nil, the position of the current buffer's point is used.") | ||
| 458 | (pos) | ||
| 459 | Lisp_Object pos; | ||
| 460 | { | ||
| 461 | int beg, end; | ||
| 462 | find_field (pos, Qnil, &beg, &end); | ||
| 463 | return make_buffer_string (beg, end, 1); | ||
| 464 | } | ||
| 465 | |||
| 466 | DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0, | ||
| 467 | "Return the contents of the field around POS, without text-properties.\n\ | ||
| 468 | A field is a region of text with the same `field' property.\n\ | ||
| 469 | If POS is nil, the position of the current buffer's point is used.") | ||
| 470 | (pos) | ||
| 471 | Lisp_Object pos; | ||
| 472 | { | ||
| 473 | int beg, end; | ||
| 474 | find_field (pos, Qnil, &beg, &end); | ||
| 475 | return make_buffer_string (beg, end, 0); | ||
| 476 | } | ||
| 477 | |||
| 478 | DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0, | ||
| 479 | "Return the beginning of the field surrounding POS.\n\ | ||
| 480 | A field is a region of text with the same `field' property.\n\ | ||
| 481 | If POS is nil, the position of the current buffer's point is used.\n\ | ||
| 482 | If ESCAPE-FROM-EDGE is non-nil and POS is already at beginning of an\n\ | ||
| 483 | field, then the beginning of the *previous* field is returned.") | ||
| 484 | (pos, escape_from_edge) | ||
| 485 | Lisp_Object pos, escape_from_edge; | ||
| 486 | { | ||
| 487 | int beg; | ||
| 488 | find_field (pos, escape_from_edge, &beg, 0); | ||
| 489 | return make_number (beg); | ||
| 490 | } | ||
| 491 | |||
| 492 | DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0, | ||
| 493 | "Return the end of the field surrounding POS.\n\ | ||
| 494 | A field is a region of text with the same `field' property.\n\ | ||
| 495 | If POS is nil, the position of the current buffer's point is used.\n\ | ||
| 496 | If ESCAPE-FROM-EDGE is non-nil and POS is already at end of a field,\n\ | ||
| 497 | then the end of the *following* field is returned.") | ||
| 498 | (pos, escape_from_edge) | ||
| 499 | Lisp_Object pos, escape_from_edge; | ||
| 500 | { | ||
| 501 | int end; | ||
| 502 | find_field (pos, escape_from_edge, 0, &end); | ||
| 503 | return make_number (end); | ||
| 504 | } | ||
| 505 | |||
| 506 | DEFUN ("constrain-to-field", Fconstrain_to_field, Sconstrain_to_field, 2, 4, 0, | ||
| 507 | "Return the position closest to NEW-POS that is in the same field as OLD-POS.\n\ | ||
| 508 | A field is a region of text with the same `field' property.\n\ | ||
| 509 | If NEW-POS is nil, then the current point is used instead, and set to the\n\ | ||
| 510 | constrained position if that is is different.\n\ | ||
| 511 | \n\ | ||
| 512 | If OLD-POS is at the boundary of two fields, then the allowable\n\ | ||
| 513 | positions for NEW-POS depends on the value of the optional argument\n\ | ||
| 514 | ESCAPE-FROM-EDGE: If ESCAPE-FROM-EDGE is nil, then NEW-POS is\n\ | ||
| 515 | constrained to the field that has the same `field' text-property\n\ | ||
| 516 | as any new characters inserted at OLD-POS, whereas if ESCAPE-FROM-EDGE\n\ | ||
| 517 | is non-nil, NEW-POS is constrained to the union of the two adjacent\n\ | ||
| 518 | fields.\n\ | ||
| 519 | \n\ | ||
| 520 | If the optional argument ONLY-IN-LINE is non-nil and constraining\n\ | ||
| 521 | NEW-POS would move it to a different line, NEW-POS is returned\n\ | ||
| 522 | unconstrained. This useful for commands that move by line, like\n\ | ||
| 523 | \\[next-line] or \\[beginning-of-line], which should generally respect field boundaries\n\ | ||
| 524 | only in the case where they can still move to the right line.") | ||
| 525 | (new_pos, old_pos, escape_from_edge, only_in_line) | ||
| 526 | Lisp_Object new_pos, old_pos, escape_from_edge, only_in_line; | ||
| 527 | { | ||
| 528 | /* If non-zero, then the original point, before re-positioning. */ | ||
| 529 | int orig_point = 0; | ||
| 530 | |||
| 531 | if (NILP (new_pos)) | ||
| 532 | /* Use the current point, and afterwards, set it. */ | ||
| 533 | { | ||
| 534 | orig_point = PT; | ||
| 535 | XSETFASTINT (new_pos, PT); | ||
| 536 | } | ||
| 537 | |||
| 538 | if (!EQ (new_pos, old_pos) && !text_property_eq (Qfield, new_pos, old_pos)) | ||
| 539 | /* NEW_POS is not within the same field as OLD_POS; try to | ||
| 540 | move NEW_POS so that it is. */ | ||
| 541 | { | ||
| 542 | int fwd; | ||
| 543 | Lisp_Object field_bound; | ||
| 544 | |||
| 545 | CHECK_NUMBER_COERCE_MARKER (new_pos, 0); | ||
| 546 | CHECK_NUMBER_COERCE_MARKER (old_pos, 0); | ||
| 547 | |||
| 548 | fwd = (XFASTINT (new_pos) > XFASTINT (old_pos)); | ||
| 549 | |||
| 550 | if (fwd) | ||
| 551 | field_bound = Ffield_end (old_pos, escape_from_edge); | ||
| 552 | else | ||
| 553 | field_bound = Ffield_beginning (old_pos, escape_from_edge); | ||
| 554 | |||
| 555 | if (/* If ONLY_IN_LINE is non-nil, we only constrain NEW_POS if doing | ||
| 556 | so would remain within the same line. */ | ||
| 557 | NILP (only_in_line) | ||
| 558 | /* In that case, see if ESCAPE_FROM_EDGE caused FIELD_BOUND | ||
| 559 | to jump to the other side of NEW_POS, which would mean | ||
| 560 | that NEW_POS is already acceptable, and that we don't | ||
| 561 | have to do the line-check. */ | ||
| 562 | || ((XFASTINT (field_bound) < XFASTINT (new_pos)) ? !fwd : fwd) | ||
| 563 | /* If not, see if there's no newline intervening between | ||
| 564 | NEW_POS and FIELD_BOUND. */ | ||
| 565 | || (find_before_next_newline (XFASTINT (new_pos), | ||
| 566 | XFASTINT (field_bound), | ||
| 567 | fwd ? -1 : 1) | ||
| 568 | == XFASTINT (field_bound))) | ||
| 569 | /* Constrain NEW_POS to FIELD_BOUND. */ | ||
| 570 | new_pos = field_bound; | ||
| 571 | |||
| 572 | if (orig_point && XFASTINT (new_pos) != orig_point) | ||
| 573 | /* The NEW_POS argument was originally nil, so automatically set PT. */ | ||
| 574 | SET_PT (XFASTINT (new_pos)); | ||
| 575 | } | ||
| 576 | |||
| 577 | return new_pos; | ||
| 578 | } | ||
| 579 | |||
| 279 | DEFUN ("line-beginning-position", Fline_beginning_position, Sline_beginning_position, | 580 | DEFUN ("line-beginning-position", Fline_beginning_position, Sline_beginning_position, |
| 280 | 0, 1, 0, | 581 | 0, 1, 0, |
| 281 | "Return the character position of the first character on the current line.\n\ | 582 | "Return the character position of the first character on the current line.\n\ |
| @@ -300,14 +601,10 @@ the return value is never within the prompt either.") | |||
| 300 | Fforward_line (make_number (XINT (n) - 1)); | 601 | Fforward_line (make_number (XINT (n) - 1)); |
| 301 | end = PT; | 602 | end = PT; |
| 302 | 603 | ||
| 303 | if (INTEGERP (current_buffer->prompt_end_charpos) | ||
| 304 | && orig >= XFASTINT (current_buffer->prompt_end_charpos) | ||
| 305 | && end < XFASTINT (current_buffer->prompt_end_charpos)) | ||
| 306 | end = XFASTINT (current_buffer->prompt_end_charpos); | ||
| 307 | |||
| 308 | SET_PT_BOTH (orig, orig_byte); | 604 | SET_PT_BOTH (orig, orig_byte); |
| 309 | 605 | ||
| 310 | return make_number (end); | 606 | /* Return END constrained to the current input field. */ |
| 607 | return Fconstrain_to_field (make_number (end), make_number (orig), Qnil, Qt); | ||
| 311 | } | 608 | } |
| 312 | 609 | ||
| 313 | DEFUN ("line-end-position", Fline_end_position, Sline_end_position, | 610 | DEFUN ("line-end-position", Fline_end_position, Sline_end_position, |
| @@ -319,13 +616,19 @@ This function does not move point.") | |||
| 319 | (n) | 616 | (n) |
| 320 | Lisp_Object n; | 617 | Lisp_Object n; |
| 321 | { | 618 | { |
| 619 | int end_pos; | ||
| 620 | register int orig = PT; | ||
| 621 | |||
| 322 | if (NILP (n)) | 622 | if (NILP (n)) |
| 323 | XSETFASTINT (n, 1); | 623 | XSETFASTINT (n, 1); |
| 324 | else | 624 | else |
| 325 | CHECK_NUMBER (n, 0); | 625 | CHECK_NUMBER (n, 0); |
| 326 | 626 | ||
| 327 | return make_number (find_before_next_newline | 627 | end_pos = find_before_next_newline (orig, 0, XINT (n) - (XINT (n) <= 0)); |
| 328 | (PT, 0, XINT (n) - (XINT (n) <= 0))); | 628 | |
| 629 | /* Return END_POS constrained to the current input field. */ | ||
| 630 | return | ||
| 631 | Fconstrain_to_field (make_number (end_pos), make_number (orig), Qnil, Qt); | ||
| 329 | } | 632 | } |
| 330 | 633 | ||
| 331 | Lisp_Object | 634 | Lisp_Object |
| @@ -1724,15 +2027,7 @@ of the buffer. If in a mini-buffer, don't include the prompt in the\n\ | |||
| 1724 | string returned.") | 2027 | string returned.") |
| 1725 | () | 2028 | () |
| 1726 | { | 2029 | { |
| 1727 | int start = BEGV; | 2030 | return make_buffer_string (BEGV, ZV, 1); |
| 1728 | |||
| 1729 | if (INTEGERP (current_buffer->prompt_end_charpos)) | ||
| 1730 | { | ||
| 1731 | int len = XFASTINT (current_buffer->prompt_end_charpos); | ||
| 1732 | start = min (ZV, max (len, start)); | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | return make_buffer_string (start, ZV, 1); | ||
| 1736 | } | 2031 | } |
| 1737 | 2032 | ||
| 1738 | DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring, | 2033 | DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring, |
| @@ -3419,6 +3714,15 @@ functions if all the text being accessed has this property."); | |||
| 3419 | defsubr (&Sregion_beginning); | 3714 | defsubr (&Sregion_beginning); |
| 3420 | defsubr (&Sregion_end); | 3715 | defsubr (&Sregion_end); |
| 3421 | 3716 | ||
| 3717 | staticpro (&Qfield); | ||
| 3718 | Qfield = intern ("field"); | ||
| 3719 | defsubr (&Sfield_beginning); | ||
| 3720 | defsubr (&Sfield_end); | ||
| 3721 | defsubr (&Sfield_string); | ||
| 3722 | defsubr (&Sfield_string_no_properties); | ||
| 3723 | defsubr (&Serase_field); | ||
| 3724 | defsubr (&Sconstrain_to_field); | ||
| 3725 | |||
| 3422 | defsubr (&Sline_beginning_position); | 3726 | defsubr (&Sline_beginning_position); |
| 3423 | defsubr (&Sline_end_position); | 3727 | defsubr (&Sline_end_position); |
| 3424 | 3728 | ||