summaryrefslogtreecommitdiff
path: root/emacs
diff options
context:
space:
mode:
Diffstat (limited to 'emacs')
-rw-r--r--emacs730
1 files changed, 730 insertions, 0 deletions
diff --git a/emacs b/emacs
new file mode 100644
index 0000000..af1c628
--- /dev/null
+++ b/emacs
@@ -0,0 +1,730 @@
+;-*- coding: utf-8 -*-
+;
+; anrxc's .emacs for GNU/Emacs 23.1 on Arch GNU/Linux.
+
+
+;{{{ Initialization
+;
+;; Define the load path
+(setq load-path (cons "~/.emacs.d/" load-path))
+
+;; Start the daemon, then use emacsclient as editor
+;(server-start)
+
+;; Turn off the toolbar
+(tool-bar-mode -1)
+;;
+;; Turn off the menu bar
+(menu-bar-mode -1)
+;;
+;; Turn off the scrollbar
+(scroll-bar-mode -1)
+;}}}
+
+
+
+;{{{ Look & Feel
+;
+;; Default font
+;; - problematic with new frames, also set in Xdefaults:
+;; Emacs.font: -xos4-terminus-medium-r-normal-*-12-120-72-72-c-60-iso8859-2
+(set-default-font "-xos4-terminus-medium-r-normal-*-12-120-72-72-c-60-iso8859-2")
+
+
+;; Color theme initialization
+;; - http://emacswiki.org/cgi-bin/wiki/ColorTheme
+(require 'color-theme)
+(setq color-theme-is-global t)
+(color-theme-initialize)
+;;
+;; Load preferred theme
+;; - http://www.brockman.se/software/zenburn/zenburn.el
+(color-theme-zenburn)
+
+
+;; Don't show the welcome message
+(setq inhibit-startup-screen t)
+(setq initial-scratch-message nil)
+
+;; Shut off message buffer
+(setq message-log-max nil)
+(kill-buffer "*Messages*")
+
+;; Display time in the modeline
+;(display-time)
+;;
+;; Show column number in modeline
+(setq column-number-mode t)
+
+;; Modeline setup
+;; - somewhat cleaner than default
+(setq default-mode-line-format
+ '("-"
+ mode-line-mule-info
+ mode-line-modified
+ mode-line-frame-identification
+ mode-line-buffer-identification
+ " "
+ global-mode-string
+ " %[(" mode-name mode-line-process minor-mode-alist "%n"")%]--"
+ (line-number-mode "L%l--")
+ (column-number-mode "C%c--")
+ (-3 . "%p")
+ "-%-")
+)
+
+
+;; Syntax coloring (font-lock-mode)
+(global-font-lock-mode t)
+
+;; Always flash for parens and define a more distinctive color
+(show-paren-mode 1)
+(set-face-foreground 'show-paren-match-face "#bc8383")
+
+;; Answer y or n instead of yes or no at prompts
+(defalias 'yes-or-no-p 'y-or-n-p)
+
+;; Use ANSI colors within shell-mode
+(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)
+;}}}
+
+
+
+;{{{ General settings
+;
+;; Provide a useful error trace if loading .emacs fails
+(setq debug-on-error t)
+
+;; Encoding
+(prefer-coding-system 'utf-8)
+(set-language-environment 'UTF-8)
+(setq locale-coding-system 'utf-8)
+(set-terminal-coding-system 'utf-8)
+(set-keyboard-coding-system 'utf-8)
+(set-selection-coding-system 'utf-8)
+
+;; Spell checking
+(setq-default ispell-program-name "aspell")
+(setq-default ispell-dictionary "en_US")
+
+;; Default Web Browser
+(setq browse-url-browser-function 'browse-url-firefox)
+
+;; Show unfinished keystrokes early
+(setq echo-keystrokes 0.1)
+
+;; Ignore case on completion
+(setq completion-ignore-case t
+ read-file-name-completion-ignore-case t)
+
+
+;; Save after a certain amount of time.
+(setq auto-save-timeout 1800)
+;;
+;; Change backup behavior to save in a specified directory
+(setq backup-directory-alist '(("." . "~/.emacs.d/saves/"))
+ backup-by-copying t
+ version-control t
+ delete-old-versions t
+ kept-new-versions 6
+ kept-old-versions 2
+)
+
+;; Keep bookmarks in the load path
+(setq bookmark-default-file "~/.emacs.d/emacs-bookmarks")
+
+;; Keep abbreviations in the load path
+(setq abbrev-file-name "~/.emacs.d/emacs-abbrev-defs")
+
+
+;; Default major mode
+(setq default-major-mode 'text-mode)
+;;
+;; Wrap lines at 70, for txt mode or,
+(add-hook 'text-mode-hook 'turn-on-auto-fill)
+;(add-hook 'text-mode-hook 'longlines-mode)
+;; ...for all major modes
+;(setq-default auto-fill-function 'do-auto-fill)
+;;
+;; Text files end in new lines.
+(setq require-final-newline t)
+
+;; Narrowing enabled
+(put 'narrow-to-region 'disabled nil)
+
+
+;{{{ Mouse and cursor settings
+;
+;; Enable mouse scrolling
+(mouse-wheel-mode t)
+;;
+;; Fix mouse scrolling in GNU Screen
+(if window-system
+ (xterm-mouse-mode -1)
+ (xterm-mouse-mode 1)
+)
+
+;; Push the mouse out of the way on cursor approach
+(mouse-avoidance-mode 'jump)
+
+;; Stop cursor from blinking
+(blink-cursor-mode nil)
+
+;; Accelerate the cursor when scrolling
+(load "accel" t t)
+;;
+;; Start scrolling when 2 lines from top/bottom
+(setq scroll-margin 2)
+;;
+;; Fix the whole huge-jumps-scrolling-between-windows
+(setq scroll-conservatively 5)
+
+;; Cursor in same relative row and column during PgUP/DN
+(setq scroll-preserve-screen-position t)
+
+
+;; Always paste at the cursor
+(setq mouse-yank-at-point t)
+
+;; Kill (and paste) text from read-only buffers
+(setq kill-read-only-ok 1)
+
+;; Partially integrate the kill-ring and X cut-buffer
+'(x-select-enable-clipboard t)
+
+;; Copy/paste with accentuation intact
+(setq selection-coding-system 'compound-text-with-extensions)
+
+;; Delete selection on a key press
+(delete-selection-mode t)
+;}}}
+;}}}
+
+
+
+;{{{ Settings for various modes
+; - major modes for editing code and other formats are defined below
+;
+;; IDO (interactive buffer and file management)
+(require 'ido)
+(ido-mode t)
+(setq
+ ido-save-directory-list-file "~/.emacs.d/emacs-ido-last"
+ ;ido-work-directory-list '("~/" "~/Docs" "~/Work")
+ ido-ignore-buffers ; Ignore buffers:
+ '("\\` " "^\*Back" "^\*Compile-Log" ".*Completion" "^\*Ido")
+ ;ido-confirm-unique-completion t ; Wait for RET, even on unique
+ ido-everywhere t ; Enabled for various dialogs
+ ido-case-fold t ; Case-insensitive
+ ido-use-filename-at-point nil ; Don't use filename at point
+ ido-use-url-at-point nil ; Don't use url at point
+ ido-enable-flex-matching t ; More flexible
+ ido-max-prospects 6 ; Keep minibuffer clean
+)
+
+
+;; EasyPG assistant (GPG mode)
+(require 'epa)
+
+
+;; Tramp (remote files editing)
+(require 'tramp)
+(setq tramp-default-method "ssh")
+;; Disable version control to speed up things
+;(setq vc-handled-backends nil)
+
+
+;; SCPaste (scp pastebin)
+;; - http://www.emacswiki.org/cgi-bin/wiki/SCPaste
+(autoload 'scpaste "scpaste" "Paste the current buffer." t nil)
+
+
+;; Linum (line numbering)
+(require 'linum)
+;; - do not enable by default, breaks org-mode
+;(global-linum-mode)
+
+
+;; Folding
+;; - http://www.emacswiki.org/emacs/FoldIngo
+(require 'foldingo)
+
+
+;; Dired (directory management)
+(load "dired-x")
+(setq dired-dwim-target t)
+
+
+;; Ediff
+;;
+;; Don't spawn a new frame
+(setq ediff-window-setup-function 'ediff-setup-windows-plain)
+;;
+;; Split the frame horizontally
+;(setq ediff-split-window-function 'split-window-horizontally)
+
+
+;; Saveplace
+;; - places cursor in the last place you edited file
+(require 'saveplace)
+(setq-default save-place t)
+;; Keep places in the load path
+(setq save-place-file "~/.emacs.d/emacs-places")
+
+
+;; Icomplete
+;; - completion in the mini-buffer
+(icomplete-mode t)
+
+
+;; CUA mode
+;; - use C-c and C-v for copy and paste
+;(cua-mode t)
+;(setq cua-keep-region-after-copy t)
+
+
+;; Auto Compression
+;; - edit files in compressed archives (tar/jar/zip...)
+(auto-compression-mode 1)
+
+
+;; Speedbar settings
+(require 'speedbar)
+;;
+;; Additional extensions we are interested in
+(speedbar-add-supported-extension
+ '("PKGBUILD"
+ ".txt"
+ ".org"
+ ".pdf"
+ ".css"
+ ".php"
+ ".conf"
+ ".patch"
+ ".diff"
+ ".lua"
+ ".sh")
+)
+;}}}
+
+
+
+;{{{ Custom functions
+
+;{{{ Web search, browser defined earlier
+; - yubnub: a (social) commandline for the web
+;
+(defun aic-web-search ()
+ "Prompt for a web search query in the minibuffer."
+ (interactive)
+ (let ((search (read-from-minibuffer "Search: ")))
+ (browse-url (concat "http://www.yubnub.org/parser/parse?command=" search)))
+)
+;}}}
+
+;{{{ Timestamp function, for public config files
+; - date-stamp is more appropriate for txt files
+;
+(defun aic-dotfile-stamp ()
+ "Insert time stamp at point."
+ (interactive)
+ (insert "Updated on: " (format-time-string "%b %e, %H:%M:%S %Z %Y" nil nil))
+)
+(defun aic-txtfile-stamp ()
+ "Insert date at point."
+ (interactive)
+ (insert (format-time-string "%d.%m.%Y %H:%M"))
+)
+;}}}
+
+;{{{ Reload or edit .emacs on the fly
+; - key bindings defined below
+;
+(defun aic-reload-dot-emacs ()
+ "Reload user configuration from .emacs"
+ (interactive)
+ ;; Fails on killing the Messages buffer, workaround:
+ (get-buffer-create "*Messages*")
+ (load-file "~/.emacs")
+)
+(defun aic-edit-dot-emacs ()
+ "Edit user configuration in .emacs"
+ (interactive)
+ (find-file "~/.emacs")
+)
+;}}}
+
+;{{{ Quick access to ansi-term
+; - key binding defined below
+;
+(defun aic-visit-ansi-term ()
+ "If we are in an *ansi-term*, rename it.
+If *ansi-term* is running, switch the buffer.
+If there is no *ansi-term*, run it."
+ (interactive)
+ (if (equal "*ansi-term*" (buffer-name))
+ (call-interactively 'rename-buffer)
+ (if (get-buffer "*ansi-term*")
+ (switch-to-buffer "*ansi-term*")
+ (ansi-term "/bin/zsh")))
+)
+;}}}
+
+;{{{ Quick acces to coding functions
+; - I deal with utf8, latin-2 and cp1250
+;
+(defun aic-recode-buffer ()
+ "Define the coding system for a file."
+ (interactive)
+ (call-interactively 'set-buffer-file-coding-system)
+)
+(defun aic-encode-buffer ()
+ "Revisit the buffer with another coding system."
+ (interactive)
+ (call-interactively 'revert-buffer-with-coding-system)
+)
+;}}}
+
+;{{{ Kill all buffers except scratch
+;
+(defun aic-nuke-all-buffers ()
+ "Kill all buffers, leaving *scratch* only."
+ (interactive)
+ (mapcar (lambda (x) (kill-buffer x)) (buffer-list))
+ (delete-other-windows)
+)
+;}}}
+
+;{{{ Quick access to OrgMode and the OrgMode agenda
+; - org-mode configuration defined below
+;
+(defun aic-org-index ()
+ "Show the main org file."
+ (interactive)
+ (find-file "~/.org/index.org")
+)
+(defun aic-org-agenda ()
+ "Show the org-mode agenda."
+ (interactive)
+ ;; To be used with a keybinding (see below)
+ (call-interactively 'org-agenda-list)
+)
+;}}}
+
+;{{{ Alias some custom functions
+;
+(defalias 'search-web 'aic-web-search)
+(defalias 'stamp 'aic-dotfile-stamp)
+(defalias 'date-stamp 'aic-txtfile-stamp)
+(defalias 'recode-buffer 'aic-recode-buffer)
+(defalias 'encode-buffer 'aic-encode-buffer)
+(defalias 'nuke 'aic-nuke-all-buffers)
+(defalias 'org 'aic-org-index)
+;}}}
+
+;{{{ Shortcut a few commonly used functions
+;
+(defalias 'cr 'comment-region)
+(defalias 'ucr 'uncomment-region)
+(defalias 'eb 'eval-buffer)
+(defalias 'er 'eval-region)
+(defalias 'ee 'eval-expression)
+(defalias 'day 'color-theme-vim-colors)
+(defalias 'night 'color-theme-zenburn)
+(defalias 'fold 'fold-enter-fold-mode-close-all-folds)
+;}}}
+;}}}
+
+
+
+;{{{ Key bindings
+; - with switched Caps_Lock and Control_L keys system wide
+
+;{{{ Main bindings
+;
+;; M-x without Alt
+(global-set-key "\C-x\C-m" 'execute-extended-command)
+(global-set-key "\C-c\C-m" 'execute-extended-command)
+
+;; C-w to backward kill for compatibility (and ease of use)
+(global-set-key "\C-w" 'backward-kill-word)
+;; ...and then provide alternative for cutting
+(global-set-key "\C-x\C-k" 'kill-region)
+(global-set-key "\C-c\C-k" 'kill-region)
+
+;; Change C-x C-b behavior (buffer management)
+;(global-set-key "\C-x\C-b" 'bs-show)
+;(global-set-key "\C-x\C-b" 'ibuffer)
+(global-set-key "\C-x\C-b" 'electric-buffer-list)
+
+;; Alternative to C-x o, as in Mozilla
+(global-set-key [(control tab)] 'other-window)
+
+;; Reload or edit .emacs as defined above
+(global-set-key "\C-c\C-r" 'aic-reload-dot-emacs)
+(global-set-key "\C-c\C-e" 'aic-edit-dot-emacs)
+
+;; Toggle soft word wrapping
+(global-set-key "\C-cw" 'toggle-truncate-lines)
+
+;; Quick access to the speedbar
+(global-set-key "\C-cs" 'speedbar-get-focus)
+
+;; org-mode bindings for quick access (see below)
+(global-set-key "\C-cl" 'org-store-link)
+(global-set-key "\C-ca" 'org-agenda)
+(global-set-key "\C-cr" 'org-remember)
+
+;; Quicker access to go-to line
+(global-set-key (kbd "M-g") 'goto-line)
+
+;; Menu bar toggle, as in my vimperator setup
+(global-set-key (kbd "<M-down>") 'menu-bar-mode)
+
+;; Jump to the start/end of the document with C-PgUP/DN
+(global-set-key [C-prior] (lambda()(interactive)(goto-char (point-min))))
+(global-set-key [C-next] (lambda()(interactive)(goto-char (point-max))))
+
+;; Avoid accidental scrolling
+(global-set-key (kbd "<Scroll_Lock>") '(lambda () (interactive) nil))
+
+;; Disable C-z on X11 sessions
+(when window-system
+ (global-unset-key "\C-z")
+)
+
+;; Require C-x C-c prompt. So you can't shut it off by accident
+(global-set-key [(control x) (control c)]
+ (function
+ (lambda () (interactive)
+ (cond ((y-or-n-p "Quit? ")
+ (save-buffers-kill-emacs)))))
+)
+;}}}
+
+;{{{ Fn bindings
+;
+;; Invoke manual for word under the cursor
+(global-set-key [f1] (lambda () (interactive) (manual-entry (current-word))))
+(global-set-key [f2] (lambda () (interactive) (find-file "~/.org/notes.org")))
+(global-set-key [f3] 'aic-org-agenda) ; Function defined previously
+(global-set-key [f4] 'aic-visit-ansi-term) ; Function defined previously
+;(global-set-key [f5] 'aic-fold-toggle-fold) ; Todo: Toggle all folds
+(global-set-key [f6] 'linum-mode) ; Toggle line numbering
+(global-set-key [f7] 'htmlize-buffer)
+(global-set-key [f8] 'ispell-buffer)
+(global-set-key [f9] 'ispell-change-dictionary) ; Switching 'en_US' and 'hr' often
+;(global-set-key [f10] ; Quick menu by default
+(global-set-key [f11] 'speedbar)
+(global-set-key [f12] 'kill-buffer)
+;}}}
+;}}}
+
+
+;{{{ OrgMode
+; - http://www.emacswiki.org/emacs/OrgMode
+;
+;; Initialization
+(add-to-list 'load-path "~/.emacs.d/org/lisp")
+(require 'org-install)
+;;
+;; Extended mouse functionality
+(load "~/.emacs.d/org/lisp/org-mouse.el")
+
+;; Settings
+(setq org-directory "~/.org/")
+(add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
+;; Misc
+(setq org-log-done t)
+(setq org-completion-use-ido t)
+(setq org-return-follows-link t)
+(add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))
+
+;; Pass mailto links to Alpine instead of browse-url
+(setq org-link-mailto-program
+ '(shell-command "urxvt -title Alpine -e alpine -url 'mailto:%a?Subject=%s'")
+)
+
+;; Files that are included in org-mode agenda
+(setq org-agenda-files
+ (list "~/.org/index.org" "~/.org/work.org" "~/.org/personal.org" "~/.org/computers.org")
+)
+
+;; Finally, connect org-mode with remember
+(org-remember-insinuate)
+;}}}
+
+
+
+;{{{ Remember mode
+; - connected with org-mode
+;
+;; Initialization
+(require 'remember)
+
+;; Notes file
+(setq org-default-notes-file (concat org-directory "/notes.org"))
+;
+;; Templates for Notes
+(setq org-remember-templates
+ '(("Note" ?n "* NOTE %?\n%i\n%a" "~/.org/notes.org" "Notes")
+ ("Download" ?d "* DL %?\n%i\n%a" "~/.org/notes.org" "Download")
+ ("Login" ?l "* LOGIN %?\n%i\n%a" "~/.org/notes.org" "Logins")
+ ("Music" ?m "* MUSIC %?\n%i\n%a" "~/.org/notes.org" "Music")
+ ("Idea" ?i "* %^{Title}\n%i\n%a" "~/.org/notes.org" "Brainstorm")
+ ("Clipboard" ?c "* %^{Description} %T\n%x" "~/.org/notes.org" "Clipboard"))
+)
+
+;; Remember frames
+;; - capture a note from any desktop/tag with a small emacs frame
+;; - call: emacsclient -e '(make-remember-frame)'
+;;
+;; Org-remember splits windows, force it to a single window
+(add-hook 'remember-mode-hook 'delete-other-windows)
+
+;; Automatic closing of remember frames
+(defadvice remember-finalize (after delete-remember-frame activate)
+ "Advise remember-finalize to close the frame if it is the remember frame"
+ (if (equal "*Remember*" (frame-parameter nil 'name))
+ (delete-frame))
+)
+(defadvice remember-destroy (after delete-remember-frame activate)
+ "Advise remember-destroy to close the frame if it is the remember frame"
+ (if (equal "*Remember*" (frame-parameter nil 'name))
+ (delete-frame))
+)
+
+;; Initialization of remember frames
+(defun make-remember-frame ()
+ "Create a new frame and run org-remember"
+ (interactive)
+ (make-frame '((name . "*Remember*") (width . 80) (height . 10)))
+ (select-frame-by-name "*Remember*")
+ (org-remember)
+)
+;}}}
+
+
+
+;{{{ Calendar settings
+; - for me only important in the context of org-mode
+;
+(setq
+ holidays-in-diary-buffer t
+ mark-holidays-in-calendar t
+ all-christian-calendar-holidays t
+ all-islamic-calendar-holidays nil
+ all-hebrew-calendar-holidays nil
+ european-calendar-style t
+ ;display-time-24hr-format t
+ display-time-day-and-date nil
+ ;display-time-format nil
+ ;display-time-use-mail-icon nil
+ calendar-latitude 45.21
+ calendar-longitude 14.26
+ calendar-location-name "Rijeka, Croatia"
+)
+;}}}
+
+
+
+;{{{ Major modes for editing code and other formats
+
+;{{{ Custom modes for some custom files
+;
+;; Shell script mode for Arch PKGBUILDs
+(setq auto-mode-alist (cons '("\\PKGBUILD$" . sh-mode) auto-mode-alist))
+;;
+;; Conf mode for personal config files
+(when (locate-library "conf-mode")
+ (autoload 'conf-mode "conf-mode" "Major-mode for editing config files." t)
+ (add-to-list 'auto-mode-alist '("\\awesomerc$" . conf-mode))
+ (add-to-list 'auto-mode-alist '("\\gitconfig$" . conf-mode))
+ (add-to-list 'auto-mode-alist '("\\pinerc$" . conf-mode))
+ (add-to-list 'auto-mode-alist '("\\screenrc$" . conf-mode))
+)
+;}}}
+
+;{{{ Python mode
+; - switched from sf.net py-mode to python-mode distributed with Emacs
+;
+;; ipython is my shell of choice, glad to have it here
+(defcustom python-python-command "ipython -cl"
+ "Shell command to run Python interpreter."
+ :group 'python
+ :type 'string
+)
+;}}}
+
+;{{{ PHP mode
+; - http://www.ontosys.com/src/php-mode.el
+;
+(autoload 'php-mode "php-mode" "PHP editing mode" t)
+(add-to-list 'auto-mode-alist '("\\.php\\'" . php-mode))
+;}}}
+
+;{{{ Fvwm mode
+; - http://www.lair.be/projects_fvwm-mode.php
+;
+(setq fvwm-fvwmcommand-path "/usr/bin/FvwmCommand")
+(require 'fvwm-mode)
+(autoload 'fvwm-mode "fvwm-mode" "Mode for editing fvwm files" t)
+(add-to-list 'auto-mode-alist '("\\.fvwm2rc$\\|\\.fvwmrc$" . fvwm-mode))
+;}}}
+
+;{{{ Lua mode
+; - http://lua-mode.luaforge.net/
+;
+(autoload 'lua-mode "lua-mode" "Major-mode for editing lua scripts." t)
+(setq auto-mode-alist (cons '("\\.lua$" . lua-mode) auto-mode-alist))
+;}}}
+
+;{{{ Crontab mode
+; - http://www.mahalito.net/~harley/elisp/crontab-mode.el
+;
+(autoload 'crontab-mode "~/.emacs.d/crontab-mode.el" "Major mode for editing the crontab" t)
+(add-to-list 'auto-mode-alist '("cron\\(tab\\)?\\." . crontab-mode))
+;}}}
+
+;{{{ Post mode
+; - http://post-mode.sourceforge.net/
+;
+(autoload 'post-mode "~/.emacs.d/post.el" "Major mode for editing e-mail and journal articles" t)
+(add-to-list 'auto-mode-alist
+ '("\\.*mutt-*\\|\\.*pico.*\\|.article\\|\\.*200\\(T\\)?\\|\\.followup" . post-mode))
+;}}}
+
+;{{{ Undoc mode
+; - http://www.ccs.neu.edu/home/guttman/undoc.el
+;
+(autoload 'undoc "~/.emacs.d/undoc.el" "A minor mode which kills MS Word files dead." t)
+(autoload 'undoc-current-buffer "undoc" "" t)
+(autoload 'undoc-region-after-mime-decode "undoc" "" t)
+;}}}
+
+;{{{ Htmlize mode
+; - http://www.emacswiki.org/emacs/Htmlize
+;
+(load "~/.emacs.d/htmlize.el")
+(setq htmlize-convert-nonascii-to-entities nil)
+(setq htmlize-html-charset "utf-8")
+;}}}
+;}}}
+
+
+
+;{{{ Custom
+;
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+)
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ )
+;}}}