emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] scratch/hyperbole-lexbind 78848ae: Fix compilation warnings in ko


From: Stefan Monnier
Subject: [elpa] scratch/hyperbole-lexbind 78848ae: Fix compilation warnings in kotl/*.el and use lexical-binding
Date: Tue, 12 Dec 2017 11:45:05 -0500 (EST)

branch: scratch/hyperbole-lexbind
commit 78848ae0a44b417507c4cb44dc2dc4c1a87ffc56
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    Fix compilation warnings in kotl/*.el and use lexical-binding
    
    Change some `require` dependencies to help with that:
    - Remove (if t (require 'klink)) from hibtypes.el
    - Remove kview from kotl/kcell.el
    - Add kcell and kvspec to kotl/kfile.el
    - Add kview, hpath, hbut, and hact to kotl/klink.el
    - Remove hyperbole from kotl/kproperties.el (and hversion from 
kprop-em/xm.el)
    - add kproperty and kcell to kotl/kview.el
    - add outline and kproperty to kotl/kvspec.el
    
    Move a few private-var sections to before their use.  Replace a few
    let-bindings of buffer-read-only inhibit-read-only while I'm at it.
    
    * kotl/kview.el (kview): Use `defvar'.
    
    * kotl/kprop-em.el, kotl/kprop-xm.el: Merge into kotl/kproperty.el.
    
    * kotl/kotl-mode.el (kotl-mode-map): Move initialization into declaration.
    Use command remapping rather than substitute-key-definition.
    (kotl-mode): Call kill-all-local-variables, as god intended.
    Don't mess with minor-mode-alist (was probably needed because of the lack
    of call to kill-all-local-variables).  Fix spurious close-paren.
    Use run-mode-hooks and use it last, as god intended.
    (kotl-mode:set-fill-prefix): Don't use the extra arg that was provided by
    the redefined version of set-fill-prefix.
    (kotl-mode:clipboard-yank): gui-select-enable-clipboard doesn't exist.
    
    * kotl/kfill.el (kfill:function-table): Remove.
    (fill-paragraph, set-fill-prefix): Use advice rather than redefinition.
    (kfill:funcall): Remove.
    
    * hyperbole.el: Add .../kotl/ to load-path from autoloads.
---
 hargs.el          |   4 +-
 hibtypes.el       |   5 -
 hyperbole.el      |   7 +
 kotl/kcell.el     |  25 ++-
 kotl/kexport.el   |  19 ++-
 kotl/kfile.el     |  28 +--
 kotl/kfill.el     |  87 ++++------
 kotl/kimport.el   |   6 +-
 kotl/klabel.el    |  48 ++++--
 kotl/klink.el     |  48 +++---
 kotl/kmenu.el     |   9 +-
 kotl/knode.el     |   4 +-
 kotl/kotl-mode.el | 500 ++++++++++++++++++++++++++++--------------------------
 kotl/kprop-em.el  |  92 ----------
 kotl/kprop-xe.el  | 135 ---------------
 kotl/kproperty.el | 145 +++++++++++++++-
 kotl/kview.el     | 270 ++++++++++++++++-------------
 kotl/kvspec.el    |  74 ++++----
 18 files changed, 748 insertions(+), 758 deletions(-)

diff --git a/hargs.el b/hargs.el
index 50cea02..98ba9ad 100644
--- a/hargs.el
+++ b/hargs.el
@@ -4,7 +4,7 @@
 ;;
 ;; Orig-Date:    31-Oct-91 at 23:17:35
 ;;
-;; Copyright (C) 1991-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1991-2017  Free Software Foundation, Inc.
 ;; See the "HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -443,7 +443,7 @@ Insert in minibuffer if active or in other window if 
minibuffer is inactive."
              entry)))))
 
 (defun hargs:iform-read (iform &optional modifying)
-  "Reads action arguments according to IFORM, a list with car = 'interactive.
+  "Read action arguments according to IFORM, a list with car = 'interactive.
 Optional MODIFYING non-nil indicates current button is being modified, so
 button's current values should be presented as defaults.  Otherwise, uses
 hargs:defaults as list of defaults, if any.
diff --git a/hibtypes.el b/hibtypes.el
index fbaaa22..631a814 100644
--- a/hibtypes.el
+++ b/hibtypes.el
@@ -604,11 +604,6 @@ Requires the Emacs builtin Tramp library for ftp file 
retrievals."
 ;;; Follows links to Hyperbole Koutliner cells.
 ;;; ========================================================================
 
-;; FIXME: Not sure if it's important to avoid loading `klink' during
-;; bytecompilation, but that was the behavior when the condition was more
-;; complex, so I kept the `if' even though it's now trivial.
-(if t (require 'klink))
-
 ;;; ========================================================================
 ;;; Jumps to source line associated with grep or compilation error messages.
 ;;; With credit to Michael Lipp and Mike Williams for the idea.
diff --git a/hyperbole.el b/hyperbole.el
index 74a7831..57ba586 100644
--- a/hyperbole.el
+++ b/hyperbole.el
@@ -463,6 +463,13 @@ With optional ARG, override them iff ARG is positive."
 ;; 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.
diff --git a/kotl/kcell.el b/kotl/kcell.el
index 323af2c..bbd476c 100644
--- a/kotl/kcell.el
+++ b/kotl/kcell.el
@@ -1,10 +1,10 @@
-;;; kcell.el --- Internal representation of koutline kcells used by kviews
+;;; kcell.el --- Internal representation of koutline kcells used by kviews  
-*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    5/1/1993
 ;;
-;; Copyright (C) 1993-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1993-2017  Free Software Foundation, Inc.
 ;; See the "../HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -20,7 +20,7 @@
 ;;; Other required Elisp libraries
 ;;; ************************************************************************
 
-(eval-and-compile (mapc #'require '(hinit htz klabel knode kview)))
+(eval-and-compile (mapc #'require '(hinit htz klabel knode)))
 
 ;;; ************************************************************************
 ;;; Public variables
@@ -153,16 +153,21 @@ now."
 ;;; kcell-data - Persistent representation of kotl cells (written to files).
 ;;;
 
+;; FIXME: circular dependency: We'd like to `require' kview for
+;; kview:id-increment, but kview `require's us for various other functions.
+(declare-function kview:id-increment "kview" (kview))
+
 (defun kcell-data:create (cell)
   "Given a kotl CELL, return a kcell-data structure to write to a file.
 If CELL, its idstamp, or its property list are nil, this repairs the cell by
 assuming it is the cell at point and filling in the missing information."
-   (let ((idstamp (kcell:idstamp cell))
-        (plist (nthcdr 2 (kcell:plist cell))))
-     (if (and cell idstamp plist)
-        (vector idstamp plist)
-       (kcell-data:create
-       (kcell:create nil (or idstamp (kview:id-increment kview)) plist)))))
+  (let ((idstamp (kcell:idstamp cell))
+       (plist (nthcdr 2 (kcell:plist cell))))
+    (if (and cell idstamp plist)
+       (vector idstamp plist)
+      (with-no-warnings (defvar kview)) ;Presumably the "current kview"?!
+      (kcell-data:create
+       (kcell:create nil (or idstamp (kview:id-increment kview)) plist)))))
 
 (defun kcell-data:idstamp (kcell-data)
   (aref kcell-data 0))
@@ -174,6 +179,7 @@ assuming it is the cell at point and filling in the missing 
information."
   (aref kcell-data 1))
 
 (defun kcell-data:to-kcell-v2 (kcell-data)
+  (with-no-warnings (defvar kview))   ;Presumably the "current kview"?!
   (if (vectorp kcell-data)
       (kcell:create
        ;; Cell contents are no longer put into cells themselves by default
@@ -187,6 +193,7 @@ assuming it is the cell at point and filling in the missing 
information."
     (kcell:create nil (kview:id-increment kview))))
 
 (defun kcell-data:to-kcell-v3 (kcell-data)
+  (with-no-warnings (defvar kview))   ;Presumably the "current kview"?!
   (if (vectorp kcell-data)
       (kcell:create
        ;; Cell contents are no longer put into cells themselves by default
diff --git a/kotl/kexport.el b/kotl/kexport.el
index 1e9dc09..d0a0de3 100644
--- a/kotl/kexport.el
+++ b/kotl/kexport.el
@@ -1,4 +1,4 @@
-;;; kexport.el --- Convert koutlines to other textual formats, including HTML
+;;; kexport.el --- Convert koutlines to other textual formats, including HTML  
-*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
@@ -20,6 +20,7 @@
 (require 'hpath)
 (require 'hibtypes)
 (require 'klink)
+(declare-function kotl-mode:beginning-of-buffer "kotl-mode")
 
 ;;; ************************************************************************
 ;;; Public variables
@@ -121,6 +122,17 @@ STILL TODO:
   Make delimited pathnames into file links (but not if within klinks).
   Copy attributes stored in cell 0 and attributes from each cell."
   (interactive "fKoutline buffer/file to export: \nFHTML buffer/file to save 
to: \nP")
+  ;; 
+  (defvar html-mode-hook)
+  (defvar hm--html-mode-hook)
+  (defvar psgml-mode-hook)
+  ;; FIXME: These are presumably used to prevent syntax highlighting, but in
+  ;; Emacs they don't exist, so I'm not sure if it means that we have a bug (we
+  ;; need to prevent font-lock for Emacs as well), or rather that Emacs's
+  ;; version of font-lock doesn't get in the way.
+  (defvar font-lock-auto-fontify)
+  (defvar font-lock-mode-disable-list)
+  (defvar font-lock-mode-enable-list)
   (let* ((export-buf-name
          (cond ((or (bufferp export-from)
                     (get-buffer export-from))
@@ -134,6 +146,9 @@ STILL TODO:
         (font-lock-auto-fontify) ;; Prevent syntax highlighting
         (font-lock-mode-disable-list '(html-mode))
         (font-lock-mode-enable-list)
+         ;; Avoid running user hooks in the destination file.
+         ;; FIXME: There should be a better way to do that than to enumerate
+         ;; the possible modes's hooks.
         (html-mode-hook)
         (hm--html-mode-hook)
         (psgml-mode-hook)
@@ -188,7 +203,7 @@ STILL TODO:
             "&gt;"))
           i level label contents)
       (kview:map-tree
-       (lambda (kview)
+       (lambda (_kview)
         (setq level (kcell-view:level)
               i level)
         (while (> i 1)
diff --git a/kotl/kfile.el b/kotl/kfile.el
index a196ee3..c63ec58 100644
--- a/kotl/kfile.el
+++ b/kotl/kfile.el
@@ -1,10 +1,10 @@
-;;; kfile.el --- Save and restore koutlines from files
+;;; kfile.el --- Save and restore koutlines from files  -*- lexical-binding:t 
-*-
 ;;
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    10/31/93
 ;;
-;; Copyright (C) 1993-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1993-2017  Free Software Foundation, Inc.
 ;; See the "../HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -16,7 +16,7 @@
 ;;; Other required Elisp libraries
 ;;; ************************************************************************
 
-(eval-and-compile (mapc #'require '(kproperty kmenu kview)))
+(eval-and-compile (mapc #'require '(kproperty kmenu kview kcell kvspec)))
 
 ;;; ************************************************************************
 ;;; Public variables
@@ -114,8 +114,10 @@ Return file's kview."
     (if (not empty-p)
        ;; This is a foreign file whose elements must be converted into
        ;; koutline cells.
-       (progn (setq import-from (kimport:copy-and-set-buffer buffer))
-              (set-buffer buffer)
+       (progn (require 'kimport)
+               (declare-function kimport:copy-and-set-buffer "kimport" 
(source))
+               (setq import-from (save-current-buffer
+                                   (kimport:copy-and-set-buffer buffer)))
               (erase-buffer))) ;; We copied the contents to `import-from'.
 
     (setq view (kview:create (buffer-name buffer))
@@ -206,7 +208,7 @@ Return the new view."
     (goto-char (point-min))
     ;;
     ;; Add attributes to cells.
-    (kfile:insert-attributes-v2 view kcell-list)
+    (kfile:insert-attributes-v2 kcell-list)
     ;;
     ;; Mark view unmodified and move to first cell.
     (set-buffer-modified-p nil)
@@ -242,7 +244,7 @@ If V3-FLAG is true, read as a version-3 buffer."
     (goto-char (point-min))
     ;;
     ;; Add attributes to cells.
-    (kfile:insert-attributes-v3 view cell-data)
+    (kfile:insert-attributes-v3 cell-data)
     ;;
     ;; Mark view unmodified and move to first cell.
     (set-buffer-modified-p nil)
@@ -278,7 +280,7 @@ VISIBLE-ONLY-P is non-nil.  Signal an error if kotl is not 
attached to a file."
       ;; Prepare cell data for saving.
       (kfile:narrow-to-kcells)
       (kview:map-tree
-        (lambda (view)
+        (lambda (_view)
          (setq cell (kcell-view:cell))
          (aset kcell-data
                kcell-num
@@ -366,11 +368,11 @@ included in the list."
      (lambda (item)
        (setq func (cdr (assoc item
                              (list
-                              (cons "\("
+                              (cons "("
                                     (lambda ()
                                       (setq stack (cons sibling-p stack)
                                             sibling-p nil)))
-                              (cons "\)" 
+                              (cons ")" 
                                     (lambda ()
                                       (setq sibling-p (car stack)
                                             stack (cdr stack))))))))
@@ -384,7 +386,7 @@ included in the list."
      kotl-structure)
     (nreverse cell-list)))
 
-(defun kfile:insert-attributes-v2 (kview kcell-list)
+(defun kfile:insert-attributes-v2 (kcell-list)
   "Set cell attributes within kview for each element in KCELL-LIST.
 Assumes all cell contents are already in kview and that no cells are
 hidden."
@@ -402,12 +404,12 @@ hidden."
                (setq kcell-list (cdr kcell-list))))
          (search-forward "\n\n" nil t)))))
 
-(defun kfile:insert-attributes-v3 (kview kcell-vector)
+(defun kfile:insert-attributes-v3 (kcell-vector)
   "Set cell attributes within kview for each element in KCELL-VECTOR.
 Assumes all cell contents are already in kview and that no cells are
 hidden."
   (let ((kcell-num 1)
-       (buffer-read-only))
+       (inhibit-read-only t))
     (while
        (progn
          (skip-chars-forward "\n")
diff --git a/kotl/kfill.el b/kotl/kfill.el
index a8387e8..238d7f5 100644
--- a/kotl/kfill.el
+++ b/kotl/kfill.el
@@ -1,10 +1,10 @@
-;;; kfill.el --- Fill and justify koutline cells
+;;; kfill.el --- Fill and justify koutline cells  -*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    23-Jan-94
 ;;
-;; Copyright (C) 1994-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1994-2017  Free Software Foundation, Inc.
 ;; See the "../HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -14,21 +14,10 @@
 
 ;;; Code:
 
-;; Quiet byte compiler warnings for this free variable.
-(eval-when-compile
-  (unless (require 'filladapt nil t)
-    (defvar filladapt-function-table nil)))
-
 ;;; ************************************************************************
 ;;; Public variables
 ;;; ************************************************************************
 
-(defvar kfill:function-table
-  (if (featurep 'filladapt)
-      filladapt-function-table
-    (list (cons 'fill-paragraph (symbol-function 'fill-paragraph))))
-  "Table containing the old function definitions that kfill overrides.")
-
 (defvar kfill:prefix-table
   '(
     ;; Lists with hanging indents, e.g.
@@ -91,12 +80,18 @@ Setting this variable automatically makes it local to the 
current buffer.")
 ;;; Public functions 
 ;;; ************************************************************************
 
+;; FIXME: circular dependency: kview `require's kfill because of
+;; kfill:forward-line, and kfill would like to `require' kview because of
+;; kcell-view:indent.
+(declare-function kcell-view:indent "kview" (&optional pos lsl))
+
 (defun kfill:forward-line (&optional n)
   "Move N lines forward (backward if N is negative) to the start of line.
 If there isn’t room, go as far as possible (no error).  Return the
 number of lines that could not be moved, otherwise 0."
   (or (integerp n) (setq n 1))
-  (let ((opoint (point)))
+  (let (;; (opoint (point))
+        )
     (forward-visible-line n)
     (if (< n 0)
        nil
@@ -116,13 +111,12 @@ number of lines that could not be moved, otherwise 0."
          (do-auto-fill))
       (do-auto-fill))))
 
-;;; Redefine this built-in function.
-
-(defun fill-paragraph (arg &optional skip-prefix-remove)
-  "Fill paragraph at or after point.  Prefix ARG means justify as well."
-  (interactive "*P")
-  (if (not (eq major-mode 'kotl-mode))
-      (kfill:funcall 'fill-paragraph arg)
+;; Redefine this built-in function.
+(advice-add 'fill-paragraph :around #'kill:fill-paragraph)
+(defun kill:fill-paragraph (orig-fun arg &optional skip-prefix-remove)
+  "`kotl-mode' specific paragraph filling code."
+  (if (not (derived-mode-p 'kotl-mode))
+      (funcall orig-fun arg skip-prefix-remove)
     ;; This may be called from `fill-region-as-paragraph' in "filladapt.el"
     ;; which narrows the region to the current paragraph.  A side-effect is
     ;; that the cell identifier and indent information needed by this function
@@ -130,8 +124,7 @@ number of lines that could not be moved, otherwise 0."
     ;; buffer here.  Don't rewiden past the paragraph of interest or any
     ;; following blank line may be removed by the filling routines.
     (save-restriction
-      (if (eq major-mode 'kotl-mode)
-         (narrow-to-region 1 (point-max)))
+      (narrow-to-region 1 (point-max))
       ;; Emacs expects a specific symbol here.
       (if (and arg (not (symbolp arg))) (setq arg 'full))
       (or skip-prefix-remove (kfill:remove-paragraph-prefix))
@@ -145,37 +138,28 @@ number of lines that could not be moved, otherwise 0."
                  (paragraph-separate paragraph-separate)
                  fill-prefix)
              (if (kfill:adapt t)
-                 (throw 'done (kfill:funcall 'fill-paragraph arg)))))
+                 (throw 'done (funcall orig-fun arg skip-prefix-remove)))))
        ;; Kfill:adapt failed or fill-prefix is set, so do a basic
        ;; paragraph fill as adapted from par-align.el.
        (kfill:fallback-fill-paragraph arg skip-prefix-remove)))))
 
-;;;
-;;; Redefine this built-in function so that it sets `prior-fill-prefix' also.
-;;;
-(defun set-fill-prefix (&optional turn-off)
-  "Set `fill-prefix' to the current line up to point or remove it if optional 
TURN-OFF flag is non-nil.
-Also sets `prior-fill-prefix' to the previous value of `fill-prefix'.
-Filling removes any prior fill prefix, adjusts line lengths and then adds the
-fill prefix at the beginning of each line."
-  (interactive)
-  (setq prior-fill-prefix fill-prefix
-       fill-prefix (if turn-off
-                       nil
-                     (buffer-substring
-                      (save-excursion (beginning-of-line) (point))
-                      (point))))
-  (if (equal prior-fill-prefix "")
-      (setq prior-fill-prefix nil))
-  (if (equal fill-prefix "")
-      (setq fill-prefix nil))
-  (cond (fill-prefix
-        (message "fill-prefix: \"%s\"; prior-fill-prefix: \"%s\""
-                 fill-prefix (or prior-fill-prefix "")))
-       (prior-fill-prefix
-        (message "fill-prefix cancelled; prior-fill-prefix: \"%s\""
-                 prior-fill-prefix))
-       (t (message "fill-prefix and prior-fill-prefix cancelled"))))
+;; Redefine this built-in function so that it sets `prior-fill-prefix' also.
+(advice-add 'set-fill-prefix :around #'kfill:set-fill-prefix)
+(defun kfill:set-fill-prefix (orig-fun &rest args)
+  "Set `prior-fill-prefix' to the previous value of `fill-prefix'."
+  (if (not (derived-mode-p 'kotl-mode))
+      (apply orig-fun args)
+    (setq prior-fill-prefix fill-prefix)
+    (if (equal prior-fill-prefix "")
+        (setq prior-fill-prefix nil))
+    (apply orig-fun args)
+    (cond (fill-prefix
+          (message "fill-prefix: \"%s\"; prior-fill-prefix: \"%s\""
+                   fill-prefix (or prior-fill-prefix "")))
+         (prior-fill-prefix
+          (message "fill-prefix cancelled; prior-fill-prefix: \"%s\""
+                   prior-fill-prefix))
+         (t (message "fill-prefix and prior-fill-prefix cancelled")))))
 
 ;;; ************************************************************************
 ;;; Private functions
@@ -231,9 +215,6 @@ fill prefix at the beginning of each line."
                 (funcall function justify-flag)))
          (fill-region-as-paragraph from (point) justify-flag)))))
 
-(defun kfill:funcall (function &rest args)
-  (apply (cdr (assq function kfill:function-table)) args))
-
 (defun kfill:hanging-list (paragraph)
   (let (prefix match beg end)
     (setq prefix (make-string (- (match-end 0) (match-beginning 0)) ?\ ))
diff --git a/kotl/kimport.el b/kotl/kimport.el
index 702a19c..5956306 100644
--- a/kotl/kimport.el
+++ b/kotl/kimport.el
@@ -1,4 +1,4 @@
-;;; kimport.el --- Convert and insert other outline file formats into koutlines
+;;; kimport.el --- Convert and insert other outline file formats into 
koutlines  -*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
@@ -371,7 +371,7 @@ The variable, `paragraph-start,' is used to determine 
paragraphs."
          ;; Total number of paragraphs.
          (setq total (kimport:count-paragraphs)
                count (kimport:text-paragraphs import-from output-to klabel
-                                              output-level count total))))
+                                              output-level total))))
       (pop-to-buffer output-to)
       (kfile:narrow-to-kcells)
       (if no-renumber nil (klabel-type:update-labels klabel))
@@ -656,7 +656,7 @@ in IMPORT-FROM, used to show a running tally of the 
imported entries."
   count)
 
 (defun kimport:text-paragraphs (import-from output-to klabel
-                               output-level count total)
+                               output-level total)
   "Insert text paragraphs from IMPORT-FROM into existing OUTPUT-TO.
 First cell is inserted with KLABEL at OUTPUT-LEVEL, as the sibling of the
 previous cell, with the COUNT of inserted paragraphs starting at 0.  TOTAL is
diff --git a/kotl/klabel.el b/kotl/klabel.el
index 0328563..177759f 100644
--- a/kotl/klabel.el
+++ b/kotl/klabel.el
@@ -1,10 +1,10 @@
-;;; klabel.el --- Display label handling for koutlines
+;;; klabel.el --- Display label handling for koutlines  -*- lexical-binding:t 
-*-
 ;;
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    17-Apr-94
 ;;
-;; Copyright (C) 1994-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1994-2017  Free Software Foundation, Inc.
 ;; See the "../HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -12,6 +12,28 @@
 ;;; Commentary:
 
 ;;; Code:
+
+
+;; FIXME: circular dependency: can't require `kview' because it requires us.
+(defvar kview)
+(defvar kview:default-label-type)
+(declare-function kview:get-attr "kview")
+(declare-function kview:label-type "kview")
+(declare-function kcell-view:level "kview")
+(declare-function kview:id-counter "kview")
+(declare-function kview:id-increment "kview")
+(declare-function kcell-view:parent "kview")
+(declare-function kcell-view:label "kview")
+(declare-function kcell-view:idstamp "kview")
+(declare-function kcell-view:start "kview")
+(declare-function kcell-view:child "kview")
+(declare-function kcell-view:next "kview")
+(declare-function kcell-view:indent "kview")
+(declare-function kview:label-separator-length "kview")
+(declare-function kview:level-indent "kview")
+(declare-function kcell-view:to-label-end "kview")
+(declare-function kotl-mode:first-cell-p "kotl-mode")
+
 ;;; ************************************************************************
 ;;; Public variables
 ;;; ************************************************************************
@@ -79,11 +101,11 @@
         (intern-soft (concat "klabel:child-"
                              (symbol-name label-type))))
        ((eq label-type 'no)
-        (lambda (label) ""))
+        (lambda (_label) ""))
        ((eq label-type 'star)
         (lambda (label) (concat label "*")))
        ((eq label-type 'id)
-        (lambda (label) (format "0%s" (or (kview:id-counter kview) ""))))
+        (lambda (_label) (format "0%s" (or (kview:id-counter kview) ""))))
        (t (error
            "(klabel-type:child): Invalid label type setting: `%s'"
            label-type))))
@@ -94,11 +116,11 @@ If the label is \"0\", its first child is computed, 
otherwise, the next sibling
   (cond ((memq label-type '(alpha legal partial-alpha))
         (intern-soft (concat "klabel:increment-" (symbol-name label-type))))
        ((eq label-type 'no)
-        (lambda (label) ""))
+        (lambda (_label) ""))
        ((eq label-type 'star)
         (lambda (label) (if (string-equal label "0") "*" label)))
        ((eq label-type 'id)
-        (lambda (label) (format "0%s" (or (kview:id-increment kview) ""))))
+        (lambda (_label) (format "0%s" (or (kview:id-increment kview) ""))))
        (t (error
            "(klabel:increment): Invalid label type setting: `%s'" 
label-type))))
 
@@ -261,7 +283,7 @@ is the display label of the cell preceding the current one 
and child-p is
 non-nil if cell is to be the child of the preceding cell."
   (or label-type (setq label-type (kview:label-type kview)))
   (cond ((eq label-type 'no)
-        (lambda (prev-label &optional child-p)
+        (lambda (_prev-label &optional _child-p)
           ""))
        ((eq label-type 'partial-alpha)
         (lambda (prev-label &optional child-p)
@@ -270,7 +292,7 @@ non-nil if cell is to be the child of the preceding cell."
                   "a" "1")
             (kotl-label:increment prev-label 1))))
        ((eq label-type 'id)
-        (lambda (prev-label &optional child-p)
+        (lambda (_prev-label &optional _child-p)
           (kcell-view:idstamp)))
        (t (intern-soft (concat "klabel-type:"
                                (symbol-name label-type) "-label")))))
@@ -366,7 +388,7 @@ and the start of its contents."
        (goto-char opoint)
        (setq current-cell-label nil)))))
 
-(defun klabel-type:set-id (current-cell-label label-sep-len &rest ignore)
+(defun klabel-type:set-id (_current-cell-label label-sep-len &rest _)
   "Set the labels of current cell, its following siblings and their subtrees.
 CURRENT-CELL-LABEL is the label to display for the current cell."
   ;; Only need to do this when switching from one label type to another,
@@ -410,7 +432,7 @@ and the start of its contents."
        (goto-char opoint)
        (setq current-cell-label nil)))))
 
-(defun klabel-type:set-no (current-cell-label label-sep-len &rest ignore)
+(defun klabel-type:set-no (_current-cell-label label-sep-len &rest _)
   "Set the labels of current cell, its following siblings and their subtrees.
 CURRENT-CELL-LABEL is the label to display for the current cell."
   ;; Only need to do this when switching from one label type to another,
@@ -459,7 +481,7 @@ and the start of its contents."
        (goto-char opoint)
        (setq current-cell-label nil)))))
 
-(defun klabel-type:set-star (current-cell-label label-sep-len &rest ignore)
+(defun klabel-type:set-star (_current-cell-label label-sep-len &rest _)
   "Set the labels of current cell, its following siblings and their subtrees.
 CURRENT-CELL-LABEL is the label to display for the current cell.
 LABEL-SEP-LEN is the length of the separation between a cell's label
@@ -486,10 +508,10 @@ If, however, it is \"0\", then all cell labels are 
updated."
          (klabel-type:update-labels-from-point
           label-type current-cell-label)))))
 
-(defun klabel-type:update-tree-labels (current-cell-label first-label)
+(defun klabel-type:update-tree-labels (_current-cell-label first-label)
   "Update the labels of current cell and its subtree.
 CURRENT-CELL-LABEL is the label to display for the current cell.
-Use `(klabel-type:update-labels "0")' to update all cells in an outline."
+Use `(klabel-type:update-labels \"0\")' to update all cells in an outline."
   (let ((label-type (kview:label-type kview))
        (label-sep-len (kview:label-separator-length kview)))
     (save-excursion
diff --git a/kotl/klink.el b/kotl/klink.el
index d63d91f..6ff14eb 100644
--- a/kotl/klink.el
+++ b/kotl/klink.el
@@ -1,10 +1,10 @@
-;;; klink.el --- Implicit reference to a kcell action type, for use in 
koutlines
+;;; klink.el --- Implicit reference to a kcell action type, for use in 
koutlines  -*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    15-Nov-93 at 12:15:16
 ;;
-;; Copyright (C) 1993-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1993-2017  Free Software Foundation, Inc.
 ;; See the "../HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
@@ -61,7 +61,10 @@
 ;;; ************************************************************************
 
 (require 'subr-x) ;; For string-trim
-(eval-when-compile (require 'hbut)) ;; For defib.
+(require 'hbut) ;; For defib.
+(require 'kview)
+(require 'hpath)
+(require 'hact)
 
 ;;; ************************************************************************
 ;;; Public functions
@@ -75,11 +78,13 @@ See documentation for `kcell:ref-to-id' for valid cell-ref 
formats."
   (interactive
    ;; Don't change the name or delete default-dir used here.  It is referenced
    ;; in "hargs.el" for argument getting.
-   (let ((default-dir default-directory))
-     (barf-if-buffer-read-only)
-     (save-excursion
-       (hargs:iform-read
-       (list 'interactive "*+LInsert link to <[file,] cell-id [|vspecs]>: 
")))))
+   (progn
+     (defvar default-dir) ;; FIXME: Use appropriate package prefix
+     (let ((default-dir default-directory))
+       (barf-if-buffer-read-only)
+       (save-excursion
+         (hargs:iform-read
+         (list 'interactive "*+LInsert link to <[file,] cell-id [|vspecs]>: 
"))))))
   (barf-if-buffer-read-only)
   ;; Reference generally is a string.  It may be a list as a string, e.g.
   ;; "(\"file\" \"cell\")", in which case, we remove the unneeded internal
@@ -87,6 +92,7 @@ See documentation for `kcell:ref-to-id' for valid cell-ref 
formats."
   (and (stringp reference) (> (length reference) 0)
        (eq (aref reference 0) ?\()
        (setq reference (hypb:replace-match-string "\\\"" reference "" t)))
+  (defvar default-dir) ;; FIXME: Use appropriate package prefix
   (let ((default-dir default-directory)
        file-ref cell-ref)
     (setq reference (klink:parse reference)
@@ -135,6 +141,7 @@ link-end-position, (including delimiters)."
               (beginning-of-line)
               (setq bol (point))
               (require 'hmouse-tag)
+               (defvar smart-c-include-regexp)
               (not (looking-at smart-c-include-regexp)))
           t)
         (save-excursion
@@ -164,6 +171,16 @@ link-end-position, (including delimiters)."
        klink)))
 
 ;;; ************************************************************************
+;;; Private variables.
+;;; ************************************************************************
+
+(defvar klink:cell-ref-regexp
+  ;; FIXME: Use [:alnum:]?
+  "[|:0-9a-zA-Z][|:.*~=0-9a-zA-Z \t\n\r]*"
+  "Regexp matching a cell reference including relative and view specs.
+Contains no groupings.")
+
+;;; ************************************************************************
 ;;; Hyperbole type definitions
 ;;; ************************************************************************
 
@@ -191,9 +208,11 @@ See documentation for `kcell:ref-to-id' for valid cell-ref 
formats."
                            link))
   (cond
    ((or (string-match (format "\\`<address@hidden(%s\\)\\s-*>?\\'"
-                             klink:cell-ref-regexp) link)
+                             klink:cell-ref-regexp)
+                      link)
        (string-match (format "\\`<?\\s-*\\([|:]%s\\)\\s-*>?\\'"
-                             klink:cell-ref-regexp) link))
+                             klink:cell-ref-regexp)
+                      link))
     ;; < @ cell-ref > or < |viewspec > or < :augment-viewspec >
     (hact 'link-to-kcell
          nil
@@ -282,15 +301,6 @@ Assume point is in klink referent buffer, where the klink 
points."
          (if (and new-label (not (equal label new-label)))
              (klink:replace-label klink link-buf start new-label)))))
 
-;;; ************************************************************************
-;;; Private variables.
-;;; ************************************************************************
-
-(defvar klink:cell-ref-regexp
-  "[|:0-9a-zA-Z][|:.*~=0-9a-zA-Z \t\n\r]*"
-  "Regexp matching a cell reference including relative and view specs.
-Contains no groupings.")
-
 (provide 'klink)
 
 ;;; klink.el ends here
diff --git a/kotl/kmenu.el b/kotl/kmenu.el
index c1d6c33..4d3d074 100644
--- a/kotl/kmenu.el
+++ b/kotl/kmenu.el
@@ -1,4 +1,4 @@
-;;; kmenu.el --- Pulldown and popup menus for kotl-mode, the Koutliner mode
+;;; kmenu.el --- Pulldown and popup menus for kotl-mode, the Koutliner mode  
-*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
@@ -188,10 +188,14 @@
 ;;; Public functions
 ;;; ************************************************************************
 
-;;; This definition is used only by XEmacs and Emacs.
+;; This definition is used only by XEmacs and Emacs.
 (defun kotl-menubar-menu ()
   "Add a Koutline menu to the menubar for each koutline buffer."
+  (defvar kotl-mode-map)                ;Called from kotl-mode-hook.
+  ;; FIXME: All the menu&key settings here should only be performed once,
+  ;; rather than re-execute them for every kotl buffer!
   (cond ((fboundp 'popup-mode-menu)
+         (defvar mode-popup-menu)
         (setq mode-popup-menu id-popup-kotl-menu))
        ((featurep 'xemacs)
         (define-key kotl-mode-map 'button3 'kotl-popup-menu))
@@ -217,6 +221,7 @@
 (cond ((featurep 'infodock)
        ;; InfoDock under a window system
        (require 'id-menubars)
+       (declare-function id-menubar-set "infodock")
        (id-menubar-set 'kotl-mode 'id-menubar-kotl))
       (t
        ;; Emacs or XEmacs under a window system
diff --git a/kotl/knode.el b/kotl/knode.el
index 43f31b2..db1bcc3 100644
--- a/kotl/knode.el
+++ b/kotl/knode.el
@@ -1,10 +1,10 @@
-;;; knode.el --- Generic nodes for use as elements in data structures
+;;; knode.el --- Generic nodes for use as elements in data structures  -*- 
lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
 ;; Orig-Date:    5/1/93
 ;;
-;; Copyright (C) 1993-2016  Free Software Foundation, Inc.
+;; Copyright (C) 1993-2017  Free Software Foundation, Inc.
 ;; See the "../HY-COPY" file for license information.
 ;;
 ;; This file is part of GNU Hyperbole.
diff --git a/kotl/kotl-mode.el b/kotl/kotl-mode.el
index 6426bcd..16d5118 100644
--- a/kotl/kotl-mode.el
+++ b/kotl/kotl-mode.el
@@ -1,4 +1,4 @@
-;;; kotl-mode.el ---  Major mode for editing koutlines and associated commands
+;;; kotl-mode.el ---  Major mode for editing koutlines and associated commands 
 -*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
@@ -18,11 +18,185 @@
 
 (eval-and-compile (mapc #'require '(delsel hsettings hmail kfile kvspec 
kcell)))
 
+(declare-function outline-invisible-in-p "hyperbole")
+
 ;;; ************************************************************************
 ;;; Public variables
 ;;; ************************************************************************
 
-(defvar kotl-mode-map nil
+(defvar kotl-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map
+                      (if (boundp 'indented-text-mode-map)
+                           indented-text-mode-map
+                         text-mode-map))
+    ;; Ensure mouse wheel scrolling leaves point in a valid Koutline position
+    (if (and (boundp 'mwheel-scroll-up-function)
+            (eq (symbol-value 'mwheel-scroll-up-function) 'scroll-up))
+        (setq mwheel-scroll-up-function 'kotl-mode:scroll-up
+             mwheel-scroll-down-function 'kotl-mode:scroll-down))
+    ;; Overload edit keys to deal with structure and labels.
+    (dolist (cmd
+             '(
+               back-to-indentation
+               backward-char
+               backward-delete-char
+               backward-delete-char-untabify
+               backward-kill-word
+               backward-or-forward-delete-char
+               backward-para
+               backward-paragraph
+               backward-sentence
+               backward-word
+               beginning-of-buffer
+               beginning-of-line
+               completion-kill-region
+               copy-region-as-kill
+               copy-to-register
+               delete-blank-lines
+               delete-backward-char
+               delete-char
+               delete-forward-char
+               delete-horizontal-space
+               delete-indentation
+               end-of-buffer
+               end-of-line
+               fill-paragraph
+               fill-paragraph-or-region
+               ;; cursor keys
+               fkey-backward-char
+               fkey-forward-char
+               fkey-next-line
+               fkey-previous-line
+               backward-char-command
+               forward-char-command
+               ;;
+               forward-char
+               forward-word
+               forward-para
+               forward-paragraph
+               forward-sentence
+               just-one-space
+               kill-word
+               kill-line
+               kill-region
+               kill-ring-save
+               kill-sentence
+               left-char
+               mark-paragraph
+               mark-whole-buffer
+               move-beginning-of-line
+               move-end-of-line
+               newline
+               newline-and-indent
+               next-line
+               open-line
+               previous-line
+               right-char
+               scroll-down
+               scroll-up
+               scroll-down-command
+               scroll-up-command
+               set-fill-prefix
+               transpose-chars
+               transpose-lines
+               transpose-paragraphs
+               transpose-sentences
+               transpose-words
+               yank
+               yank-pop
+               zap-to-char
+               ))
+      (let ((local-cmd (intern-soft
+                       (concat "kotl-mode:" (symbol-name cmd)))))
+        ;; Only bind key locally if kotl-mode local-cmd has already
+        ;; been defined and cmd is a valid command.
+        (if (and local-cmd (fboundp cmd))
+           (progn
+             ;; Make local-cmd have the same property list as cmd,
+             ;; e.g. so pending-delete property is the same.
+             (setplist local-cmd (symbol-plist cmd))
+              (if (fboundp 'command-remapping)
+                  (define-key map (vector 'remap cmd) local-cmd)
+               (substitute-key-definition
+                cmd local-cmd map global-map))))))
+
+    ;; kotl-mode keys
+    (define-key map "\C-c@"     'kotl-mode:mail-tree)
+    (define-key map "\C-c+"     'kotl-mode:append-cell)
+    (define-key map "\C-c,"     'kotl-mode:beginning-of-cell)
+    (define-key map "\C-c."     'kotl-mode:end-of-cell)
+    (define-key map "\C-c<"     'kotl-mode:first-sibling)
+    (define-key map "\C-c>"     'kotl-mode:last-sibling)
+    (define-key map "\C-c^"     'kotl-mode:beginning-of-tree)
+    (define-key map "\C-c$"     'kotl-mode:end-of-tree)
+    (define-key map "\C-ca"     'kotl-mode:add-child)
+    (define-key map "\C-c\C-a"  'kotl-mode:show-all)
+    (define-key map "\C-cb"     'kvspec:toggle-blank-lines)
+    (define-key map "\C-c\C-b"  'kotl-mode:backward-cell)
+    (define-key map "\C-cc"     'kotl-mode:copy-after)
+    (define-key map "\C-c\C-c"  'kotl-mode:copy-before)
+    (define-key map "\C-c\M-c"  'kotl-mode:copy-to-buffer)
+    (define-key map "\C-cd"     'kotl-mode:down-level)
+    (define-key map "\C-c\C-d"  'kotl-mode:down-level)
+    (define-key map "\C-ce"     'kotl-mode:exchange-cells)
+    (define-key map "\C-c\C-f"  'kotl-mode:forward-cell)
+    (define-key map "\C-cg"     'kotl-mode:goto-cell)
+    (define-key map "\C-ch"     'kotl-mode:cell-help)
+    (define-key map "\C-c\C-h"  'kotl-mode:hide-tree)
+    ;; Since the next key binds M-BS, it may already have a local binding,
+    ;; in which case we don't want to bind it here.
+    (if (featurep 'xemacs)
+        (unless (lookup-key map '[(meta backspace)])
+         (define-key map '[(meta backspace)] 'kotl-mode:hide-subtree))
+      ;; Do this under GNU Emacs only or will overwrite M-BS binding above.
+      (unless (lookup-key map "\M-\C-h")
+        (define-key map "\M-\C-h"   'kotl-mode:hide-subtree)))
+    ;; Override this global binding for set-selective-display with a similar
+    ;; function appropriate for kotl-mode.
+    (define-key map "\C-x$"     'kotl-mode:hide-sublevels)
+    (define-key map "\C-i"      'kotl-mode:tab-command) ;; TAB
+    (define-key map [backtab]   'kotl-mode:untab-command) ;; Shift-TAB
+    (define-key map "\M-\C-i"   'kotl-mode:untab-command) ;; M-TAB
+    (define-key map "\C-c\C-i"  'kotl-mode:set-or-remove-cell-attribute)
+    (define-key map "\C-j"      'kotl-mode:add-cell)
+    (define-key map "\M-j"      'kotl-mode:fill-paragraph)
+    (define-key map "\C-c\M-j"  'kotl-mode:fill-cell)
+    (define-key map "\M-\C-j"   'kotl-mode:fill-tree)
+    (define-key map "\C-c\C-k"  'kotl-mode:kill-tree)
+    (define-key map "\C-ck"     'kotl-mode:kill-contents)
+    ;; Force an override of the global {C-x i} insert-file binding
+    (define-key map "\C-xi"     'kimport:insert-file)
+    ;; Force an override of the global {C-x r i} insert-register binding
+    (define-key map "\C-xri"    'kimport:insert-register)
+    (define-key map "\C-ck"     'kotl-mode:kill-contents)
+    (define-key map "\C-cl"     'klink:create)
+    (define-key map "\C-c\C-l"  'kview:set-label-type)
+    (define-key map "\C-c\M-l"  'kview:set-label-separator)
+    (define-key map "\C-m"      'kotl-mode:newline)
+    (define-key map "\C-cm"     'kotl-mode:move-after)
+    (define-key map "\C-c\C-m"  'kotl-mode:move-before)
+    (define-key map "\C-c\C-n"  'kotl-mode:next-cell)
+    (define-key map "\C-c\C-o"  'kotl-mode:overview)
+    (define-key map "\C-c\C-p"  'kotl-mode:previous-cell)
+    (define-key map "\C-cp"     'kotl-mode:add-parent)
+    (if (memq (global-key-binding "\M-q") '(fill-paragraph
+                                           fill-paragraph-or-region))
+        (progn
+         (define-key map "\C-c\M-q" 'kotl-mode:fill-cell)
+         (define-key map "\M-\C-q"  'kotl-mode:fill-tree)))
+    (define-key map "\C-cs"     'kotl-mode:split-cell)
+    (define-key map "\C-c\C-s"  'kotl-mode:show-tree)
+    (define-key map "\C-c\C-\\" 'kotl-mode:show-tree)
+    (define-key map "\M-s"      'kotl-mode:center-line)
+    (define-key map "\M-S"      'kotl-mode:center-paragraph)
+    (define-key map "\C-ct"     'kotl-mode:transpose-cells)
+    (define-key map "\C-c\C-t"  'kotl-mode:top-cells)
+    (define-key map "\C-cu"     'kotl-mode:up-level)
+    (define-key map "\C-c\C-u"  'kotl-mode:up-level)
+    (define-key map "\C-c\C-v"  'kvspec:activate)
+    (define-key map "\C-x\C-w"  'kfile:write)
+    map)
   "Keymap containing koutliner editing and viewing commands.")
 
 (defcustom kotl-mode:shrink-region-flag nil
@@ -64,72 +238,69 @@ Normally set from the UNDO element of a yank-handler; see 
`insert-for-yank'.")
 ;;; Public functions
 ;;; ************************************************************************
 
+(defvar kotl-previous-mode)
+
 ;;;###autoload
 (defun kotl-mode ()
   "The major mode used to edit and view koutlines.
 It provides the following keys:
 \\{kotl-mode-map}"
   (interactive)
+  ;; FIXME: Use define-derived-mode (but before we can do that, we have to get
+  ;; rid of this kotl-previous-mode).
+  (let ((prevmode (if (bound-and-true-p 'kotl-previous-mode)
+                      kotl-previous-mode
+                    major-mode)))
+    (kill-all-local-variables)            ;FIXME: Derive from text-mode 
instead?
+    (setq-local kotl-previous-mode prevmode))
   (use-local-map kotl-mode-map)
   (set-syntax-table text-mode-syntax-table)
   ;; Turn off filladapt minor mode if on, so that it does not interfere with
   ;; the filling code in "kfill.el".
-  (and (fboundp 'filladapt-mode) filladapt-mode (filladapt-mode 0))
-  (if (/= 3 (length (action:params (symbol-function 'fill-paragraph))))
-      ;; Some package such as filladapt has overwritten the primitives
-      ;; defined in kfill.el, so reload it.
-      (load "kfill"))
+  (and (bound-and-true-p 'filladapt-mode)
+       (fboundp 'filladapt-mode) (filladapt-mode 0))
   ;; Ensure that outline structure data is saved when save-buffer is called
   ;; from save-some-buffers, {C-x s}.
-  (add-hook 'local-write-file-hooks #'kotl-mode:update-buffer)
+  (add-hook (if (featurep 'xemacs)
+                'local-write-file-hooks
+              'write-file-functions)
+            #'kotl-mode:update-buffer nil t)
   (mapc #'make-local-variable
-       '(kotl-previous-mode indent-line-function indent-region-function
-                            outline-isearch-open-invisible-function
-                            line-move-ignore-invisible minor-mode-alist
-                            selective-display-ellipses
-                            paragraph-separate paragraph-start))
-  ;; Used by kimport.el functions.
-  (unless (and (boundp 'kotl-previous-mode) kotl-previous-mode)
-    (setq kotl-previous-mode major-mode
-         ;; Remove outline minor-mode mode-line indication.
-         minor-mode-alist (copy-sequence minor-mode-alist)
-         minor-mode-alist (set:remove '(outline-minor-mode " Outl")
-                                      minor-mode-alist)
-         minor-mode-alist (set:remove '(selective-display " Outline")
-                                      minor-mode-alist)
-         minor-mode-alist (set:remove '(selective-display " Otl")
-                                      minor-mode-alist)
-       ;; Remove indication that buffer is narrowed.
-       mode-line-format (copy-sequence mode-line-format)
-       mode-line-format (set:remove "%n" mode-line-format)))
+       '(indent-line-function indent-region-function
+         outline-isearch-open-invisible-function
+         line-move-ignore-invisible minor-mode-alist
+         selective-display-ellipses
+         paragraph-separate paragraph-start))
+  ;; Remove indication that buffer is narrowed.
+  (setq mode-line-format (copy-sequence mode-line-format)
+        ;; FIXME: mode-line-format is a sequence, not a set!
+       mode-line-format (set:remove "%n" mode-line-format))
   ;;
   (if (fboundp 'add-to-invisibility-spec)
       (add-to-invisibility-spec '(outline . t)))
-  (setq indent-line-function 'kotl-mode:indent-line
-       indent-region-function 'kotl-mode:indent-region
-       outline-isearch-open-invisible-function 
'kotl-mode:isearch-open-invisible
+  (setq indent-line-function #'kotl-mode:indent-line
+       indent-region-function #'kotl-mode:indent-region
+       outline-isearch-open-invisible-function 
#'kotl-mode:isearch-open-invisible
        line-move-ignore-invisible 'keep-column
        local-abbrev-table text-mode-abbrev-table
        ;; These par* settings must be anchored to the bol since
        ;; kfill.el and `kotl-mode:fill-paragraph' use them in regexp
        ;; searches.
-       paragraph-separate "^[ \t]*$\\|^\^L")
+       paragraph-separate "^[ \t]*$\\|^\^L"
        paragraph-start "^[ \t]*$\\|^\^L"
-       selective-display nil
        selective-display-ellipses t
        track-eol t
-  ;;
-  ;; This major-mode setting must come after the local variable settings but
-  ;; before the koutline is formatted.
-  (setq major-mode 'kotl-mode
+        ;; This major-mode setting must come after the local variable settings
+        ;; but before the koutline is formatted.
+        major-mode 'kotl-mode
        mode-name "Kotl"
        ;; Used when indenting cells.
-       indent-tabs-mode nil)
+        indent-tabs-mode nil)
 
   ;; Used when indenting lines within cells.
   (make-local-variable 'kotl-mode:indent-tabs-mode)
 
-  (setq auto-fill-function 'kfill:do-auto-fill)
+  (setq auto-fill-function #'kfill:do-auto-fill)
 
   ;; If buffer has not yet been formatted for editing, format it.
   (let (version)
@@ -155,8 +326,9 @@ It provides the following keys:
   ;; Now that it is converted, ensure that `kotl-previous-mode' is set to
   ;; koutline now.
   (setq kotl-previous-mode 'kotl-mode)
-  (run-hooks 'kotl-mode-hook)
-  (add-hook 'change-major-mode-hook #'kotl-mode:show-all nil t))
+  (add-hook 'change-major-mode-hook #'kotl-mode:show-all nil t)
+  ;; Always run the mode-hook last.
+  (run-mode-hooks 'kotl-mode-hook))
 
 ;;;###autoload
 (defun kotl-mode:example ()
@@ -518,7 +690,7 @@ Skip cells with a non-nil no-fill attribute.
 With optional prefix argument TOP-P non-nil, refill all cells in the outline."
   (interactive "P")
   ;; Temporarily expand, then refill cells lacking no-fill property.
-  (kview:map-expanded-tree (lambda (view) (kotl-mode:fill-cell)) kview top-p))
+  (kview:map-expanded-tree (lambda (_view) (kotl-mode:fill-cell)) kview top-p))
 
 (defun kotl-mode:just-one-space ()
   "Delete all spaces and tabs around point and leave one space."
@@ -730,7 +902,11 @@ useful for editing binary files."
   "Sets fill prefix to line up to point.
 With prefix arg TURN-OFF or at begin of line, turns fill prefix off."
   (interactive "P")
-  (set-fill-prefix (or turn-off (kotl-mode:bolp))))
+  (if (or turn-off (kotl-mode:bolp))
+      (save-excursion
+        (forward-line 0)
+        (set-fill-prefix))
+    (set-fill-prefix)))
 
 (defun kotl-mode:tab-command (arg)
   "Tab over by ARG tab stops or demote the current tree a maximum of ARG 
levels.
@@ -875,6 +1051,8 @@ Goes backward if ARG is negative; error if CHAR not found."
 ;;; Editing across kotls
 ;;; ------------------------------------------------------------------------
 
+(defvar hargs:defaults)
+
 (defun kotl-mode:append-cell (contents-cell append-to-cell)
   "Append CONTENTS-CELL to APPEND-TO-CELL.
 APPEND-TO-CELL is refilled if neither cell has a no-fill property and
@@ -903,7 +1081,7 @@ kotl-mode:refill-flag is enabled."
 (defun kotl-mode:clipboard-yank ()
   "Insert the clipboard contents, or the last stretch of killed text."
   (interactive "*")
-  (let ((gui-select-enable-clipboard t))
+  (let ((select-enable-clipboard t))
     (kotl-mode:yank)))
 
 (defun kotl-mode:copy-after (from-cell-ref to-cell-ref child-p)
@@ -966,10 +1144,10 @@ whole outline buffer."
   (interactive
    (let ((label-default (kcell-view:label)))
      (hargs:iform-read
-      '(interactive
+      `(interactive
        (list
         (hargs:read "Copy tree without attributes: (0 for whole outline) "
-                    nil label-default nil 'kcell)
+                    nil ',label-default nil 'kcell)
         (read-buffer "To buffer: "
                      (save-window-excursion
                        (if (one-window-p)
@@ -1329,9 +1507,8 @@ paragraph-separating line.
 
 See `forward-paragraph' for more information."
   (interactive "p")
-  (setq arg (prefix-numeric-value arg)
-       zmacs-region-stays t);; Maintain region highlight for XEmacs.
-  (kotl-mode:forward-paragraph (- arg)))
+  (when (featurep 'xemacs) (setq zmacs-region-stays t))
+  (kotl-mode:forward-paragraph (- (or arg 1))))
 
 (defalias 'kotl-mode:backward-para 'kotl-mode:backward-paragraph)
 
@@ -1574,8 +1751,8 @@ A line which `paragraph-start' matches either separates 
paragraphs
 A paragraph end is one character before the beginning of a line which is not
 part of the paragraph, or the end of the buffer."
   (interactive "p")
-  (setq arg (prefix-numeric-value arg)
-       zmacs-region-stays t);; Maintain region highlight for XEmacs.
+  (when (featurep 'xemacs) (setq zmacs-region-stays t))
+  (setq arg (or arg 1))
   (if (< arg 0)
       (progn
        (if (kotl-mode:bocp) (setq arg (1- arg)))
@@ -2283,12 +2460,14 @@ If ARG is a non-positive number, nothing is done."
 Invisible text is expanded and included in the mail only if INVISIBLE-FLAG is
 non-nil."
   (interactive
+   ;; FIXME: Why use `hargs:iform-read' here?
+   ;; Why compute `label-default' before calling `hargs:iform-read'?
    (let ((label-default (kcell-view:label)))
      (hargs:iform-read
-      '(interactive
-       (list 
+      `(interactive
+       (list
         (hargs:read "Mail tree: (0 for whole outline) "
-                    nil label-default nil 'kcell)
+                    nil ',label-default nil 'kcell)
         (y-or-n-p "Include invisible text? "))))))
   (if (equal cell-ref "0")
       (hmail:buffer nil invisible-flag)
@@ -2504,9 +2683,11 @@ With optional prefix ALL-FLAG non-nil, collapse all 
cells visible
 within the current view."
   (interactive "P")
   (kotl-mode:is-p)
-  (let (buffer-read-only)
-    (kview:map-tree (lambda (kview)
-                     ;; Use free variable label-sep-len bound in 
kview:map-tree for speed.
+  (let ((inhibit-read-only t))
+    (kview:map-tree (lambda (_kview)
+                     ;; Use free variable label-sep-len bound in
+                     ;; kview:map-tree for speed.
+                      (defvar label-sep-len)
                      (kcell-view:collapse nil label-sep-len))
                    kview all-flag t)))
 
@@ -2516,10 +2697,11 @@ With optional prefix ALL-FLAG non-nil, expand all cells 
visible within
 the current view."
   (interactive "P")
   (kotl-mode:is-p)
-  (let (buffer-read-only)
+  (let ((inhibit-read-only t))
     (kview:map-tree
-     (lambda (kview)
+     (lambda (_kview)
        ;; Use free variable label-sep-len bound in kview:map-tree for speed.
+       (defvar label-sep-len)
        (goto-char (kcell-view:start (point) label-sep-len))
        (outline-flag-region (point) (kcell-view:end-contents) nil))
      kview all-flag t)))
@@ -2644,7 +2826,7 @@ See also the documentation for `kotl-mode:cell-help'."
     (with-help-window (hypb:help-buf-name "Koutliner")
       (save-excursion
        (if (not all-flag)
-           (kotl-mode:print-attributes kview)
+           (kotl-mode:print-attributes)
          (let ((label-sep-len (kview:label-separator-length kview)))
            (kotl-mode:beginning-of-buffer)
            (while (progn (kotl-mode:print-attributes kview)
@@ -2690,7 +2872,7 @@ See also the documentation for 
`kotl-mode:cell-attributes'."
                    (t (kotl-mode:cell-attributes t))))
          (cond ((= cells-flag 1)
                 (kotl-mode:goto-cell cell-ref)
-                (kotl-mode:print-attributes kview))
+                (kotl-mode:print-attributes))
                ((> cells-flag 1)
                 (kotl-mode:goto-cell cell-ref)
                 (kview:map-tree #'kotl-mode:print-attributes kview nil t))
@@ -2776,8 +2958,7 @@ removing Koutline structure."
   (interactive)
   ;; Caller has already tested for: (and (not (kotl-mode:valid-region-p)) 
(region-active-p))
   ;; Reduce the region to within the visible portion of a single cell
-  (let ((start (min (point) (mark)))
-       (end (max (point) (mark)))
+  (let ((end (max (point) (mark)))
        (exchange-p (> (point) (mark))))
     (if exchange-p (kotl-mode:exchange-point-and-mark))
     (kotl-mode:to-visible-position)
@@ -2858,10 +3039,10 @@ newlines at end of tree."
                               temporary-goal-column))))
     (move-to-column (if (numberp col) (round col) 0) nil)))
 
-(defun kotl-mode:print-attributes (kview)
-  "Print to the `standard-output' stream the attributes of the current visible 
kcell. 
-Takes argument KVIEW (so it can be used with `kview:map-tree' and so that
-KVIEW is bound correctly) but always operates upon the current view."
+(defun kotl-mode:print-attributes (&optional _kview)
+  "Print to the `standard-output' stream the attributes of the current visible 
kcell.
+Takes dummy argument KVIEW (so it can be used with `kview:map-tree')
+but always operates upon the current view."
   ;; Move to start of visible cell to avoid printing attributes for an
   ;; invisible kcell which point may be over.
   ;; Print first line of cell for reference.
@@ -2996,187 +3177,18 @@ Leave point at end of line now residing at START."
        nil)))
 
 (defun kotl-mode:maintain-region-highlight ()
-  (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
-  (setq transient-mark-mode t) ;; For GNU Emacs
-  )
+  (if (featurep 'xemacs)
+      (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
+    ;; FIXME: If the user set transient-mark-mode to nil, we shouldn't override
+    ;; his choice!
+    ;; FIXME: The way to prevent auto-deactivation of the region after buffer
+    ;; modifications is by let-binding `deactivate-mark' around the code
+    ;; modifying the buffer.
+    (setq transient-mark-mode t))) ;; For GNU Emacs
 
 ;;; ------------------------------------------------------------------------
 
-(unless kotl-mode-map
-  (setq kotl-mode-map
-       (cond ((fboundp 'copy-keymap)
-              (if (boundp 'indented-text-mode-map)
-                  (copy-keymap indented-text-mode-map)
-                (copy-keymap text-mode-map)))
-             (t (make-keymap))))
-  ;; Ensure mouse wheel scrolling leaves point in a valid Koutline position
-  (if (and (boundp 'mwheel-scroll-up-function)
-          (eq (symbol-value 'mwheel-scroll-up-function) 'scroll-up))
-      (setq mwheel-scroll-up-function 'kotl-mode:scroll-up
-           mwheel-scroll-down-function 'kotl-mode:scroll-down))
-  ;; Overload edit keys to deal with structure and labels.
-  (let (local-cmd)
-    (mapc
-     (lambda (cmd)
-       (setq local-cmd (intern-soft
-                       (concat "kotl-mode:" (symbol-name cmd))))
-       ;; Only bind key locally if kotl-mode local-cmd has already
-       ;; been defined and cmd is a valid function.
-       (if (and local-cmd (fboundp cmd))
-          (progn
-            ;; Make local-cmd have the same property list as cmd,
-            ;; e.g. so pending-delete property is the same.
-            (setplist local-cmd (symbol-plist cmd)) 
-            (substitute-key-definition
-             cmd local-cmd kotl-mode-map global-map))))
-
-     '(
-       back-to-indentation
-       backward-char
-       backward-delete-char
-       backward-delete-char-untabify
-       backward-kill-word
-       backward-or-forward-delete-char
-       backward-para
-       backward-paragraph
-       backward-sentence
-       backward-word
-       beginning-of-buffer
-       beginning-of-line
-       completion-kill-region
-       copy-region-as-kill
-       copy-to-register
-       delete-blank-lines
-       delete-backward-char
-       delete-char
-       delete-forward-char
-       delete-horizontal-space
-       delete-indentation
-       end-of-buffer
-       end-of-line
-       fill-paragraph
-       fill-paragraph-or-region
-       ;; cursor keys
-       fkey-backward-char
-       fkey-forward-char
-       fkey-next-line
-       fkey-previous-line
-       backward-char-command
-       forward-char-command
-       ;;
-       forward-char
-       forward-word
-       forward-para
-       forward-paragraph
-       forward-sentence
-       just-one-space
-       kill-word
-       kill-line
-       kill-region
-       kill-ring-save
-       kill-sentence
-       left-char
-       mark-paragraph
-       mark-whole-buffer
-       move-beginning-of-line
-       move-end-of-line
-       newline
-       newline-and-indent
-       next-line
-       open-line
-       previous-line
-       right-char
-       scroll-down
-       scroll-up
-       scroll-down-command
-       scroll-up-command
-       set-fill-prefix
-       transpose-chars
-       transpose-lines
-       transpose-paragraphs
-       transpose-sentences
-       transpose-words
-       yank
-       yank-pop
-       zap-to-char
-       )))
-
-
-  ;; kotl-mode keys
-  (define-key kotl-mode-map "\C-c@"     'kotl-mode:mail-tree)
-  (define-key kotl-mode-map "\C-c+"     'kotl-mode:append-cell)
-  (define-key kotl-mode-map "\C-c,"     'kotl-mode:beginning-of-cell)
-  (define-key kotl-mode-map "\C-c."     'kotl-mode:end-of-cell)
-  (define-key kotl-mode-map "\C-c<"     'kotl-mode:first-sibling)
-  (define-key kotl-mode-map "\C-c>"     'kotl-mode:last-sibling)
-  (define-key kotl-mode-map "\C-c^"     'kotl-mode:beginning-of-tree)
-  (define-key kotl-mode-map "\C-c$"     'kotl-mode:end-of-tree)
-  (define-key kotl-mode-map "\C-ca"     'kotl-mode:add-child)
-  (define-key kotl-mode-map "\C-c\C-a"  'kotl-mode:show-all)
-  (define-key kotl-mode-map "\C-cb"     'kvspec:toggle-blank-lines)
-  (define-key kotl-mode-map "\C-c\C-b"  'kotl-mode:backward-cell)
-  (define-key kotl-mode-map "\C-cc"     'kotl-mode:copy-after)
-  (define-key kotl-mode-map "\C-c\C-c"  'kotl-mode:copy-before)
-  (define-key kotl-mode-map "\C-c\M-c"  'kotl-mode:copy-to-buffer)
-  (define-key kotl-mode-map "\C-cd"     'kotl-mode:down-level)
-  (define-key kotl-mode-map "\C-c\C-d"  'kotl-mode:down-level)
-  (define-key kotl-mode-map "\C-ce"     'kotl-mode:exchange-cells)
-  (define-key kotl-mode-map "\C-c\C-f"  'kotl-mode:forward-cell)
-  (define-key kotl-mode-map "\C-cg"     'kotl-mode:goto-cell)
-  (define-key kotl-mode-map "\C-ch"     'kotl-mode:cell-help)
-  (define-key kotl-mode-map "\C-c\C-h"  'kotl-mode:hide-tree)
-  ;; Since the next key binds M-BS, it may already have a local binding,
-  ;; in which case we don't want to bind it here.
-  (if (string-match "XEmacs" emacs-version)
-      (unless (lookup-key kotl-mode-map '[(meta backspace)])
-       (define-key kotl-mode-map '[(meta backspace)] 'kotl-mode:hide-subtree))
-    ;; Do this under GNU Emacs only or will overwrite M-BS binding above.
-    (unless (lookup-key kotl-mode-map "\M-\C-h")
-      (define-key kotl-mode-map "\M-\C-h"   'kotl-mode:hide-subtree)))
-  ;; Override this global binding for set-selective-display with a similar
-  ;; function appropriate for kotl-mode.
-  (define-key kotl-mode-map "\C-x$"     'kotl-mode:hide-sublevels)
-  (define-key kotl-mode-map "\C-i"      'kotl-mode:tab-command) ;; TAB
-  (define-key kotl-mode-map [backtab]   'kotl-mode:untab-command) ;; Shift-TAB
-  (define-key kotl-mode-map "\M-\C-i"   'kotl-mode:untab-command) ;; M-TAB
-  (define-key kotl-mode-map "\C-c\C-i"  
'kotl-mode:set-or-remove-cell-attribute)
-  (define-key kotl-mode-map "\C-j"      'kotl-mode:add-cell)
-  (define-key kotl-mode-map "\M-j"      'kotl-mode:fill-paragraph)
-  (define-key kotl-mode-map "\C-c\M-j"  'kotl-mode:fill-cell)
-  (define-key kotl-mode-map "\M-\C-j"   'kotl-mode:fill-tree)
-  (define-key kotl-mode-map "\C-c\C-k"  'kotl-mode:kill-tree)
-  (define-key kotl-mode-map "\C-ck"     'kotl-mode:kill-contents)
-  ;; Force an override of the global {C-x i} insert-file binding
-  (define-key kotl-mode-map "\C-xi"     'kimport:insert-file)
-  ;; Force an override of the global {C-x r i} insert-register binding
-  (define-key kotl-mode-map "\C-xri"    'kimport:insert-register)
-  (define-key kotl-mode-map "\C-ck"     'kotl-mode:kill-contents)
-  (define-key kotl-mode-map "\C-cl"     'klink:create)
-  (define-key kotl-mode-map "\C-c\C-l"  'kview:set-label-type)
-  (define-key kotl-mode-map "\C-c\M-l"  'kview:set-label-separator)
-  (define-key kotl-mode-map "\C-m"      'kotl-mode:newline)
-  (define-key kotl-mode-map "\C-cm"     'kotl-mode:move-after)
-  (define-key kotl-mode-map "\C-c\C-m"  'kotl-mode:move-before)
-  (define-key kotl-mode-map "\C-c\C-n"  'kotl-mode:next-cell)
-  (define-key kotl-mode-map "\C-c\C-o"  'kotl-mode:overview)
-  (define-key kotl-mode-map "\C-c\C-p"  'kotl-mode:previous-cell)
-  (define-key kotl-mode-map "\C-cp"     'kotl-mode:add-parent)
-  (if (memq (global-key-binding "\M-q") '(fill-paragraph
-                                         fill-paragraph-or-region))
-      (progn
-       (define-key kotl-mode-map "\C-c\M-q" 'kotl-mode:fill-cell)
-       (define-key kotl-mode-map "\M-\C-q"  'kotl-mode:fill-tree)))
-  (define-key kotl-mode-map "\C-cs"     'kotl-mode:split-cell)
-  (define-key kotl-mode-map "\C-c\C-s"  'kotl-mode:show-tree)
-  (define-key kotl-mode-map "\C-c\C-\\" 'kotl-mode:show-tree)
-  (define-key kotl-mode-map "\M-s"      'kotl-mode:center-line)
-  (define-key kotl-mode-map "\M-S"      'kotl-mode:center-paragraph)
-  (define-key kotl-mode-map "\C-ct"     'kotl-mode:transpose-cells)
-  (define-key kotl-mode-map "\C-c\C-t"  'kotl-mode:top-cells)
-  (define-key kotl-mode-map "\C-cu"     'kotl-mode:up-level)
-  (define-key kotl-mode-map "\C-c\C-u"  'kotl-mode:up-level)
-  (define-key kotl-mode-map "\C-c\C-v"  'kvspec:activate)
-  (define-key kotl-mode-map "\C-x\C-w"  'kfile:write))
+
 
 ;; When delete-selection-mode (pending-delete-mode) is enabled, make
 ;; these commands delete the region.
diff --git a/kotl/kprop-em.el b/kotl/kprop-em.el
deleted file mode 100644
index 3509331..0000000
--- a/kotl/kprop-em.el
+++ /dev/null
@@ -1,92 +0,0 @@
-;;; kprop-em.el --- Koutline text property handling under GNU Emacs
-;;
-;; AUTHOR:       Bob Weiner
-;;
-;; Orig-Date:    7/27/93
-;;
-;; Copyright (C) 1993-2016  Free Software Foundation, Inc.
-;; See the "../HY-COPY" file for license information.
-;;
-;; This file is part of GNU Hyperbole.
-
-;;; Commentary:
-
-;;; Code:
-;;; ************************************************************************
-;;; Other required Elisp libraries
-;;; ************************************************************************
-
-(require 'hversion)
-
-;;; ************************************************************************
-;;; Public functions
-;;; ************************************************************************
-
-(defalias 'kproperty:get 'get-text-property)
-
-(defun kproperty:map (function property value)
-  "Apply FUNCTION to each character with PROPERTY `eq' to VALUE in the current 
buffer.
-FUNCTION is called with the start and end points of the text span with the 
matching PROPERTY
-and with point at the start."
-  (let ((result)
-       (start (point-min))
-       end)
-    (save-excursion
-      (while (and (< start (point-max))
-                 (setq start (text-property-any start (point-max) property 
value)))
-       (goto-char start)
-       (setq end (or (text-property-not-all start (point-max) property value) 
(point-max))
-             result (cons (funcall function start end) result)
-             start end)))
-    (nreverse result)))
-
-(defalias 'kproperty:next-single-change 'next-single-property-change)
-
-(defalias 'kproperty:previous-single-change 'previous-single-property-change)
-
-(defalias 'kproperty:properties 'text-properties-at)
-
-(defun kproperty:put (start end property-list &optional object)
-  "From START to END, add PROPERTY-LIST properties to the text.
-The optional fourth argument, OBJECT, is the string or buffer containing the
-text.  Text inserted before or after this region does not inherit the added
-properties."
-  (add-text-properties
-   start end (append property-list '(rear-nonsticky t)) object))
-
-(defun kproperty:remove (start end property-list &optional object)
-  "From START to END, remove the text properties in PROPERTY-LIST.
-The optional fourth argument, OBJECT, is the string or buffer containing the
-text.  PROPERTY-LIST should be a plist; if the value of a property is
-non-nil, then only a property with a matching value will be removed.
-Returns t if any property was changed, nil otherwise."
-  (let ((changed) plist property value next)
-    (while property-list
-      (setq property (car property-list)
-           value (car (cdr property-list))
-           plist (list property value)
-           property-list (nthcdr 2 property-list)
-           next start)
-      (while (setq next (text-property-any next end property value object))
-       (remove-text-properties next (1+ next) plist object)
-       (setq changed t next (1+ next))))
-    changed))
-
-(defun kproperty:replace-separator (pos label-separator old-sep-len)
-  "Replace at POS the cell label separator with LABEL-SEPARATOR.
-OLD-SEP-LEN is the length of the separator being replaced."
-  (let (properties)
-    (while (setq pos (kproperty:next-single-change (point) 'kcell))
-      (goto-char pos)
-      (setq properties (text-properties-at pos))
-      ;; Replace label-separator while maintaining cell properties.
-      (insert label-separator)
-      (add-text-properties pos (+ pos 2) properties)
-      (delete-region (point) (+ (point) old-sep-len)))))
-
-(defun kproperty:set (property value)
-  "Set PROPERTY of character at point to VALUE."
-  (kproperty:put (point) (min (+ 2 (point)) (point-max))
-                (list property value)))
-
-;;; kprop-em.el ends here
diff --git a/kotl/kprop-xe.el b/kotl/kprop-xe.el
deleted file mode 100644
index 587d098..0000000
--- a/kotl/kprop-xe.el
+++ /dev/null
@@ -1,135 +0,0 @@
-;;; kprop-xe.el --- Koutline text property handling under XEmacs
-;;
-;; Author:       Bob Weiner
-;;
-;; Orig-Date:    7/27/93
-;;
-;; Copyright (C) 1993-2016  Free Software Foundation, Inc.
-;; See the "../HY-COPY" file for license information.
-;;
-;; This file is part of GNU Hyperbole.
-
-;;; Commentary:
-
-;;; Code:
-;;; ************************************************************************
-;;; Other required Elisp libraries
-;;; ************************************************************************
-
-(require 'hversion)
-
-;;; ************************************************************************
-;;; Public functions
-;;; ************************************************************************
-
-;; (get-text-property (pos prop &optional object))
-;; Return the value of position POS's property PROP, in OBJECT.
-;; OBJECT is optional and defaults to the current buffer.
-;; If POSITION is at the end of OBJECT, the value is nil.
-(defalias 'kproperty:get 'get-text-property)
-
-(defun kproperty:map (function property &optional value)
-  "Apply FUNCTION to each character with PROPERTY `eq' to VALUE in the current 
buffer.
-FUNCTION is called with the start and end points of the text span with the 
matching PROPERTY
-and with point at the start."
-  (let ((result)
-       (start) end)
-    (save-excursion
-      (map-extents (lambda (extent unused)
-                      (if (setq start (extent-start-position extent))
-                          (progn (goto-char start)
-                                 (setq end (extent-end-position extent)
-                                       result (cons (funcall function start 
end) result))))
-                      nil)
-                  nil nil nil nil nil property value))
-    (nreverse result)))
-
-;; (next-single-property-change (pos prop &optional object))
-;; Return the position of next property change for a specific property.
-;; Scans characters forward from POS till it finds
-;; a change in the PROP property, then returns the position of the change.
-;; The optional third argument OBJECT is the string or buffer to scan.
-;; Return nil if the property is constant all the way to the end of OBJECT.
-;; If the value is non-nil, it is a position greater than POS, never equal.
-(defalias 'kproperty:next-single-change 'next-single-property-change)
-
-;; (previous-single-property-change (pos prop &optional object))
-;; Return the position of previous property change for a specific property.
-;; Scans characters backward from POS till it finds
-;; a change in the PROP property, then returns the position of the change.
-;; The optional third argument OBJECT is the string or buffer to scan.
-;; Return nil if the property is constant all the way to the start of OBJECT.
-;; If the value is non-nil, it is a position less than POS, never equal.
-(defalias 'kproperty:previous-single-change 'previous-single-property-change)
-
-(defalias 'kproperty:properties 'extent-properties-at)
-
-(defun kproperty:put (start end property-list &optional object)
-  "From START to END, add PROPERTY-LIST properties to the text.
-The optional fourth argument, OBJECT, is the string or buffer containing the
-text.  Text inserted before or after this region does not inherit the added
-properties."
-  ;; Don't use text properties internally because they don't work as desired
-  ;; when copied to a string and then reinserted, at least in some versions
-  ;; of XEmacs.
-  (let ((extent (make-extent start end object)))
-    (if (null extent)
-       (error "(kproperty:put): No extent at %d-%d to add properties %s" 
-              start end property-list))
-    (if (/= (mod (length property-list) 2) 0)
-       (error "(kproperty:put): Property-list has odd number of elements, %s"
-              property-list))
-    (set-extent-property extent 'text-prop (car property-list))
-    (set-extent-property extent 'duplicable t)
-    (set-extent-property extent 'start-open t)
-    (set-extent-property extent 'end-open t)
-    (while property-list
-      (set-extent-property
-       extent (car property-list) (car (cdr property-list)))
-      (setq property-list (nthcdr 2 property-list)))
-    extent))
-
-(defun kproperty:remove (start end property-list &optional object)
-  "From START to END, remove the text properties in PROPERTY-LIST.
-The optional fourth argument, OBJECT, is the string or buffer containing the
-text.  PROPERTY-LIST should be a plist; if the value of a property is
-non-nil, then only a property with a matching value will be removed.
-Returns t if any property was changed, nil otherwise."
-  ;; Don't use text property functions internally because they only look for
-  ;; closed extents, which kproperty does not use.
-  (let ((changed) property value)
-    (while property-list
-      (setq property (car property-list)
-           value (car (cdr property-list))
-           property-list (nthcdr 2 property-list))
-      (map-extents
-       (lambda (extent maparg)
-        (if (extent-live-p extent)
-            (progn (setq changed t)
-                   (delete-extent extent)))
-        nil)
-       object start end nil nil property value))
-    changed))
-
-(defun kproperty:replace-separator (pos label-separator old-sep-len)
-  "Replace at POS the cell label separator with LABEL-SEPARATOR.
-OLD-SEP-LEN is the length of the separator being replaced."
-  (let (extent)
-    (while (setq pos (kproperty:next-single-change (point) 'kcell))
-      (goto-char pos)
-      (setq extent (extent-at pos))
-      ;; Replace label-separator while maintaining cell properties.
-      (insert label-separator)
-      (set-extent-endpoints extent pos (+ pos 2))
-      (delete-region (point) (+ (point) old-sep-len)))))
-
-(defun kproperty:set (property value)
-  "Set PROPERTY of character at point to VALUE."
-  (kproperty:put (point) (min (+ 2 (point)) (point-max))
-                (list property value)))
-
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
-
-;;; kprop-xe.el ends here
diff --git a/kotl/kproperty.el b/kotl/kproperty.el
index 9b1e0e5..134e737 100644
--- a/kotl/kproperty.el
+++ b/kotl/kproperty.el
@@ -1,4 +1,4 @@
-;;; kproperty.el --- Wrapper for koutline text property implementations
+;;; kproperty.el --- Wrapper for koutline text property implementations  -*- 
lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
@@ -12,16 +12,147 @@
 ;;; Commentary:
 
 ;;; Code:
+
 ;;; ************************************************************************
-;;; Other required Elisp libraries
+;;; Public functions
 ;;; ************************************************************************
 
-;; Ensures kotl/ is in load-path.
-(require 'hyperbole)
+;; (get-text-property (pos prop &optional object))
+;; Return the value of position POS's property PROP, in OBJECT.
+;; OBJECT is optional and defaults to the current buffer.
+;; If POSITION is at the end of OBJECT, the value is nil.
+(defalias 'kproperty:get #'get-text-property)
+
+(defun kproperty:map (function property value)
+  "Apply FUNCTION to each character with PROPERTY `eq' to VALUE in the current 
buffer.
+FUNCTION is called with the start and end points of the text span with the 
matching PROPERTY
+and with point at the start."
+  (let ((result)
+       (start) end)
+    (save-excursion
+      (if (featurep 'xemacs)
+          (map-extents (lambda (extent _)
+                        (when (setq start (extent-start-position extent))
+                           (goto-char start)
+                          (setq end (extent-end-position extent))
+                          (push (funcall function start end) result))
+                        nil)
+                      nil nil nil nil nil property value)
+        ;; Emacs version.
+       (setq start (point-min))
+        (while (and (< start (point-max))
+                   (setq start (text-property-any start (point-max)
+                                                   property value)))
+         (goto-char start)
+         (setq end (or (text-property-not-all start (point-max) property 
value) (point-max)))
+         (push (funcall function start end) result)
+         (setq start end))))
+    (nreverse result)))
+
+;; (next-single-property-change (pos prop &optional object))
+;; Return the position of next property change for a specific property.
+;; Scans characters forward from POS till it finds
+;; a change in the PROP property, then returns the position of the change.
+;; The optional third argument OBJECT is the string or buffer to scan.
+;; Return nil if the property is constant all the way to the end of OBJECT.
+;; If the value is non-nil, it is a position greater than POS, never equal.
+(defalias 'kproperty:next-single-change #'next-single-property-change)
+
+;; (previous-single-property-change (pos prop &optional object))
+;; Return the position of previous property change for a specific property.
+;; Scans characters backward from POS till it finds
+;; a change in the PROP property, then returns the position of the change.
+;; The optional third argument OBJECT is the string or buffer to scan.
+;; Return nil if the property is constant all the way to the start of OBJECT.
+;; If the value is non-nil, it is a position less than POS, never equal.
+(defalias 'kproperty:previous-single-change #'previous-single-property-change)
+
+(defalias 'kproperty:properties
+  (if (featurep 'xemacs) #'extent-properties-at #'text-properties-at))
+
+(defun kproperty:put (start end property-list &optional object)
+  "From START to END, add PROPERTY-LIST properties to the text.
+The optional fourth argument, OBJECT, is the string or buffer containing the
+text.  Text inserted before or after this region does not inherit the added
+properties."
+  (if (not (featurep 'xemacs))
+      ;; Emacs version.
+      (add-text-properties
+       ;; FIXME: Here we force `rear-nonsticky' on all properties, including
+       ;; those not applied via `kproperty:put'!
+       start end (append property-list '(rear-nonsticky t)) object)
+    ;; XEmacs version.
+    ;; Don't use text properties internally because they don't work as desired
+    ;; when copied to a string and then reinserted, at least in some versions
+    ;; of XEmacs.
+    (let ((extent (make-extent start end object)))
+      (if (null extent)
+         (error "(kproperty:put): No extent at %d-%d to add properties %s" 
+                start end property-list))
+      (if (/= (mod (length property-list) 2) 0)
+         (error "(kproperty:put): Property-list has odd number of elements, %s"
+                property-list))
+      (set-extent-property extent 'text-prop (car property-list))
+      (set-extent-property extent 'duplicable t)
+      (set-extent-property extent 'start-open t)
+      (set-extent-property extent 'end-open t)
+      (while property-list
+        (set-extent-property
+         extent (car property-list) (car (cdr property-list)))
+        (setq property-list (nthcdr 2 property-list)))
+      extent)))
+
+(defun kproperty:remove (start end property-list &optional object)
+  "From START to END, remove the text properties in PROPERTY-LIST.
+The optional fourth argument, OBJECT, is the string or buffer containing the
+text.  PROPERTY-LIST should be a plist; if the value of a property is
+non-nil, then only a property with a matching value will be removed.
+Returns t if any property was changed, nil otherwise."
+  ;; Don't use text property functions internally because they only look for
+  ;; closed extents, which kproperty does not use.
+  (let ((changed) property value)
+    (while property-list
+      (setq property (car property-list)
+           value (car (cdr property-list))
+           property-list (nthcdr 2 property-list))
+      (if (featurep 'xemacs)
+          (map-extents
+           (lambda (extent _)
+            (if (extent-live-p extent)
+                (progn (setq changed t)
+                       (delete-extent extent)))
+            nil)
+           object start end nil nil property value)
+        ;; Emacs version.
+        (let ((next start))
+          (while (setq next (text-property-any next end property value object))
+            ;; FIXME: Rather than remove it one-char at a time, we can use
+            ;; next-single-property-change to do it more efficiently!
+           (remove-text-properties next (1+ next) (list property value) object)
+           (setq changed t next (1+ next))))))
+    changed))
+
+(defun kproperty:replace-separator (pos label-separator old-sep-len)
+  "Replace at POS the cell label separator with LABEL-SEPARATOR.
+OLD-SEP-LEN is the length of the separator being replaced."
+  (while (setq pos (kproperty:next-single-change (point) 'kcell))
+    (goto-char pos)
+    (if (featurep 'xemacs)
+        (let ((extent (extent-at pos)))
+          ;; Replace label-separator while maintaining cell properties.
+          (insert label-separator)
+          (set-extent-endpoints extent pos (+ pos 2)))
+      ;; Emacs version
+      (let ((properties (text-properties-at pos)))
+        ;; Replace label-separator while maintaining cell properties.
+        (insert label-separator)
+        (add-text-properties pos (+ pos 2) properties)))
+    (delete-region (point) (+ (point) old-sep-len))))
 
-;; FIXME: Loading an Elisp file should always be harmless, so Emacs should be
-;; able to load *both* files and still work right!
-(load (if (not (featurep 'xemacs)) "kprop-em" "kprop-xe"))
+(defun kproperty:set (property value)
+  "Set PROPERTY of character at point to VALUE."
+  (kproperty:put (point) (min (+ 2 (point)) (point-max))
+                (list property value)))
 
 (provide 'kproperty)
 
diff --git a/kotl/kview.el b/kotl/kview.el
index 3c108b5..14954a4 100644
--- a/kotl/kview.el
+++ b/kotl/kview.el
@@ -16,16 +16,32 @@
 ;;; Other required Lisp Libraries
 ;;; ************************************************************************
 
-(eval-and-compile (mapc #'require '(klabel kfill hypb)))
-;; Quiet byte compiler warnings for this free variable.
-(eval-when-compile
-  (defvar label-sep-len nil))
+(eval-and-compile (mapc #'require '(klabel kfill hypb kproperty kcell)))
+
+;; Quiet byte compiler warnings for functions from kotl-mode (which
+;; we can't require because it requires us).
+(declare-function kotl-mode:to-start-of-line "kotl-mode")
+(declare-function kotl-mode:to-end-of-line "kotl-mode")
+(declare-function kotl-mode:tree-end "kotl-mode")
+(declare-function kotl-mode:goto-cell "kotl-mode")
+(declare-function kotl-mode:to-visible-position "kotl-mode")
+(declare-function kotl-mode:to-valid-position "kotl-mode")
+(declare-function kotl-mode:fill-cell "kotl-mode")
+(declare-function kotl-mode:hide-subtree "kotl-mode")
+;; Same for kfile.
+(declare-function kfile:narrow-to-kcells "kfile")
+;; Same for kvspec.
+(declare-function kvspec:show-lines-this-cell "kvspec")
+(declare-function kvspec:update "kvspec")
 
 ;;; ************************************************************************
 ;;; Public variables
 ;;; ************************************************************************
 
-(set-default 'kview nil)
+
+;; FIXME: Rename it to kview-current or something, so as to distinguish it from
+;; the uses of this identifier for function args and other lexically-bound 
vars.
+(defvar kview nil)
 
 (defcustom kview:default-blank-lines t
   "*Default setting of whether to show blank lines between koutline cells.
@@ -177,8 +193,7 @@ a cell's label and the start of its contents.
 Any cell that is invisible is also collapsed as indicated by a call to
 `kcell-view:collapsed-p'."
   (let ((start (1- (kcell-view:start pos label-sep-len))) ;; Allow for empty 
cell
-       (end (kcell-view:end-contents pos))
-       (invisible))
+       (end (kcell-view:end-contents pos)))
     (if (delq nil (mapcar (lambda (o)
                              (and (eq (overlay-get o 'invisible) 'outline)
                                   (>= start (overlay-start o))
@@ -659,7 +674,8 @@ the lines displayed, since it has hidden branches."
   ;; subcells, indicating its branches are hidden.
   (kview:map-region
    (lambda ()
-     (cond ((kcell-view:next-invisible-p (point) label-sep-len)
+     (defvar label-sep-len)             ;Bound by kview:map-region.
+     (cond ((kcell-view:next-invisible-p label-sep-len)
            ;; Skip to end of this subtree
            (prog1 (- (kcell-view:lines-visible))
              (goto-char (kotl-mode:tree-end t))))
@@ -668,8 +684,8 @@ the lines displayed, since it has hidden branches."
           (t 0)))
    kview t start end))
 
-(defun kcell-view:next-invisible-p (&optional pos label-sep-len)
-  "Return t if there is a next cell after optional POS or point and it is 
invisible."
+(defun kcell-view:next-invisible-p (&optional label-sep-len)
+  "Return t if there is a next cell after point and it is invisible."
   (save-excursion (and (kcell-view:next nil label-sep-len)
                       (kcell-view:invisible-p (point) label-sep-len))))
 
@@ -701,7 +717,7 @@ the lines displayed, since it has hidden branches."
                 label-end kcell)
             (setq label-end
                   (map-extents
-                   (lambda (extent unused)
+                   (lambda (extent _)
                      (setq kcell (extent-property extent 'kcell))
                      (and kcell (= (kcell:idstamp kcell) cell-id)
                           (extent-end-position extent)))
@@ -727,9 +743,9 @@ the lines displayed, since it has hidden branches."
     (if (kotl-mode:goto-cell permanent-id)
        (kcell-view:label))))
 
-(defun kview:insert-contents (kcell contents no-fill fill-prefix)
+(defun kview:insert-contents (kcell contents no-fill cell-fill-prefix)
   "Insert KCELL's CONTENTS into view at point and fill resulting paragraphs, 
unless NO-FILL is non-nil.
-FILL-PREFIX is the indentation string for the current cell.
+CELL-FILL-PREFIX is the indentation string for the current cell.
 If CONTENTS is nil, get contents from KCELL.  Return contents inserted (this
 value may differ from the value passed in.)"
   (let ((start (point))
@@ -751,7 +767,7 @@ value may differ from the value passed in.)"
            (narrow-to-region start end)
            (goto-char (point-min))
            (while (re-search-forward "[\n\r]" nil t)
-             (insert fill-prefix))
+             (insert cell-fill-prefix))
            (goto-char (point-max)))
        ;;
        ;; Filling cell will insert proper indent on all lines.
@@ -760,15 +776,15 @@ value may differ from the value passed in.)"
          (goto-char start)
          (beginning-of-line)
          (narrow-to-region (point) end)
-         ;; Add fill-prefix to all but paragraph separator lines, so
+         ;; Add cell-fill-prefix to all but paragraph separator lines, so
          ;; filling is done properly.
          (while (re-search-forward "[\n\r][^\n\r]" nil t)
-           (forward-char -1) (insert fill-prefix))
+           (forward-char -1) (insert cell-fill-prefix))
          (kview:fill-region start end kcell)
          (goto-char (point-min))
-         ;; Now add fill-prefix to paragraph separator lines.
+         ;; Now add cell-fill-prefix to paragraph separator lines.
          (while (re-search-forward "[\n\r][\n\r]" nil t)
-           (forward-char -1) (insert fill-prefix))
+           (forward-char -1) (insert cell-fill-prefix))
          ;;
          (goto-char (point-max))))))
   contents)
@@ -823,7 +839,7 @@ See documentation for kview:default-level-indent."
       (kview:get-attr kview 'level-indent)))
 
 (defun kview:map-branch (func kview &optional first-p visible-p)
-  "Applies FUNC to the sibling trees from point forward within KVIEW and 
returns results as a list.
+  "Apply FUNC to the sibling trees from point forward within KVIEW and return 
results as a list.
 With optional FIRST-P non-nil, begins with first sibling in current branch.
 With optional VISIBLE-P, considers only those sibling cells that are visible
 in the view.
@@ -831,26 +847,28 @@ in the view.
 FUNC should take one argument, the kview local variable of the current
 buffer or some other kview, and should operate upon the cell at point.
 
-`Cell-indent' contains the indentation value of the first cell mapped when
-FUNC is called so that it may test against this value.  `Label-sep-len'
+`cell-indent' contains the indentation value of the first cell mapped when
+FUNC is called so that it may test against this value.  `label-sep-len'
 contains the label separator length.
 
 See also `kview:map-region', `kview:map-siblings' and `kview:map-tree'."
-    (with-current-buffer (kview:buffer kview)
-      (save-excursion
-       (let ((results)
-             (label-sep-len (kview:label-separator-length kview))
-             cell-indent)
-         (if first-p
-             ;; Move back to first predecessor at same level.
-             (while (kcell-view:backward t label-sep-len)))
-         (setq cell-indent (kcell-view:indent nil label-sep-len))
-         ;; Terminate when no further cells or when reach a cell at an equal
-         ;; or higher level in the kotl than the first cell that we processed.
-         (while (and (setq results (cons (funcall func kview) results))
-                     (kcell-view:next visible-p label-sep-len)
-                     (> (kcell-view:indent nil label-sep-len) cell-indent)))
-         (nreverse results)))))
+  (defvar label-sep-len)                ;FIXME: Use appropriate package prefix!
+  (defvar cell-indent)                  ;FIXME: Not used!
+  (with-current-buffer (kview:buffer kview)
+    (save-excursion
+      (let ((results)
+           (label-sep-len (kview:label-separator-length kview))
+           cell-indent)
+       (if first-p
+           ;; Move back to first predecessor at same level.
+           (while (kcell-view:backward t label-sep-len)))
+       (setq cell-indent (kcell-view:indent nil label-sep-len))
+       ;; Terminate when no further cells or when reach a cell at an equal
+       ;; or higher level in the kotl than the first cell that we processed.
+       (while (and (setq results (cons (funcall func kview) results))
+                   (kcell-view:next visible-p label-sep-len)
+                   (> (kcell-view:indent nil label-sep-len) cell-indent)))
+       (nreverse results)))))
 
 (defun kview:map-region (func kview &optional visible-p start end)
   "Applies FUNC to each cell in the region within KVIEW and returns results as 
a list.
@@ -860,9 +878,10 @@ than the bounds of the active region.
 
 FUNC should take no arguments and should operate upon the cell at point.
 
-`Label-sep-len’ contains the label separator length.
+`label-sep-len’ contains the label separator length.
 
 See also `kview:map-tree', `kview:map-branch’, and ‘kview:map-siblings’."
+  (defvar label-sep-len)                ;FIXME: Use appropriate package prefix!
   (with-current-buffer (kview:buffer kview)
     (save-excursion
       (let* ((results)
@@ -893,7 +912,7 @@ See also `kview:map-tree', `kview:map-branch’, and 
‘kview:map-siblings’."
              (t (error "(kview:map-region): No region or invalid start and end 
positions")))))))
 
 (defun kview:map-siblings (func kview &optional first-p visible-p)
-  "Applies FUNC to the sibling cells from point forward within KVIEW and 
returns results as a list.
+  "Apply FUNC to the sibling cells from point forward within KVIEW and returns 
results as a list.
 With optional FIRST-P non-nil, begins with first sibling in current branch.
 With optional VISIBLE-P, considers only those sibling cells that are visible
 in the view.
@@ -901,30 +920,32 @@ in the view.
 FUNC should take one argument, the kview local variable of the current
 buffer or some other kview, and should operate upon the cell at point.
 
-`Cell-indent' contains the indentation value of the first cell mapped when
-FUNC is called so that it may test against this value.  `Label-sep-len'
+`cell-indent' contains the indentation value of the first cell mapped when
+FUNC is called so that it may test against this value.  `label-sep-len'
 contains the label separator length.
 
 See also `kview:map-branch' and `kview:map-tree'."
-    (with-current-buffer (kview:buffer kview)
-      (save-excursion
-       (let ((results)
-             (label-sep-len (kview:label-separator-length kview))
-             cell-indent)
-         ;; Next line ensures point is in the root of the current tree if
-         ;; the tree is at all hidden.
-         (if visible-p (kotl-mode:to-start-of-line))
-         (if first-p
-             ;; Move back to first predecessor at same level.
-             (while (kcell-view:backward t label-sep-len)))
-         (setq cell-indent (kcell-view:indent nil label-sep-len))
-         ;; Terminate when no further cells at same level.
-         (while (progn (setq results (cons (funcall func kview) results))
-                       (kcell-view:forward visible-p label-sep-len)))
-         (nreverse results)))))
+  (defvar label-sep-len)                ;FIXME: Use appropriate package prefix!
+  (defvar cell-indent)                  ;FIXME: Not used!
+  (with-current-buffer (kview:buffer kview)
+    (save-excursion
+      (let ((results)
+           (label-sep-len (kview:label-separator-length kview))
+           cell-indent)
+       ;; Next line ensures point is in the root of the current tree if
+       ;; the tree is at all hidden.
+       (if visible-p (kotl-mode:to-start-of-line))
+       (if first-p
+           ;; Move back to first predecessor at same level.
+           (while (kcell-view:backward t label-sep-len)))
+       (setq cell-indent (kcell-view:indent nil label-sep-len))
+       ;; Terminate when no further cells at same level.
+       (while (progn (setq results (cons (funcall func kview) results))
+                     (kcell-view:forward visible-p label-sep-len)))
+       (nreverse results)))))
 
 (defun kview:map-expanded-tree (func kview &optional top-p)
-  "Temporarily expands the tree at point, applies FUNC to the tree in the 
KVIEW and returns results as a list.
+  "Temporarily expand the tree at point, applies FUNC to the tree in the KVIEW 
and returns results as a list.
 This is for a FUNC that requires all cells in the tree be fully visible and
 expanded before operating upon it.  If this is not the case, use
 `kview:map-tree' instead.  FUNC may not change the number of or the order of
@@ -935,48 +956,50 @@ With optional TOP-P non-nil, maps over all of kview's 
cells.
 FUNC should take one argument, the kview with the tree to map, and should
 operate upon the cell at point.
 
-`Cell-indent' contains the indentation value of the first cell mapped when
-FUNC is called so that it may test against this value.  `Label-sep-len'
+`cell-indent' contains the indentation value of the first cell mapped when
+FUNC is called so that it may test against this value.  `label-sep-len'
 contains the label separator length.
 
 See also `kview:map-region', `kview:map-branch' and `kview:map-siblings'."
-    (with-current-buffer (kview:buffer kview)
-      (save-excursion
-       ;; Next line ensures point is in the root of the current tree if
-       ;; the tree is at all hidden.
-       (unless top-p (kotl-mode:to-start-of-line))
-       (let* ((results)
-              (label-sep-len (kview:label-separator-length kview))
-              (start (set-marker (make-marker) (if top-p (point-min) (point))))
-              (end (set-marker (make-marker) (if top-p (point-max) 
(save-excursion (kotl-mode:tree-end)))))
-              (collapsed-cells (kview:get-cells-status kview start end))
-              cell-indent)
-         ;;
-         ;; Expand all cells in tree.
-         (outline-flag-region start end nil)
-         ;;
-         (if top-p
-             (progn (goto-char (point-min))
-                    (kview:end-of-actual-line)
-                    ;; Terminate when no further cells to process.
-                    (while (progn (setq results (cons (funcall func kview) 
results))
-                                  (kcell-view:next nil label-sep-len))))
-           (setq cell-indent (kcell-view:indent nil label-sep-len))
-           ;; Terminate when no further cells or when reach a cell at an equal
-           ;; or higher level in the kotl than the first cell that we 
processed.
-           (while (and (setq results (cons (funcall func kview) results))
-                       (kcell-view:next nil label-sep-len)
-                       (> (kcell-view:indent nil label-sep-len)
-                          cell-indent))))
-         ;;
-         ;; Restore status of temporarily expanded cells.
-         (if (remq 0 collapsed-cells)
-             (kview:set-cells-status kview start end collapsed-cells))
-         ;;
-         ;; Remove markers.
-         (set-marker start nil)
-         (set-marker end nil)
-         (nreverse results)))))
+  (defvar label-sep-len)                ;FIXME: Use appropriate package prefix!
+  (defvar cell-indent)                  ;FIXME: Not used!
+  (with-current-buffer (kview:buffer kview)
+    (save-excursion
+      ;; Next line ensures point is in the root of the current tree if
+      ;; the tree is at all hidden.
+      (unless top-p (kotl-mode:to-start-of-line))
+      (let* ((results)
+            (label-sep-len (kview:label-separator-length kview))
+            (start (set-marker (make-marker) (if top-p (point-min) (point))))
+            (end (set-marker (make-marker) (if top-p (point-max) 
(save-excursion (kotl-mode:tree-end)))))
+            (collapsed-cells (kview:get-cells-status kview start end))
+            cell-indent)
+       ;;
+       ;; Expand all cells in tree.
+       (outline-flag-region start end nil)
+       ;;
+       (if top-p
+           (progn (goto-char (point-min))
+                  (kview:end-of-actual-line)
+                  ;; Terminate when no further cells to process.
+                  (while (progn (setq results (cons (funcall func kview) 
results))
+                                (kcell-view:next nil label-sep-len))))
+         (setq cell-indent (kcell-view:indent nil label-sep-len))
+         ;; Terminate when no further cells or when reach a cell at an equal
+         ;; or higher level in the kotl than the first cell that we processed.
+         (while (and (setq results (cons (funcall func kview) results))
+                     (kcell-view:next nil label-sep-len)
+                     (> (kcell-view:indent nil label-sep-len)
+                        cell-indent))))
+       ;;
+       ;; Restore status of temporarily expanded cells.
+       (if (remq 0 collapsed-cells)
+           (kview:set-cells-status kview start end collapsed-cells))
+       ;;
+       ;; Remove markers.
+       (set-marker start nil)
+       (set-marker end nil)
+       (nreverse results)))))
 
 (defun kview:map-tree (func kview &optional top-p visible-p)
   "Applies FUNC to the tree starting at point within KVIEW and returns results 
as a list.
@@ -987,33 +1010,35 @@ view.
 FUNC should take one argument, the kview with the tree to map, and
 should operate upon the cell at point.
 
-`Cell-indent' contains the indentation value of the first cell mapped when
-FUNC is called so that it may test against this value.  `Label-sep-len'
+`cell-indent' contains the indentation value of the first cell mapped when
+FUNC is called so that it may test against this value.  `label-sep-len'
 contains the label separator length.
 
 See also `kview:map-region', `kview:map-branch' and `kview:map-siblings'."
-    (with-current-buffer (kview:buffer kview)
-      (save-excursion
-       (let ((results)
-             (label-sep-len (kview:label-separator-length kview))
-             cell-indent)
-         (if top-p
-             (progn (goto-char (point-min))
-                    (kview:end-of-actual-line)
-                    ;; Terminate when no further cells to process.
-                    (while (progn (setq results (cons (funcall func kview) 
results))
-                                  (kcell-view:next visible-p label-sep-len))))
-           ;; Next line ensures point is in the root of the current tree if
-           ;; the tree is at all hidden.
-           (kotl-mode:to-start-of-line)
-           (setq cell-indent (kcell-view:indent nil label-sep-len))
-           ;; Terminate when no further cells or when reach a cell at an equal
-           ;; or higher level in the kotl than the first cell that we 
processed.
-           (while (and (setq results (cons (funcall func kview) results))
-                       (kcell-view:next visible-p label-sep-len)
-                       (> (kcell-view:indent nil label-sep-len)
-                          cell-indent))))
-         (nreverse results)))))
+  (defvar label-sep-len)                ;FIXME: Use appropriate package prefix!
+  (defvar cell-indent)                  ;FIXME: Not used!
+  (with-current-buffer (kview:buffer kview)
+    (save-excursion
+      (let ((results)
+           (label-sep-len (kview:label-separator-length kview))
+           cell-indent)
+       (if top-p
+           (progn (goto-char (point-min))
+                  (kview:end-of-actual-line)
+                  ;; Terminate when no further cells to process.
+                  (while (progn (setq results (cons (funcall func kview) 
results))
+                                (kcell-view:next visible-p label-sep-len))))
+         ;; Next line ensures point is in the root of the current tree if
+         ;; the tree is at all hidden.
+         (kotl-mode:to-start-of-line)
+         (setq cell-indent (kcell-view:indent nil label-sep-len))
+         ;; Terminate when no further cells or when reach a cell at an equal
+         ;; or higher level in the kotl than the first cell that we processed.
+         (while (and (setq results (cons (funcall func kview) results))
+                     (kcell-view:next visible-p label-sep-len)
+                     (> (kcell-view:indent nil label-sep-len)
+                        cell-indent))))
+       (nreverse results)))))
 
 (defun kview:move (from-start from-end to-start from-indent to-indent
                   &optional copy-p fill-p)
@@ -1064,7 +1089,7 @@ FILL-P is non-nil.  Leave point at TO-START."
                                         1)
                                      ?\ )))
              (kview:map-tree
-              (lambda (view)
+              (lambda (_view)
                 (save-excursion
                   (beginning-of-line)
                   (if (looking-at expr)
@@ -1073,7 +1098,7 @@ FILL-P is non-nil.  Leave point at TO-START."
          ;;
          (if fill-p
              ;; Refill cells lacking no-fill attribute.
-             (kview:map-tree (lambda (view) (kotl-mode:fill-cell nil t))
+             (kview:map-tree (lambda (_view) (kotl-mode:fill-cell nil t))
                              kview t))))
     ;;
     (goto-char new-start)
@@ -1126,6 +1151,7 @@ displayed, since it has hidden branches."
              ;; Hide the subtree of this cell and display only
              ;; (- status) lines.
              (kvspec:show-lines-this-cell (- status))
+              (defvar label-sep-len)    ;Bound by kview:map-region.
              (if (save-excursion (kcell-view:parent nil label-sep-len))
                  (kotl-mode:hide-subtree)
                (error "(kview:set-cells-status): Invisible cell `%s' is 
missing its parent cell"
diff --git a/kotl/kvspec.el b/kotl/kvspec.el
index 98dfc5f..a9e5354 100644
--- a/kotl/kvspec.el
+++ b/kotl/kvspec.el
@@ -1,4 +1,4 @@
-;;; kvspec.el --- Koutline view specification
+;;; kvspec.el --- Koutline view specification  -*- lexical-binding:t -*-
 ;;
 ;; Author:       Bob Weiner
 ;;
@@ -11,7 +11,7 @@
 
 ;;; Commentary:
 ;;
-;;; Koutliner view specs (each viewspec is invoked with its first letter)
+;; Koutliner view specs (each viewspec is invoked with its first letter)
 ;; + means support code has been written already.
 ;;
 ;; +      all:     Show all lines of cells and all cells in the outline.
@@ -53,11 +53,10 @@
 ;;; ************************************************************************
 
 (require 'kview)
+(require 'outline)                      ;For outline-flag-region.
+(require 'kproperty)
 
 ;; Quiet byte compiler warnings for these free variables.
-(eval-when-compile
-  (defvar label-sep-len nil)
-  (defvar modeline-format nil))
 
 ;;; ************************************************************************
 ;;; Public variables
@@ -89,6 +88,9 @@ VIEW-SPEC is a string or t, which means recompute the current 
view spec.  See
     (make-local-variable 'kvspec:current)
     (make-local-variable 'kvspec:string)))
 
+(declare-function kotl-mode:hide-subtree "kotl-mode"
+                  (&optional cell-ref show-flag))
+
 (defun kvspec:levels-to-show (levels-to-keep)
   "Hide all cells in outline at levels deeper than LEVELS-TO-KEEP (a number).
 Shows any hidden cells within LEVELS-TO-KEEP.  1 is the first level.  0 means
@@ -99,9 +101,9 @@ display all levels of cells."
                                  nil nil t)))
   (setq levels-to-keep (prefix-numeric-value levels-to-keep))
   (if (< levels-to-keep 0)
-      (error "(kvspec:levels-to-show): Must display at least one level."))
+      (error "(kvspec:levels-to-show): Must display at least one level"))
   (kview:map-tree
-   (lambda (kview) 
+   (lambda (_kview) 
      (if (/= (kcell-view:level) levels-to-keep)
         (kotl-mode:show-tree)
        (kotl-mode:hide-subtree)
@@ -120,9 +122,10 @@ display all levels of cells."
   (kview:set-attr kview 'lines-to-show num)
   (if (not (zerop num))
       ;; Now show NUM lines in cells.
-      (kview:map-tree (lambda (kview)
+      (kview:map-tree (lambda (_kview)
                        (kcell-view:expand (point))
-                       (kvspec:show-lines-this-cell num)) kview t t)))
+                       (kvspec:show-lines-this-cell num))
+                      kview t t)))
 
 (defun kvspec:toggle-blank-lines ()
   "Toggle blank lines between cells on or off."
@@ -159,6 +162,30 @@ view specs."
   (kvspec:update-modeline))
 
 ;;; ************************************************************************
+;;; Private variables
+;;; ************************************************************************
+
+(defconst kvspec:label-type-alist
+  '((?0 . id)
+    (?1 . alpha)
+    (?. . legal)
+    ;; (?2 . partial-alpha)
+    ;; (?* . star)
+    ;; (?~ . no)
+    )
+  "Alist of (view-spec-character . label-type) pairs.")
+
+(defvar kvspec:string ""
+  "String displayed in koutline modelines to reflect the current view spec.
+It is local to each koutline.  Set this to nil to disable modeline display of
+the view spec settings.")
+
+(defvar kvspec:string-format " <|%s>"
+  "Format of the kview spec modeline display.
+It must contain a `%s' which is replaced with the current set of view spec
+characters at run-time.")
+
+;;; ************************************************************************
 ;;; Private functions
 ;;; ************************************************************************
 
@@ -270,8 +297,9 @@ view specs."
   "Assume the current cell is fully expanded and collapse to show NUM lines 
within it.
 If NUM is greater than the number of lines available, the cell remains fully 
expanded."
   ;; Use free variable label-sep-len bound in kview:map-* for speed.
-  (let ((start (goto-char (kcell-view:start (point) label-sep-len)))
-       (end (kcell-view:end-contents)))
+  (defvar label-sep-len)
+  (goto-char (kcell-view:start (point) label-sep-len))
+  (let ((end (kcell-view:end-contents)))
     ;; Hide all but num lines of the cell.
     (and (> num 0) (search-forward "\n" end t num)
         (outline-flag-region (1- (point)) end t))))
@@ -345,30 +373,6 @@ If NUM is greater than the number of lines available, the 
cell remains fully exp
       )
     (set-buffer-modified-p modified-p)))
 
-;;; ************************************************************************
-;;; Private variables
-;;; ************************************************************************
-
-(defconst kvspec:label-type-alist
-  '((?0 . id)
-    (?1 . alpha)
-    (?. . legal)
-    ;; (?2 . partial-alpha)
-    ;; (?* . star)
-    ;; (?~ . no)
-    )
-  "Alist of (view-spec-character . label-type) pairs.")
-
-(defvar kvspec:string ""
-  "String displayed in koutline modelines to reflect the current view spec.
-It is local to each koutline.  Set this to nil to disable modeline display of
-the view spec settings.")
-
-(defvar kvspec:string-format " <|%s>"
-  "Format of the kview spec modeline display.
-It must contain a `%s' which is replaced with the current set of view spec
-characters at run-time.")
-
 (provide 'kvspec)
 
 ;;; kvspec.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]