home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / patches / x-rebind-keysym.patch < prev    next >
Encoding:
Text File  |  1991-06-19  |  30.4 KB  |  946 lines

  1. Path: dg-rtp!rock.concert.net!mcnc!stanford.edu!agate!ucbvax!cis.ohio-state.edu!tut.cis.ohio-state.edu!unreplyable!garbage
  2. From: ruprecht@ISLAND.INFORMATIK.UNI-FREIBURG.DE (Nick Ruprecht)
  3. Newsgroups: gnu.emacs.help,comp.emacs
  4. Subject: New function x-rebind-keysym etc
  5. Date: 4 Jun 91 12:01:36 GMT
  6. Organization: Gatewayed from the GNU Project mailing list help-gnu-emacs@prep.ai.mit.edu
  7.  
  8. I have written a couple of functions to enable rebinding of Keysyms
  9. under X. These functions have been successfully installed on Sun3 and
  10. Sun4 under SunOS 4.1 and X Windows Release X11R4. Now someone else can
  11. go ahead and port it to other systems.
  12.  
  13. -----------------------------------------------------------------------
  14. LCD Archive Entry:
  15. x-rebind-keysym|Nick Ruprecht|ruprecht@ISLAND.INFORMATIK.UNI-FREIBURG.DE
  16. |Rebind keysyms under X
  17. |91-06-04||~/patches/x-rebind-keysym.patch.Z
  18.  
  19. The function x-rebind-keysym (in x11fns.c) allows the specification of
  20. a STRING of up to 64 characters length to be bound to KEYSYM if the
  21. given MODIFIERS are present.
  22.  
  23. KEYSYM is the name of a keysym. For a list of all keysyms, see the
  24. file /usr/include/X11/keysymdef.h (remove the leading "XK_" to obtain
  25. the keysym names). Case is significant.
  26.  
  27. MODIFIERS is a comma separated list of modifier combinations. Each
  28. list element consists of a combination of the letters n, s, l, c, m
  29. (or 1), 2, 3, 4, 5, specifying none, shift, lock, control, meta (or
  30. mod1), mod2, mod3, mod4, mod5, respectively.
  31.  
  32. STRING is the replacement string. It can be up to MAPPING_BUF_SIZE
  33. long (defined in x11term.h as 64). The special character '^'
  34. controlifies the following character. '\' acts as an escape
  35. introducer. See the documentation of x-rebind-keysym for details.
  36.  
  37. To rebind keysyms during the startup phase of emacs, do something
  38. along the following lines in the startup file ~/.emacs:
  39.  
  40.    (defun my-x-rebindings ()
  41.         "example for a function to rebind some keys."
  42.         (x-rebind-padkeys)                      ; see below
  43.         (x-rebind-keysym "Alt_L" "n,sl,s,l" "^X")
  44.         (x-rebind-keysym "Alt_R" "n,sl,s,l" "^X4")
  45.         (x-rebind-keysym "Super_R" "n,sl,s,l" "^C")
  46.         (x-rebind-keysym "L1" "n,sl,s,l" "^X^S")
  47.         (x-rebind-keysym "L2" "n,sl,s,l" "^U")
  48.         (x-rebind-keysym "L4" "n,sl,s,l" "^_"))
  49.  
  50.    ;; call only if running under X windows
  51.    (if (eq window-system 'x)
  52.         (setq term-setup-hook 'my-x-rebindings))
  53.  
  54. The function x-rebind-defaults (in x-win.el) imitates the behaviour of
  55. the previous Emacs on a Sun by rebinding keysyms to "ESC [ nnn z"
  56. escape sequences. Non-Suns will need a different x-rebind-defaults.
  57.  
  58. The function x-rebind-padkeys (in x-win.el) creates a complex keypad
  59. for Suns.
  60.  
  61. To make full use of these functions, the keys must generate the
  62. expected keysyms. If they don't, you'll have to modify the functions
  63. or the server keymap using xmodmap, e.g. with the following commands:
  64.  
  65.    ! in keysymdef.h, F11=L1, F12=L2. Therefore F11 and F12 have
  66.    ! to be moved to other keysyms, e.g. KP_F1 and KP_F2
  67.    keycode 16      = KP_F1
  68.    keycode 18      = KP_F2
  69.  
  70.    ! To use the Sun keyboard keys Compose and AltGraph, they must
  71.    ! be assigned to keysyms
  72.    keycode 20      = Alt_R
  73.    keycode 74      = Super_R
  74.  
  75.    ! On Suns, keycode 57 (./Del on the keypad) produces "Delete"
  76.    ! and is therefore undistinguishable from the Delete key.
  77.    ! This is changed by
  78.    keycode 57      = KP_Decimal
  79.  
  80. The function x-rebind-list (in x-win.el, calling functions in
  81. x11fns.c) outputs the list of current rebindings in the *Help* buffer.
  82.  
  83. The following pages contain scripts for the editor ed produced by
  84. "diff -e" to generate the modified x11term.h, x11term.c, x11fns.c, and
  85. x-win.el from the emacs-18.57 distribution. After these follow
  86. excerpts from our local site-init.el file containing some additional
  87. functions. I hope this is of use for you. Best regards,
  88.  
  89. Nick Ruprecht
  90.  
  91. e x11term.h
  92. 24a
  93. /* 21-MAY-1991/Ru: size of mapping_buf, used in x11term.c and x11fns.c */
  94. #define MAPPING_BUF_SIZE 64
  95. .
  96. 0a
  97. /*
  98.  * Modified by Nick Ruprecht, Institut fuer Informatik, Freiburg, Germany
  99.  *    define MAPPING_BUF_SIZE for common use in x11fns.c and x11term.c
  100.  *
  101.  * 28-MAY-1991/Ru: release
  102.  */
  103.  
  104. .
  105.  
  106. e x11term.c
  107. 1441a
  108. #endif  /* 0 (23-May-1991/Ru) */
  109. .
  110. 1402,1405c
  111.       nbytes = XLookupString (&event.xkey, mapping_buf, MAPPING_BUF_SIZE,
  112.                   &keysym, 0); /* use MAPPING_BUF_SIZE */
  113. #if 0            /* 23-MAY-1991/Ru: now done with x-rebind-keysym */
  114. .
  115. 1282c
  116.   char mapping_buf[MAPPING_BUF_SIZE]; /* 23-MAY-1991/Ru: see x11term.h */
  117. .
  118. 1274c
  119. #endif /* 0 (23-MAY-1991/Ru) */    
  120.  
  121. .
  122. 1121c
  123. #if 0            /* 23-MAY-1991/Ru: now done with x-rebind-keysym */
  124. .
  125. 24a
  126.  * Modified by Nick Ruprecht, Institut fuer Informatik, Freiburg, Germany
  127.  *    x11fns.c now contains the function x-rebind-keysym which allows
  128.  *    dynamic rebinding of KeySyms. For this reason I have ifdef'd out
  129.  *    the function stringFuncVal and the hardwired key translations in the
  130.  *    function internal_socket_read. Also increased size of mapping_buf to
  131.  *    accomodate long rebindings.
  132.  *
  133.  *    28-MAY-1991/Ru: release
  134.  */
  135.  
  136. /*
  137. .
  138.  
  139. e x11fns.c
  140. 927a
  141.   defsubr (&Sx_rebind_keysym);    /* 15-MAY-1991/Ru: added */
  142.   defsubr (&Sx_rebind_list_start);
  143.   defsubr (&Sx_rebind_list_next);
  144. .
  145. 142a
  146. /*
  147.  * x-rebind-keysym(keysym, modifiers, string)
  148.  * 
  149.  * call XRebindKeysym to rebind the specified KeySym for the specified 
  150.  * combinations of modifiers to string
  151.  *
  152.  * KeySyms are entered as strings containing a valid KeySym name.
  153.  *
  154.  * Modifiers are entered as a comma separated list where each element
  155.  * can contain the letters n, s, l, c, m (or 1), 2, 3, 4, 5 (for none, 
  156.  * shift, lock, control, mod1 (usually meta), mod2, mod3, mod4, mod5,
  157.  * respectively).
  158.  *
  159.  * In the replacement string, the caret (^) controlifies the following
  160.  * character, the backslash (\) produces special characters. This is
  161.  * done in str_controlify().
  162.  *
  163.  * XRebindKeysym is called through the routine RebindKeysym. This routine
  164.  * checks whether the requested Keysym/modifier combination has already
  165.  * been rebound. If so, it just replaces the string.
  166.  *
  167.  * 22-MAY-1991/Ru: new
  168.  */
  169.  
  170. /*
  171.  * controlify string in place and return resulting length.
  172.  * modification in place is ok as string never grows.
  173.  * return length of resulting string.
  174.  *
  175.  * caret (^) controlifies the following character,
  176.  * backslash (\) produces special characters.
  177.  */
  178. static int str_controlify(string)
  179. char *string;
  180. {
  181.     register char *old, *new;    /* input and output string pointers */
  182.     int num, numidx;        /* for \ooo */
  183.  
  184.     new = old = string;
  185.     do
  186.     {
  187.     switch ( *old )
  188.     {
  189.     case '^':
  190.         if ( *++old == '?' )
  191.         *new++ = '\177';    /* delete */
  192.         else
  193.         *new++ = *old & 0x9F;    /* controlify */
  194.         break;
  195.     case '\\':
  196.         switch ( *++old )
  197.         {
  198.         case 'b':
  199.         *new++ = '\b';
  200.         break;
  201.         case 'e':    /* escape */
  202.         *new++ = '\033';
  203.         break;
  204.         case 'f':
  205.         *new++ = '\f';
  206.         break;
  207.         case 'n':
  208.         *new++ = '\n';
  209.         break;
  210.         case 'r':
  211.         *new++ = '\r';
  212.         break;
  213.         case 't':
  214.         *new++ = '\t';
  215.         break;
  216.         case 'v':
  217.         *new++ = '\v';
  218.         break;
  219.         case '0':    /* \ooo 1 to 3 digit octal number sequence */
  220.         case '1':
  221.         case '2':
  222.         case '3':
  223.         case '4':
  224.         case '5':
  225.         case '6':
  226.         case '7':
  227.         num = *old++ - '0';
  228.         for ( numidx = 1; 
  229.              (numidx < 3) && ('0' <= *old) && (*old <= '7');
  230.              numidx++ )
  231.             num = num * 8 + *old++ - '0';
  232.         old--;    /* adjust */
  233.         *new++ = num;
  234.         break;
  235.         default:
  236.         *new++ = *old;
  237.         break;
  238.         }
  239.         break;
  240.     default:
  241.         *new++ = *old;
  242.         break;
  243.     }
  244.     }
  245.     while ( *old++ );
  246.  
  247.     return(new-string-1);
  248. }
  249.  
  250. /*
  251.  * definitions copied from XKeyBind.c
  252.  * sadly missing in /usr/include/X11/*.h
  253.  */
  254. #define AllMods (ShiftMask|LockMask|ControlMask| \
  255.          Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
  256.  
  257. struct XKeytrans {
  258.     struct XKeytrans *next;/* next on list */
  259.     char *string;        /* string to return when the time comes */
  260.     int len;        /* length of string (since NULL is legit)*/
  261.     KeySym key;        /* keysym rebound */
  262.     unsigned int state;    /* modifier state */
  263.     KeySym *modifiers;    /* modifier keysyms you want */
  264.     int mlen;        /* length of modifier list */
  265. };
  266.  
  267. /*
  268.  * macro to find matching KeySym for a modifier index.
  269.  */
  270. #define ComputeKeysymFromMapindex(dpy, index) \
  271.   XKeycodeToKeysym(dpy, \
  272.            ((dpy)->modifiermap)->modifiermap \
  273.            [(index)*((dpy)->modifiermap)->max_keypermod], \
  274.            0)
  275.  
  276. /*
  277.  * shell around XRebindKeysym: check whether KeySym is already rebound.
  278.  * If it is, just replace the string. XRebindKeysym should do this,
  279.  * but it doesn't.
  280.  *
  281.  * RebindKeysym also translates the modifier state into a modifier list
  282.  * as required by XRebindKeysym. XRebindKeysym then translates this back
  283.  * into a modifier state (What a waste of time!). The current implementation
  284.  * of XLookupString only checks the modifier state, so calling XRebindKeysym
  285.  * once with the generated modifier list is sufficient.
  286.  * If a later implementation of XLookupString actually checks pressed
  287.  * modifier keys, it will become necessary to call XRebindKeysym repeatedly
  288.  * for all left and right modifier keys (e.g. Shift_L and Shift_R).
  289.  * Rebinding combinations of modifiers will then become quite awkward.
  290.  */
  291. static void RebindKeysym(dpy, keysym, modmask, str, nbytes)
  292.     Display *dpy;
  293.     KeySym keysym;
  294.     unsigned int modmask;
  295.     char *str;
  296.     int nbytes;
  297. {
  298.     register struct XKeytrans *p; /* pointer into rebind list */
  299.     KeySym modlist[8];        /* Modifier array for XRebindKeysym */
  300.     register int modcnt = 0;    /* Number of Modifiers in array */
  301.     register int modidx;    /* Index into modmask */
  302.     static char *modnames[] = { 
  303.     "shift", "lock", "control", "mod1", "mod2", "mod3", "mod4", "mod5" 
  304.     };
  305.  
  306.     /* see if already rebound. if it is, just replace string */
  307.     for ( p = dpy->key_bindings; p; p = p->next )
  308.     {
  309.     if ( ( (modmask & AllMods) == p->state ) && ( keysym == p->key ) )
  310.     {
  311.         Xfree(p->string);
  312.         p->len = 0;
  313.         if ( p->string = (char *)Xmalloc((unsigned)nbytes) )
  314.         {
  315.         bcopy((char *)str, p->string, nbytes);
  316.         p->len = nbytes;
  317.         }
  318.         else
  319.         {
  320.         error("RebindKeysym: out of memory!");
  321.         }
  322.         return;
  323.     }
  324.     }
  325.  
  326.     /* create list of keysyms from modmask so XRebindKeysym can recompute
  327.      * a modmask from it. */
  328.     for ( modidx = 0; modidx <= Mod5MapIndex; modidx++ )
  329.     {
  330.     if ( ( modmask & (1<<modidx) ) && 
  331.         ( NoSymbol == ( modlist[modcnt++] = 
  332.                ComputeKeysymFromMapindex(dpy, modidx))))
  333.       error("Modifier %02s is not on any key.", 
  334.         modnames[modidx]);
  335.     }
  336.     XRebindKeysym(dpy, keysym, modlist, modcnt, str, nbytes);
  337.  
  338.     return;
  339. }
  340.  
  341.  
  342. DEFUN("x-rebind-keysym", Fx_rebind_keysym, Sx_rebind_keysym, 1, 3,
  343.       "sKeySym: \nsModifiers: \nsString: ",
  344.       "Rebind KEYSYM with combination of MODIFIERS to STRING.\n\n\
  345. KEYSYM is a string containing a valid keysym name. Case is significant.\n\n\
  346. MODIFIERS is a comma separated list of modifier combinations containing\n\
  347. the letters n, s, l, c, m (or 1), 2, 3, 4, and 5 for none, shift, lock,\n\
  348. control, mod1 (meta), mod2, mod3, mod4, and mod5, respectively.\n\n\
  349. STRING is a string up to 64 characters long. The caret (^) character can be\n\
  350. used to controlify the following character. The backslash (\\) produces\n\
  351. special characters (\\b=backspace, \\e=escape, \\f=form feed, \\n=newline,\n\
  352. \\r=carriage return, \\t=tab, \\v=vertical tab, \\ooo=1 to 3 digit octal code.\n\
  353. Other \\x=character x, e.g. \\^ gives ^).")
  354.  
  355.   (keysym, modifiers, string)
  356.     register Lisp_Object keysym;
  357.     register Lisp_Object modifiers;
  358.     register Lisp_Object string;
  359. {
  360.     KeySym sym;            /* KeySym for string keysym */
  361.     int modmask = 0;        /* Modifiers to set in array */
  362.     int stringlen;        /* Length of string */
  363.     char *modptr;        /* pointer into modifier string */
  364.  
  365.     /* check whether we understand X and whether the arguments are valid */
  366.     check_xterm();
  367.  
  368.     CHECK_STRING(keysym, 1);
  369.     if ( NoSymbol == ( sym = XStringToKeysym(XSTRING(keysym)->data) ) )
  370.     error("Invalid keysym.");
  371.  
  372.     if ( !NULL(string) )
  373.     {
  374.         CHECK_STRING(string, 3);
  375.     /* controlify. length limit comes from mapping_buf in x11term.c */
  376.     if ( ( stringlen = str_controlify( (char *)XSTRING(string)->data ) )
  377.                             > MAPPING_BUF_SIZE )
  378.         error("String must not be longer than %d characters.", 
  379.           MAPPING_BUF_SIZE);
  380.     }
  381.     else
  382.         stringlen = 0;
  383.  
  384.     if ( !NULL(modifiers) )
  385.     {
  386.         CHECK_STRING(modifiers, 2);
  387.     modptr = (char *)(XSTRING(modifiers)->data);
  388.  
  389.     do            /* scan modifier string */
  390.     {
  391.         switch ( *modptr )
  392.         {
  393.         case 'n':        /* keyletter n (for none) is a dummy */
  394.         case 'N':        /* don't be so case sensitive */
  395.         case ' ':        /* skip blanks */
  396.             break;
  397.         case 's':
  398.         case 'S':
  399.             modmask |= ShiftMask;
  400.         break;
  401.         case 'l':
  402.         case 'L':
  403.         modmask |= LockMask;
  404.         break;
  405.         case 'c':
  406.         case 'C':
  407.         modmask |= ControlMask;
  408.         break;
  409.         case 'm':
  410.         case 'M':
  411.         case '1':        /* synonym */
  412.         modmask |= Mod1Mask;
  413.         break;
  414.         case '2':
  415.         modmask |= Mod2Mask;
  416.         break;
  417.         case '3':
  418.         modmask |= Mod3Mask;
  419.         break;
  420.         case '4':
  421.         modmask |= Mod4Mask;
  422.         break;
  423.         case '5':
  424.         modmask |= Mod5Mask;
  425.         break;
  426.         case ',':        /* comma or end -> rebind */
  427.         case '\0':
  428.         RebindKeysym(XXdisplay, sym, modmask, 
  429.                  stringlen ? (char *)XSTRING(string)->data : "",
  430.                  stringlen);
  431.         modmask = 0;
  432.         break;
  433.         default:
  434.         if ( isprint(*modptr) )
  435.             error("Invalid modifier \'%c\'.", *modptr);
  436.         else
  437.             error("Invalid modifier (0x%x).", *modptr);
  438.         break;
  439.         }
  440.     } while ( *modptr++ );
  441.     }
  442.     else            /* no modifiers */
  443.         RebindKeysym(XXdisplay, sym, 0, 
  444.               stringlen ? (char *)XSTRING(string)->data : "",
  445.               stringlen);
  446.  
  447.     return;
  448. }
  449.  
  450. /*
  451.  * display the current list of key rebindings.
  452.  * x-rebind-list-start initializes the list pointer
  453.  * x-rebind-list-next  returns a string containing a key rebinding.
  454.  */
  455. static struct XKeytrans *_x_rebind_list_p; /* should be initialized to 0,
  456.                         * but that makes it a const??? */
  457.  
  458. DEFUN ("x-rebind-list-start", Fx_rebind_list_start, Sx_rebind_list_start, 
  459.        0, 0, 0, "Initialize pointer into key rebind list.")
  460.      ()
  461. {
  462.     check_xterm ();
  463.  
  464.     if ( _x_rebind_list_p = XXdisplay->key_bindings )
  465.     return(Qt);
  466.     else
  467.     return (Qnil);
  468. }
  469.  
  470. DEFUN ("x-rebind-list-next", Fx_rebind_list_next, Sx_rebind_list_next,
  471.        0, 0, 0, "Return next line of key bindings.")
  472.      ()
  473. {
  474.     char str[2*MAPPING_BUF_SIZE+32]; /* string to contain line */
  475.     char *strptr;        /* pointer to current string position */
  476.     char *ptr;            /* general purpose character pointer */
  477.     int idx;            /* index for decoding modifier state */
  478.     static char modchars[] = "slcm2345"; /* modifier chars */
  479.  
  480.     check_xterm ();
  481.  
  482.     if ( _x_rebind_list_p )
  483.     {
  484.     strcpy(str, XKeysymToString(_x_rebind_list_p->key));
  485.     strptr = str + strlen(str);
  486.     if ( ( strptr - str ) < 8 )
  487.         *strptr++ = '\t';
  488.     *strptr++ = '\t';
  489.  
  490.     /* decode modifier state */
  491.     ptr = strptr;
  492.     if ( _x_rebind_list_p->state )
  493.     {
  494.         for ( idx = 0; idx <= Mod5MapIndex; idx++ )
  495.         {
  496.         if ( _x_rebind_list_p->state & (1<<idx) )
  497.             *strptr++ = modchars[idx];
  498.         }
  499.     }
  500.     else
  501.         *strptr++ = 'n';
  502.  
  503.     /* if following entries have the same keysym and string, add
  504.      * their modifier states as comma separated list
  505.      */
  506.     while ( _x_rebind_list_p->next &&
  507.            ( _x_rebind_list_p->key == _x_rebind_list_p->next->key ) &&
  508.            ( _x_rebind_list_p->len == _x_rebind_list_p->next->len ) &&
  509.            ( 0 == bcmp(_x_rebind_list_p->string,
  510.                _x_rebind_list_p->next->string,
  511.                _x_rebind_list_p->len) ) )
  512.     {
  513.         _x_rebind_list_p = _x_rebind_list_p->next;
  514.         *strptr++ = ',';
  515.         if ( _x_rebind_list_p->state )
  516.         {
  517.         for ( idx = 0; idx <= Mod5MapIndex; idx++ )
  518.         {
  519.             if ( _x_rebind_list_p->state & (1<<idx) )
  520.             *strptr++ = modchars[idx];
  521.         }
  522.         }
  523.         else
  524.         *strptr++ = 'n';
  525.     }
  526.     if ( ( strptr - ptr ) < 8 )
  527.         *strptr++ = '\t';
  528.     *strptr++ = '\t';
  529.     
  530.     /* uncontrolify string */
  531.     *strptr++ = '\"';
  532.     for ( ptr = _x_rebind_list_p->string;
  533.          ptr < _x_rebind_list_p->string + _x_rebind_list_p->len;
  534.          ptr++ )
  535.     {
  536.         if ( isprint(*ptr) )
  537.         *strptr++ = *ptr;
  538.         else 
  539.         {
  540.         *strptr++ = '^';
  541.         if ( *ptr < ' ')
  542.             *strptr++ = *ptr + '@';
  543.         else
  544.             *strptr++ = '?';
  545.         }
  546.     }
  547.     *strptr++ = '\"';
  548.     *strptr = '\0';
  549.     _x_rebind_list_p = _x_rebind_list_p->next;
  550.     }
  551.     else
  552.         *str = '\0';
  553.  
  554.     return(build_string(str));
  555. }
  556. /* end of x-rebind-... functions */
  557.  
  558. .
  559. 23a
  560. /*
  561.  * Modified by Nick Ruprecht, Institut fuer Informatik, Freiburg, Germany
  562.  *
  563.  * Added functions to rebind keysyms (x-rebind-keysym etc)
  564.  * Note: This works on a Sun under SunOS 4.1.1 with X11R4.
  565.  *      The routines make use of internal X data structures to make up
  566.  *     for some missing functionality in X. This will probably make it
  567.  *     necessary to review the code to make it portable.
  568.  *
  569.  * 28-MAY-1991/Ru: release
  570.  */
  571.  
  572. /*
  573.  * The following includes and the macro toupper are needed for x-rebind-keysym.
  574.  * Xlibos.h must be included before lisp.h - it redefines NULL.
  575.  */
  576. #include <sys/types.h>        /* needed by Xlibos.h */
  577. #include <X11/Xlibos.h>        /* for Xmalloc, Xfree */
  578. #include <ctype.h>
  579.  
  580. .
  581.  
  582. e x-win.el
  583. 221a
  584.  
  585.       ;; 23-MAY-1991/Ru: additional mouse buttons missing in x-mouse.el
  586.       (define-key mouse-map x-button-s-left 'x-mouse-set-mark)
  587.       (define-key mouse-map x-button-c-left 'x-mouse-select)
  588.  
  589.       ;; 23-MAY-1991/Ru: set default keysym bindings if not already done
  590.       (if (not x-rebind-defaults-done)
  591.       (x-rebind-defaults))
  592. .
  593. 177a
  594. ;; 16-MAY-1991/Ru: define function for setting default rebindings for Suns.
  595. ;;    This might have to be changed if the keys produce different keysyms.
  596. (defun x-rebind-defaults ()
  597.   "Set X key bindings for function keys to match previous version.
  598. The following table shows all key bindings (can be shifted, locked or both):
  599.  
  600. L1 ... L10 :    M-[ 192 z ... M-[ 201 z
  601. R1 ... R15 :    M-[ 208 z ... M-[ 222 z
  602. F1 ... F10 :    M-[ 224 z ... M-[ 233 z
  603. KP_F1 .. KP_F4:    M-[ 234 z ... M-[ 237 z    (for F11, F12, ...)
  604. Break :        M-[ 223 z        (for backward compatibility)
  605. Left :        C-b
  606. Right :        C-f
  607. Up :        C-p
  608. Down :        C-n
  609. Help :        C-h"
  610.  
  611.   (interactive)
  612.   (x-rebind-keysym "F1" "n,sl,s,l" "\e[224z")
  613.   (x-rebind-keysym "F2" "n,sl,s,l" "\e[225z")
  614.   (x-rebind-keysym "F3" "n,sl,s,l" "\e[226z")
  615.   (x-rebind-keysym "F4" "n,sl,s,l" "\e[227z")
  616.   (x-rebind-keysym "F5" "n,sl,s,l" "\e[228z")
  617.   (x-rebind-keysym "F6" "n,sl,s,l" "\e[229z")
  618.   (x-rebind-keysym "F7" "n,sl,s,l" "\e[230z")
  619.   (x-rebind-keysym "F8" "n,sl,s,l" "\e[231z")
  620.   (x-rebind-keysym "F9" "n,sl,s,l" "\e[232z")
  621.   (x-rebind-keysym "F10" "n,sl,s,l" "\e[233z")
  622.   (x-rebind-keysym "L1" "n,sl,s,l" "\e[192z")
  623.   (x-rebind-keysym "L2" "n,sl,s,l" "\e[193z")
  624.   (x-rebind-keysym "L3" "n,sl,s,l" "\e[194z")
  625.   (x-rebind-keysym "L4" "n,sl,s,l" "\e[195z")
  626.   (x-rebind-keysym "L5" "n,sl,s,l" "\e[196z")
  627.   (x-rebind-keysym "L6" "n,sl,s,l" "\e[197z")
  628.   (x-rebind-keysym "L7" "n,sl,s,l" "\e[198z")
  629.   (x-rebind-keysym "L8" "n,sl,s,l" "\e[199z")
  630.   (x-rebind-keysym "L9" "n,sl,s,l" "\e[200z")
  631.   (x-rebind-keysym "L10" "n,sl,s,l" "\e[201z")
  632.   (x-rebind-keysym "R1" "n,sl,s,l" "\e[208z")
  633.   (x-rebind-keysym "R2" "n,sl,s,l" "\e[209z")
  634.   (x-rebind-keysym "R3" "n,sl,s,l" "\e[210z")
  635.   (x-rebind-keysym "R4" "n,sl,s,l" "\e[211z")
  636.   (x-rebind-keysym "R5" "n,sl,s,l" "\e[212z")
  637.   (x-rebind-keysym "R6" "n,sl,s,l" "\e[213z")
  638.   (x-rebind-keysym "R7" "n,sl,s,l" "\e[214z")
  639.   (x-rebind-keysym "R8" "n,sl,s,l" "\e[215z")
  640.   (x-rebind-keysym "R9" "n,sl,s,l" "\e[216z")
  641.   (x-rebind-keysym "R10" "n,sl,s,l" "\e[217z")
  642.   (x-rebind-keysym "R11" "n,sl,s,l" "\e[218z")
  643.   (x-rebind-keysym "R12" "n,sl,s,l" "\e[219z")
  644.   (x-rebind-keysym "R13" "n,sl,s,l" "\e[220z")
  645.   (x-rebind-keysym "R14" "n,sl,s,l" "\e[221z")
  646.   (x-rebind-keysym "R15" "n,sl,s,l" "\e[222z")
  647.   (x-rebind-keysym "KP_F1" "n,sl,s,l" "\e[234z")
  648.   (x-rebind-keysym "KP_F2" "n,sl,s,l" "\e[235z")
  649.   (x-rebind-keysym "KP_F3" "n,sl,s,l" "\e[236z")
  650.   (x-rebind-keysym "KP_F4" "n,sl,s,l" "\e[237z")
  651.   (x-rebind-keysym "Break" "n,sl,s,l" "\e[223z")
  652.   (x-rebind-keysym "Left" "n,sl,s,l" "^B")
  653.   (x-rebind-keysym "Right" "n,sl,s,l" "^F")
  654.   (x-rebind-keysym "Up" "n,sl,s,l" "^P")
  655.   (x-rebind-keysym "Down" "n,sl,s,l" "^N")
  656.   (x-rebind-keysym "Help" "n,sl,s,l" "^H")
  657.  
  658.   (setq x-rebind-defaults-done t))
  659.  
  660. ;; 28-MAY-1991/Ru: rebind keypad on the right of the keyboard for Suns.
  661. ;;    This might have to be changed if the keys produce different keysyms.
  662. ;;    Some rebindings are made comments as XLookupString already returns
  663. ;;    the correct character.
  664. (defun x-rebind-padkeys ()
  665.   "Set standard X key bindings for keypad keys.
  666. With no modifier, or lock+shift, the numeric keys give simple motion commands.
  667. With shift or lock, the keys produce the indicated characters.
  668. With meta, the numeric keys and the minus key form part of a numeric argument
  669. for the next command.
  670. With control, the numeric keys produce additional motion commands. The other
  671. keypad keys produce commands deemed useful, see table for details.
  672. The following table shows all keypad key bindings produced by this function:
  673.  
  674. modifrs.| n,sl        | s,l    | c,cl            | m,ml
  675. --------|---------------|-------|-----------------------|---------------
  676. R1    | C-x C-b    | C-xC-b|            |
  677. R2    | electric-comm.| elect.|            |
  678. R3    | C-g        | C-g    |            |
  679. Num_Lock| C-u        | C-u    |            |
  680. R4    | what-line    | =    | what-cursor-position    | M-=
  681. R5    | C-s        | /    | C-r            | re-search-forward
  682. R6    | auto-fill-mode| *    | toggle-read-only    | revert-buffer
  683. KP_Subt.| C-k        | -    | M-k            | M--
  684. R7    | M-<        | 7    | backward-beg-of-line    | M-7
  685. Up    | C-p        | 8    | backward-paragraph    | M-8
  686. R9    | M-v        | 9    | backward-end-of-line    | M-9
  687. KP_Add    | C-x o        | +    | C-x 1            | C-x 2
  688. Left    | C-b        | 4    | M-b            | M-4
  689. R11    | C-l        | 5    | back-to-indentation    | M-5
  690. Right    | C-f        | 6    | M-f            | M-6
  691. R13    | M->        | 1    | forward-beg-of-line    | M-1
  692. Down    | C-n        | 2    | forward-paragraph    | M-2
  693. R15    | C-v        | 3    | forward-end-of-line    | M-3
  694. Insert    | C-@        | 0    | forward-to-indentation| M-0
  695. KP_Deci.| C-d        | .    | M-d            | M-.
  696. KP_Enter| C-m        | C-m    | C-m            | C-m"
  697.  
  698.   (interactive)
  699.   (x-rebind-keysym "R1" "n,sl,s,l" "^X^B")
  700.   (x-rebind-keysym "R2" "n,sl,s,l" "\exelectric-command-history\r")
  701.   (x-rebind-keysym "R3" "n,sl,s,l" "^G")
  702.   (x-rebind-keysym "Num_Lock" "n,sl,s,l" "^U")
  703.   (x-rebind-keysym "R4" "n,sl" "\exwhat-line\r")
  704.   (x-rebind-keysym "R4" "s,l" "=")
  705.   (x-rebind-keysym "R4" "c,cl" "\exwhat-cursor-position\r")
  706.   (x-rebind-keysym "R4" "m,ml" "\e=")
  707.   (x-rebind-keysym "R5" "n,sl" "^S")
  708.   (x-rebind-keysym "R5" "s,l" "/")
  709.   (x-rebind-keysym "R5" "c,cl" "^R")
  710.   (x-rebind-keysym "R5" "m,ml" "\exre-search-forward\r")
  711.   (x-rebind-keysym "R6" "n,sl" "\exauto-fill-mode\r")
  712.   (x-rebind-keysym "R6" "s,l" "*")
  713.   (x-rebind-keysym "R6" "c,cl" "\extoggle-read-only\r")
  714.   (x-rebind-keysym "R6" "m,ml" "\exrevert-buffer")
  715.   (x-rebind-keysym "KP_Subtract" "n,sl" "^K")
  716. ;  (x-rebind-keysym "KP_Subtract" "s,l" "-")
  717.   (x-rebind-keysym "KP_Subtract" "c,cl" "\ek")
  718.   (x-rebind-keysym "KP_Subtract" "m,ml" "\e-")
  719.   (x-rebind-keysym "KP_Add" "n,sl" "^Xo")
  720. ;  (x-rebind-keysym "KP_Add" "s,l" "+")
  721.   (x-rebind-keysym "KP_Add" "c,cl" "^X1")
  722.   (x-rebind-keysym "KP_Add" "m,ml" "^X2")
  723. ;  (x-rebind-keysym "KP_Enter" "n,sl" "\r")
  724. ;  (x-rebind-keysym "KP_Enter" "s,l" "\r")
  725. ;  (x-rebind-keysym "KP_Enter" "c,cl" "\r")
  726. ;  (x-rebind-keysym "KP_Enter" "m,ml" "\r")
  727.   (x-rebind-keysym "KP_Decimal" "n,sl" "^D")
  728. ;  (x-rebind-keysym "KP_Decimal" "s,l" ".")
  729.   (x-rebind-keysym "KP_Decimal" "c,cl" "\ed")
  730.   (x-rebind-keysym "KP_Decimal" "m,ml" "\e.")
  731.   (x-rebind-keysym "Insert" "n,sl" "^@")
  732.   (x-rebind-keysym "Insert" "s,l" "0")
  733.   (x-rebind-keysym "Insert" "c,cl" "\exforward-to-indentation\r")
  734.   (x-rebind-keysym "Insert" "m,ml" "\e0")
  735.   (x-rebind-keysym "R13" "n,sl" "\e>")
  736.   (x-rebind-keysym "R13" "s,l" "1")
  737.   (x-rebind-keysym "R13" "c,cl" "\exforward-beg-of-line\r")
  738.   (x-rebind-keysym "R13" "m,ml" "\e1")
  739.   (x-rebind-keysym "Down" "n,sl" "^N")
  740.   (x-rebind-keysym "Down" "s,l" "2")
  741.   (x-rebind-keysym "Down" "c,cl" "\exforward-paragraph\r")
  742.   (x-rebind-keysym "Down" "m,ml" "\e2")
  743.   (x-rebind-keysym "R15" "n,sl" "^V")
  744.   (x-rebind-keysym "R15" "s,l" "3")
  745.   (x-rebind-keysym "R15" "c,cl" "\exforward-end-of-line\r")
  746.   (x-rebind-keysym "R15" "m,ml" "\e3")
  747.   (x-rebind-keysym "Left" "n,sl" "^B")
  748.   (x-rebind-keysym "Left" "s,l" "4")
  749.   (x-rebind-keysym "Left" "c,cl" "\eb")
  750.   (x-rebind-keysym "Left" "m,ml" "\e4")
  751.   (x-rebind-keysym "R11" "n,sl" "^L")
  752.   (x-rebind-keysym "R11" "s,l" "5")
  753.   (x-rebind-keysym "R11" "c,cl" "\exback-to-indentation\r")
  754.   (x-rebind-keysym "R11" "m,ml" "\e5")
  755.   (x-rebind-keysym "Right" "n,sl" "^F")
  756.   (x-rebind-keysym "Right" "s,l" "6")
  757.   (x-rebind-keysym "Right" "c,cl" "\ef")
  758.   (x-rebind-keysym "Right" "m,ml" "\e6")
  759.   (x-rebind-keysym "R7" "n,sl" "\e<")
  760.   (x-rebind-keysym "R7" "s,l" "7")
  761.   (x-rebind-keysym "R7" "c,cl" "\exbackward-beg-of-line\r")
  762.   (x-rebind-keysym "R7" "m,ml" "\e7")
  763.   (x-rebind-keysym "Up" "n,sl" "^P")
  764.   (x-rebind-keysym "Up" "s,l" "8")
  765.   (x-rebind-keysym "Up" "c,cl" "\exbackward-paragraph\r")
  766.   (x-rebind-keysym "Up" "m,ml" "\e8")
  767.   (x-rebind-keysym "R9" "n,sl" "\ev")
  768.   (x-rebind-keysym "R9" "s,l" "9")
  769.   (x-rebind-keysym "R9" "c,cl" "\exbackward-end-of-line\r")
  770.   (x-rebind-keysym "R9" "m,ml" "\e9"))
  771.  
  772. ;; Output list of rebound keys in Help window
  773. ;; 28-MAY-1991/Ru
  774. (defun x-rebind-list ()
  775.   "Show list of keys that are rebound."
  776.   (interactive)
  777.   (if (x-rebind-list-start)
  778.       (with-output-to-temp-buffer "*Help*"
  779.     (princ "KeySym        Modifiers    String")
  780.     (terpri)
  781.     (princ "------        ---------    ------")
  782.     (terpri) (terpri)
  783.     (while (string< "" (princ (x-rebind-list-next)))
  784.       (terpri))
  785.     (print-help-return-message))
  786.     (message "List of rebound keys is empty.")))
  787.  
  788. .
  789. 19a
  790. ;; Modified by Nick Ruprecht, Institut fuer Informatik, Freiburg, Germany
  791. ;;    Support x-rebind-keysym. Define some simple functions for
  792. ;;    collections of default keysym rebindings for Suns.
  793. ;;    Define function x-rebind-list to show rebindings.
  794. ;;
  795. ;; 28-MAY-1991/Ru: release
  796.  
  797. ;; 28-MAY-1991/Ru: rebind defaults if not inhibited by user
  798. (defvar x-rebind-defaults-done nil
  799.   "*Non-NIL means x-rebind-defaults has been executed successfully.")
  800.  
  801. .
  802.  
  803. ;; site-init.el
  804. ;; Created by Nick Ruprecht, Institut fuer Informatik, Freiburg, Germany
  805. ;;
  806. ;; 28-MAY-1991/Ru: release
  807.  
  808. ;; insert date and name at point.
  809. ;; define insert-date-name-string in default.el, e.g. to
  810. ;; (defconst insert-date-name-string (user-full-name)
  811. ;;   "*String to insert after the current date in function insert-date-name.
  812. ;; Default is user-full-name.")
  813. ;; To insert \"date/Initial: \", enter the following lines in your .emacs file:
  814. ;; (setq insert-date-name-string
  815. ;;     (concat (capitalize (substring (user-real-login-name) 0 2)) \": \"))")
  816. ;;
  817. (defun insert-date-name ()
  818.   "Insert current date and user name at cursor (format dd-mmm-yyyy/user-name). 
  819. For customization of user-name, see variable insert-date-name-string."
  820.   (interactive "*")
  821.   (let ((time (current-time-string)))
  822.     (insert (substring time 8 10) "-"        ; day
  823.         (upcase (substring time 4 7)) "-"    ; month
  824.         (substring time 20 24))        ; year
  825.         (if insert-date-name-string        ; name 
  826.         (insert "/" insert-date-name-string))))
  827.  
  828. ;; advanced move commands
  829. (defun forward-beg-of-line (arg)
  830.   "Move forward to the beginning of the next line. With ARG, move ARG lines."
  831.   (interactive "p")
  832.   (if (< arg 0)
  833.       (backward-beg-of-line (- 0 arg))
  834.     (end-of-line arg)
  835.     (forward-char)))
  836.  
  837. (defun backward-beg-of-line (arg)
  838.   "Move backward to previous beginning of line. With ARG, move ARG lines."
  839.   (interactive "p")
  840.   (if (< arg 0)
  841.       (forward-beg-of-line (- 0 arg))
  842.     (backward-char)
  843.     (beginning-of-line (- 2 arg))))
  844.  
  845. (defun forward-end-of-line (arg)
  846.   "Move forward to the next end of line. With ARG, move ARG lines."
  847.   (interactive "p")
  848.   (forward-char)
  849.   (end-of-line arg))
  850.  
  851. (defun backward-end-of-line (arg)
  852.   "Move backward to the previous end of line. With ARG, move ARG lines."
  853.   (interactive "p")
  854.   (if (< arg 0)
  855.       (forward-end-of-line (- 0 arg))
  856.     (beginning-of-line (- 2 arg))
  857.     (backward-char)))
  858.  
  859. ;; undelete things just deleted. Sort of an un-undo.
  860. (defun undelete ()
  861.   "Undeletes what has just been deleted in current buffer. (Uses undo
  862. on last batch of delete entries in buffer-undo-list.)"
  863.   (interactive "*")
  864.  
  865.   ;; initialize for undo
  866.   (undo-start)
  867.   (undo-more 1)
  868.   (setq this-command 'undo)
  869.  
  870.   ;; check whether we can undelete or uninsert, else signal user
  871.   (if (eq pending-undo-list nil)
  872.       (error "Nothing to undelete"))
  873.   (if (not (stringp (car (car pending-undo-list))))
  874.       (error "Nothing to undelete. To uninsert, use undo."))
  875.  
  876.   ;; undo until no more deleted chars
  877.   (while (stringp (car (car pending-undo-list)))
  878.     (undo-more 1))
  879.   (if (eq pending-undo-list nil)
  880.       (message "Undelete!")
  881.     (message "Undelete! (To uninsert, use undo)")))
  882.  
  883. ;; insert a template, see also autoinsert.el
  884. (defvar insert-template-alist '(("\\.tex$" . "template.tex")
  885.                             ("\\.c$" . "template.c")
  886.                             ("\\.h$" . "template.h")
  887.                             ("[Mm]akefile" . "template.Makefile")
  888.                             ("\\.bib$" . "template.tex"))
  889.   "Alist specifying names of template files inserted with the command
  890. insert-template. See also auto-insert-alist.")
  891.  
  892. (defvar insert-template-directory "~/insert/"
  893.   "Directory from which templates are taken.")
  894.  
  895. (defun insert-template (arg)
  896.   "Insert template from template file into file.
  897. Matches the visited file name against `insert-template-alist'.
  898. With ARG, concatenates `-ARG' to template file name."
  899.   (interactive "*P")
  900.   (let ((alist insert-template-alist)
  901.     (name (file-name-sans-versions buffer-file-name))
  902.     (insert-file nil))
  903.     (while (and (not insert-file) alist)
  904.       (if (string-match (car (car alist)) name)
  905.       (setq insert-file (cdr (car alist)))
  906.     (setq alist (cdr alist))))
  907.  
  908.     (if insert-file
  909.         (let ((file (concat insert-template-directory insert-file)))
  910.       (if arg
  911.           (setq file (concat file "-" arg)))
  912.       (if (file-readable-p file)
  913.         (insert-file-contents file)
  914.             (error "insert-template: file %s not found" file))))))
  915.  
  916. ;; a few functions I find useful and think maybe some others might too
  917.  
  918. ;; Save buffers silently, then kill emacs. Put this on C-x 4 C-c.
  919. (defun save-buffers-silently-kill-emacs ()
  920.   "Silently save all file-visiting buffers, then kill this Emacs fork."
  921.   (interactive)
  922.   (save-buffers-kill-emacs t))
  923.  
  924. (define-key ctl-x-4-map "\C-c" 'save-buffers-silently-kill-emacs)
  925.  
  926. ;; Open a new line after the current line.
  927. ;; Put key definition on mode-hooks for modes where desired.
  928. (defun newline-and-indent-at-eol (arg)
  929.   "Insert a newline at end of current line (or at beginning of line if point
  930. is within indentation) and indent. With arg, insert that many newlines."
  931.   (interactive "*p")
  932.   (if (> (point) (save-excursion (back-to-indentation) (point)))
  933.       (end-of-line)
  934.     (beginning-of-line))
  935.   (newline arg)
  936.   (indent-according-to-mode))
  937.  
  938. (defun newline-at-eol (arg)
  939.   "Insert a newline at end of current line (or at beginning of line if point
  940. is within indentation). With arg, insert that many newlines."
  941.   (interactive "*p")
  942.   (if (> (point) (save-excursion (back-to-indentation) (point)))
  943.       (end-of-line)
  944.     (beginning-of-line))
  945.   (newline arg))
  946.