aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1999-11-09 18:42:28 +0000
committerRichard M. Stallman1999-11-09 18:42:28 +0000
commita3caef99aeab0951b80cfee91b4687a44d9bc24d (patch)
tree269ec81aa3791a1aab92362ff9e872ec7b39bd59 /src
parent94886883f00692901b81020893509a6f1b3ec596 (diff)
downloademacs-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.
Diffstat (limited to 'src')
-rw-r--r--src/editfns.c117
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. */
277static Lisp_Object
278preceding_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. */
292static int 278static int
293text_property_eq (prop, pos1, pos2) 279text_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
308static int 296static int
309text_property_stickiness (prop, pos) 297text_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. */
345Lisp_Object Qfield; 333Lisp_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
356void 347void
357find_field (pos, merge_at_boundary, beg, end) 348find_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)
437DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, "d", 432DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, "d",
438 "Delete the field surrounding POS.\n\ 433 "Delete the field surrounding POS.\n\
439A field is a region of text with the same `field' property.\n\ 434A field is a region of text with the same `field' property.\n\
440If POS is nil, the position of the current buffer's point is used.") 435If 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.")
450DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0, 445DEFUN ("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\
452A field is a region of text with the same `field' property.\n\ 447A field is a region of text with the same `field' property.\n\
453If POS is nil, the position of the current buffer's point is used.") 448If 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.")
462DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0, 457DEFUN ("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\
464A field is a region of text with the same `field' property.\n\ 459A field is a region of text with the same `field' property.\n\
465If POS is nil, the position of the current buffer's point is used.") 460If 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.")
474DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0, 469DEFUN ("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\
476A field is a region of text with the same `field' property.\n\ 471A field is a region of text with the same `field' property.\n\
477If POS is nil, the position of the current buffer's point is used.\n\ 472If POS is nil, the value of point is used for POS.\n\
478If ESCAPE-FROM-EDGE is non-nil and POS is already at beginning of an\n\ 473If ESCAPE-FROM-EDGE is non-nil and POS is at the beginning of its\n\
479field, then the beginning of the *previous* field is returned.") 474field, 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.")
488DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0, 483DEFUN ("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\
490A field is a region of text with the same `field' property.\n\ 485A field is a region of text with the same `field' property.\n\
491If POS is nil, the position of the current buffer's point is used.\n\ 486If POS is nil, the value of point is used for POS.\n\
492If ESCAPE-FROM-EDGE is non-nil and POS is already at end of a field,\n\ 487If ESCAPE-FROM-EDGE is non-nil and POS is at the end of its field,\n\
493then the end of the *following* field is returned.") 488then 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\
579With argument N not nil or 1, move forward N - 1 lines first.\n\ 574With argument N not nil or 1, move forward N - 1 lines first.\n\
580If scan reaches end of buffer, return that position.\n\ 575If scan reaches end of buffer, return that position.\n\
581This function does not move point.\n\n\ 576The scan does not cross a field boundary unless it would move\n\
582In the minibuffer, if point is not within the prompt,\n\ 577beyond there to a different line. And if N is nil or 1,\n\
583the return value is never within the prompt either.") 578and scan starts at a field boundary, the scan stops as soon as it starts.\n\n\
584 579This 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
606DEFUN ("line-end-position", Fline_end_position, Sline_end_position, 603DEFUN ("line-end-position", Fline_end_position, Sline_end_position,