;;; hyperbole.el --- GNU Hyperbole: The Everyday Hypertextual Information Manager ;; Copyright (C) 1992-2019 Free Software Foundation, Inc. ;; Author: Bob Weiner ;; Maintainer: Bob Weiner , Mats Lidell ;; Created: 06-Oct-92 at 11:52:51 ;; Released: 21-Jan-19 ;; Version: 7.0.3 ;; Keywords: comm, convenience, files, frames, hypermedia, languages, mail, matching, mouse, multimedia, outlines, tools, wp ;; Package: hyperbole ;; Package-Requires: ((emacs "24.4")) ;; URL: http://www.gnu.org/software/hyperbole ;; See the "HY-COPY" file for license information. ;; This file is part of GNU Hyperbole. ;;; Commentary: ;; ;; GNU Hyperbole (pronounced Ga-new Hi-per-bo-lee), or just Hyperbole, is an ;; easy-to-use, yet powerful and programmable hypertextual information ;; management system implemented as a GNU Emacs package. It offers rapid views ;; and interlinking of all kinds of textual information, utilizing Emacs for ;; editing. It can dramatically increase your productivity and greatly reduce ;; the number of keyboard/mouse keys you'll need to work efficiently. ;; ;; Hyperbole lets you: ;; ;; 1. Quickly create hyperlink buttons either from the keyboard or by dragging ;; between a source and destination window with a mouse button depressed. ;; Later activate buttons by pressing/clicking on them or by giving the name of ;; the button. ;; ;; 2. Activate many kinds of `implicit buttons' recognized by context within ;; text buffers, e.g. URLs, grep output lines, and git commits. A single key ;; or mouse button automatically does the right thing in dozens of contexts; ;; just press and go. ;; ;; 3. Build outlines with multi-level numbered outline nodes, e.g. 1.4.8.6, ;; that all renumber automatically as any node or tree is moved in the ;; outline. Each node also has a permanent hyperlink anchor that you can ;; reference from any other node; ;; ;; 4. Manage all your contacts quickly with hierarchical categories and embed ;; hyperlinks within each entry. Or create an archive of documents with ;; hierarchical entries and use the same search mechanism to quickly find any ;; matching entry; ;; ;; 5. Use single keys to easily manage your Emacs windows or frames and quickly ;; retrieve saved window and frame configurations; ;; ;; 6. Search for things in your current buffers, in a directory tree or across ;; major web search engines with the touch of a few keys. ;; ;; The common thread in all these features is making retrieval, management and ;; display of information fast and easy. That is Hyperbole's purpose. ;; ;; ---- ;; ;; See the "INSTALL" file for installation instructions and the "README" file ;; for general information. ;; ;; There is no need to manually edit this file unless there are specific ;; customizations you would like to make, such as whether a Hyperbole Action ;; Mouse Key is bound to the middle mouse button. (See the call of the ;; function, `hmouse-install', below). ;; ;; Other site-specific customizations belong in "hsettings.el". ;;; Code: ;;; ************************************************************************ ;;; Start Initializations ;;; ************************************************************************ (defconst hyperbole-loading t "Temporary constant available for testing while Hyperbole is loading.") ;; Ensure defgroup and defcustom are defined for use throughout Hyperbole. (require 'custom) (defgroup hyperbole nil "Hyperbole customizations category." :group 'applications) (defgroup hyperbole-buttons nil "Hyperbole explicit, global and implicit button customizations." :group 'hyperbole) (defgroup hyperbole-commands nil "Hyperbole command customizations." :group 'hyperbole) (defgroup hyperbole-keys nil "Hyperbole keyboard and mouse key customizations." :group 'hyperbole) ;; defgroup hyperbole-rolo is in "hyrolo.el". (defgroup hyperbole-screen nil "Hyperbole screen/display customizations, typically frame or window-related." :group 'hyperbole) ;; Reinitialize hyperb:dir on reload if initialization failed for any reason. (eval-and-compile (when (and (boundp 'hyperb:dir) (null hyperb:dir)) (makunbound 'hyperb:dir) (setq features (delq 'hload-path features) features (delq 'hversion features))) ;; Defines hyperb:path-being-loaded, hyperb:stack-frame, ;; (hyperb:window-system) and hyperb:dir, which are used later in ;; this file. Also adds Hyperbole to the load-path if need be. ;; ;; This handles the case when the Hyperbole package directory is not yet in load-path. (unless (or (require 'hversion nil t) (and (stringp load-file-name) (require 'hversion (expand-file-name "hversion" (file-name-directory load-file-name)) t))) (error "(Hyperbole): Startup failure: `hyperb:dir' must be manually added to `load-path' to fix."))) ;; This must be defined before the defcustom `inhbit-hyperbole-messaging'. ;;;###autoload (defun hyperbole-toggle-messaging (&optional arg) "Toggle Hyperbole support for explicit buttons in mail and news buffers. Toggles the boolean variable `inhibit-hyperbole-messaging’ and either adds hooks (nil value) or removes them (t value). With optional prefix ARG > 0, enables support. If ARG <= 0, disables/inhibits support." (interactive "P") (setq inhibit-hyperbole-messaging (if (null arg) (not inhibit-hyperbole-messaging) (<= (prefix-numeric-value arg) 0))) (if inhibit-hyperbole-messaging (var:remove-all) (var:append-all) ;; Add any hooks that were skipped when inhibit-hyperbole-messaging ;; was nil. (cond ((boundp 'hyperbole-loading)) ((not after-init-time) (add-hook 'after-init-hook (lambda () (load "hyperbole")))) (t (load "hyperbole")))) (if (called-interactively-p 'interactive) (message "Hyperbole messaging button support is %s" (if inhibit-hyperbole-messaging "disabled" "enabled")))) (defgroup hyperbole-koutliner nil "Hyperbole multi-level autonumbered outliner customizations." :group 'hyperbole) ;;; ************************************************************************ ;;; Other required Elisp libraries ;;; ************************************************************************ ;; Avoid any potential library name conflict by giving the load directory. (require 'set (expand-file-name "set" hyperb:dir)) (require 'hui-select) ;; This requires 'hvar which defines the var:append function. ;;; ************************************************************************ ;;; Public Variables ;;; ************************************************************************ (defcustom hkey-init t "*A non-nil value (default) at system load time binds the Action and Assist Keyboard Keys, as well as other keys. {\\[hkey-either]} invokes the Action Key and {C-u \\[hkey-either]} invokes the Assist Key. Additionally, {\\[hkey-help]} shows what the Action Key will do in the current context (wherever point is). {C-u \\[hkey-help]} shows what the Assist Key will do." :type 'boolean :group 'hyperbole-keys) (defcustom hkey-init-override-local-keys t "*If set together with `hkey-init', remove any local key bindings that hide the Hyperbole Smart Keys." :type 'boolean :group 'hyperbole-keys) ;;; ************************************************************************ ;;; Public key bindings ;;; ************************************************************************ ;; ;; Hyperbole key binding for many read-only modes. Set to nil if unwanted. ;; No longer used; use regular Action Key instead. ;;(defvar action-key-read-only "\C-m" ;; "Local Action Key binding for special read-only modes. Set to nil if unwanted.") (defvar hkey-bindings nil "List of global key sequences bound by Hyperbole. See `hkey-binding-entry' for format.") (defvar hkey-bindings-flag nil "True if Hyperbole key bindings are in use, else nil.") (defvar hkey-previous-bindings nil "List of global key sequences and their pre-Hyperbole bindings that Hyperbole has overridden. See `hkey-binding-entry' for format.") (defun hkey-binding-entry (key) "Given an Emacs KEY that may be bound, returns an entry to save the associated binding. Entry format is: (key-description key-sequence key-binding)." (list (key-description key) key (key-binding key))) (defun hkey-bindings-keys (entries) (mapcar #'cadr entries)) (defun hkey-get-bindings () "Returns a list of entries for storage of Hyperbole key bindings. `hkey-initialize' must have already been called or the list will be empty." (mapcar (lambda (key) (hkey-binding-entry key)) (hkey-bindings-keys hkey-previous-bindings))) (defun hkey-global-set-key (key command &optional no-add) (or no-add (add-to-list 'hkey-previous-bindings (hkey-binding-entry key))) (global-set-key key command)) (defun hkey-initialize () "If `hkey-init' is non-nil, initialize Hyperbole key bindings." (when hkey-init ;; ;; Binds the Action Key to {M-RET} and the Assist Key to {C-u M-RET} ;; and loads the Hyperbole mouse key bindings. (unless (where-is-internal 'hkey-either) (hkey-global-set-key "\M-\C-m" 'hkey-either)) ;; ;; Bind a key, {C-h A}, for Action Key help and {C-u C-h A} for Assist key ;; help. (or (where-is-internal 'hkey-help) (hkey-global-set-key "\C-hA" 'hkey-help)) ;; ;; Setup so Hyperbole menus can be accessed from a key. If not ;; already bound to a key, binds the function `hyperbole' to {C-h h}. (or (where-is-internal 'hyperbole) ;; In GNU Emacs, this binding replaces a command that shows ;; the word hello in foreign languages; this binding makes this ;; key much more useful. (hkey-global-set-key "\C-hh" 'hyperbole)) ;; ;; Provides a site standard way of emulating most Hyperbole mouse drag ;; commands from the keyboard. This is most useful for rapidly creating ;; Hyperbole link buttons from the keyboard without invoking the Hyperbole ;; menu. Only works if Hyperbole is run under a window system. (when (hyperb:window-system) (if (eq (global-key-binding "\M-o") 'facemenu-keymap) ;; Override facemenu package that adds a keymap on M-o, ;; since this binding is more important to Hyperbole ;; users. (hkey-global-set-key "\M-o" 'hkey-operate) (hkey-maybe-global-set-key "\M-o" 'hkey-operate))) ;; ;; Binds {C-c @} to created a user-specified sized grid of windows ;; displaying different buffers. ;; ;; Don't override local bindings of this key. (hkey-maybe-global-set-key "\C-c@" 'hycontrol-windows-grid t) ;; ;; Binds {C-c C-r} as a site standard way of performing explicit ;; button renames without invoking the Hyperbole menu. ;; ;; Don't override local bindings of this key. (hkey-maybe-global-set-key "\C-c\C-r" 'hui:ebut-rename t) ;; ;; Binds {C-c RET} to select larger and larger synctactical units in a ;; buffer when invoked repeatedly, showing in the minibuffer the type ;; of unit selected each time. (hkey-maybe-global-set-key "\C-c\C-m" 'hui-select-thing) ;; ;; Binds {C-c \} to interactively manage windows and frames. (hkey-maybe-global-set-key "\C-c\\" 'hycontrol-enable-windows-mode) ;; ;; Binds {C-c /} to display the Hyperbole Find/Web search menu. (hkey-maybe-global-set-key "\C-c/" 'hui-search-web) ;; ;; Binds {C-c .} to jump between the start and end of an delimited thing. ;; Don't override local bindings of this key. (hkey-maybe-global-set-key "\C-c." 'hui-select-goto-matching-delimiter t) ;; ;; This initializes the Smart Mouse Key bindings. Shifted mouse buttons ;; are always set up. Under InfoDock or with `hmouse-middle-flag' ;; non-nil, this also binds the middle mouse button to the Action Key. ;; These bindings are ignored if a particular frame does not have mouse ;; support. (hmouse-install hmouse-middle-flag) ;; ;; This makes a double or triple click of the left mouse button do the ;; same thing as {C-c RET}. It also sets up Java, C++ and HTML modes ;; for proper entity selection. (hui-select-initialize) ;; ;; Store Hyperbole key bindings so can turn them on and off. (setq hkey-bindings (hkey-get-bindings) hkey-bindings-flag t) )) (defun hkey-maybe-global-set-key (key command &optional no-add) "Globally set KEY to COMMAND if KEY is unbound and COMMAND is not on any global key. With third argument NO-ADD non-nil, skip storage of prior KEY binding which prevents automatic removal of any local bindings to the same key." (or (global-key-binding key) (where-is-internal command) (hkey-global-set-key key command no-add))) (defun hkey-set-bindings (key-binding-list) "Set keys bound by Hyperbole to those in KEY-BINDING-LIST. KEY-BINDING-LIST is the value of either `hkey-previous-bindings' \(key bindings prior to Hyperbole load) or `hkey-bindings' (Hyperbole bindings after load)." (dolist (key-and-binding key-binding-list) (global-set-key (cadr key-and-binding) (car (cddr key-and-binding))))) (defun hyperbole-toggle-bindings () "Toggles between Hyperbole mouse and keyboard keys and their prior bindings." (interactive) (let ((key-binding-list (if hkey-bindings-flag hkey-previous-bindings hkey-bindings)) (other-bindings-var (if hkey-bindings-flag 'hkey-bindings 'hkey-previous-bindings))) (if key-binding-list (progn (set other-bindings-var (hkey-get-bindings)) (hkey-set-bindings key-binding-list) (setq hkey-bindings-flag (not hkey-bindings-flag) hmouse-bindings-flag (not hmouse-bindings-flag)) (if (called-interactively-p 'interactive) (message "%s mouse and keyboard bindings are now in use." (if hkey-bindings-flag "Hyperbole" "Non-Hyperbole")))) (error "(hyperbole-toggle-bindings): `%s' is empty." (if hkey-bindings-flag 'hkey-previous-bindings 'hkey-bindings))))) ;;; ************************************************************************ ;;; Load Hyperbole mouse bindings ;;; ************************************************************************ ;; From mouse-position.c in Emacs: ;; f = SELECTED_FRAME (); ;; XSETFRAME (lispy_dummy, f); ;; ;; It seems like the XSETFRAME macro is not properly copying the value of f on initial frame selection under the macOS window system. ;; The problem occurs on other systems as well, e.g. Emacs 25.2 under Windows 7. ;; ;; Hyperbole resolves this problem by setting the ;; `mouse-position-function' variable below to properly set the ;; newly selected frame. (if (boundp 'mouse-position-function) (setq mouse-position-function (lambda (frame-x-dot-y) "Make `mouse-position' and `mouse-pixel-position' always return the selected frame. Under macOS and Windows 7 at least, upon initial selection of a new frame, those functions by default still return the prior frame." (if (consp frame-x-dot-y) (setcar frame-x-dot-y (selected-frame))) frame-x-dot-y))) ;; hmouse-drv will load hui-mouse and hmouse-key (mapc #'require '(hsettings hmouse-drv hmouse-sh)) ;;; ************************************************************************ ;;; You shouldn't need to modify anything below here. ;;; ************************************************************************ ;; Add Hyperbole Info directory to Info-directory-list after the Info ;; manual reader package is loaded. (eval-after-load "info" '(when (boundp 'hyperb:dir) (info-initialize) (let ((info-dir (expand-file-name "man/" hyperb:dir))) (if (file-exists-p info-dir) (add-to-list 'Info-directory-list info-dir))))) ;;; ************************************************************************ ;;; Prevent local key maps from hiding/overriding the Action and Assist Keys ;;; ************************************************************************ ;; (defun hkey-read-only-bindings () ;; "Binds Action and Assist Key functions in many read-only modes to the key sequence value of `action-key-read-only'. ;; Does nothing if this variable is nil." ;; (and action-key-read-only ;; (mapcar ;; (lambda (keymap-sym) ;; (if (and (boundp keymap-sym) (keymapp keymap-sym)) ;; (define-key (symbol-value keymap-sym) action-key-read-only #'action-key))) ;; '(Buffer-menu-mode-map calendar-mode-map dired-mode-map gnus-group-mode-map ;; gnus-summary-mode-map Info-mode-map oo-browse-mode-map rmail-mode-map ;; rmail-summary-mode-map unix-apropos-map)))) ;; ;; Overriding of local key bindings that interfere with global ;; bindings from Hyperbole. See `hyperb:init' for the hook that calls ;; these functions. ;; (defun hkey-override-local-bindings () "If `hkey-init-override-local-keys' and `hkey-init' are t, override a local key binding that hides the global Hyperbole Smart Keys, by removing it." (interactive) (when hkey-init ;; Do read-only bindings here, even though this will run ;; many times, since each key map exists only after ;; its major mode is first used or loaded. ;; (hkey-read-only-bindings) (if hkey-init-override-local-keys (let (hkey binding) (mapc (lambda (descrip-key-cmd) (and (setq hkey (cadr descrip-key-cmd)) ;; To see the key name, use: (key-description hkey) (setq binding (local-key-binding hkey)) ;; A number indicates an invalid key prefix, so ;; there is not actually a local binding for ;; this key sequence. (not (numberp binding)) (local-unset-key hkey))) hkey-previous-bindings))))) (defun hkey-install-override-local-bindings () ;; Run after any major-mode change within any buffer. (add-hook 'change-major-mode-after-body-hook #'hkey-override-local-bindings) ;; Need to override bindings in any buffers that exist already if ;; overriding is enabled. (and hkey-init hkey-init-override-local-keys (mapc (lambda (buf) (with-current-buffer buf (hkey-override-local-bindings))) (buffer-list)))) (defun hkey-toggle-override-local-bindings (&optional arg) "Toggle whether conflicting local key bindings are overridden by Hyperbole. With optional ARG, override them iff ARG is positive." (interactive "P") (if (or (and arg (<= (prefix-numeric-value arg) 0)) (and (not (and arg (> (prefix-numeric-value arg) 0))) hkey-init-override-local-keys)) (progn (setq hkey-init-override-local-keys nil) (message "Local key bindings that conflict with Hyperbole will be left in place.")) (setq hkey-init-override-local-keys t) (message "Local key bindings that conflict with Hyperbole will be removed."))) ;;; ************************************************************************ ;;; Display Hooks ;;; ************************************************************************ ;; Permits restore of the prior window configuration after any help buffer ;; is shown by pressing either the Action or Assist Key at the end of the ;; help buffer. (Help buffer names end with "Help*".) Only one of ;; these two settings is used, dependent on emacs version. ;; (add-hook 'temp-buffer-show-hook #'hkey-help-show) (setq temp-buffer-show-function #'hkey-help-show) ;;; ************************************************************************ ;;; Autoloads ;;; ************************************************************************ ;; Koutliner autoloads in the kotl/ subdirectory are generated by 'make pkg'. ;; This next line ensures they are loaded by hyperbole-autoloads whenever ;; the Hyperbole package is activated in an Emacs session. ;;;###autoload (load "kotl/kotl-autoloads" nil 'nowarn) ;; This is needed so that the autoloads from "kotl/kotl-autoloads" refer to ;; files found in `load-path'. Otherwise `M-x kotl-mode' fails right after ;; starting Emacs. ;;;###autoload (add-to-list 'load-path (expand-file-name "kotl/" ;;;###autoload (file-name-directory load-file-name))) ;; Before the 6.0.1 release, Hyperbole used to patch the package-generate-autoloads ;; function to ensure that kotl/ subdirectories were autoloaded. This ;; is no longer used but is left here temporarily for reference. ;; ;; Ensure Koutliner autoloads in kotl/ subdirectory are generated and loaded. ;; (unless (or (fboundp 'kotl-mode) ;; (and (load "hyperbole-autoloads" t t) ;; (fboundp 'kotl-mode))) ;; (defun hyperb:package-autoloads-subdirectories-p () ;; (require 'package) ;; (let ((func (symbol-function 'package-generate-autoloads))) ;; ;; If this function contains a call to apply, then it is patched ;; ;; with support for finding autoloads in subdirectories and ;; ;; nothing more need be done. ;; (if (byte-code-function-p func) ;; (delq nil (mapcar (lambda (item) (eq item 'apply)) (aref func 2))) ;; (string-match "(apply " (prin1-to-string func))))) ;; (unless (hyperb:package-autoloads-subdirectories-p) ;; ;; Function is not patched, so define it here, call it, and then load ;; ;; the generated autoloads. This will happen maximally only once ;; ;; per installation of a Hyperbole release. ;; (if (not (file-writable-p (expand-file-name "hyperbole-autoloads.el" hyperb:dir))) ;; (error "(Hyperbole): Failure loading, need write permission to \"%s\"" hyperb:dir)) ;; (defun package-generate-autoloads (name pkg-dir) ;; (let* ((auto-name (format "%s-autoloads.el" name)) ;; (generated-autoload-file (expand-file-name auto-name pkg-dir)) ;; ;; Silence `autoload-generate-file-autoloads'. ;; (noninteractive t) ;; (backup-inhibited t) ;; (version-control 'never)) ;; (package-autoload-ensure-default-file generated-autoload-file) ;; (apply #'update-directory-autoloads pkg-dir ;; (delq nil (mapcar (lambda (f) (and (file-directory-p f) ;; (not (file-symlink-p f)) ;; f)) ;; (directory-files pkg-dir t "[a-zA-Z].*" nil)))) ;; (let ((buf (find-buffer-visiting generated-autoload-file))) ;; (when buf (kill-buffer buf))) ;; auto-name)) ;; (package-generate-autoloads "hyperbole" hyperb:dir)) ;; (load "hyperbole-autoloads")) ;; Menu items could call this function before Info is loaded. (autoload 'Info-goto-node "info" "Jump to specific Info node." t) ;;; Hyperbole user interface entry points that trigger loading of the ;;; full Hyperbole system. These are left commented here for ;;; reference in case we ever go back to autoloading Hyperbole rather ;;; than initializing it fully in this file. ;; ;; Action type definitions. ;; (autoload 'defact "hyperbole" ;; "Creates an action TYPE (an unquoted symbol) with PARAMS, described by DOC." ;; nil 'macro) ;; ;; Implicit button type definitions. ;; (autoload 'defib "hyperbole" ;; "Creates implicit button TYPE (unquoted sym) with PARAMS, described by DOC." ;; nil 'macro) ;; (autoload 'ebut:map "hyperbole" "Map over the Hyperbole explicit buttons in a buffer." nil) ;; (autoload 'hbut:key-src "hyperbole" "Called by {e} command in rolo match buffer.") ;; (autoload 'hui:ebut-rename "hyperbole" "Rename a Hyperbole button." t) ;; (autoload 'hyperbole "hyperbole" "Hyperbole info manager menus." t) ;; (autoload 'action-key "hyperbole" ;; "Context-sensitive Action Key command." t) ;; (autoload 'action-key-depress "hyperbole" "Depress context-sensitive Action Key." t) ;; (autoload 'assist-key-depress "hyperbole" "Depress context-sensitive Assist Key." t) ;; (autoload 'action-key-depress-emacs "hyperbole" "Depress context-sensitive Action Key." t) ;; (autoload 'assist-key-depress-emacs "hyperbole" "Depress context-sensitive Assist Key." t) ;; (autoload 'action-mouse-key-emacs "hyperbole" "Execute context-sensitive Action Key." t) ;; (autoload 'assist-mouse-key-emacs "hyperbole" "Execute context-sensitive Assist Key." t) ;; (autoload 'hkey-help "hyperbole" ;; "Display help for the Action Key command in current context. ;; With optional ASSIST-FLAG non-nil, display help for the Assist Key command. ;; Returns non-nil iff associated help documentation is found." t) ;; (autoload 'hkey-assist-help "hyperbole" ;; "Display help for the Assist Key command in current context." t) ;; (autoload 'hkey-help-hide "hyperbole" ;; "Restores frame to configuration prior to help buffer display." nil) ;; (autoload 'hkey-help-show "hyperbole" ;; "Saves prior frame configuration if BUFFER displays help." nil) ;; (autoload 'assist-key "hyperbole" ;; "Context-sensitive Assist Key command." t) ;; (autoload 'action-mouse-key "hyperbole" ;; "Context-sensitive Action Mouse Key command." t) ;; (autoload 'assist-mouse-key "hyperbole" ;; "Context-sensitive Assist Mouse Key command." t) ;; (autoload 'hkey-operate "hyperbole" "Emulate Hyperbole mouse key drags." t) ;; (autoload 'symset:add "hyperbole" "Adds ELT to SYMBOL's PROP set." nil) ;; (autoload 'hact "hyperbole" "Performs action formed from rest of ARGS." nil) ;; (autoload 'actypes::exec-window-cmd "hyperbole" ;; "Executes an external window-based SHELL-CMD string asynchronously." nil) ;; (autoload 'hpath:absolute-to "hyperbole" ;; "Make PATH absolute from optional DEFAULT-DIRS." nil) ;; (autoload 'hpath:display-buffer "hyperbole" ;; "Displays and selects BUFFER at optional DISPLAY-WHERE location or at `hpath:display-where'." t) ;; (autoload 'hpath:find "hyperbole" ;; "Edit file FILENAME, possibly using a special command." t) ;; (autoload 'hpath:find-other-frame "hyperbole" ;; "Edit file FILENAME in other frame, possibly using a special command." t) ;; (autoload 'hpath:find-other-window "hyperbole" ;; "Edit file FILENAME in other window, possibly using a special command." t) ;;; Auto-autoload doesn't work for next item because it is defined ;;; within a condition-case, so autoload it here. (autoload 'Vm-init "hvm" "Initializes Hyperbole Vm support." t) ;;; ************************************************************************ ;;; Outline Mode Aliases ;;; ************************************************************************ (require 'outline) (unless (fboundp 'outline-hide-body) (defalias 'outline-hide-body 'hide-body)) (unless (fboundp 'outline-hide-entry) (defalias 'outline-hide-entry 'hide-entry)) (unless (fboundp 'outline-show-entry) (defalias 'outline-show-entry 'show-entry)) (unless (fboundp 'outline-show-all) (defalias 'outline-show-all 'show-all)) (unless (fboundp 'outline-hide-subtree) (defalias 'outline-hide-subtree 'hide-subtree)) (unless (fboundp 'outline-show-subtree) (defalias 'outline-show-subtree 'show-subtree)) (unless (fboundp 'outline-flag-region) (defun outline-flag-region (from to flag) "Hide or show lines from FROM to TO, according to FLAG. If FLAG is nil then text is shown, while if FLAG is t the text is hidden." (if flag (subst-char-in-region from to ?\n ?\r t) (subst-char-in-region from to ?\r ?\n t)))) (unless (fboundp 'outline-invisible-in-p) (defun outline-invisible-in-p (beg end) "Return t if there is an invisible character between BEG and END, else nil." (catch 'result (delq nil (mapcar (lambda (o) (if (eq 'outline (overlay-get o 'invisible)) (throw 'result t))) (overlays-in beg end)))))) ;;; ************************************************************************ ;;; Message System Support Configuration ;;; ************************************************************************ ;; Even if you don't need some of the following hook settings, you might ;; as well leave them in so that if they ever become useful to you, you ;; need not reconfigure Hyperbole. These settings do nothing if the ;; corresponding subsystems are never invoked. ;; ;; GNUS USENET news reader/poster support. ;; (var:append 'gnus-Startup-hook '(Gnus-init)) ;; ;; Hyperbole mail reader support configuration. ;; ;; Rmail (var:append 'rmail-mode-hook '(Rmail-init)) ;; Mh-e (var:append 'mh-inc-folder-hook '(Mh-init)) ;; ;; VM support is based on V5.72 beta of VM. If you have a version of VM ;; earlier than 5.70 beta, you should either upgrade or comment out the ;; following line so that Hyperbole support for VM is not enabled. (var:append 'vm-mode-hook '(Vm-init)) ;; ;; Hyperbole mail composer support configuration. ;; (var:append 'message-mode-hook (list (lambda () (require 'hsmail)))) (var:append 'mh-letter-mode-hook (list (lambda () (require 'hsmail)))) (var:append 'vm-mail-mode-hook (list (lambda () (require 'hsmail)))) ;;; ************************************************************************ ;;; URL Browsing ;;; ************************************************************************ (require 'browse-url) ;; Use any obsolete URL setting from earlier Hyperbole releases to set the ;; new URL browsing variable. (if (and (boundp 'action-key-url-function) action-key-url-function) (cond ((eq action-key-url-function 'w3-fetch) (setq browse-url-browser-function 'browse-url-w3)) ((eq action-key-url-function 'highlight-headers-follow-url-netscape) (setq browse-url-browser-function 'browse-url-netscape browse-url-new-window-flag nil)) ((eq action-key-url-function 'highlight-headers-follow-url-netscape-new-window) (setq browse-url-browser-function 'browse-url-netscape browse-url-new-window-flag t)))) ;;; ************************************************************************ ;;; Load Site-specific Configurations and Initialize Hyperbole Package ;;; ************************************************************************ (defun hyperb:init () "Standard configuration routine for Hyperbole." (interactive) (message "Initializing Hyperbole...") (run-hooks 'hyperbole-init-hook) (hyperb:check-dir-user) (or (stringp hyperb:user-email) (setq hyperb:user-email (or (and (boundp 'user-mail-address) (stringp user-mail-address) (string-match "@" user-mail-address) user-mail-address) (concat (user-login-name) (hypb:domain-name))))) ;; ;; Conditionally initialize Hyperbole key bindings (when hkey-init is t) (hkey-initialize) ;; ;; Abbreviate MSWindows mount point paths. (when (or (file-exists-p "/mnt/c") (file-exists-p "/cygdrive")) (add-to-list 'directory-abbrev-alist '("\\`\\(/mnt\\|/cygdrive\\)/" . "/"))) ;; When running under a POSIX system with possible access to MSWindows servers, ;; cache valid MSWindows mount points. (hpath:cache-mswindows-mount-points) ;; ;; Save button attribute file whenever same dir file is saved and ;; `ebut:hattr-save' is non-nil. (add-hook (if (boundp 'write-file-functions) 'write-file-functions 'write-file-hooks) #'hattr:save t) ;; (hyperb:init-menubar) ;; ;; This installs a hook that removes any local key bindings which ;; hide the global Action Key, if `hkey-init' and ;; `hkey-init-override-local-keys' are t. Typically, the Action Key ;; will be much more useful than the local key anyway. Setting ;; `hkey-init-override-local-keys' to nil at any time, will prevent ;; removal of further local bindings. (if (featurep 'hyperbole) (hkey-install-override-local-bindings) (add-hook 'after-load-alist '(hyperbole hkey-install-override-local-bindings))) ;; ;; Hyperbole initialization is complete. (message "Initializing Hyperbole...done") (message "Hyperbole %s is ready for action." hyperb:version)) ;; This call loads the rest of the Hyperbole system. (require 'hinit) (if after-init-time ;; This call initializes Hyperbole key bindings and hooks. (hyperb:init) ;; Initialize after other key bindings are loaded at startup. (add-hook 'after-init-hook #'hyperb:init t)) (makunbound 'hyperbole-loading) (provide 'hyperbole) ;;; hyperbole.el ends here