diff options
| author | Richard M. Stallman | 1999-11-09 18:42:28 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1999-11-09 18:42:28 +0000 |
| commit | a3caef99aeab0951b80cfee91b4687a44d9bc24d (patch) | |
| tree | 269ec81aa3791a1aab92362ff9e872ec7b39bd59 | |
| parent | 94886883f00692901b81020893509a6f1b3ec596 (diff) | |
| download | emacs-a3caef99aeab0951b80cfee91b4687a44d9bc24d.tar.gz emacs-a3caef99aeab0951b80cfee91b4687a44d9bc24d.zip | |
(Fline_beginning_position): If N is not 1,
pass t to Fconstrain_to_field for ESCAPE-FROM-EDGE.
(preceding_pos): Function deleted.
(text_property_stickiness): Decrement POS directly.
Fix a confusion that used PT instead of POS.
(find_field): Properly handle the case
of a field boundary where `field' inherits from neither side.
(Ffield_beginning, Ffield_end): Doc fixes.
(Ferase_field, Ffield_string, Ffield_string_no_properties): Doc fixes.
| -rw-r--r-- | src/editfns.c | 117 |
1 files changed, 57 insertions, 60 deletions
diff --git a/src/editfns.c b/src/editfns.c index 89db0a1bd3c..d648fd24f7d 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -272,23 +272,9 @@ If you set the marker not to point anywhere, the buffer will have no mark.") | |||
| 272 | return current_buffer->mark; | 272 | return current_buffer->mark; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | /* Returns the position before POS in the current buffer. POS must not | 275 | /* Return nonzero if POS1 and POS2 have the same value |
| 276 | be at the beginning of the buffer. */ | 276 | for the text property PROP. */ |
| 277 | static Lisp_Object | ||
| 278 | preceding_pos (int pos) | ||
| 279 | { | ||
| 280 | int pos_byte = CHAR_TO_BYTE (pos); | ||
| 281 | |||
| 282 | /* Decrement POS_BYTE (is all this cruft really necessary?). */ | ||
| 283 | if (NILP (current_buffer->enable_multibyte_characters)) | ||
| 284 | pos_byte--; | ||
| 285 | else | ||
| 286 | DEC_POS (pos_byte); | ||
| 287 | 277 | ||
| 288 | return make_number (BYTE_TO_CHAR (pos_byte)); | ||
| 289 | } | ||
| 290 | |||
| 291 | /* Returns true if POS1 and POS2 have the same value for text property PROP. */ | ||
| 292 | static int | 278 | static int |
| 293 | text_property_eq (prop, pos1, pos2) | 279 | text_property_eq (prop, pos1, pos2) |
| 294 | Lisp_Object prop; | 280 | Lisp_Object prop; |
| @@ -302,9 +288,11 @@ text_property_eq (prop, pos1, pos2) | |||
| 302 | return EQ (pval1, pval2); | 288 | return EQ (pval1, pval2); |
| 303 | } | 289 | } |
| 304 | 290 | ||
| 305 | /* Returns the direction that the text-property PROP would be inherited | 291 | /* Return the direction from which the text-property PROP would be |
| 306 | by any new text inserted at POS: 1 if it would be inherited from POS, | 292 | inherited by any new text inserted at POS: 1 if it would be |
| 307 | -1 if it would be inherited from POS-1, and 0 if from neither. */ | 293 | inherited from the char after POS, -1 if it would be inherited from |
| 294 | the char before POS, and 0 if from neither. */ | ||
| 295 | |||
| 308 | static int | 296 | static int |
| 309 | text_property_stickiness (prop, pos) | 297 | text_property_stickiness (prop, pos) |
| 310 | Lisp_Object prop; | 298 | Lisp_Object prop; |
| @@ -312,58 +300,60 @@ text_property_stickiness (prop, pos) | |||
| 312 | { | 300 | { |
| 313 | Lisp_Object front_sticky; | 301 | Lisp_Object front_sticky; |
| 314 | 302 | ||
| 315 | if (PT > BEGV) | 303 | if (XINT (pos) > BEGV) |
| 316 | /* Consider previous position. */ | 304 | /* Consider previous character. */ |
| 317 | { | 305 | { |
| 318 | Lisp_Object prev_pos, rear_non_sticky; | 306 | Lisp_Object prev_pos, rear_non_sticky; |
| 319 | 307 | ||
| 320 | prev_pos = preceding_pos (pos); | 308 | prev_pos = make_number (XINT (pos) - 1); |
| 321 | rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil); | 309 | rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil); |
| 322 | 310 | ||
| 323 | if (EQ (rear_non_sticky, Qnil) | 311 | if (EQ (rear_non_sticky, Qnil) |
| 324 | || (CONSP (rear_non_sticky) | 312 | || (CONSP (rear_non_sticky) |
| 325 | && !Fmemq (prop, rear_non_sticky))) | 313 | && !Fmemq (prop, rear_non_sticky))) |
| 326 | /* PROP is not rear-non-sticky, and since this takes precedence over | 314 | /* PROP is not rear-non-sticky, and since this takes precedence over |
| 327 | any front-stickiness, that must be the answer. */ | 315 | any front-stickiness, PROP is inherited from before. */ |
| 328 | return -1; | 316 | return -1; |
| 329 | } | 317 | } |
| 330 | 318 | ||
| 331 | /* Consider current position. */ | 319 | /* Consider following character. */ |
| 332 | front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil); | 320 | front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil); |
| 333 | 321 | ||
| 334 | if (EQ (front_sticky, Qt) | 322 | if (EQ (front_sticky, Qt) |
| 335 | || (CONSP (front_sticky) | 323 | || (CONSP (front_sticky) |
| 336 | && Fmemq (prop, front_sticky))) | 324 | && Fmemq (prop, front_sticky))) |
| 337 | /* PROP is front-sticky. */ | 325 | /* PROP is inherited from after. */ |
| 338 | return 1; | 326 | return 1; |
| 339 | 327 | ||
| 340 | /* PROP is not sticky at all. */ | 328 | /* PROP is not inherited from either side. */ |
| 341 | return 0; | 329 | return 0; |
| 342 | } | 330 | } |
| 343 | 331 | ||
| 344 | /* Name for the text property we use to distinguish fields. */ | 332 | /* Symbol for the text property used to mark fields. */ |
| 345 | Lisp_Object Qfield; | 333 | Lisp_Object Qfield; |
| 346 | 334 | ||
| 347 | /* Returns the field surrounding POS in *BEG and *END; an | 335 | /* Find the field surrounding POS in *BEG and *END. If POS is nil, |
| 348 | `field' is a region of text with the same `field' property. | 336 | the value of point is used instead. |
| 349 | If POS is nil, the position of the current buffer's point is used. | 337 | |
| 350 | If MERGE_AT_BOUNDARY is true, then if POS is at the very first | 338 | If MERGE_AT_BOUNDARY is nonzero, then if POS is at the very first |
| 351 | position of a field, then the beginning of the previous field | 339 | position of a field, then the beginning of the previous field |
| 352 | is returned instead of the beginning of POS's field (since the end of | 340 | is returned instead of the beginning of POS's field (since the end of |
| 353 | a field is actually also the beginning of the next input | 341 | a field is actually also the beginning of the next input |
| 354 | field, this behavior is sometimes useful). BEG or END may be 0, in | 342 | field, this behavior is sometimes useful). |
| 355 | which case the corresponding value is not returned. */ | 343 | |
| 344 | Either BEG or END may be 0, in which case the corresponding value | ||
| 345 | is not stored. */ | ||
| 346 | |||
| 356 | void | 347 | void |
| 357 | find_field (pos, merge_at_boundary, beg, end) | 348 | find_field (pos, merge_at_boundary, beg, end) |
| 358 | Lisp_Object pos; | 349 | Lisp_Object pos; |
| 359 | Lisp_Object merge_at_boundary; | 350 | Lisp_Object merge_at_boundary; |
| 360 | int *beg, *end; | 351 | int *beg, *end; |
| 361 | { | 352 | { |
| 362 | /* If POS is at the edge of a field, then -1 or 1 depending on | 353 | /* 1 if POS counts as the start of a field. */ |
| 363 | whether it should be considered as the beginning of the following | 354 | int at_field_start = 0; |
| 364 | field, or the end of the previous field, respectively. If POS is | 355 | /* 1 if POS counts as the end of a field. */ |
| 365 | not at a field-boundary, then STICKINESS is 0. */ | 356 | int at_field_end = 0; |
| 366 | int stickiness = 0; | ||
| 367 | 357 | ||
| 368 | if (NILP (pos)) | 358 | if (NILP (pos)) |
| 369 | XSETFASTINT (pos, PT); | 359 | XSETFASTINT (pos, PT); |
| @@ -382,30 +372,35 @@ find_field (pos, merge_at_boundary, beg, end) | |||
| 382 | Lisp_Object after_field, before_field; | 372 | Lisp_Object after_field, before_field; |
| 383 | 373 | ||
| 384 | after_field = Fget_text_property (pos, Qfield, Qnil); | 374 | after_field = Fget_text_property (pos, Qfield, Qnil); |
| 385 | before_field = Fget_text_property (preceding_pos (pos), Qfield, Qnil); | 375 | before_field = Fget_text_property (make_number (XINT (pos) - 1), |
| 376 | Qfield, Qnil); | ||
| 386 | 377 | ||
| 387 | if (! EQ (after_field, before_field)) | 378 | if (! EQ (after_field, before_field)) |
| 388 | /* We are at a boundary, see which direction is inclusive. */ | 379 | /* We are at a boundary, see which direction is inclusive. */ |
| 389 | { | 380 | { |
| 390 | stickiness = text_property_stickiness (Qfield, pos); | 381 | int stickiness = text_property_stickiness (Qfield, pos); |
| 391 | 382 | ||
| 392 | if (stickiness == 0) | 383 | if (stickiness > 0) |
| 384 | at_field_start = 1; | ||
| 385 | else if (stickiness < 0) | ||
| 386 | at_field_end = 1; | ||
| 387 | else | ||
| 393 | /* STICKINESS == 0 means that any inserted text will get a | 388 | /* STICKINESS == 0 means that any inserted text will get a |
| 394 | `field' text-property of nil, so check to see if that | 389 | `field' text-property of nil, so check to see if that |
| 395 | matches either of the adjacent characters (this being a | 390 | matches either of the adjacent characters (this being a |
| 396 | kind of `stickiness by default'). */ | 391 | kind of "stickiness by default"). */ |
| 397 | { | 392 | { |
| 398 | if (NILP (before_field)) | 393 | if (NILP (before_field)) |
| 399 | stickiness = -1; /* Sticks to the left. */ | 394 | at_field_end = 1; /* Sticks to the left. */ |
| 400 | else if (NILP (after_field)) | 395 | else if (NILP (after_field)) |
| 401 | stickiness = 1; /* Sticks to the right. */ | 396 | at_field_start = 1; /* Sticks to the right. */ |
| 402 | } | 397 | } |
| 403 | } | 398 | } |
| 404 | } | 399 | } |
| 405 | 400 | ||
| 406 | if (beg) | 401 | if (beg) |
| 407 | { | 402 | { |
| 408 | if (stickiness > 0) | 403 | if (at_field_start) |
| 409 | /* POS is at the edge of a field, and we should consider it as | 404 | /* POS is at the edge of a field, and we should consider it as |
| 410 | the beginning of the following field. */ | 405 | the beginning of the following field. */ |
| 411 | *beg = XFASTINT (pos); | 406 | *beg = XFASTINT (pos); |
| @@ -414,13 +409,13 @@ find_field (pos, merge_at_boundary, beg, end) | |||
| 414 | { | 409 | { |
| 415 | Lisp_Object prev; | 410 | Lisp_Object prev; |
| 416 | prev = Fprevious_single_property_change (pos, Qfield, Qnil, Qnil); | 411 | prev = Fprevious_single_property_change (pos, Qfield, Qnil, Qnil); |
| 417 | *beg = NILP(prev) ? BEGV : XFASTINT (prev); | 412 | *beg = NILP (prev) ? BEGV : XFASTINT (prev); |
| 418 | } | 413 | } |
| 419 | } | 414 | } |
| 420 | 415 | ||
| 421 | if (end) | 416 | if (end) |
| 422 | { | 417 | { |
| 423 | if (stickiness < 0) | 418 | if (at_field_end) |
| 424 | /* POS is at the edge of a field, and we should consider it as | 419 | /* POS is at the edge of a field, and we should consider it as |
| 425 | the end of the previous field. */ | 420 | the end of the previous field. */ |
| 426 | *end = XFASTINT (pos); | 421 | *end = XFASTINT (pos); |
| @@ -429,7 +424,7 @@ find_field (pos, merge_at_boundary, beg, end) | |||
| 429 | { | 424 | { |
| 430 | Lisp_Object next; | 425 | Lisp_Object next; |
| 431 | next = Fnext_single_property_change (pos, Qfield, Qnil, Qnil); | 426 | next = Fnext_single_property_change (pos, Qfield, Qnil, Qnil); |
| 432 | *end = NILP(next) ? ZV : XFASTINT (next); | 427 | *end = NILP (next) ? ZV : XFASTINT (next); |
| 433 | } | 428 | } |
| 434 | } | 429 | } |
| 435 | } | 430 | } |
| @@ -437,7 +432,7 @@ find_field (pos, merge_at_boundary, beg, end) | |||
| 437 | DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, "d", | 432 | DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, "d", |
| 438 | "Delete the field surrounding POS.\n\ | 433 | "Delete the field surrounding POS.\n\ |
| 439 | A field is a region of text with the same `field' property.\n\ | 434 | A field is a region of text with the same `field' property.\n\ |
| 440 | If POS is nil, the position of the current buffer's point is used.") | 435 | If POS is nil, the value of point is used for POS.") |
| 441 | (pos) | 436 | (pos) |
| 442 | Lisp_Object pos; | 437 | Lisp_Object pos; |
| 443 | { | 438 | { |
| @@ -450,7 +445,7 @@ If POS is nil, the position of the current buffer's point is used.") | |||
| 450 | DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0, | 445 | DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0, |
| 451 | "Return the contents of the field surrounding POS as a string.\n\ | 446 | "Return the contents of the field surrounding POS as a string.\n\ |
| 452 | A field is a region of text with the same `field' property.\n\ | 447 | A field is a region of text with the same `field' property.\n\ |
| 453 | If POS is nil, the position of the current buffer's point is used.") | 448 | If POS is nil, the value of point is used for POS.") |
| 454 | (pos) | 449 | (pos) |
| 455 | Lisp_Object pos; | 450 | Lisp_Object pos; |
| 456 | { | 451 | { |
| @@ -462,7 +457,7 @@ If POS is nil, the position of the current buffer's point is used.") | |||
| 462 | DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0, | 457 | DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0, |
| 463 | "Return the contents of the field around POS, without text-properties.\n\ | 458 | "Return the contents of the field around POS, without text-properties.\n\ |
| 464 | A field is a region of text with the same `field' property.\n\ | 459 | A field is a region of text with the same `field' property.\n\ |
| 465 | If POS is nil, the position of the current buffer's point is used.") | 460 | If POS is nil, the value of point is used for POS.") |
| 466 | (pos) | 461 | (pos) |
| 467 | Lisp_Object pos; | 462 | Lisp_Object pos; |
| 468 | { | 463 | { |
| @@ -474,8 +469,8 @@ If POS is nil, the position of the current buffer's point is used.") | |||
| 474 | DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0, | 469 | DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0, |
| 475 | "Return the beginning of the field surrounding POS.\n\ | 470 | "Return the beginning of the field surrounding POS.\n\ |
| 476 | A field is a region of text with the same `field' property.\n\ | 471 | A field is a region of text with the same `field' property.\n\ |
| 477 | If POS is nil, the position of the current buffer's point is used.\n\ | 472 | If POS is nil, the value of point is used for POS.\n\ |
| 478 | If ESCAPE-FROM-EDGE is non-nil and POS is already at beginning of an\n\ | 473 | If ESCAPE-FROM-EDGE is non-nil and POS is at the beginning of its\n\ |
| 479 | field, then the beginning of the *previous* field is returned.") | 474 | field, then the beginning of the *previous* field is returned.") |
| 480 | (pos, escape_from_edge) | 475 | (pos, escape_from_edge) |
| 481 | Lisp_Object pos, escape_from_edge; | 476 | Lisp_Object pos, escape_from_edge; |
| @@ -488,8 +483,8 @@ field, then the beginning of the *previous* field is returned.") | |||
| 488 | DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0, | 483 | DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0, |
| 489 | "Return the end of the field surrounding POS.\n\ | 484 | "Return the end of the field surrounding POS.\n\ |
| 490 | A field is a region of text with the same `field' property.\n\ | 485 | A field is a region of text with the same `field' property.\n\ |
| 491 | If POS is nil, the position of the current buffer's point is used.\n\ | 486 | If POS is nil, the value of point is used for POS.\n\ |
| 492 | If ESCAPE-FROM-EDGE is non-nil and POS is already at end of a field,\n\ | 487 | If ESCAPE-FROM-EDGE is non-nil and POS is at the end of its field,\n\ |
| 493 | then the end of the *following* field is returned.") | 488 | then the end of the *following* field is returned.") |
| 494 | (pos, escape_from_edge) | 489 | (pos, escape_from_edge) |
| 495 | Lisp_Object pos, escape_from_edge; | 490 | Lisp_Object pos, escape_from_edge; |
| @@ -578,10 +573,10 @@ DEFUN ("line-beginning-position", Fline_beginning_position, Sline_beginning_posi | |||
| 578 | "Return the character position of the first character on the current line.\n\ | 573 | "Return the character position of the first character on the current line.\n\ |
| 579 | With argument N not nil or 1, move forward N - 1 lines first.\n\ | 574 | With argument N not nil or 1, move forward N - 1 lines first.\n\ |
| 580 | If scan reaches end of buffer, return that position.\n\ | 575 | If scan reaches end of buffer, return that position.\n\ |
| 581 | This function does not move point.\n\n\ | 576 | The scan does not cross a field boundary unless it would move\n\ |
| 582 | In the minibuffer, if point is not within the prompt,\n\ | 577 | beyond there to a different line. And if N is nil or 1,\n\ |
| 583 | the return value is never within the prompt either.") | 578 | and scan starts at a field boundary, the scan stops as soon as it starts.\n\n\ |
| 584 | 579 | This function does not move point.") | |
| 585 | (n) | 580 | (n) |
| 586 | Lisp_Object n; | 581 | Lisp_Object n; |
| 587 | { | 582 | { |
| @@ -600,7 +595,9 @@ the return value is never within the prompt either.") | |||
| 600 | SET_PT_BOTH (orig, orig_byte); | 595 | SET_PT_BOTH (orig, orig_byte); |
| 601 | 596 | ||
| 602 | /* Return END constrained to the current input field. */ | 597 | /* Return END constrained to the current input field. */ |
| 603 | return Fconstrain_to_field (make_number (end), make_number (orig), Qnil, Qt); | 598 | return Fconstrain_to_field (make_number (end), make_number (orig), |
| 599 | XINT (n) != 1 ? Qt : Qnil, | ||
| 600 | Qt); | ||
| 604 | } | 601 | } |
| 605 | 602 | ||
| 606 | DEFUN ("line-end-position", Fline_end_position, Sline_end_position, | 603 | DEFUN ("line-end-position", Fline_end_position, Sline_end_position, |