Function: combine-after-change-execute

combine-after-change-execute is a function defined in insdel.c.

Signature

(combine-after-change-execute)

Documentation

This function is for use internally in the function combine-after-change-calls(var)/combine-after-change-calls(fun).

Source Code

// Defined in /usr/src/emacs/src/insdel.c
{
  specpdl_ref count = SPECPDL_INDEX ();
  ptrdiff_t beg, end, change;
  ptrdiff_t begpos, endpos;
  Lisp_Object tail;

  if (NILP (combine_after_change_list))
    return Qnil;

  /* It is rare for combine_after_change_buffer to be invalid, but
     possible.  It can happen when combine-after-change-calls is
     non-nil, and insertion calls a file name handler (e.g. through
     lock_file) which scribbles into a temp file -- cyd  */
  if (!BUFFERP (combine_after_change_buffer)
      || !BUFFER_LIVE_P (XBUFFER (combine_after_change_buffer)))
    {
      combine_after_change_list = Qnil;
      return Qnil;
    }

  record_unwind_current_buffer ();

  Fset_buffer (combine_after_change_buffer);

  /* # chars unchanged at beginning of buffer.  */
  beg = Z - BEG;
  /* # chars unchanged at end of buffer.  */
  end = beg;
  /* Total amount of insertion (negative for deletion).  */
  change = 0;

  /* Scan the various individual changes,
     accumulating the range info in BEG, END and CHANGE.  */
  for (tail = combine_after_change_list; CONSP (tail);
       tail = XCDR (tail))
    {
      Lisp_Object elt;
      ptrdiff_t thisbeg, thisend, thischange;

      /* Extract the info from the next element.  */
      elt = XCAR (tail);
      if (! CONSP (elt))
	continue;
      thisbeg = XFIXNUM (XCAR (elt));

      elt = XCDR (elt);
      if (! CONSP (elt))
	continue;
      thisend = XFIXNUM (XCAR (elt));

      elt = XCDR (elt);
      if (! CONSP (elt))
	continue;
      thischange = XFIXNUM (XCAR (elt));

      /* Merge this range into the accumulated range.  */
      change += thischange;
      if (thisbeg < beg)
	beg = thisbeg;
      if (thisend < end)
	end = thisend;
    }

  /* Get the current start and end positions of the range
     that was changed.  */
  begpos = BEG + beg;
  endpos = Z - end;

  /* We are about to handle these, so discard them.  */
  combine_after_change_list = Qnil;

  /* Now run the after-change functions for real.
     Turn off the flag that defers them.  */
  record_unwind_protect (Fcombine_after_change_execute_1,
			 Vcombine_after_change_calls);
  signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
  update_compositions (begpos, endpos, CHECK_ALL);

  return unbind_to (count, Qnil);
}