mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-21 06:55:39 +00:00
Initial revision
This commit is contained in:
parent
0d20f9a04e
commit
a2535589a9
340
lib-src/emacstool.c
Normal file
340
lib-src/emacstool.c
Normal file
@ -0,0 +1,340 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 1986 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
*
|
||||
*
|
||||
* For Emacs in SunView/Sun-Windows: (supported by Sun Unix v3.2)
|
||||
* Insert a notifier filter-function to convert all useful input
|
||||
* to "key" sequences that emacs can understand. See: Emacstool(1).
|
||||
*
|
||||
* Author: Jeff Peck, Sun Microsystems, Inc. <peck@sun.com>
|
||||
*
|
||||
* Original Idea: Ian Batten
|
||||
* Updated 15-Mar-88, Jeff Peck: set IN_EMACSTOOL, TERM, TERMCAP
|
||||
*
|
||||
*/
|
||||
|
||||
#include <suntool/sunview.h>
|
||||
#include <suntool/tty.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
#define BUFFER_SIZE 128 /* Size of all the buffers */
|
||||
|
||||
/* define WANT_CAPS_LOCK to make f-key T1 (aka F1) behave as CapsLock */
|
||||
#define WANT_CAPS_LOCK
|
||||
#ifdef WANT_CAPS_LOCK
|
||||
int caps_lock; /* toggle indicater for f-key T1 caps lock */
|
||||
static char *Caps = "[CAPS] "; /* Caps Lock prefix string */
|
||||
#define CAPS_LEN 7 /* strlen (Caps) */
|
||||
#endif
|
||||
|
||||
static char *mouse_prefix = "\030\000"; /* C-x C-@ */
|
||||
static int m_prefix_length = 2; /* mouse_prefix length */
|
||||
|
||||
static char *key_prefix = "\030*"; /* C-x * */
|
||||
static int k_prefix_length = 2; /* key_prefix length */
|
||||
|
||||
static char *emacs_name = "emacs"; /* default run command */
|
||||
static char buffer[BUFFER_SIZE]; /* send to ttysw_input */
|
||||
static char *title = "Emacstool - "; /* initial title */
|
||||
|
||||
Frame frame; /* Base frame for system */
|
||||
Tty ttysw; /* Where emacs is */
|
||||
int font_width, font_height; /* For translating pixels to chars */
|
||||
|
||||
int console_fd = 0; /* for debugging: setenv DEBUGEMACSTOOL */
|
||||
FILE *console; /* for debugging: setenv DEBUGEMACSTOOL */
|
||||
|
||||
Icon frame_icon;
|
||||
/* make an icon_image for the default frame_icon */
|
||||
static short default_image[258] =
|
||||
{
|
||||
#include <images/terminal.icon>
|
||||
};
|
||||
mpr_static(icon_image, 64, 64, 1, default_image);
|
||||
|
||||
|
||||
/*
|
||||
* Assign a value to a set of keys
|
||||
*/
|
||||
int
|
||||
button_value (event)
|
||||
Event *event;
|
||||
{
|
||||
int retval = 0;
|
||||
/*
|
||||
* Code up the current situation:
|
||||
*
|
||||
* 1 = MS_LEFT;
|
||||
* 2 = MS_MIDDLE;
|
||||
* 4 = MS_RIGHT;
|
||||
* 8 = SHIFT;
|
||||
* 16 = CONTROL;
|
||||
* 32 = META;
|
||||
* 64 = DOUBLE;
|
||||
* 128 = UP;
|
||||
*/
|
||||
|
||||
if (MS_LEFT == (event_id (event))) retval = 1;
|
||||
if (MS_MIDDLE == (event_id (event))) retval = 2;
|
||||
if (MS_RIGHT == (event_id (event))) retval = 4;
|
||||
|
||||
if (event_shift_is_down (event)) retval += 8;
|
||||
if (event_ctrl_is_down (event)) retval += 16;
|
||||
if (event_meta_is_down (event)) retval += 32;
|
||||
if (event_is_up (event)) retval += 128;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Variables to store the time of the previous mouse event that was
|
||||
* sent to emacs.
|
||||
*
|
||||
* The theory is that to time double clicks while ignoreing UP buttons,
|
||||
* we must keep track of the accumulated time.
|
||||
*
|
||||
* If someone writes a SUN-SET-INPUT-MASK for emacstool,
|
||||
* That could be used to selectively disable UP events,
|
||||
* and then this cruft wouldn't be necessary.
|
||||
*/
|
||||
static long prev_event_sec = 0;
|
||||
static long prev_event_usec = 0;
|
||||
|
||||
/*
|
||||
* Give the time difference in milliseconds, where one second
|
||||
* is considered infinite.
|
||||
*/
|
||||
int
|
||||
time_delta (now_sec, now_usec, prev_sec, prev_usec)
|
||||
long now_sec, now_usec, prev_sec, prev_usec;
|
||||
{
|
||||
long sec_delta = now_sec - prev_sec;
|
||||
long usec_delta = now_usec - prev_usec;
|
||||
|
||||
if (usec_delta < 0) { /* "borrow" a second */
|
||||
usec_delta += 1000000;
|
||||
--sec_delta;
|
||||
}
|
||||
|
||||
if (sec_delta >= 10)
|
||||
return (9999); /* Infinity */
|
||||
else
|
||||
return ((sec_delta * 1000) + (usec_delta / 1000));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Filter function to translate selected input events for emacs
|
||||
* Mouse button events become ^X^@(button x-col y-line time-delta) .
|
||||
* Function keys: ESC-*{c}{lrt} l,r,t for Left, Right, Top;
|
||||
* {c} encodes the keynumber as a character [a-o]
|
||||
*/
|
||||
static Notify_value
|
||||
input_event_filter_function (window, event, arg, type)
|
||||
Window window;
|
||||
Event *event;
|
||||
Notify_arg arg;
|
||||
Notify_event_type type;
|
||||
{
|
||||
struct timeval time_stamp;
|
||||
|
||||
if (console_fd) fprintf(console, "Event: %d\n", event_id(event));
|
||||
|
||||
/* UP L1 is the STOP key */
|
||||
if (event_id(event) == WIN_STOP) {
|
||||
ttysw_input(ttysw, "\007\007\007\007\007\007\007", 7);
|
||||
return NOTIFY_IGNORED;
|
||||
}
|
||||
|
||||
/* UP L5 & L7 is Expose & Open, let them pass to sunview */
|
||||
if (event_id(event) == KEY_LEFT(5) || event_id(event) == KEY_LEFT(7))
|
||||
if(event_is_up (event))
|
||||
return notify_next_event_func (window, event, arg, type);
|
||||
else return NOTIFY_IGNORED;
|
||||
|
||||
if (event_is_button (event)) { /* do Mouse Button events */
|
||||
/* Commented out so that we send mouse up events too.
|
||||
if (event_is_up (event))
|
||||
return notify_next_event_func (window, event, arg, type);
|
||||
*/
|
||||
time_stamp = event_time (event);
|
||||
ttysw_input (ttysw, mouse_prefix, m_prefix_length);
|
||||
sprintf (buffer, "(%d %d %d %d)\015",
|
||||
button_value (event),
|
||||
event_x (event) / font_width,
|
||||
event_y (event) / font_height,
|
||||
time_delta (time_stamp.tv_sec, time_stamp.tv_usec,
|
||||
prev_event_sec, prev_event_usec)
|
||||
);
|
||||
ttysw_input (ttysw, buffer, strlen(buffer));
|
||||
prev_event_sec = time_stamp.tv_sec;
|
||||
prev_event_usec = time_stamp.tv_usec;
|
||||
return NOTIFY_IGNORED;
|
||||
}
|
||||
|
||||
{ /* Do the function key events */
|
||||
int d;
|
||||
char c = (char) 0;
|
||||
if ((event_is_key_left (event)) ?
|
||||
((d = event_id(event) - KEY_LEFT(1) + 'a'), c='l') :
|
||||
((event_is_key_right (event)) ?
|
||||
((d = event_id(event) - KEY_RIGHT(1) + 'a'), c='r') :
|
||||
((event_is_key_top (event)) ?
|
||||
((d = event_id(event) - KEY_TOP(1) + 'a'), c='t') : 0)))
|
||||
{
|
||||
if (event_is_up(event)) return NOTIFY_IGNORED;
|
||||
if (event_shift_is_down (event)) c = c - 32;
|
||||
/* this will give a non-{lrt} for unshifted keys */
|
||||
if (event_ctrl_is_down (event)) c = c - 64;
|
||||
if (event_meta_is_down (event)) c = c + 128;
|
||||
#ifdef WANT_CAPS_LOCK
|
||||
/* set a toggle and relabel window so T1 can act like caps-lock */
|
||||
if (event_id(event) == KEY_TOP(1))
|
||||
{
|
||||
/* make a frame label with and without CAPS */
|
||||
strcpy (buffer, Caps);
|
||||
title = &buffer[CAPS_LEN];
|
||||
strncpy (title, (char *)window_get (frame, FRAME_LABEL),
|
||||
BUFFER_SIZE - CAPS_LEN);
|
||||
buffer[BUFFER_SIZE] = (char) 0;
|
||||
if (strncmp (title, Caps, CAPS_LEN) == 0)
|
||||
title += CAPS_LEN; /* already Caps */
|
||||
caps_lock = (caps_lock ? 0 : CAPS_LEN);
|
||||
window_set(frame, FRAME_LABEL, (title -= caps_lock), 0);
|
||||
return NOTIFY_IGNORED;
|
||||
}
|
||||
#endif
|
||||
ttysw_input (ttysw, key_prefix, k_prefix_length);
|
||||
sprintf (buffer, "%c%c", d, c);
|
||||
ttysw_input(ttysw, buffer, strlen(buffer));
|
||||
|
||||
return NOTIFY_IGNORED;
|
||||
}
|
||||
}
|
||||
if ((event_is_ascii(event) || event_is_meta(event))
|
||||
&& event_is_up(event)) return NOTIFY_IGNORED;
|
||||
#ifdef WANT_CAPS_LOCK
|
||||
/* shift alpha chars to upper case if toggle is set */
|
||||
if ((caps_lock) && event_is_ascii(event)
|
||||
&& (event_id(event) >= 'a') && (event_id(event) <= 'z'))
|
||||
event_set_id(event, (event_id(event) - 32));
|
||||
/* crufty, but it works for now. is there an UPCASE(event)? */
|
||||
#endif
|
||||
return notify_next_event_func (window, event, arg, type);
|
||||
}
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int error_code; /* Error codes */
|
||||
|
||||
if(getenv("DEBUGEMACSTOOL"))
|
||||
console = fdopen (console_fd = open("/dev/console",O_WRONLY), "w");
|
||||
|
||||
/* do this first, so arglist can override it */
|
||||
frame_icon = icon_create (ICON_LABEL, "Emacstool",
|
||||
ICON_IMAGE, &icon_image,
|
||||
0);
|
||||
|
||||
putenv("IN_EMACSTOOL=t"); /* notify subprocess that it is in emacstool */
|
||||
|
||||
if (putenv("TERM=sun") != 0) /* TTYSW will be a TERM=sun window */
|
||||
{fprintf (stderr, "%s: Could not set TERM=sun, using `%s'\n",
|
||||
argv[0], (char *)getenv("TERM")) ;};
|
||||
/*
|
||||
* If TERMCAP starts with a slash, it is the pathname of the
|
||||
* termcap file, not an entry extracted from it, so KEEP it!
|
||||
* Otherwise, it may not relate to the new TERM, so Nuke-It.
|
||||
* If there is no TERMCAP environment variable, don't make one.
|
||||
*/
|
||||
{
|
||||
char *termcap ; /* Current TERMCAP value */
|
||||
termcap = (char *)getenv("TERMCAP") ;
|
||||
if (termcap && (*termcap != '/'))
|
||||
{
|
||||
if (putenv("TERMCAP=") != 0)
|
||||
{fprintf (stderr, "%s: Could not clear TERMCAP\n", argv[0]) ;} ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
/* find command to run as subprocess in window */
|
||||
if (!(argv[0] = (char *)getenv("EMACSTOOL"))) /* Set emacs command name */
|
||||
argv[0] = emacs_name;
|
||||
for (argc = 1; argv[argc]; argc++) /* Use last one on line */
|
||||
if(!(strcmp ("-rc", argv[argc]))) /* Override if -rc given */
|
||||
{
|
||||
int i = argc;
|
||||
argv[argc--]=0; /* kill the -rc argument */
|
||||
if (argv[i+1]) { /* move to agrv[0] and squeeze the rest */
|
||||
argv[0]=argv[i+1];
|
||||
for (; argv[i+2]; (argv[i]=argv[i+2],argv[++i]=0));
|
||||
}
|
||||
}
|
||||
|
||||
strcpy (buffer, title);
|
||||
strncat (buffer, argv[0], /* append run command name */
|
||||
(BUFFER_SIZE - (strlen (buffer)) - (strlen (argv[0]))) - 1);
|
||||
|
||||
/* Build a frame to run in */
|
||||
frame = window_create ((Window)NULL, FRAME,
|
||||
FRAME_LABEL, buffer,
|
||||
FRAME_ICON, frame_icon,
|
||||
FRAME_ARGC_PTR_ARGV, &argc, argv,
|
||||
0);
|
||||
|
||||
/* Create a tty with emacs in it */
|
||||
ttysw = window_create (frame, TTY,
|
||||
TTY_QUIT_ON_CHILD_DEATH, TRUE,
|
||||
TTY_BOLDSTYLE, 8,
|
||||
TTY_ARGV, argv,
|
||||
0);
|
||||
|
||||
window_set(ttysw,
|
||||
WIN_CONSUME_PICK_EVENTS,
|
||||
WIN_STOP,
|
||||
WIN_MOUSE_BUTTONS, WIN_UP_EVENTS,
|
||||
/* LOC_WINENTER, LOC_WINEXIT, LOC_MOVE, */
|
||||
0,
|
||||
|
||||
WIN_CONSUME_KBD_EVENTS,
|
||||
WIN_STOP,
|
||||
WIN_ASCII_EVENTS,
|
||||
WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
|
||||
/* WIN_UP_ASCII_EVENTS, */
|
||||
0,
|
||||
|
||||
0);
|
||||
|
||||
font_height = (int)window_get (ttysw, WIN_ROW_HEIGHT);
|
||||
font_width = (int)window_get (ttysw, WIN_COLUMN_WIDTH);
|
||||
|
||||
/* Interpose my event function */
|
||||
error_code = (int) notify_interpose_event_func
|
||||
(ttysw, input_event_filter_function, NOTIFY_SAFE);
|
||||
|
||||
if (error_code != 0) /* Barf */
|
||||
{
|
||||
fprintf (stderr, "notify_interpose_event_func got %d.\n", error_code);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
window_main_loop (frame); /* And away we go */
|
||||
}
|
101
lisp/case-table.el
Normal file
101
lisp/case-table.el
Normal file
@ -0,0 +1,101 @@
|
||||
;; Functions for extending the character set and dealing with case tables.
|
||||
;; Copyright (C) 1988 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;; Written by:
|
||||
;; TN/ETX/TX/UMG Howard Gayle UUCP : seismo!enea!erix!howard
|
||||
;; Telefonaktiebolaget L M Ericsson Phone: +46 8 719 55 65
|
||||
;; Ericsson Telecom Telex: 14910 ERIC S
|
||||
;; S-126 25 Stockholm FAX : +46 8 719 64 82
|
||||
;; Sweden
|
||||
|
||||
(defun describe-buffer-case-table ()
|
||||
"Describe the case table of the current buffer."
|
||||
(interactive)
|
||||
(let ((vector (make-vector 256 nil))
|
||||
(case-table (current-case-table))
|
||||
(i 0))
|
||||
(while (< i 256)
|
||||
(aset vector i
|
||||
(cond ((/= ch (downcase ch))
|
||||
(concat "uppercase, matches "
|
||||
(text-char-description (downcase ch))))
|
||||
((/= ch (upcase ch))
|
||||
(concat "lowercase, matches "
|
||||
(text-char-description (upcase ch))))
|
||||
(t "case-invariant")))
|
||||
(setq i (1+ i))))
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(describe-vector vector)))
|
||||
|
||||
(defun invert-case (count)
|
||||
"Change the case of the character just after point and move over it.
|
||||
With arg, applies to that many chars.
|
||||
Negative arg inverts characters before point but does not move."
|
||||
(interactive "p")
|
||||
(if (< count 0)
|
||||
(progn (setq count (min (1- (point)) (- count)))
|
||||
(forward-char (- count))))
|
||||
(while (> count 0)
|
||||
(let ((oc (following-char))) ; Old character.
|
||||
(cond ((/= (upcase ch) ch)
|
||||
(replace-char (upcase ch)))
|
||||
((/= (downcase ch) ch)
|
||||
(replace-char (downcase ch)))))
|
||||
(forward-char 1)
|
||||
(setq count (1- count))))
|
||||
|
||||
(defun set-case-syntax-delims (l r table)
|
||||
"Make characters L and R a matching pair of non-case-converting delimiters.
|
||||
Sets the entries for L and R in standard-case-table,
|
||||
standard-syntax-table, and text-mode-syntax-table to indicate
|
||||
left and right delimiters."
|
||||
(aset (car table) l l)
|
||||
(aset (car table) r r)
|
||||
(modify-syntax-entry l (concat "(" (char-to-string r) " ")
|
||||
(standard-syntax-table))
|
||||
(modify-syntax-entry l (concat "(" (char-to-string r) " ")
|
||||
text-mode-syntax-table)
|
||||
(modify-syntax-entry r (concat ")" (char-to-string l) " ")
|
||||
(standard-syntax-table))
|
||||
(modify-syntax-entry r (concat ")" (char-to-string l) " ")
|
||||
text-mode-syntax-table))
|
||||
|
||||
(defun set-case-syntax-pair (uc lc table)
|
||||
"Make characters UC and LC a pair of inter-case-converting letters.
|
||||
Sets the entries for characters UC and LC in
|
||||
standard-case-table, standard-syntax-table, and
|
||||
text-mode-syntax-table to indicate an (uppercase, lowercase)
|
||||
pair of letters."
|
||||
(aset (car table) uc lc)
|
||||
(modify-syntax-entry lc "w " (standard-syntax-table))
|
||||
(modify-syntax-entry lc "w " text-mode-syntax-table)
|
||||
(modify-syntax-entry uc "w " (standard-syntax-table))
|
||||
(modify-syntax-entry uc "w " text-mode-syntax-table))
|
||||
|
||||
(defun set-case-syntax (c syntax table)
|
||||
"Make characters C case-invariant with syntax SYNTAX.
|
||||
Sets the entries for character C in standard-case-table,
|
||||
standard-syntax-table, and text-mode-syntax-table to indicate this.
|
||||
SYNTAX should be \" \", \"w\", \".\" or \"_\"."
|
||||
(aset (car table) c c)
|
||||
(modify-syntax-entry c syntax (standard-syntax-table))
|
||||
(modify-syntax-entry c syntax text-mode-syntax-table))
|
||||
|
||||
(provide 'case-table)
|
115
lisp/disp-table.el
Normal file
115
lisp/disp-table.el
Normal file
@ -0,0 +1,115 @@
|
||||
;; Functions for dealing with char tables.
|
||||
;; Copyright (C) 1987 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;; Written by Howard Gayle. See case-table.el for details.
|
||||
|
||||
(require 'case-table)
|
||||
|
||||
(defun rope-to-vector (rope)
|
||||
(let* ((len (/ (length rope) 2))
|
||||
(vector (make-vector len nil))
|
||||
(i 0))
|
||||
(while (< i len)
|
||||
(aset vector i (rope-elt rope i))
|
||||
(setq i (1+ i)))))
|
||||
|
||||
(defun describe-display-table (DT)
|
||||
"Describe the display-table DT in a help buffer."
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(princ "\nTruncation glyf: ")
|
||||
(prin1 (aref dt 256))
|
||||
(princ "\nWrap glyf: ")
|
||||
(prin1 (aref dt 257))
|
||||
(princ "\nEscape glyf: ")
|
||||
(prin1 (aref dt 258))
|
||||
(princ "\nCtrl glyf: ")
|
||||
(prin1 (aref dt 259))
|
||||
(princ "\nSelective display rope: ")
|
||||
(prin1 (rope-to-vector (aref dt 260)))
|
||||
(princ "\nCharacter display ropes:\n")
|
||||
(let ((vector (make-vector 256 nil))
|
||||
(i 0))
|
||||
(while (< i 256)
|
||||
(aset vector i
|
||||
(if (stringp (aref dt i))
|
||||
(rope-to-vector (aref dt i))
|
||||
(aref dt i)))
|
||||
(setq i (1+ i)))
|
||||
(describe-vector vector))
|
||||
(print-help-return-message)))
|
||||
|
||||
(defun describe-current-display-table ()
|
||||
"Describe the display-table in use in the selected window and buffer."
|
||||
(interactive)
|
||||
(describe-display-table
|
||||
(or (window-display-table (selected-window))
|
||||
buffer-display-table
|
||||
standard-display-table)))
|
||||
|
||||
(defun make-display-table ()
|
||||
(make-vector 261 nil))
|
||||
|
||||
(defun standard-display-8bit (l h)
|
||||
"Display characters in the range [L, H] literally."
|
||||
(while (<= l h)
|
||||
(if (and (>= l ?\ ) (< l 127))
|
||||
(if standard-display-table (aset standard-display-table l nil))
|
||||
(or standard-display-table
|
||||
(setq standard-display-table (make-vector 261 nil)))
|
||||
(aset standard-display-table l l))
|
||||
(setq l (1+ l))))
|
||||
|
||||
(defun standard-display-ascii (c s)
|
||||
"Display character C using string S."
|
||||
(or standard-display-table
|
||||
(setq standard-display-table (make-vector 261 nil)))
|
||||
(aset standard-display-table c (apply 'make-rope (append s nil))))
|
||||
|
||||
(defun standard-display-g1 (c sc)
|
||||
"Display character C as character SC in the g1 character set."
|
||||
(or standard-display-table
|
||||
(setq standard-display-table (make-vector 261 nil)))
|
||||
(aset standard-display-table c
|
||||
(make-rope (create-glyf (concat "\016" (char-to-string sc) "\017")))))
|
||||
|
||||
(defun standard-display-graphic (c gc)
|
||||
"Display character C as character GC in graphics character set."
|
||||
(or standard-display-table
|
||||
(setq standard-display-table (make-vector 261 nil)))
|
||||
(aset standard-display-table c
|
||||
(make-rope (create-glyf (concat "\e(0" (char-to-string gc) "\e(B")))))
|
||||
|
||||
(defun standard-display-underline (c uc)
|
||||
"Display character C as character UC plus underlining."
|
||||
(or standard-display-table
|
||||
(setq standard-display-table (make-vector 261 nil)))
|
||||
(aset standard-display-table c
|
||||
(make-rope (create-glyf (concat "\e[4m" (char-to-string uc) "\e[m")))))
|
||||
|
||||
(defun create-glyf (string)
|
||||
(let ((i 256))
|
||||
(while (and (< i 65536) (aref glyf-table i)
|
||||
(not (string= (aref glyf-table i) string)))
|
||||
(setq i (1+ i)))
|
||||
(if (= i 65536)
|
||||
(error "No free glyf codes remain"))
|
||||
(aset glyf-table i string)))
|
||||
|
||||
(provide 'disp-table)
|
338
lisp/ehelp.el
Normal file
338
lisp/ehelp.el
Normal file
@ -0,0 +1,338 @@
|
||||
;; Copyright (C) 1986 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
(require 'electric)
|
||||
(provide 'ehelp)
|
||||
|
||||
(defvar electric-help-map ()
|
||||
"Keymap defining commands available whilst scrolling
|
||||
through a buffer in electric-help-mode")
|
||||
|
||||
(put 'electric-help-undefined 'suppress-keymap t)
|
||||
(if electric-help-map
|
||||
()
|
||||
(let ((map (make-keymap)))
|
||||
(fillarray map 'electric-help-undefined)
|
||||
(define-key map (char-to-string meta-prefix-char) (copy-keymap map))
|
||||
(define-key map (char-to-string help-char) 'electric-help-help)
|
||||
(define-key map "?" 'electric-help-help)
|
||||
(define-key map " " 'scroll-up)
|
||||
(define-key map "\^?" 'scroll-down)
|
||||
(define-key map "." 'beginning-of-buffer)
|
||||
(define-key map "<" 'beginning-of-buffer)
|
||||
(define-key map ">" 'end-of-buffer)
|
||||
;(define-key map "\C-g" 'electric-help-exit)
|
||||
(define-key map "q" 'electric-help-exit)
|
||||
(define-key map "Q" 'electric-help-exit)
|
||||
;;a better key than this?
|
||||
(define-key map "r" 'electric-help-retain)
|
||||
|
||||
(setq electric-help-map map)))
|
||||
|
||||
(defun electric-help-mode ()
|
||||
"with-electric-help temporarily places its buffer in this mode
|
||||
\(On exit from with-electric-help, the buffer is put in default-major-mode)"
|
||||
(setq buffer-read-only t)
|
||||
(setq mode-name "Help")
|
||||
(setq major-mode 'help)
|
||||
(setq mode-line-buffer-identification '(" Help: %b"))
|
||||
(use-local-map electric-help-map)
|
||||
;; this is done below in with-electric-help
|
||||
;(run-hooks 'electric-help-mode-hook)
|
||||
)
|
||||
|
||||
(defun with-electric-help (thunk &optional buffer noerase)
|
||||
"Arguments are THUNK &optional BUFFER NOERASE.
|
||||
BUFFER defaults to \"*Help*\"
|
||||
THUNK is a function of no arguments which is called to initialise
|
||||
the contents of BUFFER. BUFFER will be erased before THUNK is called unless
|
||||
NOERASE is non-nil. THUNK will be called with standard-output bound to
|
||||
the buffer specified by BUFFER
|
||||
|
||||
After THUNK has been called, this function \"electrically\" pops up a window
|
||||
in which BUFFER is displayed and allows the user to scroll through that buffer
|
||||
in electric-help-mode.
|
||||
When the user exits (with electric-help-exit, or otherwise) the help
|
||||
buffer's window disappears (ie we use save-window-excursion)
|
||||
BUFFER is put into default-major-mode (or fundamental-mode) when we exit"
|
||||
(setq buffer (get-buffer-create (or buffer "*Help*")))
|
||||
(let ((one (one-window-p t))
|
||||
(two nil))
|
||||
(save-window-excursion
|
||||
(save-excursion
|
||||
(if one (goto-char (window-start (selected-window))))
|
||||
(let ((pop-up-windows t))
|
||||
(pop-to-buffer buffer))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(save-excursion
|
||||
(set-buffer buffer)
|
||||
(electric-help-mode)
|
||||
(setq buffer-read-only nil)
|
||||
(or noerase (erase-buffer)))
|
||||
(let ((standard-output buffer))
|
||||
(if (funcall thunk)
|
||||
()
|
||||
(set-buffer buffer)
|
||||
(set-buffer-modified-p nil)
|
||||
(goto-char (point-min))
|
||||
(if one (shrink-window-if-larger-than-buffer (selected-window)))))
|
||||
(set-buffer buffer)
|
||||
(run-hooks 'electric-help-mode-hook)
|
||||
(setq two (electric-help-command-loop))
|
||||
(cond ((eq (car-safe two) 'retain)
|
||||
(setq two (vector (window-height (selected-window))
|
||||
(window-start (selected-window))
|
||||
(window-hscroll (selected-window))
|
||||
(point))))
|
||||
(t (setq two nil))))
|
||||
|
||||
(message "")
|
||||
(set-buffer buffer)
|
||||
(setq buffer-read-only nil)
|
||||
(condition-case ()
|
||||
(funcall (or default-major-mode 'fundamental-mode))
|
||||
(error nil)))))
|
||||
(if two
|
||||
(let ((pop-up-windows t)
|
||||
tem)
|
||||
(pop-to-buffer buffer)
|
||||
(setq tem (- (window-height (selected-window)) (elt two 0)))
|
||||
(if (> tem 0) (shrink-window tem))
|
||||
(set-window-start (selected-window) (elt two 1) t)
|
||||
(set-window-hscroll (selected-window) (elt two 2))
|
||||
(goto-char (elt two 3)))
|
||||
;;>> Perhaps this shouldn't be done.
|
||||
;; so that when we say "Press space to bury" we mean it
|
||||
(replace-buffer-in-windows buffer)
|
||||
;; must do this outside of save-window-excursion
|
||||
(bury-buffer buffer))))
|
||||
|
||||
(defun electric-help-command-loop ()
|
||||
(catch 'exit
|
||||
(if (pos-visible-in-window-p (point-max))
|
||||
(progn (message "<<< Press Space to bury the help buffer >>>")
|
||||
(if (= (setq unread-command-char (read-char)) ?\ )
|
||||
(progn (setq unread-command-char -1)
|
||||
(throw 'exit t)))))
|
||||
(let (up down both neither
|
||||
(standard (and (eq (key-binding " ")
|
||||
'scroll-up)
|
||||
(eq (key-binding "\^?")
|
||||
'scroll-down)
|
||||
(eq (key-binding "Q")
|
||||
'electric-help-exit)
|
||||
(eq (key-binding "q")
|
||||
'electric-help-exit))))
|
||||
(Electric-command-loop
|
||||
'exit
|
||||
(function (lambda ()
|
||||
(let ((min (pos-visible-in-window-p (point-min)))
|
||||
(max (pos-visible-in-window-p (point-max))))
|
||||
(cond ((and min max)
|
||||
(cond (standard "Press Q to exit ")
|
||||
(neither)
|
||||
(t (setq neither (substitute-command-keys "Press \\[scroll-up] to exit ")))))
|
||||
(min
|
||||
(cond (standard "Press SPC to scroll, Q to exit ")
|
||||
(up)
|
||||
(t (setq up (substitute-command-keys "Press \\[scroll-up] to scroll; \\[electric-help-exit] to exit ")))))
|
||||
(max
|
||||
(cond (standard "Press DEL to scroll back, Q to exit ")
|
||||
(down)
|
||||
(t (setq down (substitute-command-keys "Press \\[scroll-down] to scroll back, \\[scroll-up] to exit ")))))
|
||||
(t
|
||||
(cond (standard "Press SPC to scroll, DEL to scroll back, Q to exit ")
|
||||
(both)
|
||||
(t (setq both (substitute-command-keys "Press \\[scroll-up] to scroll, \\[scroll-down] to scroll back, \\[electric-help-exit] to exit ")))))))))
|
||||
t))))
|
||||
|
||||
|
||||
|
||||
;(defun electric-help-scroll-up (arg)
|
||||
; ">>>Doc"
|
||||
; (interactive "P")
|
||||
; (if (and (null arg) (pos-visible-in-window-p (point-max)))
|
||||
; (electric-help-exit)
|
||||
; (scroll-up arg)))
|
||||
|
||||
(defun electric-help-exit ()
|
||||
">>>Doc"
|
||||
(interactive)
|
||||
(throw 'exit t))
|
||||
|
||||
(defun electric-help-retain ()
|
||||
"Exit electric-help, retaining the current window/buffer conifiguration.
|
||||
\(The *Help* buffer will not be selected, but \\[switch-to-buffer-other-window] RET
|
||||
will select it.)"
|
||||
(interactive)
|
||||
(throw 'exit '(retain)))
|
||||
|
||||
|
||||
;(defun electric-help-undefined ()
|
||||
; (interactive)
|
||||
; (let* ((keys (this-command-keys))
|
||||
; (n (length keys)))
|
||||
; (if (or (= n 1)
|
||||
; (and (= n 2)
|
||||
; meta-flag
|
||||
; (eq (aref keys 0) meta-prefix-char)))
|
||||
; (setq unread-command-char last-input-char
|
||||
; current-prefix-arg prefix-arg)
|
||||
; ;;>>> I don't care.
|
||||
; ;;>>> The emacs command-loop is too much pure pain to
|
||||
; ;;>>> duplicate
|
||||
; ))
|
||||
; (throw 'exit t))
|
||||
|
||||
(defun electric-help-undefined ()
|
||||
(interactive)
|
||||
(error "%s is undefined -- Press %s to exit"
|
||||
(mapconcat 'single-key-description (this-command-keys) " ")
|
||||
(if (eq (key-binding "Q") 'electric-help-exit)
|
||||
"Q"
|
||||
(substitute-command-keys "\\[electric-help-exit]"))))
|
||||
|
||||
|
||||
;>>> this needs to be hairified (recursive help, anybody?)
|
||||
(defun electric-help-help ()
|
||||
(interactive)
|
||||
(if (and (eq (key-binding "Q") 'electric-help-exit)
|
||||
(eq (key-binding " ") 'scroll-up)
|
||||
(eq (key-binding "\^?") 'scroll-down))
|
||||
(message "SPC scrolls forward, DEL scrolls back, Q exits and burys help buffer")
|
||||
;; to give something for user to look at while slow substitute-cmd-keys
|
||||
;; grinds away
|
||||
(message "Help...")
|
||||
(message "%s" (substitute-command-keys "\\[scroll-up] scrolls forward, \\[scroll-down] scrolls back, \\[electric-help-exit] exits.")))
|
||||
(sit-for 2))
|
||||
|
||||
|
||||
(defun electric-helpify (fun)
|
||||
(let ((name "*Help*"))
|
||||
(if (save-window-excursion
|
||||
;; kludge-o-rama
|
||||
(let* ((p (symbol-function 'print-help-return-message))
|
||||
(b (get-buffer name))
|
||||
(m (buffer-modified-p b)))
|
||||
(and b (not (get-buffer-window b))
|
||||
(setq b nil))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(message "%s..." (capitalize (symbol-name fun)))
|
||||
;; with-output-to-temp-buffer marks the buffer as unmodified.
|
||||
;; kludging excessively and relying on that as some sort
|
||||
;; of indication leads to the following abomination...
|
||||
;;>> This would be doable without such icky kludges if either
|
||||
;;>> (a) there were a function to read the interactive
|
||||
;;>> args for a command and return a list of those args.
|
||||
;;>> (To which one would then just apply the command)
|
||||
;;>> (The only problem with this is that interactive-p
|
||||
;;>> would break, but that is such a misfeature in
|
||||
;;>> any case that I don't care)
|
||||
;;>> It is easy to do this for emacs-lisp functions;
|
||||
;;>> the only problem is getting the interactive spec
|
||||
;;>> for subrs
|
||||
;;>> (b) there were a function which returned a
|
||||
;;>> modification-tick for a buffer. One could tell
|
||||
;;>> whether a buffer had changed by whether the
|
||||
;;>> modification-tick were different.
|
||||
;;>> (Presumably there would have to be a way to either
|
||||
;;>> restore the tick to some previous value, or to
|
||||
;;>> suspend updating of the tick in order to allow
|
||||
;;>> things like momentary-string-display)
|
||||
(and b
|
||||
(save-excursion
|
||||
(set-buffer b)
|
||||
(set-buffer-modified-p t)))
|
||||
(fset 'print-help-return-message 'ignore)
|
||||
(call-interactively fun)
|
||||
(and (get-buffer name)
|
||||
(get-buffer-window (get-buffer name))
|
||||
(or (not b)
|
||||
(not (eq b (get-buffer name)))
|
||||
(not (buffer-modified-p b)))))
|
||||
(fset 'print-help-return-message p)
|
||||
(and b (buffer-name b)
|
||||
(save-excursion
|
||||
(set-buffer b)
|
||||
(set-buffer-modified-p m))))))
|
||||
(with-electric-help 'ignore name t))))
|
||||
|
||||
|
||||
(defun electric-describe-key ()
|
||||
(interactive)
|
||||
(electric-helpify 'describe-key))
|
||||
|
||||
(defun electric-describe-mode ()
|
||||
(interactive)
|
||||
(electric-helpify 'describe-mode))
|
||||
|
||||
(defun electric-view-lossage ()
|
||||
(interactive)
|
||||
(electric-helpify 'view-lossage))
|
||||
|
||||
;(defun electric-help-for-help ()
|
||||
; "See help-for-help"
|
||||
; (interactive)
|
||||
; )
|
||||
|
||||
(defun electric-describe-function ()
|
||||
(interactive)
|
||||
(electric-helpify 'describe-function))
|
||||
|
||||
(defun electric-describe-variable ()
|
||||
(interactive)
|
||||
(electric-helpify 'describe-variable))
|
||||
|
||||
(defun electric-describe-bindings ()
|
||||
(interactive)
|
||||
(electric-helpify 'describe-bindings))
|
||||
|
||||
(defun electric-describe-syntax ()
|
||||
(interactive)
|
||||
(electric-helpify 'describe-syntax))
|
||||
|
||||
(defun electric-command-apropos ()
|
||||
(interactive)
|
||||
(electric-helpify 'command-apropos))
|
||||
|
||||
;(define-key help-map "a" 'electric-command-apropos)
|
||||
|
||||
|
||||
|
||||
|
||||
;;;; ehelp-map
|
||||
|
||||
(defvar ehelp-map ())
|
||||
(if ehelp-map
|
||||
nil
|
||||
(let ((map (copy-keymap help-map)))
|
||||
(substitute-key-definition 'describe-key 'electric-describe-key map)
|
||||
(substitute-key-definition 'describe-mode 'electric-describe-mode map)
|
||||
(substitute-key-definition 'view-lossage 'electric-view-lossage map)
|
||||
(substitute-key-definition 'describe-function 'electric-describe-function map)
|
||||
(substitute-key-definition 'describe-variable 'electric-describe-variable map)
|
||||
(substitute-key-definition 'describe-bindings 'electric-describe-bindings map)
|
||||
(substitute-key-definition 'describe-syntax 'electric-describe-syntax map)
|
||||
|
||||
(setq ehelp-map map)
|
||||
(fset 'ehelp-command map)))
|
||||
|
||||
;; Do (define-key global-map "\C-h" 'ehelp-command) if you want to win
|
||||
|
147
lisp/emacs-lisp/helper.el
Normal file
147
lisp/emacs-lisp/helper.el
Normal file
@ -0,0 +1,147 @@
|
||||
;; helper - utility help package for modes which want to provide help
|
||||
;; without relinquishing control, e.g. `electric' modes.
|
||||
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
;; Principal author K. Shane Hartman
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(provide 'helper) ; hey, here's a helping hand.
|
||||
|
||||
;; Bind this to a string for <blank> in "... Other keys <blank>".
|
||||
;; Helper-help uses this to construct help string when scrolling.
|
||||
;; Defaults to "return"
|
||||
(defvar Helper-return-blurb nil)
|
||||
|
||||
;; Keymap implementation doesn't work too well for non-standard loops.
|
||||
;; But define it anyway for those who can use it. Non-standard loops
|
||||
;; will probably have to use Helper-help. You can't autoload the
|
||||
;; keymap either.
|
||||
|
||||
|
||||
(defvar Helper-help-map nil)
|
||||
(if Helper-help-map
|
||||
nil
|
||||
(setq Helper-help-map (make-keymap))
|
||||
;(fillarray Helper-help-map 'undefined)
|
||||
(define-key Helper-help-map "m" 'Helper-describe-mode)
|
||||
(define-key Helper-help-map "b" 'Helper-describe-bindings)
|
||||
(define-key Helper-help-map "c" 'Helper-describe-key-briefly)
|
||||
(define-key Helper-help-map "k" 'Helper-describe-key)
|
||||
;(define-key Helper-help-map "f" 'Helper-describe-function)
|
||||
;(define-key Helper-help-map "v" 'Helper-describe-variable)
|
||||
(define-key Helper-help-map "?" 'Helper-help-options)
|
||||
(define-key Helper-help-map (char-to-string help-char) 'Helper-help-options)
|
||||
(fset 'Helper-help-map Helper-help-map))
|
||||
|
||||
(defun Helper-help-scroller ()
|
||||
(let ((blurb (or (and (boundp 'Helper-return-blurb)
|
||||
Helper-return-blurb)
|
||||
"return")))
|
||||
(save-window-excursion
|
||||
(goto-char (window-start (selected-window)))
|
||||
(if (get-buffer-window "*Help*")
|
||||
(pop-to-buffer "*Help*")
|
||||
(switch-to-buffer "*Help*"))
|
||||
(goto-char (point-min))
|
||||
(let ((continue t) state)
|
||||
(while continue
|
||||
(setq state (+ (* 2 (if (pos-visible-in-window-p (point-max)) 1 0))
|
||||
(if (pos-visible-in-window-p (point-min)) 1 0)))
|
||||
(message
|
||||
(nth state
|
||||
'("Space forward, Delete back. Other keys %s"
|
||||
"Space scrolls forward. Other keys %s"
|
||||
"Delete scrolls back. Other keys %s"
|
||||
"Type anything to %s"))
|
||||
blurb)
|
||||
(setq continue (read-char))
|
||||
(cond ((and (memq continue '(?\ ?\C-v)) (< state 2))
|
||||
(scroll-up))
|
||||
((= continue ?\C-l)
|
||||
(recenter))
|
||||
((and (= continue ?\177) (zerop (% state 2)))
|
||||
(scroll-down))
|
||||
(t (setq continue nil))))))))
|
||||
|
||||
(defun Helper-help-options ()
|
||||
"Describe help options."
|
||||
(interactive)
|
||||
(message "c (key briefly), m (mode), k (key), b (bindings)")
|
||||
;(message "c (key briefly), m (mode), k (key), v (variable), f (function)")
|
||||
(sit-for 4))
|
||||
|
||||
(defun Helper-describe-key-briefly (key)
|
||||
"Briefly describe binding of KEYS."
|
||||
(interactive "kDescribe key briefly: ")
|
||||
(describe-key-briefly key)
|
||||
(sit-for 4))
|
||||
|
||||
(defun Helper-describe-key (key)
|
||||
"Describe binding of KEYS."
|
||||
(interactive "kDescribe key: ")
|
||||
(save-window-excursion (describe-key key))
|
||||
(Helper-help-scroller))
|
||||
|
||||
(defun Helper-describe-function ()
|
||||
"Describe a function. Name read interactively."
|
||||
(interactive)
|
||||
(save-window-excursion (call-interactively 'describe-function))
|
||||
(Helper-help-scroller))
|
||||
|
||||
(defun Helper-describe-variable ()
|
||||
"Describe a variable. Name read interactively."
|
||||
(interactive)
|
||||
(save-window-excursion (call-interactively 'describe-variable))
|
||||
(Helper-help-scroller))
|
||||
|
||||
(defun Helper-describe-mode ()
|
||||
"Describe the current mode."
|
||||
(interactive)
|
||||
(let ((name mode-name)
|
||||
(documentation (documentation major-mode)))
|
||||
(save-excursion
|
||||
(set-buffer (get-buffer-create "*Help*"))
|
||||
(erase-buffer)
|
||||
(insert name " Mode\n" documentation)))
|
||||
(Helper-help-scroller))
|
||||
|
||||
(defun Helper-describe-bindings ()
|
||||
"Describe local key bindings of current mode."
|
||||
(interactive)
|
||||
(message "Making binding list...")
|
||||
(save-window-excursion (describe-bindings))
|
||||
(Helper-help-scroller))
|
||||
|
||||
(defun Helper-help ()
|
||||
"Provide help for current mode."
|
||||
(interactive)
|
||||
(let ((continue t) c)
|
||||
(while continue
|
||||
(message "Help (Type ? for further options)")
|
||||
(setq c (char-to-string (downcase (read-char))))
|
||||
(setq c (lookup-key Helper-help-map c))
|
||||
(cond ((eq c 'Helper-help-options)
|
||||
(Helper-help-options))
|
||||
((commandp c)
|
||||
(call-interactively c)
|
||||
(setq continue nil))
|
||||
(t
|
||||
(ding)
|
||||
(setq continue nil))))))
|
||||
|
272
lisp/emulation/mlconvert.el
Normal file
272
lisp/emulation/mlconvert.el
Normal file
@ -0,0 +1,272 @@
|
||||
;; Convert buffer of Mocklisp code to real lisp.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
(defun convert-mocklisp-buffer ()
|
||||
"Convert buffer of Mocklisp code to real Lisp that GNU Emacs can run."
|
||||
(interactive)
|
||||
(emacs-lisp-mode)
|
||||
(set-syntax-table (copy-sequence (syntax-table)))
|
||||
(modify-syntax-entry ?\| "w")
|
||||
(message "Converting mocklisp (ugh!)...")
|
||||
(goto-char (point-min))
|
||||
(fix-mlisp-syntax)
|
||||
|
||||
;; Emulation of mocklisp is accurate only within a mocklisp-function
|
||||
;; so turn any non-function into a defun and then call it.
|
||||
(goto-char (point-min))
|
||||
(condition-case ignore
|
||||
(while t
|
||||
(let ((opt (point))
|
||||
(form (read (current-buffer))))
|
||||
(and (listp form)
|
||||
(not (eq (car form) 'defun))
|
||||
(progn (insert "))\n\n(ml-foo)\n\n")
|
||||
(save-excursion
|
||||
(goto-char opt)
|
||||
(skip-chars-forward "\n")
|
||||
(insert "(defun (ml-foo \n "))))))
|
||||
(end-of-file nil))
|
||||
|
||||
(goto-char (point-min))
|
||||
(insert ";;; GNU Emacs code converted from Mocklisp\n")
|
||||
(insert "(require 'mlsupport)\n\n")
|
||||
(fix-mlisp-symbols)
|
||||
|
||||
(goto-char (point-min))
|
||||
(message "Converting mocklisp...done"))
|
||||
|
||||
(defun fix-mlisp-syntax ()
|
||||
(while (re-search-forward "['\"]" nil t)
|
||||
(if (= (preceding-char) ?\")
|
||||
(progn (forward-char -1)
|
||||
(forward-sexp 1))
|
||||
(delete-char -1)
|
||||
(insert "?")
|
||||
(if (or (= (following-char) ?\\) (= (following-char) ?^))
|
||||
(forward-char 1)
|
||||
(if (looking-at "[^a-zA-Z]")
|
||||
(insert ?\\)))
|
||||
(forward-char 1)
|
||||
(delete-char 1))))
|
||||
|
||||
(defun fix-mlisp-symbols ()
|
||||
(while (progn
|
||||
(skip-chars-forward " \t\n()")
|
||||
(not (eobp)))
|
||||
(cond ((or (= (following-char) ?\?)
|
||||
(= (following-char) ?\"))
|
||||
(forward-sexp 1))
|
||||
((= (following-char) ?\;)
|
||||
(forward-line 1))
|
||||
(t
|
||||
(let ((start (point)) prop)
|
||||
(forward-sexp 1)
|
||||
(setq prop (get (intern-soft (buffer-substring start (point)))
|
||||
'mocklisp))
|
||||
(cond ((null prop))
|
||||
((stringp prop)
|
||||
(delete-region start (point))
|
||||
(insert prop))
|
||||
(t
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(funcall prop)))))))))
|
||||
|
||||
(defun ml-expansion (ml-name lisp-string)
|
||||
(put ml-name 'mocklisp lisp-string))
|
||||
|
||||
(ml-expansion 'defun "ml-defun")
|
||||
(ml-expansion 'if "ml-if")
|
||||
(ml-expansion 'setq '(lambda ()
|
||||
(if (looking-at "setq[ \t\n]+buffer-modified-p")
|
||||
(replace-match "set-buffer-modified-p"))))
|
||||
|
||||
(ml-expansion 'while '(lambda ()
|
||||
(let ((end (progn (forward-sexp 2) (point-marker)))
|
||||
(start (progn (forward-sexp -1) (point))))
|
||||
(let ((cond (buffer-substring start end)))
|
||||
(cond ((equal cond "1")
|
||||
(delete-region (point) end)
|
||||
(insert "t"))
|
||||
(t
|
||||
(insert "(not (zerop ")
|
||||
(goto-char end)
|
||||
(insert "))")))
|
||||
(set-marker end nil)
|
||||
(goto-char start)))))
|
||||
|
||||
(ml-expansion 'arg "ml-arg")
|
||||
(ml-expansion 'nargs "ml-nargs")
|
||||
(ml-expansion 'interactive "ml-interactive")
|
||||
(ml-expansion 'message "ml-message")
|
||||
(ml-expansion 'print "ml-print")
|
||||
(ml-expansion 'set "ml-set")
|
||||
(ml-expansion 'set-default "ml-set-default")
|
||||
(ml-expansion 'provide-prefix-argument "ml-provide-prefix-argument")
|
||||
(ml-expansion 'prefix-argument-loop "ml-prefix-argument-loop")
|
||||
(ml-expansion 'prefix-argument "ml-prefix-arg")
|
||||
(ml-expansion 'use-local-map "ml-use-local-map")
|
||||
(ml-expansion 'use-global-map "ml-use-global-map")
|
||||
(ml-expansion 'modify-syntax-entry "ml-modify-syntax-entry")
|
||||
(ml-expansion 'error-message "error")
|
||||
|
||||
(ml-expansion 'dot "point-marker")
|
||||
(ml-expansion 'mark "mark-marker")
|
||||
(ml-expansion 'beginning-of-file "beginning-of-buffer")
|
||||
(ml-expansion 'end-of-file "end-of-buffer")
|
||||
(ml-expansion 'exchange-dot-and-mark "exchange-point-and-mark")
|
||||
(ml-expansion 'set-mark "set-mark-command")
|
||||
(ml-expansion 'argument-prefix "universal-arg")
|
||||
|
||||
(ml-expansion 'previous-page "ml-previous-page")
|
||||
(ml-expansion 'next-page "ml-next-page")
|
||||
(ml-expansion 'next-window "ml-next-window")
|
||||
(ml-expansion 'previous-window "ml-previous-window")
|
||||
|
||||
(ml-expansion 'newline "ml-newline")
|
||||
(ml-expansion 'next-line "ml-next-line")
|
||||
(ml-expansion 'previous-line "ml-previous-line")
|
||||
(ml-expansion 'self-insert "self-insert-command")
|
||||
(ml-expansion 'meta-digit "digit-argument")
|
||||
(ml-expansion 'meta-minus "negative-argument")
|
||||
|
||||
(ml-expansion 'newline-and-indent "ml-newline-and-indent")
|
||||
(ml-expansion 'yank-from-killbuffer "yank")
|
||||
(ml-expansion 'yank-buffer "insert-buffer")
|
||||
(ml-expansion 'copy-region "copy-region-as-kill")
|
||||
(ml-expansion 'delete-white-space "delete-horizontal-space")
|
||||
(ml-expansion 'widen-region "widen")
|
||||
|
||||
(ml-expansion 'forward-word '(lambda ()
|
||||
(if (looking-at "forward-word[ \t\n]*)")
|
||||
(replace-match "forward-word 1)"))))
|
||||
(ml-expansion 'backward-word '(lambda ()
|
||||
(if (looking-at "backward-word[ \t\n]*)")
|
||||
(replace-match "backward-word 1)"))))
|
||||
|
||||
(ml-expansion 'forward-paren "forward-list")
|
||||
(ml-expansion 'backward-paren "backward-list")
|
||||
(ml-expansion 'search-reverse "ml-search-backward")
|
||||
(ml-expansion 're-search-reverse "ml-re-search-backward")
|
||||
(ml-expansion 'search-forward "ml-search-forward")
|
||||
(ml-expansion 're-search-forward "ml-re-search-forward")
|
||||
(ml-expansion 'quote "regexp-quote")
|
||||
(ml-expansion 're-query-replace "query-replace-regexp")
|
||||
(ml-expansion 're-replace-string "replace-regexp")
|
||||
|
||||
; forward-paren-bl, backward-paren-bl
|
||||
|
||||
(ml-expansion 'get-tty-character "read-char")
|
||||
(ml-expansion 'get-tty-input "read-input")
|
||||
(ml-expansion 'get-tty-string "read-string")
|
||||
(ml-expansion 'get-tty-buffer "read-buffer")
|
||||
(ml-expansion 'get-tty-command "read-command")
|
||||
(ml-expansion 'get-tty-variable "read-variable")
|
||||
(ml-expansion 'get-tty-no-blanks-input "read-no-blanks-input")
|
||||
(ml-expansion 'get-tty-key "read-key")
|
||||
|
||||
(ml-expansion 'c= "char-equal")
|
||||
(ml-expansion 'goto-character "goto-char")
|
||||
(ml-expansion 'substr "ml-substr")
|
||||
(ml-expansion 'variable-apropos "apropos")
|
||||
(ml-expansion 'execute-mlisp-buffer "eval-current-buffer")
|
||||
(ml-expansion 'execute-mlisp-file "load")
|
||||
(ml-expansion 'visit-file "find-file")
|
||||
(ml-expansion 'read-file "find-file")
|
||||
(ml-expansion 'write-modified-files "save-some-buffers")
|
||||
(ml-expansion 'backup-before-writing "make-backup-files")
|
||||
(ml-expansion 'write-file-exit "save-buffers-kill-emacs")
|
||||
(ml-expansion 'write-named-file "write-file")
|
||||
(ml-expansion 'change-file-name "set-visited-file-name")
|
||||
(ml-expansion 'change-buffer-name "rename-buffer")
|
||||
(ml-expansion 'buffer-exists "get-buffer")
|
||||
(ml-expansion 'delete-buffer "kill-buffer")
|
||||
(ml-expansion 'unlink-file "delete-file")
|
||||
(ml-expansion 'unlink-checkpoint-files "delete-auto-save-files")
|
||||
(ml-expansion 'file-exists "file-exists-p")
|
||||
(ml-expansion 'write-current-file "save-buffer")
|
||||
(ml-expansion 'change-directory "cd")
|
||||
(ml-expansion 'temp-use-buffer "set-buffer")
|
||||
(ml-expansion 'fast-filter-region "filter-region")
|
||||
|
||||
(ml-expansion 'pending-input "input-pending-p")
|
||||
(ml-expansion 'execute-keyboard-macro "call-last-kbd-macro")
|
||||
(ml-expansion 'start-remembering "start-kbd-macro")
|
||||
(ml-expansion 'end-remembering "end-kbd-macro")
|
||||
(ml-expansion 'define-keyboard-macro "name-last-kbd-macro")
|
||||
(ml-expansion 'define-string-macro "ml-define-string-macro")
|
||||
|
||||
(ml-expansion 'current-column "ml-current-column")
|
||||
(ml-expansion 'current-indent "ml-current-indent")
|
||||
(ml-expansion 'insert-character "insert")
|
||||
|
||||
(ml-expansion 'users-login-name "user-login-name")
|
||||
(ml-expansion 'users-full-name "user-full-name")
|
||||
(ml-expansion 'current-time "current-time-string")
|
||||
(ml-expansion 'current-numeric-time "current-numeric-time-you-lose")
|
||||
(ml-expansion 'current-buffer-name "buffer-name")
|
||||
(ml-expansion 'current-file-name "buffer-file-name")
|
||||
|
||||
(ml-expansion 'local-binding-of "local-key-binding")
|
||||
(ml-expansion 'global-binding-of "global-key-binding")
|
||||
|
||||
;defproc (ProcedureType, "procedure-type");
|
||||
|
||||
(ml-expansion 'remove-key-binding "global-unset-key")
|
||||
(ml-expansion 'remove-binding "global-unset-key")
|
||||
(ml-expansion 'remove-local-binding "local-unset-key")
|
||||
(ml-expansion 'remove-all-local-bindings "use-local-map nil")
|
||||
(ml-expansion 'autoload "ml-autoload")
|
||||
|
||||
(ml-expansion 'checkpoint-frequency "auto-save-interval")
|
||||
|
||||
(ml-expansion 'mode-string "mode-name")
|
||||
(ml-expansion 'right-margin "fill-column")
|
||||
(ml-expansion 'tab-size "tab-width")
|
||||
(ml-expansion 'default-right-margin "default-fill-column")
|
||||
(ml-expansion 'default-tab-size "default-tab-width")
|
||||
(ml-expansion 'buffer-is-modified "(buffer-modified-p)")
|
||||
|
||||
(ml-expansion 'file-modified-time "you-lose-on-file-modified-time")
|
||||
(ml-expansion 'needs-checkpointing "you-lose-on-needs-checkpointing")
|
||||
|
||||
(ml-expansion 'lines-on-screen "set-screen-height")
|
||||
(ml-expansion 'columns-on-screen "set-screen-width")
|
||||
|
||||
(ml-expansion 'dumped-emacs "t")
|
||||
|
||||
(ml-expansion 'buffer-size "ml-buffer-size")
|
||||
(ml-expansion 'dot-is-visible "pos-visible-in-window-p")
|
||||
|
||||
(ml-expansion 'track-eol-on-^N-^P "track-eol")
|
||||
(ml-expansion 'ctlchar-with-^ "ctl-arrow")
|
||||
(ml-expansion 'help-on-command-completion-error "completion-auto-help")
|
||||
(ml-expansion 'dump-stack-trace "backtrace")
|
||||
(ml-expansion 'pause-emacs "suspend-emacs")
|
||||
(ml-expansion 'compile-it "compile")
|
||||
|
||||
(ml-expansion '!= "/=")
|
||||
(ml-expansion '& "logand")
|
||||
(ml-expansion '| "logior")
|
||||
(ml-expansion '^ "logxor")
|
||||
(ml-expansion '! "ml-not")
|
||||
(ml-expansion '<< "lsh")
|
||||
|
||||
;Variable pause-writes-files
|
||||
|
53
lisp/float-sup.el
Normal file
53
lisp/float-sup.el
Normal file
@ -0,0 +1,53 @@
|
||||
;; Basic editing commands for Emacs
|
||||
;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
;; Provide a meaningful error message if we are running on
|
||||
;; bare (non-float) emacs.
|
||||
;; Can't test for 'floatp since that may be defined by float-imitation
|
||||
;; packages like float.el in this very directory.
|
||||
|
||||
(if (fboundp 'atan)
|
||||
nil
|
||||
(error "Floating point was disabled at compile time"))
|
||||
|
||||
;; provide an easy hook to tell if we are running with floats or not.
|
||||
(provide 'lisp-float-type)
|
||||
|
||||
;; define pi and e via math-lib calls. (much less prone to killer typos.)
|
||||
(defconst pi (* 4 (atan 1)) "The value of Pi (3.1415926...)")
|
||||
(defconst e (exp 1) "The value of e (2.7182818...)")
|
||||
|
||||
;; Careful when editing this file ... typos here will be hard to spot.
|
||||
;; (defconst pi 3.14159265358979323846264338327
|
||||
;; "The value of Pi (3.14159265358979323846264338327...)")
|
||||
|
||||
(defconst degrees-to-radians (/ pi 180.0)
|
||||
"Degrees to radian conversion constant")
|
||||
(defconst radians-to-degrees (/ 180.0 pi)
|
||||
"Radian to degree conversion constant")
|
||||
|
||||
;; these expand to a single multiply by a float
|
||||
;; when byte compiled
|
||||
|
||||
(defmacro degrees-to-radians (x)
|
||||
"Convert ARG from degrees to radians."
|
||||
(list '* (/ pi 180.0) x))
|
||||
(defmacro radians-to-degrees (x)
|
||||
"Convert ARG from radians to degrees."
|
||||
(list '* (/ 180.0 pi) x))
|
102
lisp/gosmacs.el
Normal file
102
lisp/gosmacs.el
Normal file
@ -0,0 +1,102 @@
|
||||
;; Rebindings to imitate Gosmacs.
|
||||
;; Copyright (C) 1986 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defvar non-gosmacs-binding-alist nil)
|
||||
|
||||
(defun set-gosmacs-bindings ()
|
||||
"Rebind some keys globally to make GNU Emacs resemble Gosling Emacs.
|
||||
Use \\[set-gnu-bindings] to restore previous global bindings."
|
||||
(interactive)
|
||||
(setq non-gosmacs-binding-alist
|
||||
(rebind-and-record
|
||||
'(("\C-x\C-e" compile)
|
||||
("\C-x\C-f" save-buffers-kill-emacs)
|
||||
("\C-x\C-i" insert-file)
|
||||
("\C-x\C-m" save-some-buffers)
|
||||
("\C-x\C-n" next-error)
|
||||
("\C-x\C-o" switch-to-buffer)
|
||||
("\C-x\C-r" insert-file)
|
||||
("\C-x\C-u" undo)
|
||||
("\C-x\C-v" find-file-other-window)
|
||||
("\C-x\C-z" shrink-window)
|
||||
("\C-x!" shell-command)
|
||||
("\C-xd" delete-window)
|
||||
("\C-xn" gosmacs-next-window)
|
||||
("\C-xp" gosmacs-previous-window)
|
||||
("\C-xz" enlarge-window)
|
||||
("\C-z" scroll-one-line-up)
|
||||
("\e\C-c" save-buffers-kill-emacs)
|
||||
("\e!" line-to-top-of-window)
|
||||
("\e(" backward-paragraph)
|
||||
("\e)" forward-paragraph)
|
||||
("\e?" apropos)
|
||||
("\eh" delete-previous-word)
|
||||
("\ej" indent-sexp)
|
||||
("\eq" query-replace)
|
||||
("\er" replace-string)
|
||||
("\ez" scroll-one-line-down)
|
||||
("\C-_" suspend-emacs)))))
|
||||
|
||||
(defun rebind-and-record (bindings)
|
||||
"Establish many new global bindings and record the bindings replaced.
|
||||
Arg is an alist whose elements are (KEY DEFINITION).
|
||||
Value is a similar alist whose elements describe the same KEYs
|
||||
but each with the old definition that was replaced,"
|
||||
(let (old)
|
||||
(while bindings
|
||||
(let* ((this (car bindings))
|
||||
(key (car this))
|
||||
(newdef (nth 1 this)))
|
||||
(setq old (cons (list key (lookup-key global-map key)) old))
|
||||
(global-set-key key newdef))
|
||||
(setq bindings (cdr bindings)))
|
||||
(nreverse old)))
|
||||
|
||||
(defun set-gnu-bindings ()
|
||||
"Restore the global bindings that were changed by \\[set-gosmacs-bindings]."
|
||||
(interactive)
|
||||
(rebind-and-record non-gosmacs-binding-alist))
|
||||
|
||||
(defun gosmacs-previous-window ()
|
||||
"Select the window above or to the left of the window now selected.
|
||||
From the window at the upper left corner, select the one at the lower right."
|
||||
(interactive)
|
||||
(select-window (previous-window)))
|
||||
|
||||
(defun gosmacs-next-window ()
|
||||
"Select the window below or to the right of the window now selected.
|
||||
From the window at the lower right corner, select the one at the upper left."
|
||||
(interactive)
|
||||
(select-window (next-window)))
|
||||
|
||||
(defun scroll-one-line-up (&optional arg)
|
||||
"Scroll the selected window up (forward in the text) one line (or N lines)."
|
||||
(interactive "p")
|
||||
(scroll-up (or arg 1)))
|
||||
|
||||
(defun scroll-one-line-down (&optional arg)
|
||||
"Scroll the selected window down (backward in the text) one line (or N)."
|
||||
(interactive "p")
|
||||
(scroll-down (or arg 1)))
|
||||
|
||||
(defun line-to-top-of-window ()
|
||||
"Scroll the selected window up so that the current line is at the top."
|
||||
(interactive)
|
||||
(recenter 0))
|
668
lisp/hexl.el
Normal file
668
lisp/hexl.el
Normal file
@ -0,0 +1,668 @@
|
||||
;; -*-Emacs-Lisp-*-
|
||||
;; hexl-mode -- Edit a file in a hex dump format.
|
||||
;; Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
;;
|
||||
;; By: Keith Gabryelski (ag@wheaties.ai.mit.edu)
|
||||
;;
|
||||
;; This may be useful in your .emacs:
|
||||
;;
|
||||
;; (autoload 'hexl-find-file "hexl"
|
||||
;; "Edit file FILENAME in hexl-mode." t)
|
||||
;;
|
||||
;; (define-key global-map "\C-c\C-h" 'hexl-find-file)
|
||||
;;
|
||||
;; NOTE: Remember to change HEXL-PROGRAM or HEXL-OPTIONS if needed.
|
||||
;;
|
||||
;; Currently hexl only supports big endian hex output with 16 bit
|
||||
;; grouping.
|
||||
;;
|
||||
;; -iso in `hexl-options' will allow iso characters to display in the
|
||||
;; ASCII region of the screen (if your emacs supports this) instead of
|
||||
;; changing them to dots.
|
||||
|
||||
;;
|
||||
;; vars here
|
||||
;;
|
||||
|
||||
(defvar hexl-program "hexl"
|
||||
"The program that will hexlify and de-hexlify its stdin. hexl-program
|
||||
will always be concated with hexl-options and "-de" when dehexlfying a
|
||||
buffer.")
|
||||
|
||||
(defvar hexl-iso ""
|
||||
"If your emacs can handle ISO characters, this should be set to
|
||||
\"-iso\" otherwise it should be \"\".")
|
||||
|
||||
(defvar hexl-options (format "-hex %s" hexl-iso)
|
||||
"Options to hexl-program that suit your needs.")
|
||||
|
||||
(defvar hexlify-command (format "%s %s" hexl-program hexl-options)
|
||||
"The command to use to hexlify a buffer. It is the concatination of
|
||||
`hexl-program' and `hexl-options'.")
|
||||
|
||||
(defvar dehexlify-command (format "%s -de %s" hexl-program hexl-options)
|
||||
"The command to use to unhexlify a buffer. It is the concatination of
|
||||
`hexl-program', the option \"-de\", and `hexl-options'.")
|
||||
|
||||
(defvar hexl-max-address 0
|
||||
"Maximum offset into hexl buffer.")
|
||||
|
||||
(defvar hexl-mode-map nil)
|
||||
|
||||
;; routines
|
||||
|
||||
(defun hexl-mode (&optional arg)
|
||||
"\\<hexl-mode-map>
|
||||
A major mode for editting binary files in hex dump format.
|
||||
|
||||
This function automatically converts a buffer into the hexl format
|
||||
using the function `hexlify-buffer'.
|
||||
|
||||
Each line in the buffer has an `address' (displayed in hexadecimal)
|
||||
representing the offset into the file that the characters on this line
|
||||
are at and 16 characters from the file (displayed as hexadecimal
|
||||
values grouped every 16 bits) and as their ASCII values.
|
||||
|
||||
If any of the characters (displayed as ASCII characters) are
|
||||
unprintable (control or meta characters) they will be replaced as
|
||||
periods.
|
||||
|
||||
If hexl-mode is invoked with an argument the buffer is assumed to be
|
||||
in hexl-format.
|
||||
|
||||
A sample format:
|
||||
|
||||
HEX ADDR: 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f ASCII-TEXT
|
||||
-------- ---- ---- ---- ---- ---- ---- ---- ---- ----------------
|
||||
00000000: 5468 6973 2069 7320 6865 786c 2d6d 6f64 This is hexl-mod
|
||||
00000010: 652e 2020 4561 6368 206c 696e 6520 7265 e. Each line re
|
||||
00000020: 7072 6573 656e 7473 2031 3620 6279 7465 presents 16 byte
|
||||
00000030: 7320 6173 2068 6578 6164 6563 696d 616c s as hexadecimal
|
||||
00000040: 2041 5343 4949 0a61 6e64 2070 7269 6e74 ASCII.and print
|
||||
00000050: 6162 6c65 2041 5343 4949 2063 6861 7261 able ASCII chara
|
||||
00000060: 6374 6572 732e 2020 416e 7920 636f 6e74 cters. Any cont
|
||||
00000070: 726f 6c20 6f72 206e 6f6e 2d41 5343 4949 rol or non-ASCII
|
||||
00000080: 2063 6861 7261 6374 6572 730a 6172 6520 characters.are
|
||||
00000090: 6469 7370 6c61 7965 6420 6173 2070 6572 displayed as per
|
||||
000000a0: 696f 6473 2069 6e20 7468 6520 7072 696e iods in the prin
|
||||
000000b0: 7461 626c 6520 6368 6172 6163 7465 7220 table character
|
||||
000000c0: 7265 6769 6f6e 2e0a region..
|
||||
|
||||
Movement is as simple as movement in a normal emacs text buffer. Most
|
||||
cursor movement bindings are the same (ie. Use \\[hexl-backward-char], \\[hexl-forward-char], \\[hexl-next-line], and \\[hexl-previous-line]
|
||||
to move the cursor left, right, down, and up).
|
||||
|
||||
Advanced cursor movement commands (ala \\[hexl-beginning-of-line], \\[hexl-end-of-line], \\[hexl-beginning-of-buffer], and \\[hexl-end-of-buffer]) are
|
||||
also supported.
|
||||
|
||||
There are several ways to change text in hexl mode:
|
||||
|
||||
ASCII characters (character between space (0x20) and tilde (0x7E)) are
|
||||
bound to self-insert so you can simply type the character and it will
|
||||
insert itself (actually overstrike) into the buffer.
|
||||
|
||||
\\[hexl-quoted-insert] followed by another keystroke allows you to insert the key even if
|
||||
it isn't bound to self-insert. An octal number can be supplied in place
|
||||
of another key to insert the octal number's ASCII representation.
|
||||
|
||||
\\[hexl-insert-hex-char] will insert a given hexadecimal value (if it is between 0 and 0xFF)
|
||||
into the buffer at the current point.
|
||||
|
||||
\\[hexl-insert-octal-char] will insert a given octal value (if it is between 0 and 0377)
|
||||
into the buffer at the current point.
|
||||
|
||||
\\[hexl-insert-decimal-char] will insert a given decimal value (if it is between 0 and 255)
|
||||
into the buffer at the current point.
|
||||
|
||||
\\[hexl-save-buffer] will save the buffer in is binary format.
|
||||
|
||||
\\[hexl-mode-exit] will exit hexl-mode.
|
||||
|
||||
Note: \\[write-file] will write the file out in HEXL FORMAT.
|
||||
|
||||
You can use \\[hexl-find-file] to visit a file in hexl-mode.
|
||||
|
||||
\\[describe-bindings] for advanced commands."
|
||||
(interactive "p")
|
||||
(if (eq major-mode 'hexl-mode)
|
||||
(error "You are already in hexl mode.")
|
||||
(kill-all-local-variables)
|
||||
(make-local-variable 'hexl-mode-old-local-map)
|
||||
(setq hexl-mode-old-local-map (current-local-map))
|
||||
(use-local-map hexl-mode-map)
|
||||
|
||||
(make-local-variable 'hexl-mode-old-mode-name)
|
||||
(setq hexl-mode-old-mode-name mode-name)
|
||||
(setq mode-name "Hexl")
|
||||
|
||||
(make-local-variable 'hexl-mode-old-major-mode)
|
||||
(setq hexl-mode-old-major-mode major-mode)
|
||||
(setq major-mode 'hexl-mode)
|
||||
|
||||
(let ((modified (buffer-modified-p))
|
||||
(read-only buffer-read-only)
|
||||
(original-point (1- (point))))
|
||||
(if (not (or (eq arg 1) (not arg)))
|
||||
;; if no argument then we guess at hexl-max-address
|
||||
(setq hexl-max-address (+ (* (/ (1- (buffer-size)) 68) 16) 15))
|
||||
(setq buffer-read-only nil)
|
||||
(setq hexl-max-address (1- (buffer-size)))
|
||||
(hexlify-buffer)
|
||||
(set-buffer-modified-p modified)
|
||||
(setq buffer-read-only read-only)
|
||||
(hexl-goto-address original-point)))))
|
||||
|
||||
(defun hexl-save-buffer ()
|
||||
"Save a hexl format buffer as binary in visited file if modified."
|
||||
(interactive)
|
||||
(set-buffer-modified-p (if (buffer-modified-p)
|
||||
(save-excursion
|
||||
(let ((buf (generate-new-buffer " hexl"))
|
||||
(name (buffer-name))
|
||||
(file-name (buffer-file-name))
|
||||
(start (point-min))
|
||||
(end (point-max))
|
||||
modified)
|
||||
(set-buffer buf)
|
||||
(insert-buffer-substring name start end)
|
||||
(set-buffer name)
|
||||
(dehexlify-buffer)
|
||||
(save-buffer)
|
||||
(setq modified (buffer-modified-p))
|
||||
(delete-region (point-min) (point-max))
|
||||
(insert-buffer-substring buf start end)
|
||||
(kill-buffer buf)
|
||||
modified))
|
||||
(message "(No changes need to be saved)")
|
||||
nil)))
|
||||
|
||||
(defun hexl-find-file (filename)
|
||||
"Edit file FILENAME in hexl-mode.
|
||||
|
||||
Switch to a buffer visiting file FILENAME, creating one in none exists."
|
||||
(interactive "fFilename: ")
|
||||
(find-file filename)
|
||||
(if (not (eq major-mode 'hexl-mode))
|
||||
(hexl-mode)))
|
||||
|
||||
(defun hexl-mode-exit (&optional arg)
|
||||
"Exit hexl-mode returning to previous mode.
|
||||
With arg, don't unhexlify buffer."
|
||||
(interactive "p")
|
||||
(if (or (eq arg 1) (not arg))
|
||||
(let ((modified (buffer-modified-p))
|
||||
(read-only buffer-read-only)
|
||||
(original-point (1+ (hexl-current-address))))
|
||||
(setq buffer-read-only nil)
|
||||
(dehexlify-buffer)
|
||||
(set-buffer-modified-p modified)
|
||||
(setq buffer-read-only read-only)
|
||||
(goto-char original-point)))
|
||||
(setq mode-name hexl-mode-old-mode-name)
|
||||
(use-local-map hexl-mode-old-local-map)
|
||||
(setq major-mode hexl-mode-old-major-mode)
|
||||
;; Kludge to update mode-line
|
||||
(switch-to-buffer (current-buffer))
|
||||
)
|
||||
|
||||
(defun hexl-current-address ()
|
||||
"Return current hexl-address."
|
||||
(interactive)
|
||||
(let ((current-column (- (% (point) 68) 11))
|
||||
(hexl-address 0))
|
||||
(setq hexl-address (+ (* (/ (point) 68) 16)
|
||||
(/ (- current-column (/ current-column 5)) 2)))
|
||||
hexl-address))
|
||||
|
||||
(defun hexl-address-to-marker (address)
|
||||
"Return marker for ADDRESS."
|
||||
(interactive "nAddress: ")
|
||||
(+ (* (/ address 16) 68) 11 (/ (* (% address 16) 5) 2)))
|
||||
|
||||
(defun hexl-goto-address (address)
|
||||
"Goto hexl-mode (decimal) address ADDRESS.
|
||||
|
||||
Signal error if ADDRESS out of range."
|
||||
(interactive "nAddress: ")
|
||||
(if (or (< address 0) (> address hexl-max-address))
|
||||
(error "Out of hexl region."))
|
||||
(goto-char (hexl-address-to-marker address)))
|
||||
|
||||
(defun hexl-goto-hex-address (hex-address)
|
||||
"Goto hexl-mode address (hex string) HEX-ADDRESS.
|
||||
|
||||
Signal error if HEX-ADDRESS is out of range."
|
||||
(interactive "sHex Address: ")
|
||||
(hexl-goto-address (hexl-hex-string-to-integer hex-address)))
|
||||
|
||||
(defun hexl-hex-string-to-integer (hex-string)
|
||||
"Return decimal integer for HEX-STRING."
|
||||
(interactive "sHex number: ")
|
||||
(let ((hex-num 0))
|
||||
(while (not (equal hex-string ""))
|
||||
(setq hex-num (+ (* hex-num 16)
|
||||
(hexl-hex-char-to-integer (string-to-char hex-string))))
|
||||
(setq hex-string (substring hex-string 1)))
|
||||
hex-num))
|
||||
|
||||
(defun hexl-octal-string-to-integer (octal-string)
|
||||
"Return decimal integer for OCTAL-STRING."
|
||||
(interactive "sOctal number: ")
|
||||
(let ((oct-num 0))
|
||||
(while (not (equal octal-string ""))
|
||||
(setq oct-num (+ (* oct-num 8)
|
||||
(hexl-oct-char-to-integer
|
||||
(string-to-char octal-string))))
|
||||
(setq octal-string (substring octal-string 1)))
|
||||
oct-num))
|
||||
|
||||
;; move point functions
|
||||
|
||||
(defun hexl-backward-char (arg)
|
||||
"Move to left ARG bytes (right if ARG negative) in hexl-mode."
|
||||
(interactive "p")
|
||||
(hexl-goto-address (- (hexl-current-address) arg)))
|
||||
|
||||
(defun hexl-forward-char (arg)
|
||||
"Move right ARG bytes (left if ARG negative) in hexl-mode."
|
||||
(interactive "p")
|
||||
(hexl-goto-address (+ (hexl-current-address) arg)))
|
||||
|
||||
(defun hexl-backward-short (arg)
|
||||
"Move to left ARG shorts (right if ARG negative) in hexl-mode."
|
||||
(interactive "p")
|
||||
(hexl-goto-address (let ((address (hexl-current-address)))
|
||||
(if (< arg 0)
|
||||
(progn
|
||||
(setq arg (- arg))
|
||||
(while (> arg 0)
|
||||
(if (not (equal address (logior address 3)))
|
||||
(if (> address hexl-max-address)
|
||||
(progn
|
||||
(message "End of buffer.")
|
||||
(setq address hexl-max-address))
|
||||
(setq address (logior address 3)))
|
||||
(if (> address hexl-max-address)
|
||||
(progn
|
||||
(message "End of buffer.")
|
||||
(setq address hexl-max-address))
|
||||
(setq address (+ address 4))))
|
||||
(setq arg (1- arg)))
|
||||
(if (> address hexl-max-address)
|
||||
(progn
|
||||
(message "End of buffer.")
|
||||
(setq address hexl-max-address))
|
||||
(setq address (logior address 3))))
|
||||
(while (> arg 0)
|
||||
(if (not (equal address (logand address -4)))
|
||||
(setq address (logand address -4))
|
||||
(if (not (equal address 0))
|
||||
(setq address (- address 4))
|
||||
(message "Beginning of buffer.")))
|
||||
(setq arg (1- arg))))
|
||||
address)))
|
||||
|
||||
(defun hexl-forward-short (arg)
|
||||
"Move right ARG shorts (left if ARG negative) in hexl-mode."
|
||||
(interactive "p")
|
||||
(hexl-backward-short (- arg)))
|
||||
|
||||
(defun hexl-backward-word (arg)
|
||||
"Move to left ARG words (right if ARG negative) in hexl-mode."
|
||||
(interactive "p")
|
||||
(hexl-goto-address (let ((address (hexl-current-address)))
|
||||
(if (< arg 0)
|
||||
(progn
|
||||
(setq arg (- arg))
|
||||
(while (> arg 0)
|
||||
(if (not (equal address (logior address 7)))
|
||||
(if (> address hexl-max-address)
|
||||
(progn
|
||||
(message "End of buffer.")
|
||||
(setq address hexl-max-address))
|
||||
(setq address (logior address 7)))
|
||||
(if (> address hexl-max-address)
|
||||
(progn
|
||||
(message "End of buffer.")
|
||||
(setq address hexl-max-address))
|
||||
(setq address (+ address 8))))
|
||||
(setq arg (1- arg)))
|
||||
(if (> address hexl-max-address)
|
||||
(progn
|
||||
(message "End of buffer.")
|
||||
(setq address hexl-max-address))
|
||||
(setq address (logior address 7))))
|
||||
(while (> arg 0)
|
||||
(if (not (equal address (logand address -8)))
|
||||
(setq address (logand address -8))
|
||||
(if (not (equal address 0))
|
||||
(setq address (- address 8))
|
||||
(message "Beginning of buffer.")))
|
||||
(setq arg (1- arg))))
|
||||
address)))
|
||||
|
||||
(defun hexl-forward-word (arg)
|
||||
"Move right ARG words (left if ARG negative) in hexl-mode."
|
||||
(interactive "p")
|
||||
(hexl-backward-word (- arg)))
|
||||
|
||||
(defun hexl-previous-line (arg)
|
||||
"Move vertically up ARG lines [16 bytes] (down if ARG negative) in
|
||||
hexl-mode.
|
||||
|
||||
If there is byte at the target address move to the last byte in that
|
||||
line."
|
||||
(interactive "p")
|
||||
(hexl-next-line (- arg)))
|
||||
|
||||
(defun hexl-next-line (arg)
|
||||
"Move vertically down ARG lines [16 bytes] (up if ARG negative) in
|
||||
hexl-mode.
|
||||
|
||||
If there is no byte at the target address move to the last byte in that
|
||||
line."
|
||||
(interactive "p")
|
||||
(hexl-goto-address (let ((address (+ (hexl-current-address) (* arg 16)) t))
|
||||
(if (and (< arg 0) (< address 0))
|
||||
(progn (message "Out of hexl region.")
|
||||
(setq address
|
||||
(% (hexl-current-address) 16)))
|
||||
(if (and (> address hexl-max-address)
|
||||
(< (% hexl-max-address 16) (% address 16)))
|
||||
(setq address hexl-max-address)
|
||||
(if (> address hexl-max-address)
|
||||
(progn (message "Out of hexl region.")
|
||||
(setq
|
||||
address
|
||||
(+ (logand hexl-max-address -16)
|
||||
(% (hexl-current-address) 16)))))))
|
||||
address)))
|
||||
|
||||
(defun hexl-beginning-of-buffer (arg)
|
||||
"Move to the beginning of the hexl buffer; leave hexl-mark at previous
|
||||
posistion.
|
||||
|
||||
With arg N, put point N bytes of the way from the true beginning."
|
||||
(interactive "p")
|
||||
(push-mark (point))
|
||||
(hexl-goto-address (+ 0 (1- arg))))
|
||||
|
||||
(defun hexl-end-of-buffer (arg)
|
||||
"Goto hexl-max-address minus ARG."
|
||||
(interactive "p")
|
||||
(push-mark (point))
|
||||
(hexl-goto-address (- hexl-max-address (1- arg))))
|
||||
|
||||
(defun hexl-beginning-of-line ()
|
||||
"Goto beginning of line in hexl mode."
|
||||
(interactive)
|
||||
(goto-char (+ (* (/ (point) 68) 68) 11)))
|
||||
|
||||
(defun hexl-end-of-line ()
|
||||
"Goto end of line in hexl mode."
|
||||
(interactive)
|
||||
(hexl-goto-address (let ((address (logior (hexl-current-address) 15)))
|
||||
(if (> address hexl-max-address)
|
||||
(setq address hexl-max-address))
|
||||
address)))
|
||||
|
||||
(defun hexl-scroll-down (arg)
|
||||
"Scroll hexl buffer window upward ARG lines; or near full window if no ARG."
|
||||
(interactive "P")
|
||||
(if (null arg)
|
||||
(setq arg (1- (window-height)))
|
||||
(setq arg (prefix-numeric-value arg)))
|
||||
(hexl-scroll-up (- arg)))
|
||||
|
||||
(defun hexl-scroll-up (arg)
|
||||
"Scroll hexl buffer window upward ARG lines; or near full window if no ARG."
|
||||
(interactive "P")
|
||||
(if (null arg)
|
||||
(setq arg (1- (window-height)))
|
||||
(setq arg (prefix-numeric-value arg)))
|
||||
(let ((movement (* arg 16))
|
||||
(address (hexl-current-address)))
|
||||
(if (or (> (+ address movement) hexl-max-address)
|
||||
(< (+ address movement) 0))
|
||||
(message "Out of hexl region.")
|
||||
(hexl-goto-address (+ address movement))
|
||||
(recenter 0))))
|
||||
|
||||
(defun hexl-beginning-of-1k-page ()
|
||||
"Goto to beginning of 1k boundry."
|
||||
(interactive)
|
||||
(hexl-goto-address (logand (hexl-current-address) -1024)))
|
||||
|
||||
(defun hexl-end-of-1k-page ()
|
||||
"Goto to end of 1k boundry."
|
||||
(interactive)
|
||||
(hexl-goto-address (let ((address (logior (hexl-current-address) 1023)))
|
||||
(if (> address hexl-max-address)
|
||||
(setq address hexl-max-address))
|
||||
address)))
|
||||
|
||||
(defun hexl-beginning-of-512b-page ()
|
||||
"Goto to beginning of 512 byte boundry."
|
||||
(interactive)
|
||||
(hexl-goto-address (logand (hexl-current-address) -512)))
|
||||
|
||||
(defun hexl-end-of-512b-page ()
|
||||
"Goto to end of 512 byte boundry."
|
||||
(interactive)
|
||||
(hexl-goto-address (let ((address (logior (hexl-current-address) 511)))
|
||||
(if (> address hexl-max-address)
|
||||
(setq address hexl-max-address))
|
||||
address)))
|
||||
|
||||
(defun hexl-quoted-insert (arg)
|
||||
"Read next input character and insert it.
|
||||
Useful for inserting control characters.
|
||||
You may also type up to 3 octal digits, to insert a character with that code"
|
||||
(interactive "p")
|
||||
(hexl-insert-char (read-quoted-char) arg))
|
||||
|
||||
;00000000: 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789ABCDEF
|
||||
|
||||
(defun hexlify-buffer ()
|
||||
"Convert a binary buffer to hexl format"
|
||||
(interactive)
|
||||
(shell-command-on-region (point-min) (point-max) hexlify-command t))
|
||||
|
||||
(defun dehexlify-buffer ()
|
||||
"Convert a hexl format buffer to binary."
|
||||
(interactive)
|
||||
(shell-command-on-region (point-min) (point-max) dehexlify-command t))
|
||||
|
||||
(defun hexl-char-after-point ()
|
||||
"Return char for ASCII hex digits at point."
|
||||
(setq lh (char-after (point)))
|
||||
(setq rh (char-after (1+ (point))))
|
||||
(hexl-htoi lh rh))
|
||||
|
||||
(defun hexl-htoi (lh rh)
|
||||
"Hex (char) LH (char) RH to integer."
|
||||
(+ (* (hexl-hex-char-to-integer lh) 16)
|
||||
(hexl-hex-char-to-integer rh)))
|
||||
|
||||
(defun hexl-hex-char-to-integer (character)
|
||||
"Take a char and return its value as if it was a hex digit."
|
||||
(if (and (>= character ?0) (<= character ?9))
|
||||
(- character ?0)
|
||||
(let ((ch (logior character 32)))
|
||||
(if (and (>= ch ?a) (<= ch ?f))
|
||||
(- ch (- ?a 10))
|
||||
(error (format "Invalid hex digit `%c'." ch))))))
|
||||
|
||||
(defun hexl-oct-char-to-integer (character)
|
||||
"Take a char and return its value as if it was a octal digit."
|
||||
(if (and (>= character ?0) (<= character ?7))
|
||||
(- character ?0)
|
||||
(error (format "Invalid octal digit `%c'." character))))
|
||||
|
||||
(defun hexl-printable-character (ch)
|
||||
"Return a displayable string for character CH."
|
||||
(format "%c" (if hexl-iso
|
||||
(if (or (< ch 32) (and (>= ch 127) (< ch 160)))
|
||||
46
|
||||
ch)
|
||||
(if (or (< ch 32) (>= ch 127))
|
||||
46
|
||||
ch))))
|
||||
|
||||
(defun hexl-self-insert-command (arg)
|
||||
"Insert this character."
|
||||
(interactive "p")
|
||||
(hexl-insert-char last-command-char arg))
|
||||
|
||||
(defun hexl-insert-char (ch num)
|
||||
"Insert a character in a hexl buffer."
|
||||
(let ((address (hexl-current-address)))
|
||||
(while (> num 0)
|
||||
(delete-char 2)
|
||||
(insert (format "%02x" ch))
|
||||
(goto-char
|
||||
(+ (* (/ address 16) 68) 52 (% address 16)))
|
||||
(delete-char 1)
|
||||
(insert (hexl-printable-character ch))
|
||||
(if (eq address hexl-max-address)
|
||||
(hexl-goto-address address)
|
||||
(hexl-goto-address (1+ address)))
|
||||
(setq num (1- num)))))
|
||||
|
||||
;; hex conversion
|
||||
|
||||
(defun hexl-insert-hex-char (arg)
|
||||
"Insert a ASCII char ARG times at point for a given hexadecimal number."
|
||||
(interactive "p")
|
||||
(let ((num (hexl-hex-string-to-integer (read-string "Hex number: "))))
|
||||
(if (or (> num 255) (< num 0))
|
||||
(error "Hex number out of range.")
|
||||
(hexl-insert-char num arg))))
|
||||
|
||||
(defun hexl-insert-decimal-char (arg)
|
||||
"Insert a ASCII char ARG times at point for a given decimal number."
|
||||
(interactive "p")
|
||||
(let ((num (string-to-int (read-string "Decimal Number: "))))
|
||||
(if (or (> num 255) (< num 0))
|
||||
(error "Decimal number out of range.")
|
||||
(hexl-insert-char num arg))))
|
||||
|
||||
(defun hexl-insert-octal-char (arg)
|
||||
"Insert a ASCII char ARG times at point for a given octal number."
|
||||
(interactive "p")
|
||||
(let ((num (hexl-octal-string-to-integer (read-string "Octal Number: "))))
|
||||
(if (or (> num 255) (< num 0))
|
||||
(error "Decimal number out of range.")
|
||||
(hexl-insert-char num arg))))
|
||||
|
||||
;; startup stuff.
|
||||
|
||||
(if hexl-mode-map
|
||||
nil
|
||||
(setq hexl-mode-map (make-sparse-keymap))
|
||||
|
||||
(define-key hexl-mode-map "\C-a" 'hexl-beginning-of-line)
|
||||
(define-key hexl-mode-map "\C-b" 'hexl-backward-char)
|
||||
(define-key hexl-mode-map "\C-d" 'undefined)
|
||||
(define-key hexl-mode-map "\C-e" 'hexl-end-of-line)
|
||||
(define-key hexl-mode-map "\C-f" 'hexl-forward-char)
|
||||
|
||||
(if (not (eq (key-binding "\C-h") 'help-command))
|
||||
(define-key hexl-mode-map "\C-h" 'undefined))
|
||||
|
||||
(define-key hexl-mode-map "\C-i" 'hexl-self-insert-command)
|
||||
(define-key hexl-mode-map "\C-j" 'hexl-self-insert-command)
|
||||
(define-key hexl-mode-map "\C-k" 'undefined)
|
||||
(define-key hexl-mode-map "\C-m" 'hexl-self-insert-command)
|
||||
(define-key hexl-mode-map "\C-n" 'hexl-next-line)
|
||||
(define-key hexl-mode-map "\C-o" 'undefined)
|
||||
(define-key hexl-mode-map "\C-p" 'hexl-previous-line)
|
||||
(define-key hexl-mode-map "\C-q" 'hexl-quoted-insert)
|
||||
(define-key hexl-mode-map "\C-t" 'undefined)
|
||||
(define-key hexl-mode-map "\C-v" 'hexl-scroll-up)
|
||||
(define-key hexl-mode-map "\C-w" 'undefined)
|
||||
(define-key hexl-mode-map "\C-y" 'undefined)
|
||||
|
||||
(let ((ch 32))
|
||||
(while (< ch 127)
|
||||
(define-key hexl-mode-map (format "%c" ch) 'hexl-self-insert-command)
|
||||
(setq ch (1+ ch))))
|
||||
|
||||
(define-key hexl-mode-map "\e\C-a" 'hexl-beginning-of-512b-page)
|
||||
(define-key hexl-mode-map "\e\C-b" 'hexl-backward-short)
|
||||
(define-key hexl-mode-map "\e\C-c" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-d" 'hexl-insert-decimal-char)
|
||||
(define-key hexl-mode-map "\e\C-e" 'hexl-end-of-512b-page)
|
||||
(define-key hexl-mode-map "\e\C-f" 'hexl-forward-short)
|
||||
(define-key hexl-mode-map "\e\C-g" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-h" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-i" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-j" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-k" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-l" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-m" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-n" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-o" 'hexl-insert-octal-char)
|
||||
(define-key hexl-mode-map "\e\C-p" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-q" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-r" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-s" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-t" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-u" 'undefined)
|
||||
|
||||
(define-key hexl-mode-map "\e\C-w" 'undefined)
|
||||
(define-key hexl-mode-map "\e\C-x" 'hexl-insert-hex-char)
|
||||
(define-key hexl-mode-map "\e\C-y" 'undefined)
|
||||
|
||||
|
||||
(define-key hexl-mode-map "\ea" 'hexl-beginning-of-1k-page)
|
||||
(define-key hexl-mode-map "\eb" 'hexl-backward-word)
|
||||
(define-key hexl-mode-map "\ec" 'undefined)
|
||||
(define-key hexl-mode-map "\ed" 'undefined)
|
||||
(define-key hexl-mode-map "\ee" 'hexl-end-of-1k-page)
|
||||
(define-key hexl-mode-map "\ef" 'hexl-forward-word)
|
||||
(define-key hexl-mode-map "\eg" 'hexl-goto-hex-address)
|
||||
(define-key hexl-mode-map "\eh" 'undefined)
|
||||
(define-key hexl-mode-map "\ei" 'undefined)
|
||||
(define-key hexl-mode-map "\ej" 'hexl-goto-address)
|
||||
(define-key hexl-mode-map "\ek" 'undefined)
|
||||
(define-key hexl-mode-map "\el" 'undefined)
|
||||
(define-key hexl-mode-map "\em" 'undefined)
|
||||
(define-key hexl-mode-map "\en" 'undefined)
|
||||
(define-key hexl-mode-map "\eo" 'undefined)
|
||||
(define-key hexl-mode-map "\ep" 'undefined)
|
||||
(define-key hexl-mode-map "\eq" 'undefined)
|
||||
(define-key hexl-mode-map "\er" 'undefined)
|
||||
(define-key hexl-mode-map "\es" 'undefined)
|
||||
(define-key hexl-mode-map "\et" 'undefined)
|
||||
(define-key hexl-mode-map "\eu" 'undefined)
|
||||
(define-key hexl-mode-map "\ev" 'hexl-scroll-down)
|
||||
(define-key hexl-mode-map "\ey" 'undefined)
|
||||
(define-key hexl-mode-map "\ez" 'undefined)
|
||||
(define-key hexl-mode-map "\e<" 'hexl-beginning-of-buffer)
|
||||
(define-key hexl-mode-map "\e>" 'hexl-end-of-buffer)
|
||||
|
||||
(define-key hexl-mode-map "\C-c\C-c" 'hexl-mode-exit)
|
||||
|
||||
(define-key hexl-mode-map "\C-x\C-p" 'undefined)
|
||||
(define-key hexl-mode-map "\C-x\C-s" 'hexl-save-buffer)
|
||||
(define-key hexl-mode-map "\C-x\C-t" 'undefined))
|
||||
|
||||
;; The End.
|
138
lisp/ledit.el
Normal file
138
lisp/ledit.el
Normal file
@ -0,0 +1,138 @@
|
||||
;; Emacs side of ledit interface
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;;; To do:
|
||||
;;; o lisp -> emacs side of things (grind-definition and find-definition)
|
||||
|
||||
(defvar ledit-mode-map nil)
|
||||
|
||||
(defconst ledit-zap-file (concat "/tmp/" (user-login-name) ".l1")
|
||||
"File name for data sent to Lisp by Ledit.")
|
||||
(defconst ledit-read-file (concat "/tmp/" (user-login-name) ".l2")
|
||||
"File name for data sent to Ledit by Lisp.")
|
||||
(defconst ledit-compile-file
|
||||
(concat "/tmp/" (user-login-name) ".l4")
|
||||
"File name for data sent to Lisp compiler by Ledit.")
|
||||
(defconst ledit-buffer "*LEDIT*"
|
||||
"Name of buffer in which Ledit accumulates data to send to Lisp.")
|
||||
;These are now in loaddefs.el
|
||||
;(defconst ledit-save-files t
|
||||
; "*Non-nil means Ledit should save files before transferring to Lisp.")
|
||||
;(defconst ledit-go-to-lisp-string "%?lisp"
|
||||
; "*Shell commands to execute to resume Lisp job.")
|
||||
;(defconst ledit-go-to-liszt-string "%?liszt"
|
||||
; "*Shell commands to execute to resume Lisp compiler job.")
|
||||
|
||||
(defun ledit-save-defun ()
|
||||
"Save the current defun in the ledit buffer"
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(end-of-defun)
|
||||
(let ((end (point)))
|
||||
(beginning-of-defun)
|
||||
(append-to-buffer ledit-buffer (point) end))
|
||||
(message "Current defun saved for Lisp")))
|
||||
|
||||
(defun ledit-save-region (beg end)
|
||||
"Save the current region in the ledit buffer"
|
||||
(interactive "r")
|
||||
(append-to-buffer ledit-buffer beg end)
|
||||
(message "Region saved for Lisp"))
|
||||
|
||||
(defun ledit-zap-defun-to-lisp ()
|
||||
"Carry the current defun to lisp"
|
||||
(interactive)
|
||||
(ledit-save-defun)
|
||||
(ledit-go-to-lisp))
|
||||
|
||||
(defun ledit-zap-defun-to-liszt ()
|
||||
"Carry the current defun to liszt"
|
||||
(interactive)
|
||||
(ledit-save-defun)
|
||||
(ledit-go-to-liszt))
|
||||
|
||||
(defun ledit-zap-region-to-lisp (beg end)
|
||||
"Carry the current region to lisp"
|
||||
(interactive "r")
|
||||
(ledit-save-region beg end)
|
||||
(ledit-go-to-lisp))
|
||||
|
||||
(defun ledit-go-to-lisp ()
|
||||
"Suspend Emacs and restart a waiting Lisp job."
|
||||
(interactive)
|
||||
(if ledit-save-files
|
||||
(save-some-buffers))
|
||||
(if (get-buffer ledit-buffer)
|
||||
(save-excursion
|
||||
(set-buffer ledit-buffer)
|
||||
(goto-char (point-min))
|
||||
(write-region (point-min) (point-max) ledit-zap-file)
|
||||
(erase-buffer)))
|
||||
(suspend-emacs ledit-go-to-lisp-string)
|
||||
(load ledit-read-file t t))
|
||||
|
||||
(defun ledit-go-to-liszt ()
|
||||
"Suspend Emacs and restart a waiting Liszt job."
|
||||
(interactive)
|
||||
(if ledit-save-files
|
||||
(save-some-buffers))
|
||||
(if (get-buffer ledit-buffer)
|
||||
(save-excursion
|
||||
(set-buffer ledit-buffer)
|
||||
(goto-char (point-min))
|
||||
(insert "(declare (macros t))\n")
|
||||
(write-region (point-min) (point-max) ledit-compile-file)
|
||||
(erase-buffer)))
|
||||
(suspend-emacs ledit-go-to-liszt-string)
|
||||
(load ledit-read-file t t))
|
||||
|
||||
(defun ledit-setup ()
|
||||
"Set up key bindings for the Lisp / Emacs interface"
|
||||
(if (not ledit-mode-map)
|
||||
(progn (setq ledit-mode-map (make-sparse-keymap))
|
||||
(lisp-mode-commands ledit-mode-map)))
|
||||
(define-key ledit-mode-map "\e\^d" 'ledit-save-defun)
|
||||
(define-key ledit-mode-map "\e\^r" 'ledit-save-region)
|
||||
(define-key ledit-mode-map "\^xz" 'ledit-go-to-lisp)
|
||||
(define-key ledit-mode-map "\e\^c" 'ledit-go-to-liszt))
|
||||
|
||||
(ledit-setup)
|
||||
|
||||
(defun ledit-mode ()
|
||||
"Major mode for editing text and stuffing it to a Lisp job.
|
||||
Like Lisp mode, plus these special commands:
|
||||
M-C-d -- record defun at or after point
|
||||
for later transmission to Lisp job.
|
||||
M-C-r -- record region for later transmission to Lisp job.
|
||||
C-x z -- transfer to Lisp job and transmit saved text.
|
||||
M-C-c -- transfer to Liszt (Lisp compiler) job
|
||||
and transmit saved text.
|
||||
\\{ledit-mode-map}
|
||||
To make Lisp mode automatically change to Ledit mode,
|
||||
do (setq lisp-mode-hook 'ledit-from-lisp-mode)"
|
||||
(interactive)
|
||||
(lisp-mode)
|
||||
(ledit-from-lisp-mode))
|
||||
|
||||
(defun ledit-from-lisp-mode ()
|
||||
(use-local-map ledit-mode-map)
|
||||
(setq mode-name "Ledit")
|
||||
(setq major-mode 'ledit-mode)
|
||||
(run-hooks 'ledit-mode-hook))
|
103
lisp/macros.el
Normal file
103
lisp/macros.el
Normal file
@ -0,0 +1,103 @@
|
||||
;; Non-primitive commands for keyboard macros.
|
||||
;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun name-last-kbd-macro (symbol)
|
||||
"Assign a name to the last keyboard macro defined.
|
||||
One arg, a symbol, which is the name to define.
|
||||
The symbol's function definition becomes the keyboard macro string.
|
||||
Such a \"function\" cannot be called from Lisp, but it is a valid command
|
||||
definition for the editor command loop."
|
||||
(interactive "SName for last kbd macro: ")
|
||||
(or last-kbd-macro
|
||||
(error "No keyboard macro defined"))
|
||||
(and (fboundp symbol)
|
||||
(not (stringp (symbol-function symbol)))
|
||||
(error "Function %s is already defined and not a keyboard macro."
|
||||
symbol))
|
||||
(fset symbol last-kbd-macro))
|
||||
|
||||
(defun insert-kbd-macro (macroname &optional keys)
|
||||
"Insert in buffer the definition of kbd macro NAME, as Lisp code.
|
||||
Second argument KEYS non-nil means also record the keys it is on.
|
||||
(This is the prefix argument, when calling interactively.)
|
||||
|
||||
This Lisp code will, when executed, define the kbd macro with the
|
||||
same definition it has now. If you say to record the keys,
|
||||
the Lisp code will also rebind those keys to the macro.
|
||||
Only global key bindings are recorded since executing this Lisp code
|
||||
always makes global bindings.
|
||||
|
||||
To save a kbd macro, visit a file of Lisp code such as your ~/.emacs,
|
||||
use this command, and then save the file."
|
||||
(interactive "CInsert kbd macro (name): \nP")
|
||||
(insert "(fset '")
|
||||
(prin1 macroname (current-buffer))
|
||||
(insert "\n ")
|
||||
(prin1 (symbol-function macroname) (current-buffer))
|
||||
(insert ")\n")
|
||||
(if keys
|
||||
(let ((keys (where-is-internal macroname nil)))
|
||||
(while keys
|
||||
(insert "(global-set-key ")
|
||||
(prin1 (car keys) (current-buffer))
|
||||
(insert " '")
|
||||
(prin1 macroname (current-buffer))
|
||||
(insert ")\n")
|
||||
(setq keys (cdr keys))))))
|
||||
|
||||
(defun kbd-macro-query (flag)
|
||||
"Query user during kbd macro execution.
|
||||
With prefix argument, enters recursive edit,
|
||||
reading keyboard commands even within a kbd macro.
|
||||
You can give different commands each time the macro executes.
|
||||
Without prefix argument, reads a character. Your options are:
|
||||
Space -- execute the rest of the macro.
|
||||
DEL -- skip the rest of the macro; start next repetition.
|
||||
C-d -- skip rest of the macro and don't repeat it any more.
|
||||
C-r -- enter a recursive edit, then on exit ask again for a character
|
||||
C-l -- redisplay screen and ask again."
|
||||
(interactive "P")
|
||||
(or executing-macro
|
||||
defining-kbd-macro
|
||||
(error "Not defining or executing kbd macro"))
|
||||
(if flag
|
||||
(let (executing-macro defining-kbd-macro)
|
||||
(recursive-edit))
|
||||
(if (not executing-macro)
|
||||
nil
|
||||
(let ((loop t))
|
||||
(while loop
|
||||
(let ((char (let ((executing-macro nil)
|
||||
(defining-kbd-macro nil))
|
||||
(message "Proceed with macro? (Space, DEL, C-d, C-r or C-l) ")
|
||||
(read-char))))
|
||||
(cond ((= char ? )
|
||||
(setq loop nil))
|
||||
((= char ?\177)
|
||||
(setq loop nil)
|
||||
(setq executing-macro ""))
|
||||
((= char ?\C-d)
|
||||
(setq loop nil)
|
||||
(setq executing-macro t))
|
||||
((= char ?\C-l)
|
||||
(recenter nil))
|
||||
((= char ?\C-r)
|
||||
(let (executing-macro defining-kbd-macro)
|
||||
(recursive-edit))))))))))
|
38
lisp/mail/emacsbug.el
Normal file
38
lisp/mail/emacsbug.el
Normal file
@ -0,0 +1,38 @@
|
||||
;; Command to report Emacs bugs to appropriate mailing list.
|
||||
;; Not fully installed because it can work only on Internet hosts.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
;; Principal author K. Shane Hartman
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;; >> This should be an address which is accessible to your machine,
|
||||
;; >> otherwise you can't use this file. It will only work on the
|
||||
;; >> internet with this address.
|
||||
|
||||
(defvar bug-gnu-emacs "bug-gnu-emacs@prep.ai.mit.edu"
|
||||
"Address of site maintaining mailing list for Gnu emacs bugs.")
|
||||
|
||||
(defun report-emacs-bug (topic)
|
||||
"Report a bug in Gnu emacs.
|
||||
Prompts for bug subject. Leaves you in a mail buffer."
|
||||
(interactive "sBug Subject: ")
|
||||
(mail nil bug-gnu-emacs topic)
|
||||
(goto-char (point-max))
|
||||
(insert "\nIn " (emacs-version) "\n\n")
|
||||
(message (substitute-command-keys "Type \\[mail-send] to send bug report.")))
|
||||
|
195
lisp/mail/mail-utils.el
Normal file
195
lisp/mail/mail-utils.el
Normal file
@ -0,0 +1,195 @@
|
||||
;; Utility functions used both by rmail and rnews
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(provide 'mail-utils)
|
||||
|
||||
;; should be in loaddefs
|
||||
(defvar mail-use-rfc822 nil
|
||||
"*If non-nil, use a full, hairy RFC822 parser on mail addresses.
|
||||
Otherwise, (the default) use a smaller, somewhat faster and
|
||||
often-correct parser.")
|
||||
|
||||
(defun mail-string-delete (string start end)
|
||||
"Returns a string containing all of STRING except the part
|
||||
from START (inclusive) to END (exclusive)."
|
||||
(if (null end) (substring string 0 start)
|
||||
(concat (substring string 0 start)
|
||||
(substring string end nil))))
|
||||
|
||||
(defun mail-strip-quoted-names (address)
|
||||
"Delete comments and quoted strings in an address list ADDRESS.
|
||||
Also delete leading/trailing whitespace and replace FOO <BAR> with just BAR.
|
||||
Return a modified address list."
|
||||
(if mail-use-rfc822
|
||||
(progn (require 'rfc822)
|
||||
(mapconcat 'identity (rfc822-addresses address) ", "))
|
||||
(let (pos)
|
||||
(string-match "\\`[ \t\n]*" address)
|
||||
;; strip surrounding whitespace
|
||||
(setq address (substring address
|
||||
(match-end 0)
|
||||
(string-match "[ \t\n]*\\'" address
|
||||
(match-end 0))))
|
||||
|
||||
;; Detect nested comments.
|
||||
(if (string-match "[ \t]*(\\([^)\"\\]\\|\\\\.\\|\\\\\n\\)*(" address)
|
||||
;; Strip nested comments.
|
||||
(save-excursion
|
||||
(set-buffer (get-buffer-create " *temp*"))
|
||||
(erase-buffer)
|
||||
(insert address)
|
||||
(set-syntax-table lisp-mode-syntax-table)
|
||||
(goto-char 1)
|
||||
(while (search-forward "(" nil t)
|
||||
(forward-char -1)
|
||||
(skip-chars-backward " \t")
|
||||
(delete-region (point)
|
||||
(save-excursion (forward-sexp 1) (point))))
|
||||
(setq address (buffer-string))
|
||||
(erase-buffer))
|
||||
;; Strip non-nested comments an easier way.
|
||||
(while (setq pos (string-match
|
||||
;; This doesn't hack rfc822 nested comments
|
||||
;; `(xyzzy (foo) whinge)' properly. Big deal.
|
||||
"[ \t]*(\\([^)\"\\]\\|\\\\.\\|\\\\\n\\)*)"
|
||||
address))
|
||||
(setq address
|
||||
(mail-string-delete address
|
||||
pos (match-end 0)))))
|
||||
|
||||
;; strip `quoted' names (This is supposed to hack `"Foo Bar" <bar@host>')
|
||||
(setq pos 0)
|
||||
(while (setq pos (string-match
|
||||
"[ \t]*\"\\([^\"\\]\\|\\\\.\\|\\\\\n\\)*\"[ \t\n]*"
|
||||
address pos))
|
||||
;; If the next thing is "@", we have "foo bar"@host. Leave it.
|
||||
(if (and (> (length address) (match-end 0))
|
||||
(= (aref address (match-end 0)) ?@))
|
||||
(setq pos (match-end 0))
|
||||
(setq address
|
||||
(mail-string-delete address
|
||||
pos (match-end 0)))))
|
||||
;; Retain only part of address in <> delims, if there is such a thing.
|
||||
(while (setq pos (string-match "\\(,\\|\\`\\)[^,]*<\\([^>,]*>\\)"
|
||||
address))
|
||||
(let ((junk-beg (match-end 1))
|
||||
(junk-end (match-beginning 2))
|
||||
(close (match-end 0)))
|
||||
(setq address (mail-string-delete address (1- close) close))
|
||||
(setq address (mail-string-delete address junk-beg junk-end))))
|
||||
address)))
|
||||
|
||||
(or (and (boundp 'rmail-default-dont-reply-to-names)
|
||||
(not (null rmail-default-dont-reply-to-names)))
|
||||
(setq rmail-default-dont-reply-to-names "info-"))
|
||||
|
||||
; rmail-dont-reply-to-names is defined in loaddefs
|
||||
(defun rmail-dont-reply-to (userids)
|
||||
"Returns string of mail addresses USERIDS sans any recipients
|
||||
that start with matches for rmail-dont-reply-to-names.
|
||||
Usenet paths ending in an element that matches are removed also."
|
||||
(if (null rmail-dont-reply-to-names)
|
||||
(setq rmail-dont-reply-to-names
|
||||
(concat (if rmail-default-dont-reply-to-names
|
||||
(concat rmail-default-dont-reply-to-names "\\|")
|
||||
"")
|
||||
(concat (regexp-quote (user-original-login-name))
|
||||
"\\>"))))
|
||||
(let ((match (concat "\\(^\\|,\\)[ \t\n]*\\([^,\n]*!\\|\\)\\("
|
||||
rmail-dont-reply-to-names
|
||||
"\\)"))
|
||||
(case-fold-search t)
|
||||
pos epos)
|
||||
(while (setq pos (string-match match userids))
|
||||
(if (> pos 0) (setq pos (1+ pos)))
|
||||
(setq epos
|
||||
(if (string-match "[ \t\n,]+" userids (match-end 0))
|
||||
(match-end 0)
|
||||
(length userids)))
|
||||
(setq userids
|
||||
(mail-string-delete
|
||||
userids pos epos)))
|
||||
;; get rid of any trailing commas
|
||||
(if (setq pos (string-match "[ ,\t\n]*\\'" userids))
|
||||
(setq userids (substring userids 0 pos)))
|
||||
;; remove leading spaces. they bother me.
|
||||
(if (string-match "\\s *" userids)
|
||||
(substring userids (match-end 0))
|
||||
userids)))
|
||||
|
||||
(defun mail-fetch-field (field-name &optional last all)
|
||||
"Return the value of the header field FIELD.
|
||||
The buffer is expected to be narrowed to just the headers of the message.
|
||||
If 2nd arg LAST is non-nil, use the last such field if there are several.
|
||||
If 3rd arg ALL is non-nil, concatenate all such fields, with commas between."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(let ((case-fold-search t)
|
||||
(name (concat "^" (regexp-quote field-name) "[ \t]*:[ \t]*")))
|
||||
(goto-char (point-min))
|
||||
(if all
|
||||
(let ((value ""))
|
||||
(while (re-search-forward name nil t)
|
||||
(let ((opoint (point)))
|
||||
(while (progn (forward-line 1)
|
||||
(looking-at "[ \t]")))
|
||||
(setq value (concat value
|
||||
(if (string= value "") "" ", ")
|
||||
(buffer-substring opoint (1- (point)))))))
|
||||
(and (not (string= value "")) value))
|
||||
(if (re-search-forward name nil t)
|
||||
(progn
|
||||
(if last (while (re-search-forward name nil t)))
|
||||
(let ((opoint (point)))
|
||||
(while (progn (forward-line 1)
|
||||
(looking-at "[ \t]")))
|
||||
(buffer-substring opoint (1- (point))))))))))
|
||||
|
||||
;; Parse a list of tokens separated by commas.
|
||||
;; It runs from point to the end of the visible part of the buffer.
|
||||
;; Whitespace before or after tokens is ignored,
|
||||
;; but whitespace within tokens is kept.
|
||||
(defun mail-parse-comma-list ()
|
||||
(let (accumulated
|
||||
beg)
|
||||
(skip-chars-forward " ")
|
||||
(while (not (eobp))
|
||||
(setq beg (point))
|
||||
(skip-chars-forward "^,")
|
||||
(skip-chars-backward " ")
|
||||
(setq accumulated
|
||||
(cons (buffer-substring beg (point))
|
||||
accumulated))
|
||||
(skip-chars-forward "^,")
|
||||
(skip-chars-forward ", "))
|
||||
accumulated))
|
||||
|
||||
(defun mail-comma-list-regexp (labels)
|
||||
(let (pos)
|
||||
(setq pos (or (string-match "[^ \t]" labels) 0))
|
||||
;; Remove leading and trailing whitespace.
|
||||
(setq labels (substring labels pos (string-match "[ \t]*$" labels pos)))
|
||||
;; Change each comma to \|, and flush surrounding whitespace.
|
||||
(while (setq pos (string-match "[ \t]*,[ \t]*" labels))
|
||||
(setq labels
|
||||
(concat (substring labels 0 pos)
|
||||
"\\|"
|
||||
(substring labels (match-end 0))))))
|
||||
labels)
|
105
lisp/mail/rmailedit.el
Normal file
105
lisp/mail/rmailedit.el
Normal file
@ -0,0 +1,105 @@
|
||||
;; "RMAIL edit mode" Edit the current message.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(require 'rmail)
|
||||
|
||||
(defvar rmail-edit-map nil)
|
||||
(if rmail-edit-map
|
||||
nil
|
||||
(setq rmail-edit-map (nconc (make-sparse-keymap) text-mode-map))
|
||||
(define-key rmail-edit-map "\C-c\C-c" 'rmail-cease-edit)
|
||||
(define-key rmail-edit-map "\C-c\C-]" 'rmail-abort-edit))
|
||||
|
||||
;; Rmail Edit mode is suitable only for specially formatted data.
|
||||
(put 'rmail-edit-mode 'mode-class 'special)
|
||||
|
||||
(defun rmail-edit-mode ()
|
||||
"Major mode for editing the contents of an RMAIL message.
|
||||
The editing commands are the same as in Text mode, together with two commands
|
||||
to return to regular RMAIL:
|
||||
* rmail-abort-edit cancels the changes
|
||||
you have made and returns to RMAIL
|
||||
* rmail-cease-edit makes them permanent.
|
||||
\\{rmail-edit-map}"
|
||||
(use-local-map rmail-edit-map)
|
||||
(setq major-mode 'rmail-edit-mode)
|
||||
(setq mode-name "RMAIL Edit")
|
||||
(if (boundp 'mode-line-modified)
|
||||
(setq mode-line-modified (default-value 'mode-line-modified))
|
||||
(setq mode-line-format (default-value 'mode-line-format)))
|
||||
(run-hooks 'text-mode-hook 'rmail-edit-mode-hook))
|
||||
|
||||
(defun rmail-edit-current-message ()
|
||||
"Edit the contents of this message."
|
||||
(interactive)
|
||||
(rmail-edit-mode)
|
||||
(make-local-variable 'rmail-old-text)
|
||||
(setq rmail-old-text (buffer-substring (point-min) (point-max)))
|
||||
(setq buffer-read-only nil)
|
||||
(set-buffer-modified-p (buffer-modified-p))
|
||||
;; Make mode line update.
|
||||
(if (and (eq (key-binding "\C-c\C-c") 'rmail-cease-edit)
|
||||
(eq (key-binding "\C-c\C-]") 'rmail-abort-edit))
|
||||
(message "Editing: Type C-c C-c to return to Rmail, C-c C-] to abort")
|
||||
(message (substitute-command-keys
|
||||
"Editing: Type \\[rmail-cease-edit] to return to Rmail, \\[rmail-abort-edit] to abort"))))
|
||||
|
||||
(defun rmail-cease-edit ()
|
||||
"Finish editing message; switch back to Rmail proper."
|
||||
(interactive)
|
||||
;; Make sure buffer ends with a newline.
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(if (/= (preceding-char) ?\n)
|
||||
(insert "\n"))
|
||||
;; Adjust the marker that points to the end of this message.
|
||||
(set-marker (aref rmail-message-vector (1+ rmail-current-message))
|
||||
(point)))
|
||||
(let ((old rmail-old-text))
|
||||
;; Update the mode line.
|
||||
(set-buffer-modified-p (buffer-modified-p))
|
||||
(rmail-mode-1)
|
||||
(if (and (= (length old) (- (point-max) (point-min)))
|
||||
(string= old (buffer-substring (point-min) (point-max))))
|
||||
()
|
||||
(setq old nil)
|
||||
(rmail-set-attribute "edited" t)
|
||||
(if (boundp 'rmail-summary-vector)
|
||||
(progn
|
||||
(aset rmail-summary-vector (1- rmail-current-message) nil)
|
||||
(save-excursion
|
||||
(rmail-widen-to-current-msgbeg
|
||||
(function (lambda ()
|
||||
(forward-line 2)
|
||||
(if (looking-at "Summary-line: ")
|
||||
(let ((buffer-read-only nil))
|
||||
(delete-region (point)
|
||||
(progn (forward-line 1)
|
||||
(point))))))))
|
||||
(rmail-show-message))))))
|
||||
(setq buffer-read-only t))
|
||||
|
||||
(defun rmail-abort-edit ()
|
||||
"Abort edit of current message; restore original contents."
|
||||
(interactive)
|
||||
(delete-region (point-min) (point-max))
|
||||
(insert rmail-old-text)
|
||||
(rmail-cease-edit))
|
||||
|
260
lisp/mail/rmailkwd.el
Normal file
260
lisp/mail/rmailkwd.el
Normal file
@ -0,0 +1,260 @@
|
||||
;; "RMAIL" mail reader for Emacs.
|
||||
;; Copyright (C) 1985, 1988 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;; Global to all RMAIL buffers. It exists primarily for the sake of
|
||||
;; completion. It is better to use strings with the label functions
|
||||
;; and let them worry about making the label.
|
||||
|
||||
(defvar rmail-label-obarray (make-vector 47 0))
|
||||
|
||||
;; Named list of symbols representing valid message attributes in RMAIL.
|
||||
|
||||
(defconst rmail-attributes
|
||||
(cons 'rmail-keywords
|
||||
(mapcar '(lambda (s) (intern s rmail-label-obarray))
|
||||
'("deleted" "answered" "filed" "forwarded" "unseen" "edited"))))
|
||||
|
||||
(defconst rmail-deleted-label (intern "deleted" rmail-label-obarray))
|
||||
|
||||
;; Named list of symbols representing valid message keywords in RMAIL.
|
||||
|
||||
(defvar rmail-keywords nil)
|
||||
|
||||
(defun rmail-add-label (string)
|
||||
"Add LABEL to labels associated with current RMAIL message.
|
||||
Completion is performed over known labels when reading."
|
||||
(interactive (list (rmail-read-label "Add label")))
|
||||
(rmail-set-label string t))
|
||||
|
||||
(defun rmail-kill-label (string)
|
||||
"Remove LABEL from labels associated with current RMAIL message.
|
||||
Completion is performed over known labels when reading."
|
||||
(interactive (list (rmail-read-label "Remove label")))
|
||||
(rmail-set-label string nil))
|
||||
|
||||
(defun rmail-read-label (prompt)
|
||||
(if (not rmail-keywords) (rmail-parse-file-keywords))
|
||||
(let ((result
|
||||
(completing-read (concat prompt
|
||||
(if rmail-last-label
|
||||
(concat " (default "
|
||||
(symbol-name rmail-last-label)
|
||||
"): ")
|
||||
": "))
|
||||
rmail-label-obarray
|
||||
nil
|
||||
nil)))
|
||||
(if (string= result "")
|
||||
rmail-last-label
|
||||
(setq rmail-last-label (rmail-make-label result t)))))
|
||||
|
||||
(defun rmail-set-label (l state &optional n)
|
||||
(rmail-maybe-set-message-counters)
|
||||
(if (not n) (setq n rmail-current-message))
|
||||
(aset rmail-summary-vector (1- n) nil)
|
||||
(let* ((attribute (rmail-attribute-p l))
|
||||
(keyword (and (not attribute)
|
||||
(or (rmail-keyword-p l)
|
||||
(rmail-install-keyword l))))
|
||||
(label (or attribute keyword)))
|
||||
(if label
|
||||
(let ((omax (- (buffer-size) (point-max)))
|
||||
(omin (- (buffer-size) (point-min)))
|
||||
(buffer-read-only nil)
|
||||
(case-fold-search t))
|
||||
(unwind-protect
|
||||
(save-excursion
|
||||
(widen)
|
||||
(goto-char (rmail-msgbeg n))
|
||||
(forward-line 1)
|
||||
(if (not (looking-at "[01],"))
|
||||
nil
|
||||
(let ((start (1+ (point)))
|
||||
(bound))
|
||||
(narrow-to-region (point) (progn (end-of-line) (point)))
|
||||
(setq bound (point-max))
|
||||
(search-backward ",," nil t)
|
||||
(if attribute
|
||||
(setq bound (1+ (point)))
|
||||
(setq start (1+ (point))))
|
||||
(goto-char start)
|
||||
; (while (re-search-forward "[ \t]*,[ \t]*" nil t)
|
||||
; (replace-match ","))
|
||||
; (goto-char start)
|
||||
(if (re-search-forward
|
||||
(concat ", " (rmail-quote-label-name label) ",")
|
||||
bound
|
||||
'move)
|
||||
(if (not state) (replace-match ","))
|
||||
(if state (insert " " (symbol-name label) ",")))
|
||||
(if (eq label rmail-deleted-label)
|
||||
(rmail-set-message-deleted-p n state)))))
|
||||
(narrow-to-region (- (buffer-size) omin) (- (buffer-size) omax))
|
||||
(if (= n rmail-current-message) (rmail-display-labels)))))))
|
||||
|
||||
;; Commented functions aren't used by RMAIL but might be nice for user
|
||||
;; packages that do stuff with RMAIL. Note that rmail-message-labels-p
|
||||
;; is in rmailsum now.
|
||||
|
||||
;(defun rmail-message-attribute-p (attribute &optional n)
|
||||
; "Returns t if ATTRIBUTE on NTH or current message."
|
||||
; (rmail-message-labels-p (rmail-make-label attribute t) n))
|
||||
|
||||
;(defun rmail-message-keyword-p (keyword &optional n)
|
||||
; "Returns t if KEYWORD on NTH or current message."
|
||||
; (rmail-message-labels-p (rmail-make-label keyword t) n t))
|
||||
|
||||
;(defun rmail-message-label-p (label &optional n)
|
||||
; "Returns symbol if LABEL (attribute or keyword) on NTH or current message."
|
||||
; (rmail-message-labels-p (rmail-make-label label t) n 'all))
|
||||
|
||||
;; Not used by RMAIL but might be nice for user package.
|
||||
|
||||
;(defun rmail-parse-message-labels (&optional n)
|
||||
; "Returns labels associated with NTH or current RMAIL message.
|
||||
;Results is a list of two lists. The first is the message attributes
|
||||
;and the second is the message keywords. Labels are represented as symbols."
|
||||
; (let ((omin (- (buffer-size) (point-min)))
|
||||
; (omax (- (buffer-size) (point-max)))
|
||||
; (result))
|
||||
; (unwind-protect
|
||||
; (save-excursion
|
||||
; (let ((beg (rmail-msgbeg (or n rmail-current-message))))
|
||||
; (widen)
|
||||
; (goto-char beg)
|
||||
; (forward-line 1)
|
||||
; (if (looking-at "[01],")
|
||||
; (save-restriction
|
||||
; (narrow-to-region (point) (save-excursion (end-of-line) (point)))
|
||||
; (rmail-nuke-whitespace)
|
||||
; (goto-char (1+ (point-min)))
|
||||
; (list (mail-parse-comma-list) (mail-parse-comma-list))))))
|
||||
; (narrow-to-region (- (buffer-size) omin)
|
||||
; (- (buffer-size) omax))
|
||||
; nil)))
|
||||
|
||||
(defun rmail-attribute-p (s)
|
||||
(let ((symbol (rmail-make-label s)))
|
||||
(if (memq symbol (cdr rmail-attributes)) symbol)))
|
||||
|
||||
(defun rmail-keyword-p (s)
|
||||
(let ((symbol (rmail-make-label s)))
|
||||
(if (memq symbol (cdr (rmail-keywords))) symbol)))
|
||||
|
||||
(defun rmail-make-label (s &optional forcep)
|
||||
(cond ((symbolp s) s)
|
||||
(forcep (intern (downcase s) rmail-label-obarray))
|
||||
(t (intern-soft (downcase s) rmail-label-obarray))))
|
||||
|
||||
(defun rmail-force-make-label (s)
|
||||
(intern (downcase s) rmail-label-obarray))
|
||||
|
||||
(defun rmail-quote-label-name (label)
|
||||
(regexp-quote (symbol-name (rmail-make-label label t))))
|
||||
|
||||
;; Motion on messages with keywords.
|
||||
|
||||
(defun rmail-previous-labeled-message (n label)
|
||||
"Show previous message with LABEL. Defaults to last labels used.
|
||||
With prefix argument N moves backward N messages with these labels."
|
||||
(interactive "p\nsMove to previous msg with labels: ")
|
||||
(rmail-next-labeled-message (- n) label))
|
||||
|
||||
(defun rmail-next-labeled-message (n labels)
|
||||
"Show next message with LABEL. Defaults to last labels used.
|
||||
With prefix argument N moves forward N messages with these labels."
|
||||
(interactive "p\nsMove to next msg with labels: ")
|
||||
(if (string= labels "")
|
||||
(setq labels rmail-last-multi-labels))
|
||||
(or labels
|
||||
(error "No labels to find have been specified previously"))
|
||||
(setq rmail-last-multi-labels labels)
|
||||
(rmail-maybe-set-message-counters)
|
||||
(let ((lastwin rmail-current-message)
|
||||
(current rmail-current-message)
|
||||
(regexp (concat ", ?\\("
|
||||
(mail-comma-list-regexp labels)
|
||||
"\\),")))
|
||||
(save-restriction
|
||||
(widen)
|
||||
(while (and (> n 0) (< current rmail-total-messages))
|
||||
(setq current (1+ current))
|
||||
(if (rmail-message-labels-p current regexp)
|
||||
(setq lastwin current n (1- n))))
|
||||
(while (and (< n 0) (> current 1))
|
||||
(setq current (1- current))
|
||||
(if (rmail-message-labels-p current regexp)
|
||||
(setq lastwin current n (1+ n)))))
|
||||
(rmail-show-message lastwin)
|
||||
(if (< n 0)
|
||||
(message "No previous message with labels %s" labels))
|
||||
(if (> n 0)
|
||||
(message "No following message with labels %s" labels))))
|
||||
|
||||
;;; Manipulate the file's Labels option.
|
||||
|
||||
;; Return a list of symbols for all
|
||||
;; the keywords (labels) recorded in this file's Labels option.
|
||||
(defun rmail-keywords ()
|
||||
(or rmail-keywords (rmail-parse-file-keywords)))
|
||||
|
||||
;; Set rmail-keywords to a list of symbols for all
|
||||
;; the keywords (labels) recorded in this file's Labels option.
|
||||
(defun rmail-parse-file-keywords ()
|
||||
(save-restriction
|
||||
(save-excursion
|
||||
(widen)
|
||||
(goto-char 1)
|
||||
(setq rmail-keywords
|
||||
(if (search-forward "\nLabels:" (rmail-msgbeg 1) t)
|
||||
(progn
|
||||
(narrow-to-region (point) (progn (end-of-line) (point)))
|
||||
(goto-char (point-min))
|
||||
(cons 'rmail-keywords
|
||||
(mapcar 'rmail-force-make-label
|
||||
(mail-parse-comma-list)))))))))
|
||||
|
||||
;; Add WORD to the list in the file's Labels option.
|
||||
;; Any keyword used for the first time needs this done.
|
||||
(defun rmail-install-keyword (word)
|
||||
(let ((keyword (rmail-make-label word t))
|
||||
(keywords (rmail-keywords)))
|
||||
(if (not (or (rmail-attribute-p keyword)
|
||||
(rmail-keyword-p keyword)))
|
||||
(let ((omin (- (buffer-size) (point-min)))
|
||||
(omax (- (buffer-size) (point-max))))
|
||||
(unwind-protect
|
||||
(save-excursion
|
||||
(widen)
|
||||
(goto-char 1)
|
||||
(let ((case-fold-search t)
|
||||
(buffer-read-only nil))
|
||||
(or (search-forward "\nLabels:" nil t)
|
||||
(progn
|
||||
(end-of-line)
|
||||
(insert "\nLabels:")))
|
||||
(delete-region (point) (progn (end-of-line) (point)))
|
||||
(setcdr keywords (cons keyword (cdr keywords)))
|
||||
(while (setq keywords (cdr keywords))
|
||||
(insert (symbol-name (car keywords)) ","))
|
||||
(delete-char -1)))
|
||||
(narrow-to-region (- (buffer-size) omin)
|
||||
(- (buffer-size) omax)))))
|
||||
keyword))
|
100
lisp/makesum.el
Normal file
100
lisp/makesum.el
Normal file
@ -0,0 +1,100 @@
|
||||
;; Generate key binding summary for Emacs
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun make-command-summary ()
|
||||
"Make a summary of current key bindings in the buffer *Summary*.
|
||||
Previous contents of that buffer are killed first."
|
||||
(interactive)
|
||||
(message "Making command summary...")
|
||||
;; This puts a description of bindings in a buffer called *Help*.
|
||||
(save-window-excursion
|
||||
(describe-bindings))
|
||||
(with-output-to-temp-buffer "*Summary*"
|
||||
(save-excursion
|
||||
(let ((cur-mode mode-name))
|
||||
(set-buffer standard-output)
|
||||
(erase-buffer)
|
||||
(insert-buffer-substring "*Help*")
|
||||
(goto-char (point-min))
|
||||
(delete-region (point) (progn (forward-line 1) (point)))
|
||||
(while (search-forward " " nil t)
|
||||
(replace-match " "))
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "-@ " nil t)
|
||||
(replace-match "-SP"))
|
||||
(goto-char (point-min))
|
||||
(while (search-forward " .. ~ " nil t)
|
||||
(replace-match "SP .. ~"))
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "C-?" nil t)
|
||||
(replace-match "DEL"))
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "C-i" nil t)
|
||||
(replace-match "TAB"))
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward "^Local Bindings:" nil t)
|
||||
(progn
|
||||
(forward-char -1)
|
||||
(insert " for " cur-mode " Mode")
|
||||
(while (search-forward "??\n" nil t)
|
||||
(delete-region (point)
|
||||
(progn
|
||||
(forward-line -1)
|
||||
(point))))))
|
||||
(goto-char (point-min))
|
||||
(insert "Emacs command summary, " (substring (current-time-string) 0 10)
|
||||
".\n")
|
||||
;; Delete "key binding" and underlining of dashes.
|
||||
(delete-region (point) (progn (forward-line 2) (point)))
|
||||
(forward-line 1) ;Skip blank line
|
||||
(while (not (eobp))
|
||||
(let ((beg (point)))
|
||||
(or (re-search-forward "^$" nil t)
|
||||
(goto-char (point-max)))
|
||||
(double-column beg (point))
|
||||
(forward-line 1)))
|
||||
(goto-char (point-min)))))
|
||||
(message "Making command summary...done"))
|
||||
|
||||
(defun double-column (start end)
|
||||
(interactive "r")
|
||||
(let (half cnt
|
||||
line lines nlines
|
||||
(from-end (- (point-max) end)))
|
||||
(setq nlines (count-lines start end))
|
||||
(if (<= nlines 1)
|
||||
nil
|
||||
(setq half (/ (1+ nlines) 2))
|
||||
(goto-char start)
|
||||
(save-excursion
|
||||
(forward-line half)
|
||||
(while (< half nlines)
|
||||
(setq half (1+ half))
|
||||
(setq line (buffer-substring (point) (save-excursion (end-of-line) (point))))
|
||||
(setq lines (cons line lines))
|
||||
(delete-region (point) (progn (forward-line 1) (point)))))
|
||||
(setq lines (nreverse lines))
|
||||
(while lines
|
||||
(end-of-line)
|
||||
(indent-to 41)
|
||||
(insert (car lines))
|
||||
(forward-line 1)
|
||||
(setq lines (cdr lines))))
|
||||
(goto-char (- (point-max) from-end))))
|
105
lisp/novice.el
Normal file
105
lisp/novice.el
Normal file
@ -0,0 +1,105 @@
|
||||
;; Handling of disabled commands ("novice mode") for Emacs.
|
||||
;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;; This function is called (by autoloading)
|
||||
;; to handle any disabled command.
|
||||
;; The command is found in this-command
|
||||
;; and the keys are returned by (this-command-keys).
|
||||
|
||||
(defun disabled-command-hook (&rest ignore)
|
||||
(let (char)
|
||||
(save-window-excursion
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(if (= (aref (this-command-keys) 0) ?\M-x)
|
||||
(princ "You have invoked the disabled command ")
|
||||
(princ "You have typed ")
|
||||
(princ (key-description (this-command-keys)))
|
||||
(princ ", invoking disabled command "))
|
||||
(princ this-command)
|
||||
(princ ":\n")
|
||||
;; Print any special message saying why the command is disabled.
|
||||
(if (stringp (get this-command 'disabled))
|
||||
(princ (get this-command 'disabled)))
|
||||
(princ (or (condition-case ()
|
||||
(documentation this-command)
|
||||
(error nil))
|
||||
"<< not documented >>"))
|
||||
;; Keep only the first paragraph of the documentation.
|
||||
(save-excursion
|
||||
(set-buffer "*Help*")
|
||||
(goto-char (point-min))
|
||||
(if (search-forward "\n\n" nil t)
|
||||
(delete-region (1- (point)) (point-max))
|
||||
(goto-char (point-max))))
|
||||
(princ "\n\n")
|
||||
(princ "You can now type
|
||||
Space to try the command just this once,
|
||||
but leave it disabled,
|
||||
Y to try it and enable it (no questions if you use it again),
|
||||
N to do nothing (command remains disabled)."))
|
||||
(message "Type y, n or Space: ")
|
||||
(let ((cursor-in-echo-area t))
|
||||
(while (not (memq (setq char (downcase (read-char)))
|
||||
'(? ?y ?n)))
|
||||
(ding)
|
||||
(message "Please type y, n or Space: "))))
|
||||
(if (= char ?y)
|
||||
(if (y-or-n-p "Enable command for future editing sessions also? ")
|
||||
(enable-command this-command)
|
||||
(put this-command 'disabled nil)))
|
||||
(if (/= char ?n)
|
||||
(call-interactively this-command))))
|
||||
|
||||
(defun enable-command (command)
|
||||
"Allow COMMAND to be executed without special confirmation from now on.
|
||||
The user's .emacs file is altered so that this will apply
|
||||
to future sessions."
|
||||
(interactive "CEnable command: ")
|
||||
(put command 'disabled nil)
|
||||
(save-excursion
|
||||
(set-buffer (find-file-noselect (substitute-in-file-name "~/.emacs")))
|
||||
(goto-char (point-min))
|
||||
(if (search-forward (concat "(put '" (symbol-name command) " ") nil t)
|
||||
(delete-region
|
||||
(progn (beginning-of-line) (point))
|
||||
(progn (forward-line 1) (point)))
|
||||
;; Must have been disabled by default.
|
||||
(goto-char (point-max))
|
||||
(insert "\n(put '" (symbol-name command) " 'disabled nil)\n"))
|
||||
(setq foo (buffer-modified-p))
|
||||
(save-buffer)))
|
||||
|
||||
(defun disable-command (command)
|
||||
"Require special confirmation to execute COMMAND from now on.
|
||||
The user's .emacs file is altered so that this will apply
|
||||
to future sessions."
|
||||
(interactive "CDisable command: ")
|
||||
(put command 'disabled t)
|
||||
(save-excursion
|
||||
(set-buffer (find-file-noselect (substitute-in-file-name "~/.emacs")))
|
||||
(goto-char (point-min))
|
||||
(if (search-forward (concat "(put '" (symbol-name command) " ") nil t)
|
||||
(delete-region
|
||||
(progn (beginning-of-line) (point))
|
||||
(progn (forward-line 1) (point))))
|
||||
(goto-char (point-max))
|
||||
(insert "(put '" (symbol-name command) " 'disabled t)\n")
|
||||
(save-buffer)))
|
||||
|
87
lisp/play/dissociate.el
Normal file
87
lisp/play/dissociate.el
Normal file
@ -0,0 +1,87 @@
|
||||
;; Scramble text amusingly for Emacs.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun dissociated-press (&optional arg)
|
||||
"Dissociate the text of the current buffer.
|
||||
Output goes in buffer named *Dissociation*,
|
||||
which is redisplayed each time text is added to it.
|
||||
Every so often the user must say whether to continue.
|
||||
If ARG is positive, require ARG chars of continuity.
|
||||
If ARG is negative, require -ARG words of continuity.
|
||||
Default is 2."
|
||||
(interactive "P")
|
||||
(setq arg (if arg (prefix-numeric-value arg) 2))
|
||||
(let* ((inbuf (current-buffer))
|
||||
(outbuf (get-buffer-create "*Dissociation*"))
|
||||
(move-function (if (> arg 0) 'forward-char 'forward-word))
|
||||
(move-amount (if (> arg 0) arg (- arg)))
|
||||
(search-function (if (> arg 0) 'search-forward 'word-search-forward))
|
||||
(last-query-point 0))
|
||||
(switch-to-buffer outbuf)
|
||||
(erase-buffer)
|
||||
(while
|
||||
(save-excursion
|
||||
(goto-char last-query-point)
|
||||
(vertical-motion (- (window-height) 4))
|
||||
(or (= (point) (point-max))
|
||||
(and (progn (goto-char (point-max))
|
||||
(y-or-n-p "Continue dissociation? "))
|
||||
(progn
|
||||
(message "")
|
||||
(recenter 1)
|
||||
(setq last-query-point (point-max))
|
||||
t))))
|
||||
(let (start end)
|
||||
(save-excursion
|
||||
(set-buffer inbuf)
|
||||
(setq start (point))
|
||||
(if (eq move-function 'forward-char)
|
||||
(progn
|
||||
(setq end (+ start (+ move-amount (random 16))))
|
||||
(if (> end (point-max))
|
||||
(setq end (+ 1 move-amount (random 16))))
|
||||
(goto-char end))
|
||||
(funcall move-function
|
||||
(+ move-amount (random 16))))
|
||||
(setq end (point)))
|
||||
(let ((opoint (point)))
|
||||
(insert-buffer-substring inbuf start end)
|
||||
(save-excursion
|
||||
(goto-char opoint)
|
||||
(end-of-line)
|
||||
(and (> (current-column) fill-column)
|
||||
(do-auto-fill)))))
|
||||
(save-excursion
|
||||
(set-buffer inbuf)
|
||||
(if (eobp)
|
||||
(goto-char (point-min))
|
||||
(let ((overlap
|
||||
(buffer-substring (prog1 (point)
|
||||
(funcall move-function
|
||||
(- move-amount)))
|
||||
(point))))
|
||||
(let (ranval)
|
||||
(while (< (setq ranval (random)) 0))
|
||||
(goto-char (1+ (% ranval (1- (point-max))))))
|
||||
(or (funcall search-function overlap nil t)
|
||||
(let ((opoint (point)))
|
||||
(goto-char 1)
|
||||
(funcall search-function overlap opoint t))))))
|
||||
(sit-for 0))))
|
1166
lisp/play/gomoku.el
Normal file
1166
lisp/play/gomoku.el
Normal file
File diff suppressed because it is too large
Load Diff
109
lisp/play/spook.el
Normal file
109
lisp/play/spook.el
Normal file
@ -0,0 +1,109 @@
|
||||
;; Spook phrase utility
|
||||
;; Copyright (C) 1988 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
; Steve Strassmann (straz@media-lab.media.mit.edu) didn't write
|
||||
; this, and even if he did, he really didn't mean for you to use it
|
||||
; in an anarchistic way.
|
||||
; May 1987
|
||||
|
||||
; To use this:
|
||||
; Make sure you have the variable SPOOK-PHRASES-FILE pointing to
|
||||
; a valid phrase file. Phrase files are in the same format as
|
||||
; zippy's yow.lines (ITS-style LINS format).
|
||||
; Strings are terminated by ascii 0 characters. Leading whitespace ignored.
|
||||
; Everything up to the first \000 is a comment.
|
||||
;
|
||||
; Just before sending mail, do M-x spook.
|
||||
; A number of phrases will be inserted into your buffer, to help
|
||||
; give your message that extra bit of attractiveness for automated
|
||||
; keyword scanners.
|
||||
|
||||
; Variables
|
||||
(defvar spook-phrases-file (concat exec-directory "spook.lines")
|
||||
"Keep your favorite phrases here.")
|
||||
|
||||
(defvar spook-phrase-default-count 15
|
||||
"Default number of phrases to insert")
|
||||
|
||||
(defvar spook-vector nil
|
||||
"Important phrases for NSA mail-watchers")
|
||||
|
||||
; Randomize the seed in the random number generator.
|
||||
(random t)
|
||||
|
||||
; Call this with M-x spook.
|
||||
(defun spook ()
|
||||
"Adds that special touch of class to your outgoing mail."
|
||||
(interactive)
|
||||
(if (null spook-vector)
|
||||
(setq spook-vector (snarf-spooks)))
|
||||
(shuffle-vector spook-vector)
|
||||
(let ((start (point)))
|
||||
(insert ?\n)
|
||||
(spook1 (min (- (length spook-vector) 1) spook-phrase-default-count))
|
||||
(insert ?\n)
|
||||
(fill-region-as-paragraph start (point) nil)))
|
||||
|
||||
(defun spook1 (arg)
|
||||
"Inserts a spook phrase ARG times."
|
||||
(cond ((zerop arg) t)
|
||||
(t (insert (aref spook-vector arg))
|
||||
(insert " ")
|
||||
(spook1 (1- arg)))))
|
||||
|
||||
(defun snarf-spooks ()
|
||||
"Reads in the phrase file"
|
||||
(message "Checking authorization...")
|
||||
(save-excursion
|
||||
(let ((buf (generate-new-buffer "*spook*"))
|
||||
(result '()))
|
||||
(set-buffer buf)
|
||||
(insert-file-contents (expand-file-name spook-phrases-file))
|
||||
(search-forward "\0")
|
||||
(while (progn (skip-chars-forward " \t\n\r\f") (not (eobp)))
|
||||
(let ((beg (point)))
|
||||
(search-forward "\0")
|
||||
(setq result (cons (buffer-substring beg (1- (point)))
|
||||
result))))
|
||||
(kill-buffer buf)
|
||||
(message "Checking authorization... Approved.")
|
||||
(setq spook-vector (apply 'vector result)))))
|
||||
|
||||
(defun pick-random (n)
|
||||
"Returns a random number from 0 to N-1 inclusive."
|
||||
(% (logand 0777777 (random)) n))
|
||||
|
||||
; Thanks to Ian G Batten <BattenIG@CS.BHAM.AC.UK>
|
||||
; [of the University of Birmingham Computer Science Department]
|
||||
; for the iterative version of this shuffle.
|
||||
;
|
||||
(defun shuffle-vector (vector)
|
||||
"Randomly permute the elements of VECTOR (all permutations equally likely)"
|
||||
(let ((i 0)
|
||||
j
|
||||
temp
|
||||
(len (length vector)))
|
||||
(while (< i len)
|
||||
(setq j (+ i (pick-random (- len i))))
|
||||
(setq temp (aref vector i))
|
||||
(aset vector i (aref vector j))
|
||||
(aset vector j temp)
|
||||
(setq i (1+ i))))
|
||||
vector)
|
550
lisp/progmodes/icon.el
Normal file
550
lisp/progmodes/icon.el
Normal file
@ -0,0 +1,550 @@
|
||||
;; Note: use
|
||||
;; (autoload 'icon-mode "icon" nil t)
|
||||
;; (setq auto-mode-alist (cons '("\\.icn$" . icon-mode) auto-mode-alist))
|
||||
;; if not permanently installed in your emacs
|
||||
|
||||
;; Icon code editing commands for Emacs
|
||||
;; Derived from c-mode.el 15-Feb-89 Chris Smith convex!csmith
|
||||
;; Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defvar icon-mode-abbrev-table nil
|
||||
"Abbrev table in use in Icon-mode buffers.")
|
||||
(define-abbrev-table 'icon-mode-abbrev-table ())
|
||||
|
||||
(defvar icon-mode-map ()
|
||||
"Keymap used in Icon mode.")
|
||||
(if icon-mode-map
|
||||
()
|
||||
(setq icon-mode-map (make-sparse-keymap))
|
||||
(define-key icon-mode-map "{" 'electric-icon-brace)
|
||||
(define-key icon-mode-map "}" 'electric-icon-brace)
|
||||
(define-key icon-mode-map "\e\C-h" 'mark-icon-function)
|
||||
(define-key icon-mode-map "\e\C-a" 'beginning-of-icon-defun)
|
||||
(define-key icon-mode-map "\e\C-e" 'end-of-icon-defun)
|
||||
(define-key icon-mode-map "\e\C-q" 'indent-icon-exp)
|
||||
(define-key icon-mode-map "\177" 'backward-delete-char-untabify)
|
||||
(define-key icon-mode-map "\t" 'icon-indent-command))
|
||||
|
||||
(defvar icon-mode-syntax-table nil
|
||||
"Syntax table in use in Icon-mode buffers.")
|
||||
|
||||
(if icon-mode-syntax-table
|
||||
()
|
||||
(setq icon-mode-syntax-table (make-syntax-table))
|
||||
(modify-syntax-entry ?\\ "\\" icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?# "<" icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?\n ">" icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?$ "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?/ "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?* "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?+ "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?- "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?= "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?% "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?< "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?> "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?& "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?| "." icon-mode-syntax-table)
|
||||
(modify-syntax-entry ?\' "\"" icon-mode-syntax-table))
|
||||
|
||||
(defconst icon-indent-level 4
|
||||
"*Indentation of Icon statements with respect to containing block.")
|
||||
(defconst icon-brace-imaginary-offset 0
|
||||
"*Imagined indentation of a Icon open brace that actually follows a statement.")
|
||||
(defconst icon-brace-offset 0
|
||||
"*Extra indentation for braces, compared with other text in same context.")
|
||||
(defconst icon-continued-statement-offset 4
|
||||
"*Extra indent for lines not starting new statements.")
|
||||
(defconst icon-continued-brace-offset 0
|
||||
"*Extra indent for substatements that start with open-braces.
|
||||
This is in addition to icon-continued-statement-offset.")
|
||||
|
||||
(defconst icon-auto-newline nil
|
||||
"*Non-nil means automatically newline before and after braces
|
||||
inserted in Icon code.")
|
||||
|
||||
(defconst icon-tab-always-indent t
|
||||
"*Non-nil means TAB in Icon mode should always reindent the current line,
|
||||
regardless of where in the line point is when the TAB command is used.")
|
||||
|
||||
(defun icon-mode ()
|
||||
"Major mode for editing Icon code.
|
||||
Expression and list commands understand all Icon brackets.
|
||||
Tab indents for Icon code.
|
||||
Paragraphs are separated by blank lines only.
|
||||
Delete converts tabs to spaces as it moves back.
|
||||
\\{icon-mode-map}
|
||||
Variables controlling indentation style:
|
||||
icon-tab-always-indent
|
||||
Non-nil means TAB in Icon mode should always reindent the current line,
|
||||
regardless of where in the line point is when the TAB command is used.
|
||||
icon-auto-newline
|
||||
Non-nil means automatically newline before and after braces
|
||||
inserted in Icon code.
|
||||
icon-indent-level
|
||||
Indentation of Icon statements within surrounding block.
|
||||
The surrounding block's indentation is the indentation
|
||||
of the line on which the open-brace appears.
|
||||
icon-continued-statement-offset
|
||||
Extra indentation given to a substatement, such as the
|
||||
then-clause of an if or body of a while.
|
||||
icon-continued-brace-offset
|
||||
Extra indentation given to a brace that starts a substatement.
|
||||
This is in addition to icon-continued-statement-offset.
|
||||
icon-brace-offset
|
||||
Extra indentation for line if it starts with an open brace.
|
||||
icon-brace-imaginary-offset
|
||||
An open brace following other text is treated as if it were
|
||||
this far to the right of the start of its line.
|
||||
|
||||
Turning on Icon mode calls the value of the variable icon-mode-hook with no args,
|
||||
if that value is non-nil."
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
(use-local-map icon-mode-map)
|
||||
(setq major-mode 'icon-mode)
|
||||
(setq mode-name "Icon")
|
||||
(setq local-abbrev-table icon-mode-abbrev-table)
|
||||
(set-syntax-table icon-mode-syntax-table)
|
||||
(make-local-variable 'paragraph-start)
|
||||
(setq paragraph-start (concat "^$\\|" page-delimiter))
|
||||
(make-local-variable 'paragraph-separate)
|
||||
(setq paragraph-separate paragraph-start)
|
||||
(make-local-variable 'indent-line-function)
|
||||
(setq indent-line-function 'icon-indent-line)
|
||||
(make-local-variable 'require-final-newline)
|
||||
(setq require-final-newline t)
|
||||
(make-local-variable 'comment-start)
|
||||
(setq comment-start "# ")
|
||||
(make-local-variable 'comment-end)
|
||||
(setq comment-end "")
|
||||
(make-local-variable 'comment-column)
|
||||
(setq comment-column 32)
|
||||
(make-local-variable 'comment-start-skip)
|
||||
(setq comment-start-skip "# *")
|
||||
(make-local-variable 'comment-indent-hook)
|
||||
(setq comment-indent-hook 'icon-comment-indent)
|
||||
(run-hooks 'icon-mode-hook))
|
||||
|
||||
;; This is used by indent-for-comment
|
||||
;; to decide how much to indent a comment in Icon code
|
||||
;; based on its context.
|
||||
(defun icon-comment-indent ()
|
||||
(if (looking-at "^#")
|
||||
0
|
||||
(save-excursion
|
||||
(skip-chars-backward " \t")
|
||||
(max (if (bolp) 0 (1+ (current-column)))
|
||||
comment-column))))
|
||||
|
||||
(defun electric-icon-brace (arg)
|
||||
"Insert character and correct line's indentation."
|
||||
(interactive "P")
|
||||
(let (insertpos)
|
||||
(if (and (not arg)
|
||||
(eolp)
|
||||
(or (save-excursion
|
||||
(skip-chars-backward " \t")
|
||||
(bolp))
|
||||
(if icon-auto-newline
|
||||
(progn (icon-indent-line) (newline) t)
|
||||
nil)))
|
||||
(progn
|
||||
(insert last-command-char)
|
||||
(icon-indent-line)
|
||||
(if icon-auto-newline
|
||||
(progn
|
||||
(newline)
|
||||
;; (newline) may have done auto-fill
|
||||
(setq insertpos (- (point) 2))
|
||||
(icon-indent-line)))
|
||||
(save-excursion
|
||||
(if insertpos (goto-char (1+ insertpos)))
|
||||
(delete-char -1))))
|
||||
(if insertpos
|
||||
(save-excursion
|
||||
(goto-char insertpos)
|
||||
(self-insert-command (prefix-numeric-value arg)))
|
||||
(self-insert-command (prefix-numeric-value arg)))))
|
||||
|
||||
(defun icon-indent-command (&optional whole-exp)
|
||||
(interactive "P")
|
||||
"Indent current line as Icon code, or in some cases insert a tab character.
|
||||
If icon-tab-always-indent is non-nil (the default), always indent current line.
|
||||
Otherwise, indent the current line only if point is at the left margin
|
||||
or in the line's indentation; otherwise insert a tab.
|
||||
|
||||
A numeric argument, regardless of its value,
|
||||
means indent rigidly all the lines of the expression starting after point
|
||||
so that this line becomes properly indented.
|
||||
The relative indentation among the lines of the expression are preserved."
|
||||
(if whole-exp
|
||||
;; If arg, always indent this line as Icon
|
||||
;; and shift remaining lines of expression the same amount.
|
||||
(let ((shift-amt (icon-indent-line))
|
||||
beg end)
|
||||
(save-excursion
|
||||
(if icon-tab-always-indent
|
||||
(beginning-of-line))
|
||||
(setq beg (point))
|
||||
(forward-sexp 1)
|
||||
(setq end (point))
|
||||
(goto-char beg)
|
||||
(forward-line 1)
|
||||
(setq beg (point)))
|
||||
(if (> end beg)
|
||||
(indent-code-rigidly beg end shift-amt "#")))
|
||||
(if (and (not icon-tab-always-indent)
|
||||
(save-excursion
|
||||
(skip-chars-backward " \t")
|
||||
(not (bolp))))
|
||||
(insert-tab)
|
||||
(icon-indent-line))))
|
||||
|
||||
(defun icon-indent-line ()
|
||||
"Indent current line as Icon code.
|
||||
Return the amount the indentation changed by."
|
||||
(let ((indent (calculate-icon-indent nil))
|
||||
beg shift-amt
|
||||
(case-fold-search nil)
|
||||
(pos (- (point-max) (point))))
|
||||
(beginning-of-line)
|
||||
(setq beg (point))
|
||||
(cond ((eq indent nil)
|
||||
(setq indent (current-indentation)))
|
||||
((eq indent t)
|
||||
(setq indent (calculate-icon-indent-within-comment)))
|
||||
((looking-at "[ \t]*#")
|
||||
(setq indent 0))
|
||||
(t
|
||||
(skip-chars-forward " \t")
|
||||
(if (listp indent) (setq indent (car indent)))
|
||||
(cond ((and (looking-at "else\\b")
|
||||
(not (looking-at "else\\s_")))
|
||||
(setq indent (save-excursion
|
||||
(icon-backward-to-start-of-if)
|
||||
(current-indentation))))
|
||||
((or (= (following-char) ?})
|
||||
(looking-at "end\\b"))
|
||||
(setq indent (- indent icon-indent-level)))
|
||||
((= (following-char) ?{)
|
||||
(setq indent (+ indent icon-brace-offset))))))
|
||||
(skip-chars-forward " \t")
|
||||
(setq shift-amt (- indent (current-column)))
|
||||
(if (zerop shift-amt)
|
||||
(if (> (- (point-max) pos) (point))
|
||||
(goto-char (- (point-max) pos)))
|
||||
(delete-region beg (point))
|
||||
(indent-to indent)
|
||||
;; If initial point was within line's indentation,
|
||||
;; position after the indentation. Else stay at same point in text.
|
||||
(if (> (- (point-max) pos) (point))
|
||||
(goto-char (- (point-max) pos))))
|
||||
shift-amt))
|
||||
|
||||
(defun calculate-icon-indent (&optional parse-start)
|
||||
"Return appropriate indentation for current line as Icon code.
|
||||
In usual case returns an integer: the column to indent to.
|
||||
Returns nil if line starts inside a string, t if in a comment."
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(let ((indent-point (point))
|
||||
(case-fold-search nil)
|
||||
state
|
||||
containing-sexp
|
||||
toplevel)
|
||||
(if parse-start
|
||||
(goto-char parse-start)
|
||||
(setq toplevel (beginning-of-icon-defun)))
|
||||
(while (< (point) indent-point)
|
||||
(setq parse-start (point))
|
||||
(setq state (parse-partial-sexp (point) indent-point 0))
|
||||
(setq containing-sexp (car (cdr state))))
|
||||
(cond ((or (nth 3 state) (nth 4 state))
|
||||
;; return nil or t if should not change this line
|
||||
(nth 4 state))
|
||||
((and containing-sexp
|
||||
(/= (char-after containing-sexp) ?{))
|
||||
;; line is expression, not statement:
|
||||
;; indent to just after the surrounding open.
|
||||
(goto-char (1+ containing-sexp))
|
||||
(current-column))
|
||||
(t
|
||||
(if toplevel
|
||||
;; Outside any procedures.
|
||||
(progn (icon-backward-to-noncomment (point-min))
|
||||
(if (icon-is-continuation-line)
|
||||
icon-continued-statement-offset 0))
|
||||
;; Statement level.
|
||||
(if (null containing-sexp)
|
||||
(progn (beginning-of-icon-defun)
|
||||
(setq containing-sexp (point))))
|
||||
(goto-char indent-point)
|
||||
;; Is it a continuation or a new statement?
|
||||
;; Find previous non-comment character.
|
||||
(icon-backward-to-noncomment containing-sexp)
|
||||
;; Now we get the answer.
|
||||
(if (icon-is-continuation-line)
|
||||
;; This line is continuation of preceding line's statement;
|
||||
;; indent icon-continued-statement-offset more than the
|
||||
;; first line of the statement.
|
||||
(progn
|
||||
(icon-backward-to-start-of-continued-exp containing-sexp)
|
||||
(+ icon-continued-statement-offset (current-column)
|
||||
(if (save-excursion (goto-char indent-point)
|
||||
(skip-chars-forward " \t")
|
||||
(eq (following-char) ?{))
|
||||
icon-continued-brace-offset 0)))
|
||||
;; This line starts a new statement.
|
||||
;; Position following last unclosed open.
|
||||
(goto-char containing-sexp)
|
||||
;; Is line first statement after an open-brace?
|
||||
(or
|
||||
;; If no, find that first statement and indent like it.
|
||||
(save-excursion
|
||||
(if (looking-at "procedure\\s ")
|
||||
(forward-sexp 3)
|
||||
(forward-char 1))
|
||||
(while (progn (skip-chars-forward " \t\n")
|
||||
(looking-at "#"))
|
||||
;; Skip over comments following openbrace.
|
||||
(forward-line 1))
|
||||
;; The first following code counts
|
||||
;; if it is before the line we want to indent.
|
||||
(and (< (point) indent-point)
|
||||
(current-column)))
|
||||
;; If no previous statement,
|
||||
;; indent it relative to line brace is on.
|
||||
;; For open brace in column zero, don't let statement
|
||||
;; start there too. If icon-indent-level is zero,
|
||||
;; use icon-brace-offset + icon-continued-statement-offset
|
||||
;; instead.
|
||||
;; For open-braces not the first thing in a line,
|
||||
;; add in icon-brace-imaginary-offset.
|
||||
(+ (if (and (bolp) (zerop icon-indent-level))
|
||||
(+ icon-brace-offset
|
||||
icon-continued-statement-offset)
|
||||
icon-indent-level)
|
||||
;; Move back over whitespace before the openbrace.
|
||||
;; If openbrace is not first nonwhite thing on the line,
|
||||
;; add the icon-brace-imaginary-offset.
|
||||
(progn (skip-chars-backward " \t")
|
||||
(if (bolp) 0 icon-brace-imaginary-offset))
|
||||
;; Get initial indentation of the line we are on.
|
||||
(current-indentation))))))))))
|
||||
|
||||
;; List of words to check for as the last thing on a line.
|
||||
;; If cdr is t, next line is a continuation of the same statement,
|
||||
;; if cdr is nil, next line starts a new (possibly indented) statement.
|
||||
|
||||
(defconst icon-resword-alist
|
||||
'(("by" . t) ("case" . t) ("create") ("do") ("dynamic" . t) ("else")
|
||||
("every" . t) ("if" . t) ("global" . t) ("initial" . t)
|
||||
("link" . t) ("local" . t) ("of") ("record" . t) ("repeat" . t)
|
||||
("static" . t) ("then") ("to" . t) ("until" . t) ("while" . t)))
|
||||
|
||||
(defun icon-is-continuation-line ()
|
||||
(let* ((ch (preceding-char))
|
||||
(ch-syntax (char-syntax ch)))
|
||||
(if (eq ch-syntax ?w)
|
||||
(assoc (buffer-substring
|
||||
(progn (forward-word -1) (point))
|
||||
(progn (forward-word 1) (point)))
|
||||
icon-resword-alist)
|
||||
(not (memq ch '(0 ?\; ?\} ?\{ ?\) ?\] ?\" ?\' ?\n))))))
|
||||
|
||||
(defun icon-backward-to-noncomment (lim)
|
||||
(let (opoint stop)
|
||||
(while (not stop)
|
||||
(skip-chars-backward " \t\n\f" lim)
|
||||
(setq opoint (point))
|
||||
(beginning-of-line)
|
||||
(if (and (nth 5 (parse-partial-sexp (point) opoint))
|
||||
(< lim (point)))
|
||||
(search-backward "#")
|
||||
(setq stop t)))))
|
||||
|
||||
(defun icon-backward-to-start-of-continued-exp (lim)
|
||||
(if (memq (preceding-char) '(?\) ?\]))
|
||||
(forward-sexp -1))
|
||||
(beginning-of-line)
|
||||
(skip-chars-forward " \t")
|
||||
(cond
|
||||
((<= (point) lim) (goto-char (1+ lim)))
|
||||
((not (icon-is-continued-line)) 0)
|
||||
((and (eq (char-syntax (following-char)) ?w)
|
||||
(cdr
|
||||
(assoc (buffer-substring (point)
|
||||
(save-excursion (forward-word 1) (point)))
|
||||
icon-resword-alist))) 0)
|
||||
(t (end-of-line 0) (icon-backward-to-start-of-continued-exp lim))))
|
||||
|
||||
(defun icon-is-continued-line ()
|
||||
(save-excursion
|
||||
(end-of-line 0)
|
||||
(icon-is-continuation-line)))
|
||||
|
||||
(defun icon-backward-to-start-of-if (&optional limit)
|
||||
"Move to the start of the last ``unbalanced'' if."
|
||||
(or limit (setq limit (save-excursion (beginning-of-icon-defun) (point))))
|
||||
(let ((if-level 1)
|
||||
(case-fold-search nil))
|
||||
(while (not (zerop if-level))
|
||||
(backward-sexp 1)
|
||||
(cond ((looking-at "else\\b")
|
||||
(setq if-level (1+ if-level)))
|
||||
((looking-at "if\\b")
|
||||
(setq if-level (1- if-level)))
|
||||
((< (point) limit)
|
||||
(setq if-level 0)
|
||||
(goto-char limit))))))
|
||||
|
||||
(defun mark-icon-function ()
|
||||
"Put mark at end of Icon function, point at beginning."
|
||||
(interactive)
|
||||
(push-mark (point))
|
||||
(end-of-icon-defun)
|
||||
(push-mark (point))
|
||||
(beginning-of-line 0)
|
||||
(beginning-of-icon-defun))
|
||||
|
||||
(defun beginning-of-icon-defun ()
|
||||
"Go to the start of the enclosing procedure; return t if at top level."
|
||||
(interactive)
|
||||
(if (re-search-backward "^procedure\\s \\|^end[ \t\n]" (point-min) 'move)
|
||||
(looking-at "e")
|
||||
t))
|
||||
|
||||
(defun end-of-icon-defun ()
|
||||
(interactive)
|
||||
(if (not (bobp)) (forward-char -1))
|
||||
(re-search-forward "\\(\\s \\|^\\)end\\(\\s \\|$\\)" (point-max) 'move)
|
||||
(forward-word -1)
|
||||
(forward-line 1))
|
||||
|
||||
(defun indent-icon-exp ()
|
||||
"Indent each line of the Icon grouping following point."
|
||||
(interactive)
|
||||
(let ((indent-stack (list nil))
|
||||
(contain-stack (list (point)))
|
||||
(case-fold-search nil)
|
||||
restart outer-loop-done inner-loop-done state ostate
|
||||
this-indent last-sexp
|
||||
at-else at-brace at-do
|
||||
(opoint (point))
|
||||
(next-depth 0))
|
||||
(save-excursion
|
||||
(forward-sexp 1))
|
||||
(save-excursion
|
||||
(setq outer-loop-done nil)
|
||||
(while (and (not (eobp)) (not outer-loop-done))
|
||||
(setq last-depth next-depth)
|
||||
;; Compute how depth changes over this line
|
||||
;; plus enough other lines to get to one that
|
||||
;; does not end inside a comment or string.
|
||||
;; Meanwhile, do appropriate indentation on comment lines.
|
||||
(setq innerloop-done nil)
|
||||
(while (and (not innerloop-done)
|
||||
(not (and (eobp) (setq outer-loop-done t))))
|
||||
(setq ostate state)
|
||||
(setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
|
||||
nil nil state))
|
||||
(setq next-depth (car state))
|
||||
(if (and (car (cdr (cdr state)))
|
||||
(>= (car (cdr (cdr state))) 0))
|
||||
(setq last-sexp (car (cdr (cdr state)))))
|
||||
(if (or (nth 4 ostate))
|
||||
(icon-indent-line))
|
||||
(if (or (nth 3 state))
|
||||
(forward-line 1)
|
||||
(setq innerloop-done t)))
|
||||
(if (<= next-depth 0)
|
||||
(setq outer-loop-done t))
|
||||
(if outer-loop-done
|
||||
nil
|
||||
(if (/= last-depth next-depth)
|
||||
(setq last-sexp nil))
|
||||
(while (> last-depth next-depth)
|
||||
(setq indent-stack (cdr indent-stack)
|
||||
contain-stack (cdr contain-stack)
|
||||
last-depth (1- last-depth)))
|
||||
(while (< last-depth next-depth)
|
||||
(setq indent-stack (cons nil indent-stack)
|
||||
contain-stack (cons nil contain-stack)
|
||||
last-depth (1+ last-depth)))
|
||||
(if (null (car contain-stack))
|
||||
(setcar contain-stack (or (car (cdr state))
|
||||
(save-excursion (forward-sexp -1)
|
||||
(point)))))
|
||||
(forward-line 1)
|
||||
(skip-chars-forward " \t")
|
||||
(if (eolp)
|
||||
nil
|
||||
(if (and (car indent-stack)
|
||||
(>= (car indent-stack) 0))
|
||||
;; Line is on an existing nesting level.
|
||||
;; Lines inside parens are handled specially.
|
||||
(if (/= (char-after (car contain-stack)) ?{)
|
||||
(setq this-indent (car indent-stack))
|
||||
;; Line is at statement level.
|
||||
;; Is it a new statement? Is it an else?
|
||||
;; Find last non-comment character before this line
|
||||
(save-excursion
|
||||
(setq at-else (looking-at "else\\W"))
|
||||
(setq at-brace (= (following-char) ?{))
|
||||
(icon-backward-to-noncomment opoint)
|
||||
(if (icon-is-continuation-line)
|
||||
;; Preceding line did not end in comma or semi;
|
||||
;; indent this line icon-continued-statement-offset
|
||||
;; more than previous.
|
||||
(progn
|
||||
(icon-backward-to-start-of-continued-exp (car contain-stack))
|
||||
(setq this-indent
|
||||
(+ icon-continued-statement-offset (current-column)
|
||||
(if at-brace icon-continued-brace-offset 0))))
|
||||
;; Preceding line ended in comma or semi;
|
||||
;; use the standard indent for this level.
|
||||
(if at-else
|
||||
(progn (icon-backward-to-start-of-if opoint)
|
||||
(setq this-indent (current-indentation)))
|
||||
(setq this-indent (car indent-stack))))))
|
||||
;; Just started a new nesting level.
|
||||
;; Compute the standard indent for this level.
|
||||
(let ((val (calculate-icon-indent
|
||||
(if (car indent-stack)
|
||||
(- (car indent-stack))))))
|
||||
(setcar indent-stack
|
||||
(setq this-indent val))))
|
||||
;; Adjust line indentation according to its contents
|
||||
(if (or (= (following-char) ?})
|
||||
(looking-at "end\\b"))
|
||||
(setq this-indent (- this-indent icon-indent-level)))
|
||||
(if (= (following-char) ?{)
|
||||
(setq this-indent (+ this-indent icon-brace-offset)))
|
||||
;; Put chosen indentation into effect.
|
||||
(or (= (current-column) this-indent)
|
||||
(progn
|
||||
(delete-region (point) (progn (beginning-of-line) (point)))
|
||||
(indent-to this-indent)))
|
||||
;; Indent any comment following the text.
|
||||
(or (looking-at comment-start-skip)
|
||||
(if (re-search-forward comment-start-skip (save-excursion (end-of-line) (point)) t)
|
||||
(progn (indent-for-comment) (beginning-of-line))))))))))
|
||||
|
205
lisp/rect.el
Normal file
205
lisp/rect.el
Normal file
@ -0,0 +1,205 @@
|
||||
;; Rectangle functions for GNU Emacs.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun operate-on-rectangle (function start end coerce-tabs)
|
||||
"Call FUNCTION for each line of rectangle with corners at START, END.
|
||||
If COERCE-TABS is non-nil, convert multi-column characters
|
||||
that span the starting or ending columns on any line
|
||||
to multiple spaces before calling FUNCTION.
|
||||
FUNCTION is called with three arguments:
|
||||
position of start of segment of this line within the rectangle,
|
||||
number of columns that belong to rectangle but are before that position,
|
||||
number of columns that belong to rectangle but are after point.
|
||||
Point is at the end of the segment of this line within the rectangle."
|
||||
(let (startcol startlinepos endcol endlinepos)
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
(setq startcol (current-column))
|
||||
(beginning-of-line)
|
||||
(setq startlinepos (point)))
|
||||
(save-excursion
|
||||
(goto-char end)
|
||||
(setq endcol (current-column))
|
||||
(forward-line 1)
|
||||
(setq endlinepos (point-marker)))
|
||||
(if (< endcol startcol)
|
||||
(let ((tem startcol))
|
||||
(setq startcol endcol endcol tem)))
|
||||
(if (/= endcol startcol)
|
||||
(save-excursion
|
||||
(goto-char startlinepos)
|
||||
(while (< (point) endlinepos)
|
||||
(let (startpos begextra endextra)
|
||||
(move-to-column startcol)
|
||||
(and coerce-tabs
|
||||
(> (current-column) startcol)
|
||||
(rectangle-coerce-tab startcol))
|
||||
(setq begextra (- (current-column) startcol))
|
||||
(setq startpos (point))
|
||||
(move-to-column endcol)
|
||||
(if (> (current-column) endcol)
|
||||
(if coerce-tabs
|
||||
(rectangle-coerce-tab endcol)
|
||||
(forward-char -1)))
|
||||
(setq endextra (- endcol (current-column)))
|
||||
(if (< begextra 0)
|
||||
(setq endextra (+ endextra begextra)
|
||||
begextra 0))
|
||||
(funcall function startpos begextra endextra))
|
||||
(forward-line 1))))
|
||||
(- endcol startcol)))
|
||||
|
||||
(defun delete-rectangle-line (startdelpos ignore ignore)
|
||||
(delete-region startdelpos (point)))
|
||||
|
||||
(defun delete-extract-rectangle-line (startdelpos begextra endextra)
|
||||
(save-excursion
|
||||
(extract-rectangle-line startdelpos begextra endextra))
|
||||
(delete-region startdelpos (point)))
|
||||
|
||||
(defun extract-rectangle-line (startdelpos begextra endextra)
|
||||
(let ((line (buffer-substring startdelpos (point)))
|
||||
(end (point)))
|
||||
(goto-char startdelpos)
|
||||
(while (search-forward "\t" end t)
|
||||
(let ((width (- (current-column)
|
||||
(save-excursion (forward-char -1)
|
||||
(current-column)))))
|
||||
(setq line (concat (substring line 0 (- (point) end 1))
|
||||
(spaces-string width)
|
||||
(substring line (+ (length line) (- (point) end)))))))
|
||||
(if (or (> begextra 0) (> endextra 0))
|
||||
(setq line (concat (spaces-string begextra)
|
||||
line
|
||||
(spaces-string endextra))))
|
||||
(setq lines (cons line lines))))
|
||||
|
||||
(defconst spaces-strings
|
||||
'["" " " " " " " " " " " " " " " " "])
|
||||
|
||||
(defun spaces-string (n)
|
||||
(if (<= n 8) (aref spaces-strings n)
|
||||
(let ((val ""))
|
||||
(while (> n 8)
|
||||
(setq val (concat " " val)
|
||||
n (- n 8)))
|
||||
(concat val (aref spaces-strings n)))))
|
||||
|
||||
(defun delete-rectangle (start end)
|
||||
"Delete (don't save) text in rectangle with point and mark as corners.
|
||||
The same range of columns is deleted in each line
|
||||
starting with the line where the region begins
|
||||
and ending with the line where the region ends."
|
||||
(interactive "r")
|
||||
(operate-on-rectangle 'delete-rectangle-line start end t))
|
||||
|
||||
(defun delete-extract-rectangle (start end)
|
||||
"Delete contents of rectangle and return it as a list of strings.
|
||||
Arguments START and END are the corners of the rectangle.
|
||||
The value is list of strings, one for each line of the rectangle."
|
||||
(let (lines)
|
||||
(operate-on-rectangle 'delete-extract-rectangle-line
|
||||
start end t)
|
||||
(nreverse lines)))
|
||||
|
||||
(defun extract-rectangle (start end)
|
||||
"Return contents of rectangle with corners at START and END.
|
||||
Value is list of strings, one for each line of the rectangle."
|
||||
(let (lines)
|
||||
(operate-on-rectangle 'extract-rectangle-line start end nil)
|
||||
(nreverse lines)))
|
||||
|
||||
(defvar killed-rectangle nil
|
||||
"Rectangle for yank-rectangle to insert.")
|
||||
|
||||
(defun kill-rectangle (start end)
|
||||
"Delete rectangle with corners at point and mark; save as last killed one.
|
||||
Calling from program, supply two args START and END, buffer positions.
|
||||
But in programs you might prefer to use delete-extract-rectangle."
|
||||
(interactive "r")
|
||||
(setq killed-rectangle (delete-extract-rectangle start end)))
|
||||
|
||||
(defun yank-rectangle ()
|
||||
"Yank the last killed rectangle with upper left corner at point."
|
||||
(interactive)
|
||||
(insert-rectangle killed-rectangle))
|
||||
|
||||
(defun insert-rectangle (rectangle)
|
||||
"Insert text of RECTANGLE with upper left corner at point.
|
||||
RECTANGLE's first line is inserted at point,
|
||||
its second line is inserted at a point vertically under point, etc.
|
||||
RECTANGLE should be a list of strings."
|
||||
(let ((lines rectangle)
|
||||
(insertcolumn (current-column))
|
||||
(first t))
|
||||
(while lines
|
||||
(or first
|
||||
(progn
|
||||
(forward-line 1)
|
||||
(or (bolp) (insert ?\n))
|
||||
(move-to-column insertcolumn)
|
||||
(if (> (current-column) insertcolumn)
|
||||
(rectangle-coerce-tab insertcolumn))
|
||||
(if (< (current-column) insertcolumn)
|
||||
(indent-to insertcolumn))))
|
||||
(setq first nil)
|
||||
(insert (car lines))
|
||||
(setq lines (cdr lines)))))
|
||||
|
||||
(defun open-rectangle (start end)
|
||||
"Blank out rectangle with corners at point and mark, shifting text right.
|
||||
The text previously in the region is not overwritten by the blanks,
|
||||
but insted winds up to the right of the rectangle."
|
||||
(interactive "r")
|
||||
(operate-on-rectangle 'open-rectangle-line start end nil))
|
||||
|
||||
(defun open-rectangle-line (startpos begextra endextra)
|
||||
(let ((column (+ (current-column) begextra endextra)))
|
||||
(goto-char startpos)
|
||||
(let ((ocol (current-column)))
|
||||
(skip-chars-forward " \t")
|
||||
(setq column (+ column (- (current-column) ocol))))
|
||||
(delete-region (point)
|
||||
(progn (skip-chars-backward " \t")
|
||||
(point)))
|
||||
(indent-to column)))
|
||||
|
||||
(defun clear-rectangle (start end)
|
||||
"Blank out rectangle with corners at point and mark.
|
||||
The text previously in the region is overwritten by the blanks.
|
||||
When called from a program, requires two args which specify the corners."
|
||||
(interactive "r")
|
||||
(operate-on-rectangle 'clear-rectangle-line start end t))
|
||||
|
||||
(defun clear-rectangle-line (startpos begextra endextra)
|
||||
(skip-chars-forward " \t")
|
||||
(let ((column (+ (current-column) endextra)))
|
||||
(delete-region (point)
|
||||
(progn (goto-char startpos)
|
||||
(skip-chars-backward " \t")
|
||||
(point)))
|
||||
(indent-to column)))
|
||||
|
||||
(defun rectangle-coerce-tab (column)
|
||||
(let ((aftercol (current-column))
|
||||
(indent-tabs-mode nil))
|
||||
(delete-char -1)
|
||||
(indent-to aftercol)
|
||||
(backward-char (- aftercol column))))
|
51
lisp/tabify.el
Normal file
51
lisp/tabify.el
Normal file
@ -0,0 +1,51 @@
|
||||
;; Tab conversion commands for Emacs
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun untabify (start end)
|
||||
"Convert all tabs in region to multiple spaces, preserving columns.
|
||||
The variable tab-width controls the action."
|
||||
(interactive "r")
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(narrow-to-region start end)
|
||||
(goto-char start)
|
||||
(while (search-forward "\t" nil t) ; faster than re-search
|
||||
(let ((start (point))
|
||||
(column (current-column))
|
||||
(indent-tabs-mode nil))
|
||||
(skip-chars-backward "\t")
|
||||
(delete-region start (point))
|
||||
(indent-to column))))))
|
||||
|
||||
(defun tabify (start end)
|
||||
"Convert multiple spaces in region to tabs when possible.
|
||||
A group of spaces is partially replaced by tabs
|
||||
when this can be done without changing the column they end at.
|
||||
The variable tab-width controls the action."
|
||||
(interactive "r")
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(narrow-to-region start end)
|
||||
(goto-char start)
|
||||
(while (re-search-forward "[ \t][ \t][ \t]*" nil t)
|
||||
(let ((column (current-column))
|
||||
(indent-tabs-mode t))
|
||||
(delete-region (match-beginning 0) (point))
|
||||
(indent-to column))))))
|
203
lisp/textmodes/nroff-mode.el
Normal file
203
lisp/textmodes/nroff-mode.el
Normal file
@ -0,0 +1,203 @@
|
||||
;; GNU Emacs major mode for editing nroff source
|
||||
;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
|
||||
(defvar nroff-mode-abbrev-table nil
|
||||
"Abbrev table used while in nroff mode.")
|
||||
|
||||
(defvar nroff-mode-map nil
|
||||
"Major mode keymap for nroff-mode buffers")
|
||||
(if (not nroff-mode-map)
|
||||
(progn
|
||||
(setq nroff-mode-map (make-sparse-keymap))
|
||||
(define-key nroff-mode-map "\t" 'tab-to-tab-stop)
|
||||
(define-key nroff-mode-map "\es" 'center-line)
|
||||
(define-key nroff-mode-map "\e?" 'count-text-lines)
|
||||
(define-key nroff-mode-map "\n" 'electric-nroff-newline)
|
||||
(define-key nroff-mode-map "\en" 'forward-text-line)
|
||||
(define-key nroff-mode-map "\ep" 'backward-text-line)))
|
||||
|
||||
(defun nroff-mode ()
|
||||
"Major mode for editing text intended for nroff to format.
|
||||
\\{nroff-mode-map}
|
||||
Turning on Nroff mode runs text-mode-hook, then nroff-mode-hook.
|
||||
Also, try nroff-electric-mode, for automatically inserting
|
||||
closing requests for requests that are used in matched pairs."
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
(use-local-map nroff-mode-map)
|
||||
(setq mode-name "Nroff")
|
||||
(setq major-mode 'nroff-mode)
|
||||
(set-syntax-table text-mode-syntax-table)
|
||||
(setq local-abbrev-table nroff-mode-abbrev-table)
|
||||
(make-local-variable 'nroff-electric-mode)
|
||||
;; now define a bunch of variables for use by commands in this mode
|
||||
(make-local-variable 'page-delimiter)
|
||||
(setq page-delimiter "^\\.\\(bp\\|SK\\|OP\\)")
|
||||
(make-local-variable 'paragraph-start)
|
||||
(setq paragraph-start (concat "^[.']\\|" paragraph-start))
|
||||
(make-local-variable 'paragraph-separate)
|
||||
(setq paragraph-separate (concat "^[.']\\|" paragraph-separate))
|
||||
;; comment syntax added by mit-erl!gildea 18 Apr 86
|
||||
(make-local-variable 'comment-start)
|
||||
(setq comment-start "\\\" ")
|
||||
(make-local-variable 'comment-start-skip)
|
||||
(setq comment-start-skip "\\\\\"[ \t]*")
|
||||
(make-local-variable 'comment-column)
|
||||
(setq comment-column 24)
|
||||
(make-local-variable 'comment-indent-hook)
|
||||
(setq comment-indent-hook 'nroff-comment-indent)
|
||||
(run-hooks 'text-mode-hook 'nroff-mode-hook))
|
||||
|
||||
;;; Compute how much to indent a comment in nroff/troff source.
|
||||
;;; By mit-erl!gildea April 86
|
||||
(defun nroff-comment-indent ()
|
||||
"Compute indent for an nroff/troff comment.
|
||||
Puts a full-stop before comments on a line by themselves."
|
||||
(let ((pt (point)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(skip-chars-backward " \t")
|
||||
(if (bolp)
|
||||
(progn
|
||||
(setq pt (1+ pt))
|
||||
(insert ?.)
|
||||
1)
|
||||
(if (save-excursion
|
||||
(backward-char 1)
|
||||
(looking-at "^[.']"))
|
||||
1
|
||||
(max comment-column
|
||||
(* 8 (/ (+ (current-column)
|
||||
9) 8)))))) ; add 9 to ensure at least two blanks
|
||||
(goto-char pt))))
|
||||
|
||||
(defun count-text-lines (start end &optional print)
|
||||
"Count lines in region, except for nroff request lines.
|
||||
All lines not starting with a period are counted up.
|
||||
Interactively, print result in echo area.
|
||||
Noninteractively, return number of non-request lines from START to END."
|
||||
(interactive "r\np")
|
||||
(if print
|
||||
(message "Region has %d text lines" (count-text-lines start end))
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(narrow-to-region start end)
|
||||
(goto-char (point-min))
|
||||
(- (buffer-size) (forward-text-line (buffer-size)))))))
|
||||
|
||||
(defun forward-text-line (&optional cnt)
|
||||
"Go forward one nroff text line, skipping lines of nroff requests.
|
||||
An argument is a repeat count; if negative, move backward."
|
||||
(interactive "p")
|
||||
(if (not cnt) (setq cnt 1))
|
||||
(while (and (> cnt 0) (not (eobp)))
|
||||
(forward-line 1)
|
||||
(while (and (not (eobp)) (looking-at "[.']."))
|
||||
(forward-line 1))
|
||||
(setq cnt (- cnt 1)))
|
||||
(while (and (< cnt 0) (not (bobp)))
|
||||
(forward-line -1)
|
||||
(while (and (not (bobp))
|
||||
(looking-at "[.']."))
|
||||
(forward-line -1))
|
||||
(setq cnt (+ cnt 1)))
|
||||
cnt)
|
||||
|
||||
(defun backward-text-line (&optional cnt)
|
||||
"Go backward one nroff text line, skipping lines of nroff requests.
|
||||
An argument is a repeat count; negative means move forward."
|
||||
(interactive "p")
|
||||
(forward-text-line (- cnt)))
|
||||
|
||||
(defconst nroff-brace-table
|
||||
'((".(b" . ".)b")
|
||||
(".(l" . ".)l")
|
||||
(".(q" . ".)q")
|
||||
(".(c" . ".)c")
|
||||
(".(x" . ".)x")
|
||||
(".(z" . ".)z")
|
||||
(".(d" . ".)d")
|
||||
(".(f" . ".)f")
|
||||
(".LG" . ".NL")
|
||||
(".SM" . ".NL")
|
||||
(".LD" . ".DE")
|
||||
(".CD" . ".DE")
|
||||
(".BD" . ".DE")
|
||||
(".DS" . ".DE")
|
||||
(".DF" . ".DE")
|
||||
(".FS" . ".FE")
|
||||
(".KS" . ".KE")
|
||||
(".KF" . ".KE")
|
||||
(".LB" . ".LE")
|
||||
(".AL" . ".LE")
|
||||
(".BL" . ".LE")
|
||||
(".DL" . ".LE")
|
||||
(".ML" . ".LE")
|
||||
(".RL" . ".LE")
|
||||
(".VL" . ".LE")
|
||||
(".RS" . ".RE")
|
||||
(".TS" . ".TE")
|
||||
(".EQ" . ".EN")
|
||||
(".PS" . ".PE")
|
||||
(".BS" . ".BE")
|
||||
(".G1" . ".G2") ; grap
|
||||
(".na" . ".ad b")
|
||||
(".nf" . ".fi")
|
||||
(".de" . "..")))
|
||||
|
||||
(defun electric-nroff-newline (arg)
|
||||
"Insert newline for nroff mode; special if electric-nroff mode.
|
||||
In electric-nroff-mode, if ending a line containing an nroff opening request,
|
||||
automatically inserts the matching closing request after point."
|
||||
(interactive "P")
|
||||
(let ((completion (save-excursion
|
||||
(beginning-of-line)
|
||||
(and (null arg)
|
||||
nroff-electric-mode
|
||||
(<= (point) (- (point-max) 3))
|
||||
(cdr (assoc (buffer-substring (point)
|
||||
(+ 3 (point)))
|
||||
nroff-brace-table)))))
|
||||
(needs-nl (not (looking-at "[ \t]*$"))))
|
||||
(if (null completion)
|
||||
(newline (prefix-numeric-value arg))
|
||||
(save-excursion
|
||||
(insert "\n\n" completion)
|
||||
(if needs-nl (insert "\n")))
|
||||
(forward-char 1))))
|
||||
|
||||
(defun electric-nroff-mode (&optional arg)
|
||||
"Toggle nroff-electric-newline minor mode
|
||||
Nroff-electric-newline forces emacs to check for an nroff
|
||||
request at the beginning of the line, and insert the
|
||||
matching closing request if necessary.
|
||||
This command toggles that mode (off->on, on->off),
|
||||
with an argument, turns it on iff arg is positive, otherwise off."
|
||||
(interactive "P")
|
||||
(or (eq major-mode 'nroff-mode) (error "Must be in nroff mode"))
|
||||
(or (assq 'nroff-electric-mode minor-mode-alist)
|
||||
(setq minor-mode-alist (append minor-mode-alist
|
||||
(list '(nroff-electric-mode
|
||||
" Electric")))))
|
||||
(setq nroff-electric-mode
|
||||
(cond ((null arg) (null nroff-electric-mode))
|
||||
(t (> (prefix-numeric-value arg) 0)))))
|
||||
|
123
lisp/textmodes/page.el
Normal file
123
lisp/textmodes/page.el
Normal file
@ -0,0 +1,123 @@
|
||||
;; Page motion commands for emacs.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun forward-page (&optional count)
|
||||
"Move forward to page boundary. With arg, repeat, or go back if negative.
|
||||
A page boundary is any line whose beginning matches the regexp page-delimiter."
|
||||
(interactive "p")
|
||||
(or count (setq count 1))
|
||||
(while (and (> count 0) (not (eobp)))
|
||||
(if (re-search-forward page-delimiter nil t)
|
||||
nil
|
||||
(goto-char (point-max)))
|
||||
(setq count (1- count)))
|
||||
(while (and (< count 0) (not (bobp)))
|
||||
(forward-char -1)
|
||||
(if (re-search-backward page-delimiter nil t)
|
||||
(goto-char (match-end 0))
|
||||
(goto-char (point-min)))
|
||||
(setq count (1+ count))))
|
||||
|
||||
(defun backward-page (&optional count)
|
||||
"Move backward to page boundary. With arg, repeat, or go fwd if negative.
|
||||
A page boundary is any line whose beginning matches the regexp page-delimiter."
|
||||
(interactive "p")
|
||||
(or count (setq count 1))
|
||||
(forward-page (- count)))
|
||||
|
||||
(defun mark-page (&optional arg)
|
||||
"Put mark at end of page, point at beginning.
|
||||
A numeric arg specifies to move forward or backward by that many pages,
|
||||
thus marking a page other than the one point was originally in."
|
||||
(interactive "P")
|
||||
(setq arg (if arg (prefix-numeric-value arg) 0))
|
||||
(if (> arg 0)
|
||||
(forward-page arg)
|
||||
(if (< arg 0)
|
||||
(forward-page (1- arg))))
|
||||
(forward-page)
|
||||
(push-mark nil t)
|
||||
(forward-page -1))
|
||||
|
||||
(defun narrow-to-page (&optional arg)
|
||||
"Make text outside current page invisible.
|
||||
A numeric arg specifies to move forward or backward by that many pages,
|
||||
thus showing a page other than the one point was originally in."
|
||||
(interactive "P")
|
||||
(setq arg (if arg (prefix-numeric-value arg) 0))
|
||||
(save-excursion
|
||||
(widen)
|
||||
(if (> arg 0)
|
||||
(forward-page arg)
|
||||
(if (< arg 0)
|
||||
(forward-page (1- arg))))
|
||||
;; Find the end of the page.
|
||||
(forward-page)
|
||||
;; If we stopped due to end of buffer, stay there.
|
||||
;; If we stopped after a page delimiter, put end of restriction
|
||||
;; at the beginning of that line.
|
||||
(if (save-excursion (beginning-of-line)
|
||||
(looking-at page-delimiter))
|
||||
(beginning-of-line))
|
||||
(narrow-to-region (point)
|
||||
(progn
|
||||
;; Find the top of the page.
|
||||
(forward-page -1)
|
||||
;; If we found beginning of buffer, stay there.
|
||||
;; If extra text follows page delimiter on same line,
|
||||
;; include it.
|
||||
;; Otherwise, show text starting with following line.
|
||||
(if (and (eolp) (not (bobp)))
|
||||
(forward-line 1))
|
||||
(point)))))
|
||||
|
||||
(defun count-lines-page ()
|
||||
"Report number of lines on current page, and how many are before or after point."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(let ((opoint (point)) beg end
|
||||
total before after)
|
||||
(forward-page)
|
||||
(beginning-of-line)
|
||||
(or (looking-at page-delimiter)
|
||||
(end-of-line))
|
||||
(setq end (point))
|
||||
(backward-page)
|
||||
(setq beg (point))
|
||||
(setq total (count-lines beg end)
|
||||
before (count-lines beg opoint)
|
||||
after (count-lines opoint end))
|
||||
(message "Page has %d lines (%d + %d)" total before after))))
|
||||
|
||||
(defun what-page ()
|
||||
"Print page and line number of point."
|
||||
(interactive)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(let ((count 1)
|
||||
(opoint (point)))
|
||||
(goto-char 1)
|
||||
(while (re-search-forward page-delimiter opoint t)
|
||||
(setq count (1+ count)))
|
||||
(message "Page %d, line %d"
|
||||
count
|
||||
(1+ (count-lines (point) opoint)))))))
|
205
lisp/textmodes/paragraphs.el
Normal file
205
lisp/textmodes/paragraphs.el
Normal file
@ -0,0 +1,205 @@
|
||||
;; Paragraph and sentence parsing.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defvar paragraph-ignore-fill-prefix nil
|
||||
"Non-nil means the paragraph commands are not affected by fill-prefix.
|
||||
This is desirable in modes where blank lines are the paragraph delimiters.")
|
||||
|
||||
(defun forward-paragraph (&optional arg)
|
||||
"Move forward to end of paragraph.
|
||||
With arg N, do it N times; negative arg -N means move forward N paragraphs.
|
||||
|
||||
A line which `paragraph-start' matches either separates paragraphs
|
||||
\(if `paragraph-separate' matches it also) or is the first line of a paragraph.
|
||||
A paragraph end is the beginning of a line which is not part of the paragraph
|
||||
to which the end of the previous line belongs, or the end of the buffer."
|
||||
(interactive "p")
|
||||
(or arg (setq arg 1))
|
||||
(let* ((fill-prefix-regexp
|
||||
(and fill-prefix (not (equal fill-prefix ""))
|
||||
(not paragraph-ignore-fill-prefix)
|
||||
(regexp-quote fill-prefix)))
|
||||
(paragraph-separate
|
||||
(if fill-prefix-regexp
|
||||
(concat paragraph-separate "\\|^"
|
||||
fill-prefix-regexp "[ \t]*$")
|
||||
paragraph-separate)))
|
||||
(while (< arg 0)
|
||||
(if (and (not (looking-at paragraph-separate))
|
||||
(re-search-backward "^\n" (max (1- (point)) (point-min)) t))
|
||||
nil
|
||||
(forward-char -1) (beginning-of-line)
|
||||
(while (and (not (bobp)) (looking-at paragraph-separate))
|
||||
(forward-line -1))
|
||||
(end-of-line)
|
||||
;; Search back for line that starts or separates paragraphs.
|
||||
(if (if fill-prefix-regexp
|
||||
;; There is a fill prefix; it overrides paragraph-start.
|
||||
(progn
|
||||
(while (progn (beginning-of-line)
|
||||
(and (not (bobp))
|
||||
(not (looking-at paragraph-separate))
|
||||
(looking-at fill-prefix-regexp)))
|
||||
(forward-line -1))
|
||||
(not (bobp)))
|
||||
(re-search-backward paragraph-start nil t))
|
||||
;; Found one.
|
||||
(progn
|
||||
(while (and (not (eobp)) (looking-at paragraph-separate))
|
||||
(forward-line 1))
|
||||
(if (eq (char-after (- (point) 2)) ?\n)
|
||||
(forward-line -1)))
|
||||
;; No starter or separator line => use buffer beg.
|
||||
(goto-char (point-min))))
|
||||
(setq arg (1+ arg)))
|
||||
(while (> arg 0)
|
||||
(beginning-of-line)
|
||||
(while (prog1 (and (not (eobp))
|
||||
(looking-at paragraph-separate))
|
||||
(forward-line 1)))
|
||||
(if fill-prefix-regexp
|
||||
;; There is a fill prefix; it overrides paragraph-start.
|
||||
(while (and (not (eobp))
|
||||
(not (looking-at paragraph-separate))
|
||||
(looking-at fill-prefix-regexp))
|
||||
(forward-line 1))
|
||||
(if (re-search-forward paragraph-start nil t)
|
||||
(goto-char (match-beginning 0))
|
||||
(goto-char (point-max))))
|
||||
(setq arg (1- arg)))))
|
||||
|
||||
(defun backward-paragraph (&optional arg)
|
||||
"Move backward to start of paragraph.
|
||||
With arg N, do it N times; negative arg -N means move forward N paragraphs.
|
||||
|
||||
A paragraph start is the beginning of a line which is a first-line-of-paragraph
|
||||
or which is ordinary text and follows a paragraph-separating line; except:
|
||||
if the first real line of a paragraph is preceded by a blank line,
|
||||
the paragraph starts at that blank line.
|
||||
See forward-paragraph for more information."
|
||||
(interactive "p")
|
||||
(or arg (setq arg 1))
|
||||
(forward-paragraph (- arg)))
|
||||
|
||||
(defun mark-paragraph ()
|
||||
"Put point at beginning of this paragraph, mark at end.
|
||||
The paragraph marked is the one that contains point or follows point."
|
||||
(interactive)
|
||||
(forward-paragraph 1)
|
||||
(push-mark nil t)
|
||||
(backward-paragraph 1))
|
||||
|
||||
(defun kill-paragraph (arg)
|
||||
"Kill forward to end of paragraph.
|
||||
With arg N, kill forward to Nth end of paragraph;
|
||||
negative arg -N means kill backward to Nth start of paragraph."
|
||||
(interactive "*p")
|
||||
(kill-region (point) (progn (forward-paragraph arg) (point))))
|
||||
|
||||
(defun backward-kill-paragraph (arg)
|
||||
"Kill back to start of paragraph.
|
||||
With arg N, kill back to Nth start of paragraph;
|
||||
negative arg -N means kill forward to Nth end of paragraph."
|
||||
(interactive "*p")
|
||||
(kill-region (point) (progn (backward-paragraph arg) (point))))
|
||||
|
||||
(defun transpose-paragraphs (arg)
|
||||
"Interchange this (or next) paragraph with previous one."
|
||||
(interactive "*p")
|
||||
(transpose-subr 'forward-paragraph arg))
|
||||
|
||||
(defun start-of-paragraph-text ()
|
||||
(let ((opoint (point)) npoint)
|
||||
(forward-paragraph -1)
|
||||
(setq npoint (point))
|
||||
(skip-chars-forward " \t\n")
|
||||
(if (>= (point) opoint)
|
||||
(progn
|
||||
(goto-char npoint)
|
||||
(if (> npoint (point-min))
|
||||
(start-of-paragraph-text))))))
|
||||
|
||||
(defun end-of-paragraph-text ()
|
||||
(let ((opoint (point)))
|
||||
(forward-paragraph 1)
|
||||
(if (eq (preceding-char) ?\n) (forward-char -1))
|
||||
(if (<= (point) opoint)
|
||||
(progn
|
||||
(forward-char 1)
|
||||
(if (< (point) (point-max))
|
||||
(end-of-paragraph-text))))))
|
||||
|
||||
(defun forward-sentence (&optional arg)
|
||||
"Move forward to next sentence-end. With argument, repeat.
|
||||
With negative argument, move backward repeatedly to sentence-beginning.
|
||||
|
||||
The variable `sentence-end' is a regular expression that matches ends
|
||||
of sentences. Also, every paragraph boundary terminates sentences as
|
||||
well."
|
||||
(interactive "p")
|
||||
(or arg (setq arg 1))
|
||||
(while (< arg 0)
|
||||
(let ((par-beg (save-excursion (start-of-paragraph-text) (point))))
|
||||
(if (re-search-backward (concat sentence-end "[^ \t\n]") par-beg t)
|
||||
(goto-char (1- (match-end 0)))
|
||||
(goto-char par-beg)))
|
||||
(setq arg (1+ arg)))
|
||||
(while (> arg 0)
|
||||
(let ((par-end (save-excursion (end-of-paragraph-text) (point))))
|
||||
(if (re-search-forward sentence-end par-end t)
|
||||
(skip-chars-backward " \t\n")
|
||||
(goto-char par-end)))
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun backward-sentence (&optional arg)
|
||||
"Move backward to start of sentence. With arg, do it arg times.
|
||||
See forward-sentence for more information."
|
||||
(interactive "p")
|
||||
(or arg (setq arg 1))
|
||||
(forward-sentence (- arg)))
|
||||
|
||||
(defun kill-sentence (&optional arg)
|
||||
"Kill from point to end of sentence.
|
||||
With arg, repeat; negative arg -N means kill back to Nth start of sentence."
|
||||
(interactive "*p")
|
||||
(let ((beg (point)))
|
||||
(forward-sentence arg)
|
||||
(kill-region beg (point))))
|
||||
|
||||
(defun backward-kill-sentence (&optional arg)
|
||||
"Kill back from point to start of sentence.
|
||||
With arg, repeat, or kill forward to Nth end of sentence if negative arg -N."
|
||||
(interactive "*p")
|
||||
(let ((beg (point)))
|
||||
(backward-sentence arg)
|
||||
(kill-region beg (point))))
|
||||
|
||||
(defun mark-end-of-sentence (arg)
|
||||
"Put mark at end of sentence. Arg works as in forward-sentence."
|
||||
(interactive "p")
|
||||
(push-mark
|
||||
(save-excursion
|
||||
(forward-sentence arg)
|
||||
(point))))
|
||||
|
||||
(defun transpose-sentences (arg)
|
||||
"Interchange this (next) and previous sentence."
|
||||
(interactive "*p")
|
||||
(transpose-subr 'forward-sentence arg))
|
715
lisp/textmodes/refbib.el
Normal file
715
lisp/textmodes/refbib.el
Normal file
@ -0,0 +1,715 @@
|
||||
;; Convert refer-style bibliographic entries to ones usable by latex bib
|
||||
;; Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
;; Use: from a buffer containing the refer-style bibliography,
|
||||
;; M-x r2b-convert-buffer
|
||||
;; Program will prompt for an output buffer name, and will log
|
||||
;; warnings during the conversion process in the buffer *Log*.
|
||||
|
||||
; HISTORY
|
||||
; 9/88, created
|
||||
; modified 1/19/89, allow books with editor but no author;
|
||||
; added %O ordering field;
|
||||
; appended illegal multiple fields, instead of
|
||||
; discarding;
|
||||
; added rule, a tech report whose %R number
|
||||
; contains "ISBN" is really a book
|
||||
; added rule, anything with an editor is a book
|
||||
; or a proceedings
|
||||
; added 'manual type, for items with institution
|
||||
; but no author or editor
|
||||
; fixed bug so trailing blanks are trimmed
|
||||
; added 'proceedings type
|
||||
; used "organization" field for proceedings
|
||||
; modified 2/16/89, updated help messages
|
||||
; modified 2/23/89, include capitalize stop words in r2b stop words,
|
||||
; fixed problems with contractions (e.g. it's),
|
||||
; caught multiple stop words in a row
|
||||
; modified 3/1/89, fixed capitialize-title for first words all caps
|
||||
; modified 3/15/89, allow use of " to delimit fields
|
||||
; modified 4/18/89, properly "quote" special characters on output
|
||||
(provide 'refer-to-bibtex)
|
||||
;**********************************************************
|
||||
; User Parameters
|
||||
|
||||
(defvar r2b-trace-on nil "*trace conversion")
|
||||
|
||||
(defvar r2b-journal-abbrevs
|
||||
'(
|
||||
)
|
||||
" Abbreviation list for journal names.
|
||||
If the car of an element matches a journal name exactly, it is replaced by
|
||||
the cadr when output. Braces must be included if replacement is a
|
||||
{string}, but not if replacement is a bibtex abbreviation. The cadr
|
||||
may be eliminated if is exactly the same as the car.
|
||||
Because titles are capitalized before matching, the abbreviation
|
||||
for the journal name should be listed as beginning with a capital
|
||||
letter, even if it really doesn't.
|
||||
For example, a value of '((\"Aij\" \"{Artificial Intelligence}\")
|
||||
(\"Ijcai81\" \"ijcai7\")) would expand Aij to the text string
|
||||
\"Artificial Intelligence\", but would replace Ijcai81 with the
|
||||
BibTeX macro \"ijcai7\".")
|
||||
|
||||
(defvar r2b-booktitle-abbrevs
|
||||
'(
|
||||
)
|
||||
" Abbreviation list for book and proceedings names. If the car of
|
||||
an element matches a title or booktitle exactly, it is replaced by
|
||||
the cadr when output. Braces must be included if replacement is
|
||||
a {string}, but not if replacement is a bibtex abbreviation. The cadr
|
||||
may be eliminated if is exactly the same as the car.
|
||||
Because titles are capitalized before matching, the abbreviated title
|
||||
should be listed as beginning with a capital letter, even if it doesn't.
|
||||
For example, a value of '((\"Aij\" \"{Artificial Intelligence}\")
|
||||
(\"Ijcai81\" \"ijcai7\")) would expand Aij to the text string
|
||||
\"Artificial Intelligence\", but would replace Ijcai81 with the
|
||||
BibTeX macro \"ijcai7\".")
|
||||
|
||||
(defvar r2b-proceedings-list
|
||||
'()
|
||||
" Assoc list of books or journals which are really conference proceedings,
|
||||
but whose name and whose abbrev expansion (as defined in r2b-journal-abbrevs
|
||||
and r2b-booktitle-abbrevs) does not contain the words 'conference' or
|
||||
'proceedings'. (Those cases are handled automatically.)
|
||||
The entry must match the given data exactly.
|
||||
Because titles are capitalized before matching, the items in this list
|
||||
should begin with a capital letter.
|
||||
For example, suppose the title \"Ijcai81\" is used for the proceedings of
|
||||
a conference, and it's expansion is the BibTeX macro \"ijcai7\". Then
|
||||
r2b-proceedings-list should be '((\"Ijcai81\") ...). If instead its
|
||||
expansion were \"Proceedings of the Seventh International Conference
|
||||
on Artificial Intelligence\", then you would NOT need to include Ijcai81
|
||||
in r2b-proceedings-list (although it wouldn't cause an error).")
|
||||
|
||||
(defvar r2b-additional-stop-words
|
||||
"Some\\|What"
|
||||
"Words other than the capitialize-title-stop-words
|
||||
which are not to be used to build the citation key")
|
||||
|
||||
|
||||
(defvar r2b-delimit-with-quote
|
||||
t
|
||||
"*If true, then use \" to delimit fields, otherwise use braces")
|
||||
|
||||
;**********************************************************
|
||||
; Utility Functions
|
||||
|
||||
(defvar capitalize-title-stop-words
|
||||
(concat
|
||||
"the\\|and\\|of\\|is\\|a\\|an\\|of\\|for\\|in\\|to\\|in\\|on\\|at\\|"
|
||||
"by\\|with\\|that\\|its")
|
||||
"Words not to be capitialized in a title (unless they are the first
|
||||
word in the title)")
|
||||
|
||||
(defvar capitalize-title-stop-regexp
|
||||
(concat "\\(" capitalize-title-stop-words "\\)\\(\\b\\|'\\)"))
|
||||
|
||||
(defun capitalize-title-region (begin end)
|
||||
"Like capitalize-region, but don't capitalize stop words, except the first"
|
||||
(interactive "r")
|
||||
(let ((case-fold-search nil) (orig-syntax-table (syntax-table)))
|
||||
(unwind-protect
|
||||
(save-restriction
|
||||
(set-syntax-table text-mode-syntax-table)
|
||||
(narrow-to-region begin end)
|
||||
(goto-char (point-min))
|
||||
(if (looking-at "[A-Z][a-z]*[A-Z]")
|
||||
(forward-word 1)
|
||||
(capitalize-word 1))
|
||||
(while (re-search-forward "\\<" nil t)
|
||||
(if (looking-at "[A-Z][a-z]*[A-Z]")
|
||||
(forward-word 1)
|
||||
(if (let ((case-fold-search t))
|
||||
(looking-at capitalize-title-stop-regexp))
|
||||
(downcase-word 1)
|
||||
(capitalize-word 1)))
|
||||
))
|
||||
(set-syntax-table orig-syntax-table))))
|
||||
|
||||
|
||||
(defun capitalize-title (s)
|
||||
"Like capitalize, but don't capitalize stop words, except the first"
|
||||
(save-excursion
|
||||
(set-buffer (get-buffer-create "$$$Scratch$$$"))
|
||||
(erase-buffer)
|
||||
(insert s)
|
||||
(capitalize-title-region (point-min) (point-max))
|
||||
(buffer-string)))
|
||||
|
||||
;*********************************************************
|
||||
(defun r2b-reset ()
|
||||
"unbind defvars, for debugging"
|
||||
(interactive)
|
||||
(makunbound 'r2b-journal-abbrevs)
|
||||
(makunbound 'r2b-booktitle-abbrevs)
|
||||
(makunbound 'r2b-proceedings-list)
|
||||
(makunbound 'capitalize-title-stop-words)
|
||||
(makunbound 'capitalize-title-stop-regexp)
|
||||
(makunbound 'r2b-additional-stop-words)
|
||||
(makunbound 'r2b-stop-regexp)
|
||||
)
|
||||
|
||||
(defvar r2b-stop-regexp
|
||||
(concat "\\`\\(\\("
|
||||
r2b-additional-stop-words "\\|" capitalize-title-stop-words
|
||||
"\\)\\('\\w*\\)?\\W+\\)*\\([A-Z0-9]+\\)"))
|
||||
|
||||
|
||||
(defun r2b-trace (&rest args)
|
||||
(if r2b-trace-on
|
||||
(progn
|
||||
(apply (function message) args)
|
||||
(sit-for 0)
|
||||
)))
|
||||
|
||||
(defun r2b-match (exp)
|
||||
"returns string matched in current buffer"
|
||||
(buffer-substring (match-beginning exp) (match-end exp)))
|
||||
|
||||
(defvar r2b-out-buf-name "*Out*" "*output from refer-to-bibtex" )
|
||||
(defvar r2b-log-name "*Log*" "*logs errors from refer-to-bibtex" )
|
||||
(defvar r2b-in-buf nil)
|
||||
(defvar r2b-out-buf nil)
|
||||
(defvar r2b-log nil)
|
||||
|
||||
(defvar r2b-error-found nil)
|
||||
|
||||
(setq r2b-variables '(
|
||||
r2b-error-found
|
||||
r2bv-author
|
||||
r2bv-primary-author
|
||||
r2bv-date
|
||||
r2bv-year
|
||||
r2bv-decade
|
||||
r2bv-month
|
||||
r2bv-title
|
||||
r2bv-title-first-word
|
||||
r2bv-editor
|
||||
r2bv-annote
|
||||
r2bv-tr
|
||||
r2bv-address
|
||||
r2bv-institution
|
||||
r2bv-keywords
|
||||
r2bv-booktitle
|
||||
r2bv-journal
|
||||
r2bv-volume
|
||||
r2bv-number
|
||||
r2bv-pages
|
||||
r2bv-booktitle
|
||||
r2bv-kn
|
||||
r2bv-publisher
|
||||
r2bv-organization
|
||||
r2bv-school
|
||||
r2bv-type
|
||||
r2bv-where
|
||||
r2bv-note
|
||||
r2bv-ordering
|
||||
))
|
||||
|
||||
(defun r2b-clear-variables ()
|
||||
"set all global vars used by r2b to nil"
|
||||
(let ((vars r2b-variables))
|
||||
(while vars
|
||||
(set (car vars) nil)
|
||||
(setq vars (cdr vars)))
|
||||
))
|
||||
|
||||
(defun r2b-warning (&rest args)
|
||||
(setq r2b-error-found t)
|
||||
(princ (apply (function format) args) r2b-log)
|
||||
(princ "\n" r2b-log)
|
||||
(princ "\n" r2b-out-buf)
|
||||
(princ "% " r2b-out-buf)
|
||||
(princ (apply (function format) args) r2b-out-buf)
|
||||
)
|
||||
|
||||
(defun r2b-get-field (var field &optional unique required capitalize)
|
||||
"Set VAR to string value of FIELD, if any. If none, VAR is set to
|
||||
nil. If multiple fields appear, then separate values with the
|
||||
'\\nand\\t\\t', unless UNIQUE is non-nil, in which case log a warning
|
||||
and just concatenate the values. Trim off leading blanks and tabs on
|
||||
first line, and trailing blanks and tabs of every line. Log a warning
|
||||
and set VAR to the empty string if REQUIRED is true. Capitalize as a
|
||||
title if CAPITALIZE is true. Returns value of VAR."
|
||||
(let (item val (not-past-end t))
|
||||
(r2b-trace "snarfing %s" field)
|
||||
(goto-char (point-min))
|
||||
(while (and not-past-end
|
||||
(re-search-forward
|
||||
(concat "^" field "\\b[ \t]*\\(.*[^ \t\n]\\)[ \t]*") nil t))
|
||||
(setq item (r2b-match 1))
|
||||
(while (and (setq not-past-end (zerop (forward-line 1)))
|
||||
(not (looking-at "[ \t]*$\\|%")))
|
||||
(looking-at "\\(.*[^ \t\n]\\)[ \t]*$")
|
||||
(setq item (concat item "\n" (r2b-match 1)))
|
||||
)
|
||||
(if (null val)
|
||||
(setq val item)
|
||||
(if unique
|
||||
(progn
|
||||
(r2b-warning "*Illegal multiple field %s %s" field item)
|
||||
(setq val (concat val "\n" item))
|
||||
)
|
||||
(setq val (concat val "\n\t\tand " item))
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (and val capitalize)
|
||||
(setq val (capitalize-title val)))
|
||||
(set var val)
|
||||
(if (and (null val) required)
|
||||
(r2b-require var))
|
||||
))
|
||||
|
||||
(defun r2b-set-match (var n regexp string )
|
||||
"set VAR to the Nth subpattern in REGEXP matched by STRING, or nil if none"
|
||||
(set var
|
||||
(if (and (stringp string) (string-match regexp string))
|
||||
(substring string (match-beginning n) (match-end n))
|
||||
nil)
|
||||
)
|
||||
)
|
||||
|
||||
(defvar r2b-month-abbrevs
|
||||
'(("jan") ("feb") ("mar") ("apr") ("may") ("jun") ("jul") ("aug")
|
||||
("sep") ("oct") ("nov") ("dec")))
|
||||
|
||||
(defun r2b-convert-month ()
|
||||
"Try to convert r2bv-month to a standard 3 letter name"
|
||||
(if r2bv-month
|
||||
(let ((months r2b-month-abbrevs))
|
||||
(if (string-match "[^0-9]" r2bv-month)
|
||||
(progn
|
||||
(while (and months (not (string-match (car (car months))
|
||||
r2bv-month)))
|
||||
(setq months (cdr months)))
|
||||
(if months
|
||||
(setq r2bv-month (car (car months)))))
|
||||
(progn
|
||||
(setq months (car (read-from-string r2bv-month)))
|
||||
(if (and (numberp months)
|
||||
(> months 0)
|
||||
(< months 13))
|
||||
(setq r2bv-month (car (nth months r2b-month-abbrevs)))
|
||||
(progn
|
||||
(r2b-warning "* Ridiculous month")
|
||||
(setq r2bv-month nil))
|
||||
))
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
(defun r2b-snarf-input ()
|
||||
"parse buffer into global variables"
|
||||
(let ((case-fold-search t))
|
||||
(r2b-trace "snarfing...")
|
||||
(sit-for 0)
|
||||
(set-buffer r2b-in-buf)
|
||||
(goto-char (point-min))
|
||||
(princ " " r2b-log)
|
||||
(princ (buffer-substring (point) (progn (end-of-line) (point))) r2b-log)
|
||||
(terpri r2b-log)
|
||||
|
||||
(r2b-get-field 'r2bv-author "%A")
|
||||
(r2b-get-field 'r2bv-editor "%E")
|
||||
(cond
|
||||
(r2bv-author
|
||||
(r2b-set-match 'r2bv-primary-author 1
|
||||
"\\b\\(\\w+\\)[ \t]*\\($\\|,\\)" r2bv-author)
|
||||
)
|
||||
(r2bv-editor
|
||||
(r2b-set-match 'r2bv-primary-author 1
|
||||
"\\b\\(\\w+\\)[ \t]*\\($\\|,\\)" r2bv-editor)
|
||||
)
|
||||
(t
|
||||
(setq r2bv-primary-author "")
|
||||
)
|
||||
)
|
||||
|
||||
(r2b-get-field 'r2bv-date "%D" t t)
|
||||
(r2b-set-match 'r2bv-year 0 "[12][0-9][0-9][0-9]" r2bv-date)
|
||||
(and (null r2bv-year)
|
||||
(r2b-set-match 'r2bv-year 1 "[^0-9]\\([0-9][0-9]\\)$" r2bv-date)
|
||||
(setq r2bv-year (concat "19" r2bv-year)))
|
||||
(r2b-set-match 'r2bv-decade 1 "..\\(..\\)" r2bv-year)
|
||||
(r2b-set-match 'r2bv-month 0
|
||||
"[0-9]+/\\|[a-zA-Z]+" r2bv-date)
|
||||
(if (and (stringp r2bv-month) (string-match "\\(.*\\)/$" r2bv-month))
|
||||
(setq r2bv-month (substring r2bv-month 0 (match-end 1))))
|
||||
(r2b-convert-month)
|
||||
|
||||
(r2b-get-field 'r2bv-title "%T" t t t)
|
||||
(r2b-set-match 'r2bv-title-first-word 4
|
||||
r2b-stop-regexp
|
||||
r2bv-title)
|
||||
|
||||
(r2b-get-field 'r2bv-annote "%X" t )
|
||||
(r2b-get-field 'r2bv-tr "%R" t)
|
||||
(r2b-get-field 'r2bv-address "%C" t)
|
||||
(r2b-get-field 'r2bv-institution "%I" t)
|
||||
(r2b-get-field 'r2bv-keywords "%K")
|
||||
(r2b-get-field 'r2bv-booktitle "%B" t nil t)
|
||||
(r2b-get-field 'r2bv-journal "%J" t nil t)
|
||||
(r2b-get-field 'r2bv-volume "%V" t)
|
||||
(r2b-get-field 'r2bv-number "%N" t)
|
||||
(r2b-get-field 'r2bv-pages "%P" t)
|
||||
(r2b-get-field 'r2bv-where "%W" t)
|
||||
(r2b-get-field 'r2bv-ordering "%O" t)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defun r2b-put-field (field data &optional abbrevs)
|
||||
"print bibtex FIELD = {DATA} if DATA not null; precede
|
||||
with a comma and newline; if ABBREVS list is given, then
|
||||
try to replace the {DATA} with an abbreviation"
|
||||
(if data
|
||||
(let (match nodelim multi-line index)
|
||||
(cond
|
||||
((and abbrevs (setq match (assoc data abbrevs)))
|
||||
(if (null (cdr match))
|
||||
(setq data (car match))
|
||||
(setq data (car (cdr match))))
|
||||
(setq nodelim t))
|
||||
((and (not (equal data ""))
|
||||
(not (string-match "[^0-9]" data)))
|
||||
(setq nodelim t))
|
||||
(t
|
||||
(setq index 0)
|
||||
(while (string-match "[\\~^]" data index)
|
||||
(setq data (concat (substring data 0 (match-beginning 0))
|
||||
"\\verb+"
|
||||
(substring data (match-beginning 0) (match-end 0))
|
||||
"+"
|
||||
(substring data (match-end 0))))
|
||||
(setq index (+ (match-end 0) 7)))
|
||||
(setq index 0)
|
||||
(while (string-match "[$&%#_{}]" data index)
|
||||
(setq data (concat (substring data 0 (match-beginning 0))
|
||||
"\\"
|
||||
(substring data (match-beginning 0))))
|
||||
(setq index (+ (match-end 0) 1)))
|
||||
(setq index 0)
|
||||
(if r2b-delimit-with-quote
|
||||
(while (string-match "\"" data index)
|
||||
(setq data (concat (substring data 0 (match-beginning 0))
|
||||
"{\"}"
|
||||
(substring data (match-end 0))))
|
||||
(setq index (+ (match-end 0) 2))))
|
||||
))
|
||||
(princ ", \n ")
|
||||
(princ field)
|
||||
(princ " =\t")
|
||||
(if (not nodelim)
|
||||
(if r2b-delimit-with-quote
|
||||
(princ "\"")
|
||||
(princ "{")))
|
||||
(string-match ".*" data)
|
||||
(if (> (match-end 0) 59)
|
||||
(princ "\n"))
|
||||
(princ data)
|
||||
(if (not nodelim)
|
||||
(if r2b-delimit-with-quote
|
||||
(princ "\"")
|
||||
(princ "}")))
|
||||
)
|
||||
))
|
||||
|
||||
|
||||
(defun r2b-require (vars)
|
||||
"If any of VARS is null, set to empty string and log error"
|
||||
(cond
|
||||
((null vars))
|
||||
((listp vars) (r2b-require (car vars)) (r2b-require (cdr vars)))
|
||||
(t
|
||||
(if (null (symbol-value vars))
|
||||
(progn
|
||||
(r2b-warning "*Missing value for field %s" vars)
|
||||
(set vars "")
|
||||
)))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defmacro r2b-moveq (new old)
|
||||
"set NEW to OLD and set OLD to nil"
|
||||
(list 'progn (list 'setq new old) (list 'setq old 'nil)))
|
||||
|
||||
(defun r2b-isa-proceedings (name)
|
||||
"return t if NAME is the name of proceedings"
|
||||
(and
|
||||
name
|
||||
(or
|
||||
(string-match "proceedings\\|conference" name)
|
||||
(assoc name r2b-proceedings-list)
|
||||
(let ((match (assoc name r2b-booktitle-abbrevs)))
|
||||
(and match
|
||||
(string-match "proceedings\\|conference" (car (cdr match)))))
|
||||
)))
|
||||
|
||||
(defun r2b-isa-university (name)
|
||||
"return t if NAME is a university or similar organization,
|
||||
but not a publisher"
|
||||
(and
|
||||
name
|
||||
(string-match "university" name)
|
||||
(not (string-match "press" name))
|
||||
|
||||
))
|
||||
|
||||
(defun r2b-barf-output ()
|
||||
"generate bibtex based on global variables"
|
||||
(let ((standard-output r2b-out-buf) (case-fold-search t) match)
|
||||
|
||||
(r2b-trace "...barfing")
|
||||
(sit-for 0)
|
||||
(set-buffer r2b-out-buf)
|
||||
|
||||
(setq r2bv-kn (concat r2bv-primary-author r2bv-decade
|
||||
r2bv-title-first-word))
|
||||
|
||||
(setq r2bv-entry-kind
|
||||
(cond
|
||||
((r2b-isa-proceedings r2bv-journal)
|
||||
(r2b-moveq r2bv-booktitle r2bv-journal)
|
||||
(if (r2b-isa-university r2bv-institution)
|
||||
(r2b-moveq r2bv-organization r2bv-institution)
|
||||
(r2b-moveq r2bv-publisher r2bv-institution))
|
||||
(r2b-moveq r2bv-note r2bv-tr)
|
||||
(r2b-require 'r2bv-author)
|
||||
'inproceedings)
|
||||
((r2b-isa-proceedings r2bv-booktitle)
|
||||
(if (r2b-isa-university r2bv-institution)
|
||||
(r2b-moveq r2bv-organization r2bv-institution)
|
||||
(r2b-moveq r2bv-publisher r2bv-institution))
|
||||
(r2b-moveq r2bv-note r2bv-tr)
|
||||
(r2b-require 'r2bv-author)
|
||||
'inproceedings)
|
||||
((and r2bv-tr (string-match "phd" r2bv-tr))
|
||||
(r2b-moveq r2bv-school r2bv-institution)
|
||||
(r2b-require 'r2bv-school )
|
||||
(r2b-require 'r2bv-author)
|
||||
'phdthesis)
|
||||
((and r2bv-tr (string-match "master" r2bv-tr))
|
||||
(r2b-moveq r2bv-school r2bv-institution)
|
||||
(r2b-require 'r2bv-school )
|
||||
(r2b-require 'r2bv-author)
|
||||
'mastersthesis)
|
||||
((and r2bv-tr (string-match "draft\\|unpublish" r2bv-tr))
|
||||
(r2b-moveq r2bv-note r2bv-institution)
|
||||
(r2b-require 'r2bv-author)
|
||||
'unpublished)
|
||||
(r2bv-journal
|
||||
(r2b-require 'r2bv-author)
|
||||
'article)
|
||||
(r2bv-booktitle
|
||||
(r2b-moveq r2bv-publisher r2bv-institution)
|
||||
(r2b-moveq r2bv-note r2bv-tr)
|
||||
(r2b-require 'r2bv-publisher)
|
||||
(r2b-require 'r2bv-author)
|
||||
'incollection)
|
||||
((and r2bv-author
|
||||
(null r2bv-editor)
|
||||
(string-match "\\`personal communication\\'" r2bv-title))
|
||||
'misc)
|
||||
((r2b-isa-proceedings r2bv-title)
|
||||
(if (r2b-isa-university r2bv-institution)
|
||||
(r2b-moveq r2bv-organization r2bv-institution)
|
||||
(r2b-moveq r2bv-publisher r2bv-institution))
|
||||
(r2b-moveq r2bv-note r2bv-tr)
|
||||
'proceedings)
|
||||
((or r2bv-editor
|
||||
(and r2bv-author
|
||||
(or
|
||||
(null r2bv-tr)
|
||||
(string-match "\\bisbn\\b" r2bv-tr))))
|
||||
(r2b-moveq r2bv-publisher r2bv-institution)
|
||||
(r2b-moveq r2bv-note r2bv-tr)
|
||||
(r2b-require 'r2bv-publisher)
|
||||
(if (null r2bv-editor)
|
||||
(r2b-require 'r2bv-author))
|
||||
'book)
|
||||
(r2bv-tr
|
||||
(r2b-require 'r2bv-institution)
|
||||
(if (string-match
|
||||
"\\`\\(\\(.\\|\n\\)+\\)[ \t\n]+\\([^ \t\n]\\)+\\'"
|
||||
r2bv-tr)
|
||||
(progn
|
||||
(setq r2bv-type (substring r2bv-tr 0 (match-end 1)))
|
||||
(setq r2bv-number (substring r2bv-tr
|
||||
(match-beginning 3)))
|
||||
(setq r2bv-tr nil))
|
||||
(r2b-moveq r2bv-number r2bv-tr))
|
||||
(r2b-require 'r2bv-author)
|
||||
'techreport)
|
||||
(r2bv-institution
|
||||
(r2b-moveq r2bv-organization r2bv-institution)
|
||||
'manual)
|
||||
(t
|
||||
'misc)
|
||||
))
|
||||
|
||||
(r2b-require '( r2bv-year))
|
||||
|
||||
(if r2b-error-found
|
||||
(princ "\n% Warning -- Errors During Conversion Next Entry\n"))
|
||||
|
||||
(princ "\n@")
|
||||
(princ r2bv-entry-kind)
|
||||
(princ "( ")
|
||||
(princ r2bv-kn)
|
||||
|
||||
(r2b-put-field "author" r2bv-author )
|
||||
(r2b-put-field "title" r2bv-title r2b-booktitle-abbrevs)
|
||||
(r2b-put-field "year" r2bv-year )
|
||||
|
||||
(r2b-put-field "month" r2bv-month r2b-month-abbrevs)
|
||||
(r2b-put-field "journal" r2bv-journal r2b-journal-abbrevs)
|
||||
(r2b-put-field "volume" r2bv-volume)
|
||||
(r2b-put-field "type" r2bv-type)
|
||||
(r2b-put-field "number" r2bv-number)
|
||||
(r2b-put-field "booktitle" r2bv-booktitle r2b-booktitle-abbrevs)
|
||||
(r2b-put-field "editor" r2bv-editor)
|
||||
(r2b-put-field "publisher" r2bv-publisher)
|
||||
(r2b-put-field "institution" r2bv-institution)
|
||||
(r2b-put-field "organization" r2bv-organization)
|
||||
(r2b-put-field "school" r2bv-school)
|
||||
(r2b-put-field "pages" r2bv-pages)
|
||||
(r2b-put-field "address" r2bv-address)
|
||||
(r2b-put-field "note" r2bv-note)
|
||||
(r2b-put-field "keywords" r2bv-keywords)
|
||||
(r2b-put-field "where" r2bv-where)
|
||||
(r2b-put-field "ordering" r2bv-ordering)
|
||||
(r2b-put-field "annote" r2bv-annote)
|
||||
|
||||
(princ " )\n")
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defun r2b-convert-record (output-name)
|
||||
"transform current bib entry and append to buffer OUTPUT;
|
||||
do M-x r2b-help for more info"
|
||||
(interactive
|
||||
(list (read-string "Output to buffer: " r2b-out-buf-name)))
|
||||
(let (rec-end rec-begin not-done)
|
||||
(setq r2b-out-buf-name output-name)
|
||||
(setq r2b-out-buf (get-buffer-create output-name))
|
||||
(setq r2b-in-buf (current-buffer))
|
||||
(set-buffer r2b-out-buf)
|
||||
(goto-char (point-max))
|
||||
(setq r2b-log (get-buffer-create r2b-log-name))
|
||||
(set-buffer r2b-log)
|
||||
(goto-char (point-max))
|
||||
(set-buffer r2b-in-buf)
|
||||
(setq not-done (re-search-forward "[^ \t\n]" nil t))
|
||||
(if not-done
|
||||
(progn
|
||||
(re-search-backward "^[ \t]*$" nil 2)
|
||||
(re-search-forward "^%")
|
||||
(beginning-of-line nil)
|
||||
(setq rec-begin (point))
|
||||
(re-search-forward "^[ \t]*$" nil 2)
|
||||
(setq rec-end (point))
|
||||
(narrow-to-region rec-begin rec-end)
|
||||
(r2b-clear-variables)
|
||||
(r2b-snarf-input)
|
||||
(r2b-barf-output)
|
||||
(set-buffer r2b-in-buf)
|
||||
(widen)
|
||||
(goto-char rec-end)
|
||||
t)
|
||||
nil
|
||||
)
|
||||
))
|
||||
|
||||
|
||||
(defun r2b-convert-buffer (output-name)
|
||||
"transform current buffer and append to buffer OUTPUT;
|
||||
do M-x r2b-help for more info"
|
||||
(interactive
|
||||
(list (read-string "Output to buffer: " r2b-out-buf-name)))
|
||||
(save-excursion
|
||||
(setq r2b-log (get-buffer-create r2b-log-name))
|
||||
(set-buffer r2b-log)
|
||||
(erase-buffer))
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(message "Working, please be patient...")
|
||||
(sit-for 0)
|
||||
(while (r2b-convert-record output-name) t)
|
||||
(message "Done, results in %s, errors in %s"
|
||||
r2b-out-buf-name r2b-log-name)
|
||||
)
|
||||
|
||||
(defvar r2b-load-quietly nil "*Don't print help message when loaded")
|
||||
|
||||
(defvar r2b-help-message
|
||||
" Refer to Bibtex Bibliography Conversion
|
||||
|
||||
A refer-style database is of the form:
|
||||
|
||||
%A Joe Blow
|
||||
%T Great Thoughts I've Thought
|
||||
%D 1977
|
||||
etc.
|
||||
|
||||
This utility converts these kind of databases to bibtex form, for
|
||||
users of TeX and LaTex. Instructions:
|
||||
1. Visit the file containing the refer-style database.
|
||||
2. The command
|
||||
M-x r2b-convert-buffer
|
||||
converts the entire buffer, appending it's output by default in a
|
||||
buffer named *Out*, and logging progress and errors in a buffer
|
||||
named *Log*. The original file is never modified.
|
||||
Note that results are appended to *Out*, so if that buffer
|
||||
buffer already exists and contains material you don't want to
|
||||
save, you should kill it first.
|
||||
3. Switch to the buffer *Out* and save it as a named file.
|
||||
4. To convert a single refer-style entry, simply position the cursor
|
||||
at the entry and enter
|
||||
M-x r2b-convert-record
|
||||
Again output is appended to *Out* and errors are logged in *Log*.
|
||||
|
||||
This utility is very robust and pretty smart about determining the
|
||||
type of the entry. It includes facilities for expanding refer macros
|
||||
to text, or substituting bibtex macros. Do M-x describe-variable on
|
||||
r2b-journal-abbrevs
|
||||
r2b-booktitle-abbrevs
|
||||
r2b-proceedings-list
|
||||
for information on these features.
|
||||
|
||||
If you don't want to see this help message when you load this utility,
|
||||
then include the following line in your .emacs file:
|
||||
(setq r2b-load-quietly t)
|
||||
To see this message again, perform
|
||||
M-x r2b-help")
|
||||
|
||||
|
||||
(defun r2b-help ()
|
||||
"print help message"
|
||||
(interactive)
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(princ r2b-help-message)))
|
||||
|
||||
(if (not r2b-load-quietly)
|
||||
(r2b-help))
|
||||
|
||||
(message "r2b loaded")
|
||||
|
132
lisp/textmodes/spell.el
Normal file
132
lisp/textmodes/spell.el
Normal file
@ -0,0 +1,132 @@
|
||||
;; Spelling correction interface for Emacs.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defvar spell-command "spell"
|
||||
"*Command to run the spell program.")
|
||||
|
||||
(defvar spell-filter nil
|
||||
"*Filter function to process text before passing it to spell program.
|
||||
This function might remove text-processor commands.
|
||||
nil means don't alter the text before checking it.")
|
||||
|
||||
(defun spell-buffer ()
|
||||
"Check spelling of every word in the buffer.
|
||||
For each incorrect word, you are asked for the correct spelling
|
||||
and then put into a query-replace to fix some or all occurrences.
|
||||
If you do not want to change a word, just give the same word
|
||||
as its \"correct\" spelling; then the query replace is skipped."
|
||||
(interactive)
|
||||
(spell-region (point-min) (point-max) "buffer"))
|
||||
|
||||
(defun spell-word ()
|
||||
"Check spelling of word at or before point.
|
||||
If it is not correct, ask user for the correct spelling
|
||||
and query-replace the entire buffer to substitute it."
|
||||
(interactive)
|
||||
(let (beg end spell-filter)
|
||||
(save-excursion
|
||||
(if (not (looking-at "\\<"))
|
||||
(forward-word -1))
|
||||
(setq beg (point))
|
||||
(forward-word 1)
|
||||
(setq end (point)))
|
||||
(spell-region beg end (buffer-substring beg end))))
|
||||
|
||||
(defun spell-region (start end &optional description)
|
||||
"Like spell-buffer but applies only to region.
|
||||
Used in a program, applies from START to END.
|
||||
DESCRIPTION is an optional string naming the unit being checked:
|
||||
for example, \"word\"."
|
||||
(interactive "r")
|
||||
(let ((filter spell-filter)
|
||||
(buf (get-buffer-create " *temp*")))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(widen)
|
||||
(erase-buffer))
|
||||
(message "Checking spelling of %s..." (or description "region"))
|
||||
(if (and (null filter) (= ?\n (char-after (1- end))))
|
||||
(if (string= "spell" spell-command)
|
||||
(call-process-region start end "spell" nil buf)
|
||||
(call-process-region start end shell-file-name
|
||||
nil buf nil "-c" spell-command))
|
||||
(let ((oldbuf (current-buffer)))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(insert-buffer-substring oldbuf start end)
|
||||
(or (bolp) (insert ?\n))
|
||||
(if filter (funcall filter))
|
||||
(if (string= "spell" spell-command)
|
||||
(call-process-region (point-min) (point-max) "spell" t buf)
|
||||
(call-process-region (point-min) (point-max) shell-file-name
|
||||
t buf nil "-c" spell-command)))))
|
||||
(message "Checking spelling of %s...%s"
|
||||
(or description "region")
|
||||
(if (save-excursion
|
||||
(set-buffer buf)
|
||||
(> (buffer-size) 0))
|
||||
"not correct"
|
||||
"correct"))
|
||||
(let (word newword
|
||||
(case-fold-search t)
|
||||
(case-replace t))
|
||||
(while (save-excursion
|
||||
(set-buffer buf)
|
||||
(> (buffer-size) 0))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(goto-char (point-min))
|
||||
(setq word (downcase
|
||||
(buffer-substring (point)
|
||||
(progn (end-of-line) (point)))))
|
||||
(forward-char 1)
|
||||
(delete-region (point-min) (point))
|
||||
(setq newword
|
||||
(read-input (concat "`" word
|
||||
"' not recognized; edit a replacement: ")
|
||||
word))
|
||||
(flush-lines (concat "^" (regexp-quote word) "$")))
|
||||
(if (not (equal word newword))
|
||||
(progn
|
||||
(goto-char (point-min))
|
||||
(query-replace-regexp (concat "\\b" (regexp-quote word) "\\b")
|
||||
newword)))))))
|
||||
|
||||
|
||||
(defun spell-string (string)
|
||||
"Check spelling of string supplied as argument."
|
||||
(interactive "sSpell string: ")
|
||||
(let ((buf (get-buffer-create " *temp*")))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(widen)
|
||||
(erase-buffer)
|
||||
(insert string "\n")
|
||||
(if (string= "spell" spell-command)
|
||||
(call-process-region (point-min) (point-max) "spell"
|
||||
t t)
|
||||
(call-process-region (point-min) (point-max) shell-file-name
|
||||
t t nil "-c" spell-command))
|
||||
(if (= 0 (buffer-size))
|
||||
(message "%s is correct" string)
|
||||
(goto-char (point-min))
|
||||
(while (search-forward "\n" nil t)
|
||||
(replace-match " "))
|
||||
(message "%sincorrect" (buffer-substring 1 (point-max)))))))
|
147
lisp/textmodes/text-mode.el
Normal file
147
lisp/textmodes/text-mode.el
Normal file
@ -0,0 +1,147 @@
|
||||
;; Text mode, and its ideosyncratic commands.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defvar text-mode-syntax-table nil
|
||||
"Syntax table used while in text mode.")
|
||||
|
||||
(defvar text-mode-abbrev-table nil
|
||||
"Abbrev table used while in text mode.")
|
||||
(define-abbrev-table 'text-mode-abbrev-table ())
|
||||
|
||||
(if text-mode-syntax-table
|
||||
()
|
||||
(setq text-mode-syntax-table (make-syntax-table))
|
||||
(modify-syntax-entry ?\" ". " text-mode-syntax-table)
|
||||
(modify-syntax-entry ?\\ ". " text-mode-syntax-table)
|
||||
(modify-syntax-entry ?' "w " text-mode-syntax-table))
|
||||
|
||||
(defvar text-mode-map nil
|
||||
"Keymap for Text mode.
|
||||
Many other modes, such as Mail mode, Outline mode and Indented Text mode,
|
||||
inherit all the commands defined in this map.")
|
||||
|
||||
(if text-mode-map
|
||||
()
|
||||
(setq text-mode-map (make-sparse-keymap))
|
||||
(define-key text-mode-map "\t" 'tab-to-tab-stop)
|
||||
(define-key text-mode-map "\es" 'center-line)
|
||||
(define-key text-mode-map "\eS" 'center-paragraph))
|
||||
|
||||
|
||||
;(defun non-saved-text-mode ()
|
||||
; "Like text-mode, but delete auto save file when file is saved for real."
|
||||
; (text-mode)
|
||||
; (make-local-variable 'delete-auto-save-files)
|
||||
; (setq delete-auto-save-files t))
|
||||
|
||||
(defun text-mode ()
|
||||
"Major mode for editing text intended for humans to read. Special commands:\\{text-mode-map}
|
||||
Turning on text-mode calls the value of the variable `text-mode-hook',
|
||||
if that value is non-nil."
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
(use-local-map text-mode-map)
|
||||
(setq mode-name "Text")
|
||||
(setq major-mode 'text-mode)
|
||||
(setq local-abbrev-table text-mode-abbrev-table)
|
||||
(set-syntax-table text-mode-syntax-table)
|
||||
(run-hooks 'text-mode-hook))
|
||||
|
||||
(defvar indented-text-mode-map ()
|
||||
"Keymap for Indented Text mode.
|
||||
All the commands defined in Text mode are inherited unless overridden.")
|
||||
|
||||
(if indented-text-mode-map
|
||||
()
|
||||
(setq indented-text-mode-map (nconc (make-sparse-keymap) text-mode-map))
|
||||
(define-key indented-text-mode-map "\t" 'indent-relative))
|
||||
|
||||
(defun indented-text-mode ()
|
||||
"Major mode for editing indented text intended for humans to read.\\{indented-text-mode-map}
|
||||
Turning on indented-text-mode calls the value of the variable `text-mode-hook',
|
||||
if that value is non-nil."
|
||||
(interactive)
|
||||
(kill-all-local-variables)
|
||||
(use-local-map text-mode-map)
|
||||
(define-abbrev-table 'text-mode-abbrev-table ())
|
||||
(setq local-abbrev-table text-mode-abbrev-table)
|
||||
(set-syntax-table text-mode-syntax-table)
|
||||
(make-local-variable 'indent-line-function)
|
||||
(setq indent-line-function 'indent-relative-maybe)
|
||||
(use-local-map indented-text-mode-map)
|
||||
(setq mode-name "Indented Text")
|
||||
(setq major-mode 'indented-text-mode)
|
||||
(run-hooks 'text-mode-hook))
|
||||
|
||||
(defun change-log-mode ()
|
||||
"Major mode for editing ChangeLog files. See M-x add-change-log-entry.
|
||||
Almost the same as Indented Text mode, but prevents numeric backups
|
||||
and sets `left-margin' to 8 and `fill-column' to 74."
|
||||
(interactive)
|
||||
(indented-text-mode)
|
||||
(setq left-margin 8)
|
||||
(setq fill-column 74)
|
||||
(make-local-variable 'version-control)
|
||||
(setq version-control 'never)
|
||||
(run-hooks 'change-log-mode-hook))
|
||||
|
||||
(defun center-paragraph ()
|
||||
"Center each nonblank line in the paragraph at or after point.
|
||||
See center-line for more info."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(forward-paragraph)
|
||||
(or (bolp) (newline 1))
|
||||
(let ((end (point)))
|
||||
(backward-paragraph)
|
||||
(center-region (point) end))))
|
||||
|
||||
(defun center-region (from to)
|
||||
"Center each nonblank line starting in the region.
|
||||
See center-line for more info."
|
||||
(interactive "r")
|
||||
(if (> from to)
|
||||
(let ((tem to))
|
||||
(setq to from from tem)))
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(narrow-to-region from to)
|
||||
(goto-char from)
|
||||
(while (not (eobp))
|
||||
(or (save-excursion (skip-chars-forward " \t") (eolp))
|
||||
(center-line))
|
||||
(forward-line 1)))))
|
||||
|
||||
(defun center-line ()
|
||||
"Center the line point is on, within the width specified by `fill-column'.
|
||||
This means adjusting the indentation so that it equals
|
||||
the distance between the end of the text and `fill-column'."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
(let (line-length)
|
||||
(beginning-of-line)
|
||||
(delete-horizontal-space)
|
||||
(end-of-line)
|
||||
(delete-horizontal-space)
|
||||
(setq line-length (current-column))
|
||||
(beginning-of-line)
|
||||
(indent-to
|
||||
(+ left-margin
|
||||
(/ (- fill-column left-margin line-length) 2))))))
|
46
lisp/textmodes/underline.el
Normal file
46
lisp/textmodes/underline.el
Normal file
@ -0,0 +1,46 @@
|
||||
;; Insert or remove underlining (done by overstriking) in Emacs.
|
||||
;; Copyright (C) 1985 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun underline-region (start end)
|
||||
"Underline all nonblank characters in the region.
|
||||
Works by overstriking underscores.
|
||||
Called from program, takes two arguments START and END
|
||||
which specify the range to operate on."
|
||||
(interactive "r")
|
||||
(save-excursion
|
||||
(let ((end1 (make-marker)))
|
||||
(move-marker end1 (max start end))
|
||||
(goto-char (min start end))
|
||||
(while (< (point) end1)
|
||||
(or (looking-at "[_\^@- ]")
|
||||
(insert "_"))
|
||||
(forward-char 1)))))
|
||||
|
||||
(defun ununderline-region (start end)
|
||||
"Remove all underlining (overstruck underscores) in the region.
|
||||
Called from program, takes two arguments START and END
|
||||
which specify the range to operate on."
|
||||
(interactive "r")
|
||||
(save-excursion
|
||||
(let ((end1 (make-marker)))
|
||||
(move-marker end1 (max start end))
|
||||
(goto-char (min start end))
|
||||
(while (re-search-forward "_\\|_" end1 t)
|
||||
(delete-char -2)))))
|
124
lisp/userlock.el
Normal file
124
lisp/userlock.el
Normal file
@ -0,0 +1,124 @@
|
||||
;; Copyright (C) 1985, 1986 Free Software Foundation, inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;; This file is autloaded to handle certain conditions
|
||||
;; detected by the file-locking code within Emacs.
|
||||
;; The two entry points are `ask-user-about-lock' and
|
||||
;; `ask-user-about-supersession-threat'.
|
||||
|
||||
|
||||
(put 'file-locked 'error-conditions '(file-locked file-error error))
|
||||
|
||||
(defun ask-user-about-lock (fn opponent)
|
||||
"Ask user what to do when he wants to edit FILE but it is locked by USER.
|
||||
This function has a choice of three things to do:
|
||||
do (signal 'buffer-file-locked (list FILE USER))
|
||||
to refrain from editing the file
|
||||
return t (grab the lock on the file)
|
||||
return nil (edit the file even though it is locked).
|
||||
You can rewrite it to use any criterion you like to choose which one to do."
|
||||
(discard-input)
|
||||
(save-window-excursion
|
||||
(let (answer)
|
||||
(while (null answer)
|
||||
(message "%s is locking %s: action (s, q, p, ?)? " opponent fn)
|
||||
(let ((tem (let ((inhibit-quit t)
|
||||
(cursor-in-echo-area t))
|
||||
(prog1 (downcase (read-char))
|
||||
(setq quit-flag nil)))))
|
||||
(if (= tem help-char)
|
||||
(ask-user-about-lock-help)
|
||||
(setq answer (assoc tem '((?s . t)
|
||||
(?q . yield)
|
||||
(?\C-g . yield)
|
||||
(?p . nil)
|
||||
(?? . help))))
|
||||
(cond ((null answer)
|
||||
(beep)
|
||||
(message "Please type q, s, or p; or ? for help")
|
||||
(sit-for 3))
|
||||
((eq (cdr answer) 'help)
|
||||
(ask-user-about-lock-help)
|
||||
(setq answer nil))
|
||||
((eq (cdr answer) 'yield)
|
||||
(signal 'file-locked (list "File is locked" fn opponent)))))))
|
||||
(cdr answer))))
|
||||
|
||||
(defun ask-user-about-lock-help ()
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(princ "It has been detected that you want to modify a file that someone else has
|
||||
already started modifying in EMACS.
|
||||
|
||||
You can <s>teal the file; The other user becomes the
|
||||
intruder if (s)he ever unmodifies the file and then changes it again.
|
||||
You can <p>roceed; you edit at your own (and the other user's) risk.
|
||||
You can <q>uit; don't modify this file.")))
|
||||
|
||||
(put
|
||||
'file-supersession 'error-conditions '(file-supersession file-error error))
|
||||
|
||||
(defun ask-user-about-supersession-threat (fn)
|
||||
"Ask a user who is about to modify an obsolete buffer what to do.
|
||||
This function has two choices: it can return, in which case the modification
|
||||
of the buffer will proceed, or it can (signal 'file-supersession (file)),
|
||||
in which case the proposed buffer modification will not be made.
|
||||
|
||||
You can rewrite this to use any criterion you like to choose which one to do.
|
||||
The buffer in question is current when this function is called."
|
||||
(discard-input)
|
||||
(save-window-excursion
|
||||
(let (answer)
|
||||
(while (null answer)
|
||||
(message "File has changed on disk; really want to edit the buffer? (y, n or C-h) ")
|
||||
(let ((tem (downcase (let ((cursor-in-echo-area t))
|
||||
(read-char)))))
|
||||
(setq answer
|
||||
(if (= tem help-char)
|
||||
'help
|
||||
(cdr (assoc tem '((?n . yield)
|
||||
(?\C-g . yield)
|
||||
(?y . proceed)
|
||||
(?? . help))))))
|
||||
(cond ((null answer)
|
||||
(beep)
|
||||
(message "Please type y or n; or ? for help")
|
||||
(sit-for 3))
|
||||
((eq answer 'help)
|
||||
(ask-user-about-supersession-help)
|
||||
(setq answer nil))
|
||||
((eq answer 'yield)
|
||||
(signal 'file-supersession
|
||||
(list "File changed on disk" fn))))))
|
||||
(message
|
||||
"File on disk now will become a backup file if you save these changes.")
|
||||
(setq buffer-backed-up nil))))
|
||||
|
||||
(defun ask-user-about-supersession-help ()
|
||||
(with-output-to-temp-buffer "*Help*"
|
||||
(princ "You want to modify a buffer whose disk file has changed
|
||||
since you last read it in or saved it with this buffer.
|
||||
|
||||
If you say `y' to go ahead and modify this buffer,
|
||||
you risk ruining the work of whoever rewrote the file.
|
||||
If you say `n', the change you started to make will be aborted.
|
||||
|
||||
Usually, you should type `n' and then `M-x revert-buffer',
|
||||
to get the latest version of the file, then make the change again.")))
|
||||
|
||||
|
99
lisp/vms-patch.el
Normal file
99
lisp/vms-patch.el
Normal file
@ -0,0 +1,99 @@
|
||||
;; Override parts of files.el for VMS.
|
||||
;; Copyright (C) 1986 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
;;; Functions that need redefinition
|
||||
|
||||
;;; VMS file names are upper case, but buffer names are more
|
||||
;;; convenient in lower case.
|
||||
|
||||
(defun create-file-buffer (filename)
|
||||
"Create a suitably named buffer for visiting FILENAME, and return it.
|
||||
FILENAME (sans directory) is used unchanged if that name is free;
|
||||
otherwise a string <2> or <3> or ... is appended to get an unused name."
|
||||
(generate-new-buffer (downcase (file-name-nondirectory filename))))
|
||||
|
||||
;;; Given a string FN, return a similar name which is a legal VMS filename.
|
||||
;;; This is used to avoid invalid auto save file names.
|
||||
(defun make-legal-file-name (fn)
|
||||
(setq fn (copy-sequence fn))
|
||||
(let ((dot nil) (indx 0) (len (length fn)) chr)
|
||||
(while (< indx len)
|
||||
(setq chr (aref fn indx))
|
||||
(cond
|
||||
((eq chr ?.) (if dot (aset fn indx ?_) (setq dot t)))
|
||||
((not (or (and (>= chr ?a) (<= chr ?z)) (and (>= chr ?A) (<= chr ?Z))
|
||||
(and (>= chr ?0) (<= chr ?9))
|
||||
(eq chr ?$) (eq chr ?_) (and (eq chr ?-) (> indx 0))))
|
||||
(aset fn indx ?_)))
|
||||
(setq indx (1+ indx))))
|
||||
fn)
|
||||
|
||||
;;; Auto save filesnames start with _$ and end with $.
|
||||
|
||||
(defun make-auto-save-file-name ()
|
||||
"Return file name to use for auto-saves of current buffer.
|
||||
Does not consider auto-save-visited-file-name; that is checked
|
||||
before calling this function.
|
||||
This is a separate function so your .emacs file or site-init.el can redefine it.
|
||||
See also auto-save-file-name-p."
|
||||
(if buffer-file-name
|
||||
(concat (file-name-directory buffer-file-name)
|
||||
"_$"
|
||||
(file-name-nondirectory buffer-file-name)
|
||||
"$")
|
||||
(expand-file-name (concat "_$_" (make-legal-file-name (buffer-name)) "$"))))
|
||||
|
||||
(defun auto-save-file-name-p (filename)
|
||||
"Return t if FILENAME can be yielded by make-auto-save-file-name.
|
||||
FILENAME should lack slashes.
|
||||
This is a separate function so your .emacs file or site-init.el can redefine it."
|
||||
(string-match "^_\\$.*\\$" filename))
|
||||
|
||||
(defun vms-suspend-resume-hook ()
|
||||
"When resuming suspended Emacs, check for file to be found.
|
||||
If the logical name `EMACS_FILE_NAME' is defined, `find-file' that file."
|
||||
(let ((file (vms-system-info "LOGICAL" "EMACS_FILE_NAME")))
|
||||
(if file (find-file file))))
|
||||
|
||||
(setq suspend-resume-hook 'vms-suspend-resume-hook)
|
||||
|
||||
(defun vms-suspend-hook ()
|
||||
"Don't allow suspending if logical name `DONT_SUSPEND_EMACS' is defined."
|
||||
(if (vms-system-info "LOGICAL" "DONT_SUSPEND_EMACS")
|
||||
(error "Can't suspend this emacs"))
|
||||
nil)
|
||||
|
||||
(setq suspend-hook 'vms-suspend-hook)
|
||||
|
||||
(defun vms-read-directory (dirname switches buffer)
|
||||
(save-excursion
|
||||
(set-buffer buffer)
|
||||
(subprocess-command-to-buffer
|
||||
(concat "DIRECTORY " switches " " dirname)
|
||||
buffer)
|
||||
(goto-char (point-min))
|
||||
;; Remove all the trailing blanks.
|
||||
(while (search-forward " \n")
|
||||
(forward-char -1)
|
||||
(delete-horizontal-space))
|
||||
(goto-char (point-min))))
|
||||
|
||||
(setq dired-listing-switches
|
||||
"/SIZE/DATE/OWNER/WIDTH=(FILENAME=32,SIZE=5)")
|
98
lisp/window.el
Normal file
98
lisp/window.el
Normal file
@ -0,0 +1,98 @@
|
||||
;; GNU Emacs window commands aside from those written in C.
|
||||
;; Copyright (C) 1985, 1989 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 1, or (at your option)
|
||||
;; any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
(defun count-windows (&optional minibuf)
|
||||
"Returns the number of visible windows.
|
||||
Optional arg NO-MINI non-nil means don't count the minibuffer
|
||||
even if it is active."
|
||||
(let ((count 0))
|
||||
(walk-windows (function (lambda ()
|
||||
(setq count (+ count 1))))
|
||||
minibuf)
|
||||
count))
|
||||
|
||||
(defun balance-windows ()
|
||||
"Makes all visible windows the same size (approximately)."
|
||||
(interactive)
|
||||
(let ((count 0))
|
||||
(walk-windows (function (lambda (w)
|
||||
(setq count (+ count 1))))
|
||||
'nomini)
|
||||
(let ((size (/ (screen-height) count)))
|
||||
(walk-windows (function (lambda (w)
|
||||
(select-window w)
|
||||
(enlarge-window (- size (window-height)))))
|
||||
'nomini))))
|
||||
|
||||
(defun split-window-vertically (&optional arg)
|
||||
"Split current window into two windows, one above the other.
|
||||
This window becomes the uppermost of the two, and gets
|
||||
ARG lines. No arg means split equally."
|
||||
(interactive "P")
|
||||
(let ((old-w (selected-window))
|
||||
new-w bottom)
|
||||
(setq new-w (split-window nil (and arg (prefix-numeric-value arg))))
|
||||
(save-excursion
|
||||
(set-buffer (window-buffer))
|
||||
(goto-char (window-start))
|
||||
(vertical-motion (window-height))
|
||||
(set-window-start new-w (point))
|
||||
(if (> (point) (window-point new-w))
|
||||
(set-window-point new-w (point)))
|
||||
(vertical-motion -1)
|
||||
(setq bottom (point)))
|
||||
(if (<= bottom (point))
|
||||
(set-window-point old-w (1- bottom)))))
|
||||
|
||||
(defun split-window-horizontally (&optional arg)
|
||||
"Split current window into two windows side by side.
|
||||
This window becomes the leftmost of the two, and gets
|
||||
ARG columns. No arg means split equally."
|
||||
(interactive "P")
|
||||
(split-window nil (and arg (prefix-numeric-value arg)) t))
|
||||
|
||||
(defun enlarge-window-horizontally (arg)
|
||||
"Make current window ARG columns wider."
|
||||
(interactive "p")
|
||||
(enlarge-window arg t))
|
||||
|
||||
(defun shrink-window-horizontally (arg)
|
||||
"Make current window ARG columns narrower."
|
||||
(interactive "p")
|
||||
(shrink-window arg t))
|
||||
|
||||
(defun window-config-to-register (name)
|
||||
"Save the current window configuration in register REG (a letter).
|
||||
It can be later retrieved using \\[M-x register-to-window-config]."
|
||||
(interactive "cSave window configuration in register: ")
|
||||
(set-register name (current-window-configuration)))
|
||||
|
||||
(defun register-to-window-config (name)
|
||||
"Restore (make current) the window configuration in register REG (a letter).
|
||||
Use with a register previously set with \\[window-config-to-register]."
|
||||
(interactive "cRestore window configuration from register: ")
|
||||
(set-window-configuration (get-register name)))
|
||||
|
||||
(define-key ctl-x-map "2" 'split-window-vertically)
|
||||
(define-key ctl-x-map "5" 'split-window-horizontally)
|
||||
(define-key ctl-x-map "6" 'window-config-to-register)
|
||||
(define-key ctl-x-map "7" 'register-to-window-config)
|
||||
(define-key ctl-x-map "}" 'enlarge-window-horizontally)
|
||||
(define-key ctl-x-map "{" 'shrink-window-horizontally)
|
Loading…
Reference in New Issue
Block a user