diff options
author | Vincent Belaïche <vincentb1@users.sourceforge.net> | 2017-07-17 19:58:12 +0200 |
---|---|---|
committer | Vincent Belaïche <vincentb1@users.sourceforge.net> | 2017-07-17 19:58:12 +0200 |
commit | 002d6abcc76a8a83e5ea191e6f8d6dbed6b714eb (patch) | |
tree | da9a2362e05509bb7db3686e9e2178e48f06b0f1 | |
parent | 727b3df056d978c05bb5dbce5cef715b3b7c31db (diff) | |
download | emacs-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.texi | 29 | ||||
-rw-r--r-- | lisp/ses.el | 172 |
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 |