summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Belaïche <vincentb1@users.sourceforge.net>2017-07-17 19:58:12 +0200
committerVincent Belaïche <vincentb1@users.sourceforge.net>2017-07-17 19:58:12 +0200
commit002d6abcc76a8a83e5ea191e6f8d6dbed6b714eb (patch)
treeda9a2362e05509bb7db3686e9e2178e48f06b0f1
parent727b3df056d978c05bb5dbce5cef715b3b7c31db (diff)
downloademacs-002d6abcc76a8a83e5ea191e6f8d6dbed6b714eb.tar.gz
emacs-002d6abcc76a8a83e5ea191e6f8d6dbed6b714eb.tar.bz2
emacs-002d6abcc76a8a83e5ea191e6f8d6dbed6b714eb.zip
Fix symbol completion and document it.
* 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.
-rw-r--r--doc/misc/ses.texi29
-rw-r--r--lisp/ses.el172
2 files changed, 194 insertions, 7 deletions
diff --git a/doc/misc/ses.texi b/doc/misc/ses.texi
index cac874d0f02..fc79b027a1d 100644
--- a/doc/misc/ses.texi
+++ b/doc/misc/ses.texi
@@ -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
diff --git a/lisp/ses.el b/lisp/ses.el
index 5c560efb703..2e214348eb9 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -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