]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix symbol completion and document it.
authorVincent Belaïche <vincentb1@users.sourceforge.net>
Mon, 17 Jul 2017 17:58:12 +0000 (19:58 +0200)
committerVincent Belaïche <vincentb1@users.sourceforge.net>
Mon, 17 Jul 2017 17:58:12 +0000 (19:58 +0200)
* doc/misc/ses.texi (Configuring what printer function
applies): Add description of keys for completing local printer
symbols and listing local printers in a help buffer.
(Formulas): Add decription for key to list the named cell
symbols in a help buffer.

* lisp/ses.el (ses-completion-keys): New constant.
(ses--completion-table): New defvar.
(ses--list-orig-buffer): New defvar.
(ses-mode-edit-map): Fixed for symbol completion, plus add
help functions to list named cells or local printers.
(ses-edit-cell-complete-symbol)
(ses--edit-cell-completion-at-point-function): New defuns for
completion during formula edition.
(ses-edit-cell): Redefine dynamically edit keymap for
completion keys to point at the right function.
(ses-read-printer-complete-symbol)
(ses--read-printer-completion-at-point-function): New defuns
for completion during printer edition.
(ses-read-printer): Redefine dynamically edit keymap for
completion keys to point at the right function.
(ses-list-local-printers): New defun.
(ses-list-named-cells): New defun.

doc/misc/ses.texi
lisp/ses.el

index cac874d0f02ea1ab4f8a6063249faed2c9174886..fc79b027a1d1708f1c98bf7bc2fd2746bb572757 100644 (file)
@@ -292,7 +292,13 @@ Self-insert an expression.  The right-parenthesis is inserted for you
 (@code{ses-read-cell}).  To access another cell's value, just use its
 identifier in your expression.  Whenever the other cell is changed,
 this cell's formula will be reevaluated.  While typing in the
-expression, you can use @kbd{M-@key{TAB}} to complete symbol names.
+expression, you can use the following keys:
+@table @kbd
+@item M-@key{TAB}
+to complete symbol names, and
+@item  C-h C-n
+to list the named cells symbols in a help buffer.
+@end table
 
 @item ' @r{(apostrophe)}
 Enter a symbol (ses-read-symbol).  @acronym{SES} remembers all symbols that have
@@ -458,11 +464,22 @@ Enter the default printer for the spreadsheet
 (@code{ses-read-default-printer}).
 @end table
 
-The @code{ses-read-@var{xxx}-printer} commands have their own
-minibuffer history, which is preloaded with the set of all printers
-used in this spreadsheet, plus the standard printers (@pxref{Standard
-printer functions}) and the local printers (@pxref{Local printer
-functions}).
+The @code{ses-read-@var{xxx}-printer} allows the following commands during editing:
+
+@table @kbd
+@item @key{arrow-up}
+@itemx @key{arrow-down}
+To browse history: the @code{ses-read-@var{xxx}-printer} commands have
+their own minibuffer history, which is preloaded with the set of all
+printers used in this spreadsheet, plus the standard printers
+(@pxref{Standard printer functions}) and the local printers
+(@pxref{Local printer functions}).
+@item @key{TAB}
+To complete the local printer symbols, and
+@item C-h C-p
+To list the local printers in a help buffer.
+@end table
+
 
 @node Standard printer functions
 @subsection Standard printer functions
index 5c560efb70320107d032c0a34de70aef692b8c85..2e214348eb91be1e0c25179831f40036bad16429 100644 (file)
@@ -167,12 +167,32 @@ Each function is called with ARG=1."
     ["Export values" ses-export-tsv t]
     ["Export formulas" ses-export-tsf t]))
 
