Distribution
************

Copyright © 1994 Carl Edman.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the same conditions as for modified versions.

Emacs 19 for NS
***************

Emacs 19 for NeXTstep is a version of GNU Emacs 19 which adds support for the NeXTstep (or NS, for short) window system while leaving most of the core functions of Emacs 19 unchanged.  As a result Emacs 19 for NS can do anything which GNU Emacs 19 can do and is fully compatible with all Emacs Lisp packages written for it.  It supports NS on the same level (and mostly in a very similar manner) as X is supported.  In addition Emacs 19 for NS has a number of NeXTy features which do not have any X equivalent.  The design aim was to make it look as similar as possible to an X application to Emacs Lisp programs and to make it look like a normal NS application to users.

Comments and bug reports relating to the window system interface are welcome.  To report a bug please use the User/Submit Bug Report menu item.  This sends messages to Carl Edman <cedman@princeton.edu>.

Problems and bugs which do not relate to the NS support (i.e. which can be reproduced even in a dumb terminal or under X) are better posted to gnu.emacs.help or mailed to <bug-gnu-emacs@prep.ai.mit.edu> where general GNU emacs improvements are discussed.  Any improvements made to it will quickly find their way into this version as well.

There are also two mailing lists for Emacs for NS, <emacs-for-ns-users@lists.princeton.edu> and <emacs-for-ns-announce@lists.princeton.edu>.  The former is intended for general discussion and allows anybody to post.  The latter restricts posting and should contain only a handful of announcements of new releases every year.  Both of these lists are handled by the CREN Listproc which means that you can subscribe and unsubscribe automatically.  For example, to subscribe to emacs-for-ns-users I'd send a message with the content SUBSCRIBE emacs-for-ns-users Carl Edman to <listproc@lists.princeton.edu>.  For more details write to the same address with the content HELP.

Introduction
============

