help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: self-insert-command source code?


From: Pascal J. Bourguignon
Subject: Re: self-insert-command source code?
Date: Fri, 05 Dec 2014 10:01:19 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> To my disappointment, I've just found out that self-insert-command is
> written in C and not in Elisp.  I don't speak C very well (and don't
> have the sources for Emacs installed (yet)), so could anyone shed some
> light on these two questions (just in some spare time – it's not that I
> /need/ it now).

Always install the sources!


> 1. Why is that so?  Since this is an interactive function, performance
> should not be the issue.

It could have been, 30 years ago!


> 2. What it might look like /if/ it was written in Elisp?

    /* Note that there's code in command_loop_1 which typically avoids
       calling this.  */
    DEFUN ("self-insert-command", Fself_insert_command, Sself_insert_command, 
1, 1, "p",
           doc: /* Insert the character you type.
    Whichever character you type to run this command is inserted.
    Before insertion, `expand-abbrev' is executed if the inserted character does
    not have word syntax and the previous character in the buffer does.
    After insertion, the value of `auto-fill-function' is called if the
    `auto-fill-chars' table has a non-nil value for the inserted character.
    At the end, it runs `post-self-insert-hook'.  */)
      (Lisp_Object n)
    {
      bool remove_boundary = 1;
      CHECK_NATNUM (n);

      if (!EQ (Vthis_command, KVAR (current_kboard, Vlast_command)))
        nonundocount = 0;

      if (NILP (Vexecuting_kbd_macro)
          && !EQ (minibuf_window, selected_window))
        {
          if (nonundocount <= 0 || nonundocount >= 20)
        {
          remove_boundary = 0;
          nonundocount = 0;
        }
          nonundocount++;
        }

      if (remove_boundary
          && CONSP (BVAR (current_buffer, undo_list))
          && NILP (XCAR (BVAR (current_buffer, undo_list)))
          /* Only remove auto-added boundaries, not boundaries
         added be explicit calls to undo-boundary.  */
          && EQ (BVAR (current_buffer, undo_list), last_undo_boundary))
        /* Remove the undo_boundary that was just pushed.  */
        bset_undo_list (current_buffer, XCDR (BVAR (current_buffer, 
undo_list)));

      /* Barf if the key that invoked this was not a character.  */
      if (!CHARACTERP (last_command_event))
        bitch_at_user ();
      {
        int character = translate_char (Vtranslation_table_for_input,
                        XINT (last_command_event));
        int val = internal_self_insert (character, XFASTINT (n));
        if (val == 2)
          nonundocount = 0;
        frame_make_pointer_invisible ();
      }

      return Qnil;
    }


would translate to:

    (defvar nonundocount 0)

    (defun self-insert-command (n)
      "Insert the character you type.
    Whichever character you type to run this command is inserted.
    Before insertion, `expand-abbrev' is executed if the inserted character does
    not have word syntax and the previous character in the buffer does.
    After insertion, the value of `auto-fill-function' is called if the
    `auto-fill-chars' table has a non-nil value for the inserted character.
    At the end, it runs `post-self-insert-hook'."
      (interactive "p")
      (let ((remove-boundary t))
        (check-type times (integer 0))
        (unless (eq this-command (last-command current-kboard))
          (setf nonundocount 0))
        (when (and (null executing-kbd-macro)
                   (not (eq minibuf-window selected-window)))
          (when (or (<= nonundocount 0) (<= 20 nonundocount))
            (setf remove-boundary nil
                  nonundocount 0))
          (incf nonundocount))
        (when (and remove-boundary
                   (consp (undo-list current-buffer))
                   (null (car (undo-list current-buffer)))
                   ;; Only remove auto-added boundaries, not boundaries
                   ;; added be explicit calls to undo-boundary. 
                   (eq (undo-list current-buffer) last-undo-boundary))
          ;; Remove the undo_boundary that was just pushed. 
          (bset-undo-list current-buffer (cdr (undo-list current-buffer))))
        (unless (characterp last-command-event)
          (bitch-at-user))
        (let* ((character (translate-char translation-table-for-input
                                          (coerce last-command-event 'integer)))
               (val (internal-self-insert character (coerce n 'fixnum))))
          (when (= 2 val)
            (setf nonundocount 0))
          (frame-make-pointer-invisible))
        nil))


-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk


reply via email to

[Prev in Thread] Current Thread [Next in Thread]