aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2002-10-30 23:11:26 +0000
committerStefan Monnier2002-10-30 23:11:26 +0000
commit58401a3476a31efdf8481293bcf58e220313bdd4 (patch)
treecfec7fbaced3d8193771f3a4e11ed44735b22378 /src
parent2baf1bfa5498425f0df6e899e554e8e91427969e (diff)
downloademacs-58401a3476a31efdf8481293bcf58e220313bdd4.tar.gz
emacs-58401a3476a31efdf8481293bcf58e220313bdd4.zip
(overlays_around, get_pos_property): New funs.
(find_field): Use them. Also be careful not to modify POS before its last use. (Fmessage): Don't Fformat if there's nothing to format.
Diffstat (limited to 'src')
-rw-r--r--src/editfns.c225
1 files changed, 158 insertions, 67 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 51cf0c0b789..bf4976273aa 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -328,6 +328,149 @@ If you set the marker not to point anywhere, the buffer will have no mark. */)
328} 328}
329 329
330 330
331/* Find all the overlays in the current buffer that touch position POS.
332 Return the number found, and store them in a vector in VEC
333 of length LEN. */
334
335static int
336overlays_around (pos, vec, len)
337 int pos;
338 Lisp_Object *vec;
339 int len;
340{
341 Lisp_Object tail, overlay, start, end;
342 int startpos, endpos;
343 int idx = 0;
344
345 for (tail = current_buffer->overlays_before;
346 GC_CONSP (tail);
347 tail = XCDR (tail))
348 {
349 overlay = XCAR (tail);
350
351 end = OVERLAY_END (overlay);
352 endpos = OVERLAY_POSITION (end);
353 if (endpos < pos)
354 break;
355 start = OVERLAY_START (overlay);
356 startpos = OVERLAY_POSITION (start);
357 if (startpos <= pos)
358 {
359 if (idx < len)
360 vec[idx] = overlay;
361 /* Keep counting overlays even if we can't return them all. */
362 idx++;
363 }
364 }
365
366 for (tail = current_buffer->overlays_after;
367 GC_CONSP (tail);
368 tail = XCDR (tail))
369 {
370 overlay = XCAR (tail);
371
372 start = OVERLAY_START (overlay);
373 startpos = OVERLAY_POSITION (start);
374 if (pos < startpos)
375 break;
376 end = OVERLAY_END (overlay);
377 endpos = OVERLAY_POSITION (end);
378 if (pos <= endpos)
379 {
380 if (idx < len)
381 vec[idx] = overlay;
382 idx++;
383 }
384 }
385
386 return idx;
387}
388
389/* Return the value of property PROP, in OBJECT at POSITION.
390 It's the value of PROP that a char inserted at POSITION would get.
391 OBJECT is optional and defaults to the current buffer.
392 If OBJECT is a buffer, then overlay properties are considered as well as
393 text properties.
394 If OBJECT is a window, then that window's buffer is used, but
395 window-specific overlays are considered only if they are associated
396 with OBJECT. */
397static Lisp_Object
398get_pos_property (position, prop, object)
399 Lisp_Object position, object;
400 register Lisp_Object prop;
401{
402 struct window *w = 0;
403
404 CHECK_NUMBER_COERCE_MARKER (position);
405
406 if (NILP (object))
407 XSETBUFFER (object, current_buffer);
408
409 if (WINDOWP (object))
410 {
411 w = XWINDOW (object);
412 object = w->buffer;
413 }
414 if (BUFFERP (object))
415 {
416 int posn = XINT (position);
417 int noverlays;
418 Lisp_Object *overlay_vec, tem;
419 struct buffer *obuf = current_buffer;
420
421 set_buffer_temp (XBUFFER (object));
422
423 /* First try with room for 40 overlays. */
424 noverlays = 40;
425 overlay_vec = (Lisp_Object *) alloca (noverlays * sizeof (Lisp_Object));
426 noverlays = overlays_around (posn, overlay_vec, noverlays);
427
428 /* If there are more than 40,
429 make enough space for all, and try again. */
430 if (noverlays > 40)
431 {
432 overlay_vec = (Lisp_Object *) alloca (noverlays * sizeof (Lisp_Object));
433 noverlays = overlays_around (posn, overlay_vec, noverlays);
434 }
435 noverlays = sort_overlays (overlay_vec, noverlays, NULL);
436
437 set_buffer_temp (obuf);
438
439 /* Now check the overlays in order of decreasing priority. */
440 while (--noverlays >= 0)
441 {
442 Lisp_Object ol = overlay_vec[noverlays];
443 tem = Foverlay_get (ol, prop);
444 if (!NILP (tem))
445 {
446 /* Check the overlay is indeed active at point. */
447 Lisp_Object start = OVERLAY_START (ol), finish = OVERLAY_END (ol);
448 if ((OVERLAY_POSITION (start) == posn
449 && XMARKER (start)->insertion_type == 1)
450 || (OVERLAY_POSITION (finish) == posn
451 && XMARKER (finish)->insertion_type == 0))
452 ; /* The overlay will not cover a char inserted at point. */
453 else
454 {
455 return tem;
456 }
457 }
458 }
459
460 }
461
462 { /* Now check the text-properties. */
463 int stickiness = text_property_stickiness (Qfield, position);
464 if (stickiness > 0)
465 return Fget_text_property (position, Qfield, Qnil);
466 else if (stickiness < 0 && XINT (position) > BEGV)
467 return Fget_text_property (make_number (XINT (position) - 1),
468 Qfield, Qnil);
469 else
470 return Qnil;
471 }
472}
473
331/* Find the field surrounding POS in *BEG and *END. If POS is nil, 474/* Find the field surrounding POS in *BEG and *END. If POS is nil,
332 the value of point is used instead. If BEG or END null, 475 the value of point is used instead. If BEG or END null,
333 means don't store the beginning or end of the field. 476 means don't store the beginning or end of the field.
@@ -357,9 +500,6 @@ find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
357{ 500{
358 /* Fields right before and after the point. */ 501 /* Fields right before and after the point. */
359 Lisp_Object before_field, after_field; 502 Lisp_Object before_field, after_field;
360 /* If the fields came from overlays, the associated overlays.
361 Qnil means they came from text-properties. */
362 Lisp_Object before_overlay = Qnil, after_overlay = Qnil;
363 /* 1 if POS counts as the start of a field. */ 503 /* 1 if POS counts as the start of a field. */
364 int at_field_start = 0; 504 int at_field_start = 0;
365 /* 1 if POS counts as the end of a field. */ 505 /* 1 if POS counts as the end of a field. */
@@ -371,12 +511,11 @@ find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
371 CHECK_NUMBER_COERCE_MARKER (pos); 511 CHECK_NUMBER_COERCE_MARKER (pos);
372 512
373 after_field 513 after_field
374 = get_char_property_and_overlay (pos, Qfield, Qnil, &after_overlay); 514 = get_char_property_and_overlay (pos, Qfield, Qnil, NULL);
375 before_field 515 before_field
376 = (XFASTINT (pos) > BEGV 516 = (XFASTINT (pos) > BEGV
377 ? get_char_property_and_overlay (make_number (XINT (pos) - 1), 517 ? get_char_property_and_overlay (make_number (XINT (pos) - 1),
378 Qfield, Qnil, 518 Qfield, Qnil, NULL)
379 &before_overlay)
380 : Qnil); 519 : Qnil);
381 520
382 /* See if we need to handle the case where MERGE_AT_BOUNDARY is nil 521 /* See if we need to handle the case where MERGE_AT_BOUNDARY is nil
@@ -385,62 +524,13 @@ find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
385 MERGE_AT_BOUNDARY is non-nil (see function comment) is actually the 524 MERGE_AT_BOUNDARY is non-nil (see function comment) is actually the
386 more natural one; then we avoid treating the beginning of a field 525 more natural one; then we avoid treating the beginning of a field
387 specially. */ 526 specially. */
388 if (NILP (merge_at_boundary) && !EQ (after_field, before_field)) 527 if (NILP (merge_at_boundary))
389 /* We are at a boundary, see which direction is inclusive. We 528 {
390 decide by seeing which field the `field' property sticks to. */ 529 Lisp_Object field = get_pos_property (pos, Qfield, Qnil);
391 { 530 if (!EQ (field, after_field))
392 /* -1 means insertions go into before_field, 1 means they go
393 into after_field, 0 means neither. */
394 int stickiness;
395 /* Whether the before/after_field come from overlays. */
396 int bop = !NILP (before_overlay);
397 int aop = !NILP (after_overlay);
398
399 if (bop && XMARKER (OVERLAY_END (before_overlay))->insertion_type == 1)
400 /* before_field is from an overlay, which expands upon
401 end-insertions. Note that it's possible for after_overlay to
402 also eat insertions here, but then they will overlap, and
403 there's not much we can do. */
404 stickiness = -1;
405 else if (aop
406 && XMARKER (OVERLAY_START (after_overlay))->insertion_type == 0)
407 /* after_field is from an overlay, which expand to contain
408 start-insertions. */
409 stickiness = 1;
410 else if (bop && aop)
411 /* Both fields come from overlays, but neither will contain any
412 insertion here. */
413 stickiness = 0;
414 else if (bop)
415 /* before_field is an overlay that won't eat any insertion, but
416 after_field is from a text-property. Assume that the
417 text-property continues underneath the overlay, and so will
418 be inherited by any insertion, regardless of any stickiness
419 settings. */
420 stickiness = 1;
421 else if (aop)
422 /* Similarly, when after_field is the overlay. */
423 stickiness = -1;
424 else
425 /* Both fields come from text-properties. Look for explicit
426 stickiness properties. */
427 stickiness = text_property_stickiness (Qfield, pos);
428
429 if (stickiness > 0)
430 at_field_start = 1;
431 else if (stickiness < 0)
432 at_field_end = 1; 531 at_field_end = 1;
433 else 532 if (!EQ (field, before_field))
434 /* STICKINESS == 0 means that any inserted text will get a 533 at_field_start = 1;
435 `field' char-property of nil, so check to see if that
436 matches either of the adjacent characters (this being a
437 kind of "stickiness by default"). */
438 {
439 if (NILP (before_field))
440 at_field_end = 1; /* Sticks to the left. */
441 else if (NILP (after_field))
442 at_field_start = 1; /* Sticks to the right. */
443 }
444 } 534 }
445 535
446 /* Note about special `boundary' fields: 536 /* Note about special `boundary' fields:
@@ -474,14 +564,15 @@ find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
474 else 564 else
475 /* Find the previous field boundary. */ 565 /* Find the previous field boundary. */
476 { 566 {
567 Lisp_Object p = pos;
477 if (!NILP (merge_at_boundary) && EQ (before_field, Qboundary)) 568 if (!NILP (merge_at_boundary) && EQ (before_field, Qboundary))
478 /* Skip a `boundary' field. */ 569 /* Skip a `boundary' field. */
479 pos = Fprevious_single_char_property_change (pos, Qfield, Qnil, 570 p = Fprevious_single_char_property_change (p, Qfield, Qnil,
480 beg_limit);
481
482 pos = Fprevious_single_char_property_change (pos, Qfield, Qnil,
483 beg_limit); 571 beg_limit);
484 *beg = NILP (pos) ? BEGV : XFASTINT (pos); 572
573 p = Fprevious_single_char_property_change (p, Qfield, Qnil,
574 beg_limit);
575 *beg = NILP (p) ? BEGV : XFASTINT (p);
485 } 576 }
486 } 577 }
487 578
@@ -2930,7 +3021,7 @@ usage: (message STRING &rest ARGS) */)
2930 else 3021 else
2931 { 3022 {
2932 register Lisp_Object val; 3023 register Lisp_Object val;
2933 val = Fformat (nargs, args); 3024 val = nargs < 2 && STRINGP (args[0]) ? args[0] : Fformat (nargs, args);
2934 message3 (val, SBYTES (val), STRING_MULTIBYTE (val)); 3025 message3 (val, SBYTES (val), STRING_MULTIBYTE (val));
2935 return val; 3026 return val;
2936 } 3027 }