/* Lisp functions pertaining to editing.
- Copyright (C) 1985,86,87,89,93,94,95,96,97,98, 1999, 2000, 2001
+ Copyright (C) 1985,86,87,89,93,94,95,96,97,98, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <unistd.h>
#endif
+/* Without this, sprintf on Mac OS Classic will produce wrong
+ result. */
+#ifdef MAC_OS8
+#include <stdio.h>
+#endif
+
#include <ctype.h>
#include "lisp.h"
extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
const struct tm *, int));
static int tm_diff P_ ((struct tm *, struct tm *));
-static void find_field P_ ((Lisp_Object, Lisp_Object, int *, int *));
+static void find_field P_ ((Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *));
static void update_buffer_properties P_ ((int, int));
static Lisp_Object region_limit P_ ((int));
static int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
m = Fmarker_position (current_buffer->mark);
if (NILP (m))
- error ("There is no region now");
+ error ("The mark is not set now, so there is no region");
if ((PT < XFASTINT (m)) == beginningp)
m = make_number (PT);
return current_buffer->mark;
}
-\f
-#if 0 /* Not used. */
-
-/* Return nonzero if POS1 and POS2 have the same value
- for the text property PROP. */
-
-static int
-char_property_eq (prop, pos1, pos2)
- Lisp_Object prop;
- Lisp_Object pos1, pos2;
-{
- Lisp_Object pval1, pval2;
-
- pval1 = Fget_char_property (pos1, prop, Qnil);
- pval2 = Fget_char_property (pos2, prop, Qnil);
-
- return EQ (pval1, pval2);
-}
-
-#endif /* 0 */
-
-/* Return the direction from which the text-property PROP would be
- inherited by any new text inserted at POS: 1 if it would be
- inherited from the char after POS, -1 if it would be inherited from
- the char before POS, and 0 if from neither. */
-
-static int
-text_property_stickiness (prop, pos)
- Lisp_Object prop;
- Lisp_Object pos;
-{
- Lisp_Object prev_pos, front_sticky;
- int is_rear_sticky = 1, is_front_sticky = 0; /* defaults */
-
- if (XINT (pos) > BEGV)
- /* Consider previous character. */
- {
- Lisp_Object rear_non_sticky;
-
- prev_pos = make_number (XINT (pos) - 1);
- rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil);
-
- if (!NILP (CONSP (rear_non_sticky)
- ? Fmemq (prop, rear_non_sticky)
- : rear_non_sticky))
- /* PROP is rear-non-sticky. */
- is_rear_sticky = 0;
- }
-
- /* Consider following character. */
- front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil);
-
- if (EQ (front_sticky, Qt)
- || (CONSP (front_sticky)
- && !NILP (Fmemq (prop, front_sticky))))
- /* PROP is inherited from after. */
- is_front_sticky = 1;
-
- /* Simple cases, where the properties are consistent. */
- if (is_rear_sticky && !is_front_sticky)
- return -1;
- else if (!is_rear_sticky && is_front_sticky)
- return 1;
- else if (!is_rear_sticky && !is_front_sticky)
- return 0;
-
- /* The stickiness properties are inconsistent, so we have to
- disambiguate. Basically, rear-sticky wins, _except_ if the
- property that would be inherited has a value of nil, in which case
- front-sticky wins. */
- if (XINT (pos) == BEGV || NILP (Fget_text_property (prev_pos, prop, Qnil)))
- return 1;
- else
- return -1;
-}
-
\f
/* Find the field surrounding POS in *BEG and *END. If POS is nil,
the value of point is used instead. If BEG or END null,
means don't store the beginning or end of the field.
+ BEG_LIMIT and END_LIMIT serve to limit the ranged of the returned
+ results; they do not effect boundary behavior.
+
If MERGE_AT_BOUNDARY is nonzero, then if POS is at the very first
position of a field, then the beginning of the previous field is
returned instead of the beginning of POS's field (since the end of a
is not stored. */
static void
-find_field (pos, merge_at_boundary, beg, end)
+find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
Lisp_Object pos;
Lisp_Object merge_at_boundary;
+ Lisp_Object beg_limit, end_limit;
int *beg, *end;
{
/* Fields right before and after the point. */
{
if (!NILP (merge_at_boundary) && EQ (before_field, Qboundary))
/* Skip a `boundary' field. */
- pos = Fprevious_single_char_property_change (pos, Qfield, Qnil,Qnil);
+ pos = Fprevious_single_char_property_change (pos, Qfield, Qnil,
+ beg_limit);
- pos = Fprevious_single_char_property_change (pos, Qfield, Qnil, Qnil);
+ pos = Fprevious_single_char_property_change (pos, Qfield, Qnil,
+ beg_limit);
*beg = NILP (pos) ? BEGV : XFASTINT (pos);
}
}
{
if (!NILP (merge_at_boundary) && EQ (after_field, Qboundary))
/* Skip a `boundary' field. */
- pos = Fnext_single_char_property_change (pos, Qfield, Qnil, Qnil);
+ pos = Fnext_single_char_property_change (pos, Qfield, Qnil,
+ end_limit);
- pos = Fnext_single_char_property_change (pos, Qfield, Qnil, Qnil);
+ pos = Fnext_single_char_property_change (pos, Qfield, Qnil,
+ end_limit);
*end = NILP (pos) ? ZV : XFASTINT (pos);
}
}
Lisp_Object pos;
{
int beg, end;
- find_field (pos, Qnil, &beg, &end);
+ find_field (pos, Qnil, Qnil, &beg, Qnil, &end);
if (beg != end)
del_range (beg, end);
return Qnil;
Lisp_Object pos;
{
int beg, end;
- find_field (pos, Qnil, &beg, &end);
+ find_field (pos, Qnil, Qnil, &beg, Qnil, &end);
return make_buffer_string (beg, end, 1);
}
Lisp_Object pos;
{
int beg, end;
- find_field (pos, Qnil, &beg, &end);
+ find_field (pos, Qnil, Qnil, &beg, Qnil, &end);
return make_buffer_string (beg, end, 0);
}
-DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0,
+DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 3, 0,
doc: /* Return the beginning of the field surrounding POS.
A field is a region of text with the same `field' property.
If POS is nil, the value of point is used for POS.
If ESCAPE-FROM-EDGE is non-nil and POS is at the beginning of its
-field, then the beginning of the *previous* field is returned. */)
- (pos, escape_from_edge)
- Lisp_Object pos, escape_from_edge;
+field, then the beginning of the *previous* field is returned.
+If LIMIT is non-nil, it is a buffer position; if the beginning of the field
+is before LIMIT, then LIMIT will be returned instead. */)
+ (pos, escape_from_edge, limit)
+ Lisp_Object pos, escape_from_edge, limit;
{
int beg;
- find_field (pos, escape_from_edge, &beg, 0);
+ find_field (pos, escape_from_edge, limit, &beg, Qnil, 0);
return make_number (beg);
}
-DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0,
+DEFUN ("field-end", Ffield_end, Sfield_end, 0, 3, 0,
doc: /* Return the end of the field surrounding POS.
A field is a region of text with the same `field' property.
If POS is nil, the value of point is used for POS.
If ESCAPE-FROM-EDGE is non-nil and POS is at the end of its field,
-then the end of the *following* field is returned. */)
- (pos, escape_from_edge)
- Lisp_Object pos, escape_from_edge;
+then the end of the *following* field is returned.
+If LIMIT is non-nil, it is a buffer position; if the end of the field
+is after LIMIT, then LIMIT will be returned instead. */)
+ (pos, escape_from_edge, limit)
+ Lisp_Object pos, escape_from_edge, limit;
{
int end;
- find_field (pos, escape_from_edge, 0, &end);
+ find_field (pos, escape_from_edge, Qnil, 0, limit, &end);
return make_number (end);
}
fwd = (XFASTINT (new_pos) > XFASTINT (old_pos));
if (fwd)
- field_bound = Ffield_end (old_pos, escape_from_edge);
+ field_bound = Ffield_end (old_pos, escape_from_edge, new_pos);
else
- field_bound = Ffield_beginning (old_pos, escape_from_edge);
+ field_bound = Ffield_beginning (old_pos, escape_from_edge, new_pos);
if (/* See if ESCAPE_FROM_EDGE caused FIELD_BOUND to jump to the
other side of NEW_POS, which would mean that NEW_POS is
characters, not just the bytes. */
int c1, c2;
+ QUIT;
+
if (! NILP (bp1->enable_multibyte_characters))
{
c1 = BUF_FETCH_MULTIBYTE_CHAR (bp1, i1_byte);
}
-DEFUN ("propertize", Fpropertize, Spropertize, 3, MANY, 0,
+DEFUN ("propertize", Fpropertize, Spropertize, 1, MANY, 0,
doc: /* Return a copy of STRING with text properties added.
First argument is the string to copy.
Remaining arguments form a sequence of PROPERTY VALUE pairs for text
int i;
/* Number of args must be odd. */
- if ((nargs & 1) == 0 || nargs < 3)
+ if ((nargs & 1) == 0 || nargs < 1)
error ("Wrong number of arguments");
properties = string = Qnil;
if (*format++ == '%')
{
int thissize = 0;
+ int actual_width = 0;
unsigned char *this_format_start = format - 1;
int field_width, precision;
{
/* Use a temp var to avoid problems when ENABLE_CHECKING
is turned on. */
- struct Lisp_String *t = XSYMBOL (args[n])->name;
+ struct Lisp_String *t = XSTRING (SYMBOL_NAME (args[n]));
XSETSTRING (args[n], t);
if (STRING_MULTIBYTE (args[n]) && ! multibyte)
{
if (*format != 's' && *format != 'S')
error ("Format specifier doesn't match argument type");
thissize = CONVERTED_BYTE_SIZE (multibyte, args[n]);
+ actual_width = lisp_string_width (args[n], -1, NULL, NULL);
}
/* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
else if (INTEGERP (args[n]) && *format != 's')
goto string;
}
- thissize = max (field_width, thissize);
+ thissize += max (0, field_width - actual_width);
total += thissize + 4;
}
staticpro (&Qbuffer_access_fontify_functions);
DEFVAR_LISP ("inhibit-field-text-motion", &Vinhibit_field_text_motion,
- doc: /* Non-nil means.text motion commands don't notice fields. */);
+ doc: /* Non-nil means text motion commands don't notice fields. */);
Vinhibit_field_text_motion = Qnil;
DEFVAR_LISP ("buffer-access-fontify-functions",