Despite the size and complexity of GNU Emacs 19, NS and the NS support code this manual can be kept mercifully short by saying that everything written in the Emacs and the Emacs Lisp manuals about GNU Emacs applies equally to this Emacs except as noted here.

  * The window-system variable can now have the value ns in addition to x and nil.  These are typical examples from ~/.emacs files which need to run different customizations depending on whether a or which window system is running.

     If you just want to distinguish between cases in which there is an window system and in which there isn't, this construct is useful.

          (if window-system
              ...       ;;; function to evaluate if any window system is running
            ...)        ;;; function to evaluate only when running on a dumb terminal

     For more detailed control, use this.

          (cond
           ((eq window-system 'ns)         ;;; NS specific instructions
            ...)
           ((eq window-system 'x)          ;;; X specific instructions
            ...)
           (t      ;;; Instructions for dumb terminal or other window systems
            ...))

  * All X specific functions have been renamed to begin with x- if they didn't already (which most did).  The equivalent NS functions have been created with the same name but the ns- prefix. Finally a function without any prefix was created which will call either the ns- or the x- function depending on which window system Emacs is running at the time.  For example, the original frame-face-alist function was renamed to x-frame-face-alist, ns-frame-face-alist was created to fulfill the same task under NS and the new frame-face-alist will call x-frame-face-alist when running Emacs under X and ns-frame-face-alist when running under NS.  As the general function will run under any window system its use is encouraged.

  * A similar renaming was done on the handful of X specific variables.  The only difference is that there are no generic variables which will work in either window system.

  * When Emacs is called by a name which ends in -nw it will always start in terminal mode.  For example, a user who needs a terminal only emacs would create a symbolic link from emacs to emacs-nw. When he launches emacs-nw from the command line, the window system will never be involved.

Events
======

Under Emacs the NS command key works as the super modifier key. In principle users can bind their command keys to whatever function they want, but to make the transition for NS users easier the default NS startup files bind the most commonly used NS command keys to work just like they do in most other NS applications.  This is the code which accomplishes that.  You can of course override all of this in your ~/.emacs file.

     (define-key global-map [?\s-'] 'next-multiframe-window)
     (define-key global-map [?\s--] 'center-line)
     (define-key global-map [?\s-:] 'ispell)
     (define-key global-map [?\s-;] 'ispell-next)
     (define-key global-map [?\s-?] 'info)
     (define-key global-map [?\s-^] 'kill-some-buffers)
     (define-key global-map [?\s-&] 'kill-this-buffer)
     (define-key global-map [?\s-D] 'dired)
     (define-key global-map [?\s-E] 'edit-abbrevs)
     (define-key global-map [?\s-G] 'hide-body)
     (define-key global-map [?\s-L] 'shell-command)
     (define-key global-map [?\s-M] 'manual-entry)
     (define-key global-map [?\s-O] 'show-all)
     (define-key global-map [?\s-S] 'write-file)
     (define-key global-map [?\s-a] 'mark-whole-buffer)
     (define-key global-map [?\s-c] 'kill-ring-save)
     (define-key global-map [?\s-d] 'isearch-repeat-backward)
     (define-key global-map [?\s-e] 'isearch-yank-kill)
     (define-key global-map [?\s-f] 'isearch-forward)
     (define-key global-map [?\s-g] 'isearch-repeat-forward)
     (define-key global-map [?\s-h] 'do-hide-emacs)
     (define-key global-map [?\s-j] 'exchange-point-and-mark)
     (define-key global-map [?\s-l] 'goto-line)
     (define-key global-map [?\s-m] 'iconify-frame)
     (define-key global-map [?\s-n] 'new-frame)
     (define-key global-map [?\s-o] 'find-file-other-frame)
     (define-key global-map [?\s-p] 'print-buffer)
     (define-key global-map [?\s-q] 'save-buffers-kill-emacs)
     (define-key global-map [?\s-s] 'save-buffer)
     (define-key global-map [?\s-t] 'ns-popup-fontpanel)
     (define-key global-map [?\s-u] 'revert-buffer)
     (define-key global-map [?\s-v] 'yank)
     (define-key global-map [?\s-w] 'delete-frame)
     (define-key global-map [?\s-x] 'kill-region)
     (define-key global-map [?\s-z] 'undo)
     (define-key global-map [?\s-|] 'shell-command-on-region)

NS applications receive a number of special events which have no X equivalent.  Under Emacs these events can be bound to functions just like ordinary keystrokes.  Here is a list of these events.

ns-open-file
     This event occurs when another NS application requests that Emacs open a file.  A typical reason for this would be a user double-clicking a file in the Workspace File Viewer.  When this event is registered the name of the file to open is found in the variable ns-input-file.

     This is the default binding.  It causes Emacs open the new file in the selected frame if the selected buffer is a scratch buffer.  Otherwise Emacs opens a new frame and display the file in that.

          (define-key global-map [ns-open-file] 'ns-find-file-fresh-frame)

     To always get a new frame one would use a binding like this.

          (define-key global-map [ns-open-file] 'ns-find-file-other-frame)

     If you prefer the opposite behavior (i.e. always putting the file into the selected frame), use this.

          (define-key global-map [ns-open-file] 'ns-find-file)

ns-open-temp-file
     This event occurs when another application requests that Emacs open a temporary file.  The file name is again in ns-input-file.  By default this is handled by just generating a ns-open-file event (which then causes the ns-open-file function to be called whatever that may be).

          (define-key global-map [ns-open-temp-file] [ns-open-file])

ns-open-file-line
     Some applications (like e.g. ProjectBuilder or gdb) request not only a particular file, but also a particular line or sequence of lines in the file.  The file name is in ns-input-file, and ns-input-line is either the line or a cons cell the car of which contains the beginning line and the cdr of which the ending line.

          (define-key global-map [ns-open-file-line]
                      'ns-open-file-select-line)

ns-drag-file
     When a user drags files from another application into an Emacs frame this event is triggered.  Here ns-input-file is a list of all dragged files.  The default binding inserts all the dragged files into the current buffer.

          (define-key global-map [ns-drag-file] 'ns-insert-files)

ns-drag-color
     When a user drags a color from the color well (or some other source) Emacs sees this event and ns-input-color contains the name of the dragged color.  The default bindings alter the foreground color of the area the color was dragged onto (or background color if the color was shift dragged).

          (define-key global-map [ns-drag-color]
                      'ns-set-foreground-at-mouse)
          (define-key global-map [S-ns-drag-color]
                      'ns-set-background-at-mouse)

ns-change-font
     Emacs allows the user to open a standard NS font panel (by default that function is bound to s-t).  When the user selects a font in that panel this event occurs.  ns-input-font will contain the name of the selected font and ns-input-fontsize is its size.  The default binding causes Emacs to adjust the font of the selected frame.

          (define-key global-map [ns-change-font] 'ns-respond-to-changefont)

ns-power-off
     Finally when the user logs out and Emacs is still running it receives this event so that it has a chance to save its files before it dies.

          (define-key global-map [ns-power-off]
            '(lambda () (interactive) (save-buffers-kill-emacs t)))

In addition there are some NS keystrokes available on some NS/FIP machines which are not available under X.  Their names are self-explanatory.  They are kp-at, kp-backslash, kp-backtick, kp-bar, kp-cube, kp-hash, kp-less, kp-more, kp-mu, kp-paragraph, kp-ring, kp-square, kp-tilde, kp-yen and scroll-lock.

Emacs 19 for NS also allows users to make use of NS services.  On the most basic level programmers can use the ns-perform-service to pass arbitrary strings to arbitrary services and receive the results back.  A more user friendly interface is offered by the ns-define-service macro.  Its argument is a list of strings which describes the menu path to the service in question (see example).  It returns a command which will send the region to the specified service and if the service returns a value, the region is replaced by the return value. Here are two usage examples:

     (define-key global-map [?\s-=] (ns-define-service '("Define in Webster")))
     (define-key global-map [?\s-H] (ns-define-service '("HeaderViewer" "Find")))

Under NS 3.2 and later such lines are in general not needed as Emacs will automatically define menu items for all the used services.

Defaults
========

Under X resources are used to customize the behavior of Emacs to the needs of the user.  These resources are queried programmatically with the x-get-resource function.  Under NS defaults fulfill a similar function.  They can be read using the ns-get-resource function. The get-resource function will read either X resources or NS defaults depending on the window system which Emacs is running under and so is the best choice for portable programs.  In addition, it is also possible to set many of the following customizations by setting the default-frame-alist in the ~/.emacs file.  Calling the function ns-save-preferences (for example through the Save Preferences menu item) will automatically write out the defaults corresponding the selected window.

This is a listing of some of the more useful defaults (and their default values).  Several of these defaults accept the names of colors as values.  For a list of all available colors look in etc/Emacs.clr and any other .clr file in the standard color search patch. Emacs also accepts color specifications of the form RGBrrggbbaa where RR, GG, BB and AA are two hexadecimal digits describing the red, green, blue and alpha content of the color respectively.  HSBhhssbbaa, CMYKccmmyykkaa and GRAYggaa are the equivalents in HSB, CMYK and gray scales.

InternalBorderWidth
     Width in pixels of the internal border of the NS frame.

          dwrite Emacs InternalBorderWidth 2.0

VerticalScrollBars
     YES or NO to enable or disable scroll bars.

          dwrite Emacs VerticalScrollBars YES

Menus
     If this option is set, emacs will create and keep up to date a NS menu.

          dwrite Emacs Menus YES

AutoRaise
     YES or NO to indicate whether windows should be automatically raised when the mouse pointer enters them.

          dwrite Emacs AutoRaise NO

AutoLower
     YES or NO to indicate whether windows should be automatically lowered when the mouse pointer leaves them.

          dwrite Emacs AutoLower NO

fooFont
     Name of the font to be used for the Emacs face of name FOO.  If FOO is the empty string, the font for the entire frame is set (which can be overriden by various faces).  If this font is not set, Emacs 19 for NS will use the system wide fixed pitch font set in Preferences.

     For most users the system fixed pitch font will be Ohlfs which doesn't have any bold or italic versions.  As a consequence bold and italic characters will be indistinguishable from unmodified characters in Emacs.  If you wish to fix this use the following defaults which cause Emacs to use Courier instead of Ohlfs for italic and bold characters.

          dwrite Emacs ItalicFont Courier-Oblique
          dwrite Emacs BoldFont Courier-Bold
          dwrite Emacs Bold-ItalicFont Courier-BoldOblique

fooFontSize
     Size of the font to be used for the Emacs face of name FOO.  If FOO is the empty string the font size for the entire frame is set. If this font size is not set, Emacs 19 for NS will use the size of the system wide fixed pitch font set in Preferences.  GNU Emacs doesn't currently handle fonts of differing sizes in one frame very well, so for most users it is probably advisable to only set FontSize and let Emacs chose fonts of the same size for all faces.

fooForeground
     Name of the color to be used to draw the Emacs face of name FOO. If FOO is the empty string the foreground color for the entire frame is set (which can be overriden by various faces).

          dwrite Emacs Foreground "Black"

fooBackground
     Name of the color to be used to draw the background for the Emacs face of name FOO.  If FOO is the empty string the background color for the entire frame is set (which can be overriden by various faces).

          dwrite Emacs Background "White"

fooUnderline
     Whether to underline the Emacs face of name FOO.  If FOO is the empty string the default sets whether the entire screen is underlined (which can be overriden by various faces).

          dwrite Emacs Underline NO

Height
     Height in rows of the default window.

          dwrite Emacs Height 48

Width
     Width in columns of the default window.

          dwrite Emacs Width 80

CursorType
     Name of the default cursor type for Emacs.  Allowed values are bar, box, hollow, line and no.

          dwrite Emacs CursorType box

CursorColor
     Name of the default cursor type for Emacs.  Of a particular use for this setting is the Highlight "color".  When it is the cursor color, Emacs will draw the cursor using the standard NS highlighting operator.

          dwrite Emacs CursorColor Highlight

Top
     Distance in pixels from the top of the screen of the upper left corner of the default window.

          dwrite Emacs Top 100

Left
     Distance in pixels from the left edge of the screen to the upper left corner of the default window.

          dwrite Emacs Left 100

HideOnAutoLaunch
     YES or NO to determine whether Emacs will hide itself when autolaunched from the dock.

          dwrite Emacs HideOnAutoLaunch NO

ShrinkSpace
     For many postscript fonts default line spacing results in lines which are very far apart.  It is possible to reduce that line spacing and get more lines in the same vertical space.  Unfortunately by just how much the line spacing can be shrunk greatly depends on the font in use and shrinking the line spacing too much results in little specks of garbage being left all over the screen.  Setting this option to YES shrinks line spacing by the maximum allowable amount for most commonly used fixed pitch fonts.  NO instructs Emacs not to shrink the line spacing at all.  By setting this option to a floating point number a user can fine-tune the line spacing.  On the scale for that number, YES corresponds to 0.75 and NO corresponds to 1.0.

          dwrite Emacs ShrinkSpace YES

AlternateIsMeta
     If this option is set, the alternate key works as meta key.  This is generally the preferable behaviour for US and British users.  However some continental users may want to turn off this option so that they can enter special characters more easily.

          dwrite Emacs AlternateIsMeta YES

     On keyboards which have two alternate keys Emacs can also be configured to use only one as a meta key while leaving the other one alone.

     To use only the left alternate key as a meta key, use this dwrite.

          dwrite Emacs AlternateIsMeta LEFT

     For the inverse, use this.

          dwrite Emacs AlternateIsMeta RIGHT

     Only when this option is set to NO NS dead key handling which allows easy entry of umlauts and accents is enabled.

ISOLatin
     YES or NO to determine whether Emacs uses the ISO-8859-1 extension to ASCII for input, output and file storage.  This encoding differs from the NS default encoding for non-ASCII characters, but coincides with that of X and some PC and Mac applications.

          dwrite Emacs ISOLatin NO

Buffered
     YES or NO depending on whether Emacs should use buffered or retained windows.  Which of the two gives the more pleasing display performance is a matter of taste.

          dwrite Emacs Buffered YES

UseOpenPanel
     If this option is set, Emacs will always use the standard NS open panel to ask for filenames.  Otherwise Emacs will use the usual Emacs method of reading a filename from the user.  Regardless of the setting of this option the NS file requester is always available using ns-read-file-name.  This option can also be turned on and off using the ns-use-open-panel Emacs Lisp variable.

          dwrite Emacs UseOpenPanel NO

CursorBlinkRate
     Users who want their cursor to blink can set the rate (in seconds) with this dwrite.  Setting it to NO disables cursor blinking.

          dwrite Emacs CursorBlinkRate NO

Another default used by many Emacs users is this.

     dwrite Workspace DefaultOpenApp Emacs

It will cause the Workspace to open files without a registered extension in Emacs instead of as usual Edit.  For this default to work, Emacs needs to be in the application search path of the Workspace (which usually includes ~/Apps and /LocalApps).

Tips and Tricks
===============

Emacs is an extremely customizable editor.  You can make it conform to virtually any conceivable user idiosyncrasy (and some which are not) by adding a few well-chosen lines of emacs lisp to your ~/.emacs. Unfortunately even many experienced C developers are unfamiliar with Emacs Lisp.  For that reason many Emacs defaults have been chosen to make it behave as similar to Edit as possible.  But there are some customizations which a majority of users probably would hate as much as a minority would love them.  This section contains a cookbook of such customizations.  New contributions by Emacs users are very welcome.

Grabbing environment variables
------------------------------

Many programs which may run under Emacs like latex or man depend on the settings of environment variables.  If Emacs is launched from the shell, it will automatically inherit these environment variables and its subprocesses will inherit them from it.  But if Emacs is launched from the Workspace it is not a descendant of any shell, so its environment variables haven't been set which often causes the subprocesses it launches to behave differently than they would when launched from the shell.

To solve this problem Emacs for NS contains grabenv.  This function will run a subshell and copy its environment variables into Emacs.

Adding this line to your ~/.emacs will grab the csh environment whenever emacs runs under a window system.

     (if window-system (grabenv))

If you have a different shell you will have to give grabenv some arguments.  For zsh you would do this.

     (if window-system (grabenv "/usr/bin/zsh"
                                "source /etc/zshenv"
                                "source ~/.zshenv"))

The reason that grabenv is not done by default is that it adds up to a second or two to the Emacs startup time.

Miscellaneous useful variables
------------------------------

This section describes a few variables you might want to set in your ~/.emacs each of which doesn't warrant its own section.

There is a conflict between the way the region behaved in emacs in the pre-GUI days and the way GUI users expect the selection to work.  By default that conflict is resolved by having the former adopt the behaviour of the latter which most people prefer.  However if you are a die-hard emacs user you may prefer things the other way around and add this line to your ~/.emacs.  Experiment with both settings.

     (setq transient-mark-mode nil)

When you try to move beyond the end of a file Emacs will add newlines as needed.  With this line in your ~/.emacs it will stop instead like most other editors do.

     (setq next-line-add-newlines nil)

By default when you kill a line with text on it, only the text is removed while the line itself remains.  You have to kill twice to really get rid of the whole line.  When this variable is set and you kill a line while at the beginning of the line it will go at once.

     (setq kill-whole-line t)

Annoyed by the Emacs startup message ?  Add this and you start with a tabula rasa.

     (setq inhibit-startup-message t)

Gnus and NeXTstep
-----------------

Gnus is a highly sophisticated news reader which comes with Emacs.  Many users prefer it over all traditional and even GUI based news readers. However all its benefits are well described in the Emacs manual.  Here let me just add a few NS specific enhancements.

If you have installed the mailapp utilities (available from better archive sites everywhere) then this code in your ~/.emacs will cause gnus to route all your attempts to reply in it to Mail.app.  This code also re-enables the delete key in the summary mode and puts an identifying line on top of all your auto-replies.

     (eval-after-load "gnus"
        '(progn
           (define-key gnus-summary-mode-map [delete] 'gnus-summary-prev-page)
           (load-library "gnus-mailapp"))

     (setq gnus-default-article-saver 'gnus-summary-save-in-nextmail
           gnus-mail-reply-method 'gnus-mail-reply-using-nextmail
           gnus-mail-forward-method 'gnus-mail-forward-using-nextmail
           gnus-mail-other-window-method 'gnus-mail-other-window-using-nextmail
           gnus-mail-send-method (function gnus-mail-send-with-note))

These lines do not depend on the mailapp utilities.  They will cause all your posted messages to be spell checked automatically (very useful !).  They will also automatically hide emacs while gnus starts up.

     (eval-after-load "gnus"
        '(progn
           (add-hook 'news-inews-hook 'ispell-message)
           (cond
            ((eq window-system 'ns)
             (add-hook 'gnus-startup-hook '(lambda () (hide-emacs t)))
             (add-hook 'gnus-group-prepare-hook '(lambda () (hide-emacs nil)) t)))))

Backspace and delete
--------------------

In the computer world there has been no end of confusion about the meaning of backspace and delete.  Here is the convention used by Emacs for NS.  Hitting the oblong key at the upper right hand corner of your main keypad (usually labeled <--) will generate a delete event.  Hitting this key while holding down a shift key generates a backspace event.  Both of these are distinct from hitting C-h (which invokes the Emacs help system).

By default both delete and backspace will delete the character preceeding the cursor.  To rebind delete to delete the character preceeding the cursor and backspace to delete the character under the cursor, do this.

     (global-set-key [delete] 'backward-delete-char-untabify)
     (global-set-key [backspace] 'delete-char)

Color adjustments
-----------------

A non-elisp hint: The easiest way to adjust your emacs color scheme is to bring up a color panel (with s-C) and drag the color you want over the emacs face you want to change.  Normal dragging will alter the foreground color.  Shift dragging will alter the background color.  To make the changes permanent select the "Save Preferences" item in the "Info" menu.  Useful in this context is the listing of all faces obtained by M-x list-faces-display.

Evaling in the minibuffer
-------------------------

Often you (at least if you are an elisp hacker) want to quickly evaluate an elisp expression.  To accomodate this desire Emacs provides the eval-expression command bound to ESC ESC.  By default it is disabled to protect novice users from themselves.  These commands re-enable it and turn on an extremely powerful completion facility.

     (put 'eval-expression 'disabled nil)

     (define-key read-expression-map "\t" 'lisp-complete-symbol)

Scrolling long completions
--------------------------

Frequently completions will contain more lines than can be displayed in the completion window.  With this bit of code, hitting TAB repeatedly will scroll through all possible completions.

     (defun minibuf-tab ()
       "Like `minibuffer-complete', but if you use this repeatedly it will scroll
     the window showing completions."
       (interactive)
       (or (eq last-command this-command) (setq minibuffer-scroll-window nil))
       (if minibuffer-scroll-window
           (save-excursion
             (set-buffer (window-buffer minibuffer-scroll-window))
             (if (pos-visible-in-window-p (point-max) minibuffer-scroll-window)
                 (set-window-start minibuffer-scroll-window (point-min))
               (scroll-other-window)))
         (minibuffer-complete)))

     (define-key minibuffer-local-must-match-map "\t" 'minibuf-tab)
     (define-key minibuffer-local-completion-map "\t" 'minibuf-tab)

This line will make completion nag you less if you select a valid response.

     (setq minibuffer-completion-confirm nil)

Highlighting matching parentheses
---------------------------------

I doubt that there is anybody who doesn't use this already, but just in case:

     (require 'paren)

Everybody who needs to match parentheses should have this in his ~/.emacs.

Resize the minibuffer automatically
-----------------------------------

Often there is more data in the minibuffer than would fit into a single line.  With this code the minibuffer expands automatically to show the entire contents.

     (require 'rsz-mini)
     (resize-minibuffer-mode 1)

Dealing with X specific packages
--------------------------------

Some emacs lisp packages explicitly call X specific functions instead of calling Emacs for NS generic function which call the NS or X versions as appropriate.  Typically such packages will result in error messages like Symbol's function definition is void: x-foo-bar.  The proper way of dealing with this is to have the author fix the code to call the generic functions.  Generally all that requires is removing the x- prefix from all function calls.

However, sometimes that is not possible.  In such ns-compat.el can help.  It redefines the X specific functions to call the generic functions without requiring any changes in code and so should make most X specific packages work.  To load ns-compat.el each time you start Emacs, add this line to your ~/.emacs.

     (require 'ns-compat)

Rebinding the numeric keypad
----------------------------

By default in Emacs the numeric keypad keys are bound to the same characters they are in all other NS applications.  But it is easy to change these bindings to commands many will find more useful.  As an example here is the code which rebinds the numeric keypad for me.

     (global-set-key [kp-0] 'other-window)
     (global-set-key [kp-1] 'end-of-buffer)
     (global-set-key [kp-2] [down])
     (global-set-key [kp-3] 'scroll-up)
     (global-set-key [kp-4] [left])
     (global-set-key [kp-5] 'set-mark-command)
     (global-set-key [kp-6] [right])
     (global-set-key [kp-7] 'beginning-of-buffer)
     (global-set-key [kp-8] [up])
     (global-set-key [kp-9] 'scroll-down)
     (global-set-key [kp-decimal] 'yank)
     (global-set-key [kp-enter] 'set-mark-command)
     (global-set-key [kp-add] 'copy-region-as-kill)
     (global-set-key [kp-subtract] 'kill-region)

On machines with function keys they can be bound as well.  This for example would bind F12 to run gnus.

     (global-set-key [f12] 'gnus)

Improving C mode
----------------

That underscores are considered to break words in C mode has been driving me insane for a long time.  This line fixes the problem.

     (modify-syntax-entry ?_ "w" c-mode-syntax-table)

Custom menu items
-----------------

The user menu is intended for customization.  Adding items to it is relatively painless as this example illustrates.

     (define-key global-map [menu-bar user www] '("WWW" . w3-use-hotlist))

Single line scrolling
---------------------

Scott Hess contributed these lines which make alternate arrow keys behave in Emacs just like they do in Stuart.app.

     (defun scroll-one-line-down (arg)
       (interactive "p")
       (scroll-down arg))

     (defun scroll-one-line-up (arg)
       (interactive "p")
       (scroll-up arg))

     (global-set-key [M-up] 'scroll-one-line-down)
     (global-set-key [M-down] 'scroll-one-line-up)

Extended font customization
---------------------------

By default Emacs tries to guess the right font when you ask for a bold, italic or bold-italic face.  Unfortunately this fails sometimes, for example Emacs won't guess that it should use Courier-Bold as the font for the bold face of Ohlfs.  As an example here is the code which sets up Courier-Bold, Courier-Oblique and Courier-BoldOblique as the fonts to be used with Ohlfs.

     (setq ns-convert-font-trait-alist
           '(("Ohlfs" "Courier-Bold" "Courier-Oblique"
              "Courier-BoldOblique")))

You will still have to set the DefaultFont, BoldFont, ItalicFont and Bold-ItalicFont defaults as Emacs initializes the default faces before it reads your ~/.emacs.

     dwrite Emacs DefaultFont Ohlfs
     dwrite Emacs BoldFont Courier-Bold
     dwrite Emacs ItalicFont Courier-Oblique
     dwrite Emacs Bold-ItalicFont Courier-BoldOblique

Thanks
======

A signficant number of people have been involved in the creation of Emacs 19 for NS, but first of all I have to thank Michael Brouwer <michael@wft.stack.urc.tue.nl>, the author of Emacs.app and co-author of Emacs 19 for NS until the Dutch army decided that so much talent shouldn't go to waste and drafted him.  He wrote most of the input code.

Also a number of others have contributed code.  Scott Hess <scott@nic.gac.edu> helped with the keyboard handling.  Timothy Bissell <bisselt@gb.swissbank.com> wrote the ProjectBuilder glue.  Scott Byer <byer@mv.us.adobe.com> suggested and partly wrote the ISOLatin1 compatibility code.  The new faster code for dumping characters to the screen is also all his fault.  The font panel code was Andrew Athans <athan@object.com> work.  Joe Reiss <jreiss@magnus.acs.ohio-state.edu> both created the beautiful icons you see and wrote the popup menu and dialog box code as well as much else.  David Griffiths <dave@prim.demon.co.uk> sent me the code which made a reasonable (or nearly so) NS file requester possible.  Some window manipulation code was stolen from John C. Randolph.  And Darcy Brockbank <darcy@amber.hasc.ca> fixed the dreaded 8-bit color bug which popped up in NS3.3.  Christian Limpach <Christian.Limpach@nice.ch> in addition to his help with tracking down bugs and fixing features wrote code which improved the font handling of emacs.  Axel Seibert <seiberta@informatik.tu-muenchen.de> and Paul J. Sanchez <paul@whimsy.umsl.edu> offered their time and machines to make the binary release possible.

Then there were a number of people who kept up the constant supply of bug reports, suggested features and praise (which is the main fuel which the development of a project like this runs) and so helped ensure that this program is as bug free (hah !)  and feature rich as you see it today.  First among them were Hardy Mayer <hardy@golem.ps.uci.edu>, Gisli Ottarsson <gisli@timoshenko.eecs.umich.edu>, Anthony Heading <ajrh@signal.dra.hmg.gb>, David Bau <bau@cs.cornell.edu>, Jamie Zawinski <jwz@lucid.com>, Martin Moncrieffe <moncrief@mayo.edu>, Simson L. Garfinkel <simsong@next.cambridge.ma.us>, Richard Stallman <rms@gnu.ai.mit.edu>, Stephen Anderson <anderson@sapir.cog.jhu.edu>, Ivo Welch <ivo@next.agsm.ucla.edu>, Magnus Nordborg <magnus@fisher.Stanford.EDU>, Tom Epperly <epperly@valeron.che.wisc.edu>, Andreas Koenig <k@franz.ww.tu-berlin.de>, Yves Arrouye <Yves.Arrouye@imag.fr>, Anil Somayaji <soma@hotspur.mit.edu>, Gregor Hoffleit <flight@mathi.uni-heidelberg.DE> and doubtlessly many more I missed when scanning the past couple thousand letters I received on this subject.

Finally, let me also thank those few hundred other people on the mailing list from whom I didn't hear much, but the presence of which assured me that maybe this project was actually worth doing.