+(defconst ses-completion-keys '("\M-\C-i" "\C-i")
+  "List for keys that can be used for completion while editing.")
+
+(defvar ses--completion-table nil
+  "Set globally to what completion table to use depending on type
+  of completion (local printers, cells, etc.). We need to go
+  through a local variable to pass the SES buffer local variable
+  to completing function while the current buffer is the
+  minibuffer.")
+
+(defvar ses--list-orig-buffer nil
+  "Calling buffer for SES listing help. Used for listing local
+  printers or renamed cells.")
+
+
 (defconst ses-mode-edit-map
   (let ((keys '("\C-c\C-r"    ses-insert-range
                "\C-c\C-s"    ses-insert-ses-range
                [S-mouse-3]   ses-insert-range-click
                [C-S-mouse-3] ses-insert-ses-range-click
-               "\M-\C-i"     lisp-complete-symbol)) ; FIXME obsolete
+                "\C-h\C-p"    ses-list-local-printers
+                "\C-h\C-n"    ses-list-named-cells
+               "\M-\C-i"     lisp-complete-symbol)) ; redefined
+                                                     ; dynamically in
+                                                     ; editing
+                                                     ; functions
        (newmap (make-sparse-keymap)))
     (set-keymap-parent newmap minibuffer-local-map)
     (while keys
@@ -2447,6 +2467,42 @@ to are recalculated first."
 ;;----------------------------------------------------------------------------
 ;; Input of cell formulas
 ;;----------------------------------------------------------------------------
+(defun ses-edit-cell-complete-symbol ()
+  (interactive)
+  (let ((completion-at-point-functions (cons 'ses--edit-cell-completion-at-point-function
+                                             completion-at-point-functions)))
+    (completion-at-point)))
+
+(defun ses--edit-cell-completion-at-point-function ()
+  (and
+   ses--completion-table
+   (let* ((bol (save-excursion (move-beginning-of-line nil) (point)))
+         start end collection
+         (prefix
+          (save-excursion
+            (setq end (point))
+            (backward-sexp)
+            (if (< (point) bol)
+                (progn
+                  (setq start bol)
+                  (buffer-substring start end))
+              (setq start (point))
+              (forward-sexp)
+              (if (>= (point) end)
+                  (progn
+                    (setq end (point))
+                    (buffer-substring start end))
+                nil))))
+         prefix-length)
+    (when (and prefix (null (string= prefix "")))
+      (setq prefix-length (length prefix))
+      (maphash (lambda (key val)
+                 (let ((key-name (symbol-name key)))
+                   (when (and (>= (length key-name) prefix-length)
+                              (string= prefix (substring key-name 0 prefix-length)))
+                     (push key-name collection))))
+               ses--completion-table)
+      (and collection (list start end collection))))))
 
 (defun ses-edit-cell (row col newval)
   "Display current cell contents in minibuffer, for editing.  Returns nil if
@@ -2468,6 +2524,10 @@ cell formula was unsafe and user declined confirmation."
        (if (stringp formula)
           ;; Position cursor inside close-quote.
           (setq initial (cons initial (length initial))))
+       (dolist (key ses-completion-keys)
+         (define-key ses-mode-edit-map key 'ses-edit-cell-complete-symbol))
+       ;; make it globally visible, so that it can be visbile from the minibuffer.
+       (setq ses--completion-table ses--named-cell-hashmap)
        (list row col
             (read-from-minibuffer (format "Cell %s: " ses--curcell)
                                   initial
@@ -2562,6 +2622,40 @@ cells."
 ;;----------------------------------------------------------------------------
 ;; Input of cell-printer functions
 ;;----------------------------------------------------------------------------
+(defun ses-read-printer-complete-symbol ()
+  (interactive)
+  (let ((completion-at-point-functions (cons 'ses--read-printer-completion-at-point-function
+                                             completion-at-point-functions)))
+    (completion-at-point)))
+
+(defun ses--read-printer-completion-at-point-function ()
+  (let* ((bol (save-excursion (move-beginning-of-line nil) (point)))
+         start end collection
+         (prefix
+          (save-excursion
+            (setq end (point))
+            (backward-sexp)
+            (if (< (point) bol)
+                (progn
+                  (setq start bol)
+                  (buffer-substring start end))
+              (setq start (point))
+              (forward-sexp)
+              (if (>= (point) end)
+                  (progn
+                    (setq end (point))
+                    (buffer-substring start end))
+                nil))))
+         prefix-length)
+    (when prefix
+      (setq prefix-length (length prefix))
+      (maphash (lambda (key val)
+                 (let ((key-name (symbol-name key)))
+                   (when (and (>= (length key-name) prefix-length)
+                              (string= prefix (substring key-name 0 prefix-length)))
+                     (push key-name collection))))
+               ses--completion-table)
+      (and collection (list start end collection)))))
 
 (defun ses-read-printer (prompt default)
   "Common code for functions `ses-read-cell-printer', `ses-read-column-printer',
@@ -2574,6 +2668,10 @@ canceled."
     (setq prompt (format "%s (default %S): "
                         (substring prompt 0 -2)
                         default)))
+  (dolist (key ses-completion-keys)
+    (define-key ses-mode-edit-map key 'ses-read-printer-complete-symbol))
+  ;; make it globally visible, so that it can be visbile from the minibuffer.
+  (setq ses--completion-table ses--local-printer-hashmap)
   (let ((new (read-from-minibuffer prompt
                                   nil ; Initial contents.
                                   ses-mode-edit-map
@@ -3282,6 +3380,78 @@ is non-nil.  Newlines and tabs in the export text are escaped."
     (setq result (apply #'concat (nreverse result)))
     (kill-new result)))
 
+;;----------------------------------------------------------------------------
+;; Interactive help on symbols
+;;----------------------------------------------------------------------------
+
+(defun ses-list-local-printers (&optional local-printer-hashmap)
+  "List local printers in a help buffer. Can be called either
+during editing a printer or a formula, or while in the SES
+buffer."
+  (interactive
+   (list (cond
+          ((derived-mode-p 'ses-mode) ses--local-printer-hashmap)
+          ((minibufferp) ses--completion-table)
+          ((derived-mode-p 'help-mode) nil)
+          (t (error "Not in a SES buffer")))))
+  (when local-printer-hashmap
+    (let ((ses--list-orig-buffer (or ses--list-orig-buffer (current-buffer))))
+      (help-setup-xref
+       (list (lambda (local-printer-hashmap buffer)
+               (let ((ses--list-orig-buffer
+                      (if (buffer-live-p buffer) buffer)))
+                 (ses-list-local-printers local-printer-hashmap)))
+             local-printer-hashmap ses--list-orig-buffer)
+       (called-interactively-p 'interactive))
+
+      (save-excursion
+        (with-help-window (help-buffer)
+          (if (= 0 (hash-table-count local-printer-hashmap))
+              (princ "No local printers defined.")
+            (princ "List of local printers definitions:\n")
+            (maphash (lambda (key val)
+                       (princ key)
+                       (princ " as ")
+                       (prin1 (ses--locprn-def val))
+                       (princ "\n"))
+                     local-printer-hashmap))
+          (with-current-buffer standard-output
+            (buffer-string)))))))
+
+(defun ses-list-named-cells (&optional named-cell-hashmap)
+  "List named cells in a help buffer. Can be called either
+during editing a printer or a formula, or while in the SES
+buffer."
+  (interactive
+   (list (cond
+          ((derived-mode-p 'ses-mode) ses--named-cell-hashmap)
+          ((minibufferp) ses--completion-table)
+          ((derived-mode-p 'help-mode) nil)
+          (t (error "Not in a SES buffer")))))
+  (when named-cell-hashmap
+    (let ((ses--list-orig-buffer (or ses--list-orig-buffer (current-buffer))))
+      (help-setup-xref
+       (list (lambda (named-cell-hashmap buffer)
+               (let ((ses--list-orig-buffer
+                      (if (buffer-live-p buffer) buffer)))
+                 (ses-list-named-cells named-cell-hashmap)))
+             named-cell-hashmap ses--list-orig-buffer)
+       (called-interactively-p 'interactive))
+
+      (save-excursion
+        (with-help-window (help-buffer)
+          (if (= 0 (hash-table-count named-cell-hashmap))
+              (princ "No cell was renamed.")
+            (princ "List of named cells definitions:\n")
+            (maphash (lambda (key val)
+                       (princ key)
+                       (princ " for ")
+                       (prin1 (ses-create-cell-symbol (car val) (cdr val)))
+                       (princ "\n"))
+                     named-cell-hashmap))
+          (with-current-buffer standard-output
+            (buffer-string)))))))
+
 
 ;;----------------------------------------------------------------------------
 ;; Other user commands