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

Fun with *zwei-comtab*



    Date: Mon, 25 Jun 90 08:23 EDT
    From: Arbaugh@DOCKMASTER.NCSC.MIL


    I'm using a Sun with the UX board and like it a great deal.  There is
    one nagging problem, however.  In zmacs, the line feed key acts as the
    line key.  This key is to small- so I normally end up hitting return and
    then tab.  In my attempts to reduce keystrokes, I've tried the
    following:

    Set package zwei ;; Note I'll use a $ instead of a sharp sign- mulitcs
    doesn't like sharps (set-comtab *zmacs-comtab* '($\line com-insert-crs))
    (set-comtab *zmacs-comtab* '($\return com-indent-new-line)) ;; This
    basically should switch the two keys- or am I doing something silly?  ;;
    When I move to zmacs and hit $\return- I end up in the debugger with ;;
    an error I can't remember at the moment.  ;; If I hit $\line, no
    problem.  It works like it should, i.e.  $\return.

    Any ideas?  And no- I don't want to buy a symbolics keyboard for the
    sun.

I'll answer this to the whole list, as it might be of general interest.

The problem you ran into is a recursion loop (the control stack probably
overflowed), due to the odd, controversial way that
ZWEI:COM-INDENT-NEW-LINE is implemented.  It contains hooks for special
new-line and indent functions, but if there are none, it just executes a
#\RETURN keystroke followed by a #\TAB keystroke.  Obviously, if you
keybind either of the latter to the command function
ZWEI:COM-INDENT-NEW-LINE, you will get a recursion loop.

The reason this was done was to keep the action of LINE in step with
whatever RETURN and TAB do, which might be changed by mode changes.
This is clearly questionable, and generated some controversy here, but
was left that way because we weren't willing to undertake a much more
general remodularization.

To do what you want to do, with only a slight loss of mode-generality,
just define a modified command as follows, and bind that to RETURN.
This will work fine if you only alternate among Lisp, Text, and
Fundamental mode.

BTW, you may define many keybindings in a single call to
ZWEI:SET-COMTAB, as shown below.

;;; -*- Syntax: Zetalisp; Base: 8; Mode: LISP; Package: ZWEI -*-

(DEFCOM COM-SPECIAL-INDENT-NEW-LINE
	"Starts a new line, indenting the new line as appropriate for the major mode.
For modes in which comments have explicit end strings, you can use this command
before the end of the comment and the comment end does not move to the new line." ()
  (WITH-NODE-WRITE-LOCKED ((BP-NODE-TO-LOCK (POINT)))
    (WHEN (FIND-COMMENT-START (BP-LINE (POINT)))	;only when there is a comment on this line
      (LET ((CANDIDATE (STRING-TRIM '(#\SPACE #\TAB)	;survive some random spaces
				    (SUBSTRING (BP-LINE (POINT)) (BP-INDEX (POINT))))))
	(IF (AND (> (STRING-LENGTH *COMMENT-END*) 0)	;only when nontrivial comment ender
		 (STRING-EQUAL CANDIDATE *COMMENT-END*));does remainder of line match?
	    (MOVE-POINT (END-LINE (POINT))))))		;so fool it by moving point to end
    (MOVE-POINT (DELETE-BACKWARD-OVER *BLANKS* (POINT)))
    (LET ((*LAST-COMMAND-TYPE* 'INDENT-NEW-LINE)
	  *CURRENT-COMMAND-TYPE*)		;Don't be fooled
      (MAX (IF *INDENT-NEW-LINE-NEW-LINE-FUNCTION*
	       (FUNCALL *INDENT-NEW-LINE-NEW-LINE-FUNCTION*)
	     (LET ((*ORIGINAL-COMMAND-LINE* (BP-LINE (POINT))))
	       (COMMAND-EXECUTE #'COM-INSERT-CRS #\RETURN NIL *COMMAND-HOOK*)))
	   (IF *INDENT-NEW-LINE-INDENT-FUNCTION*
	       (LET ((*NUMERIC-ARG-P*) (*NUMERIC-ARG* 1))
		 (FUNCALL *INDENT-NEW-LINE-INDENT-FUNCTION*))
	     (KEY-EXECUTE #\TAB))))))

(SET-COMTAB *ZMACS-COMTAB*
	    '(#\RETURN COM-SPECIAL-INDENT-NEW-LINE
	      #\LINE   COM-INSERT-CRS))