summaryrefslogtreecommitdiff
path: root/lisp/ses.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/ses.el')
-rw-r--r--lisp/ses.el139
1 files changed, 83 insertions, 56 deletions
diff --git a/lisp/ses.el b/lisp/ses.el
index c2c1efe0f93..a5fd1774dd7 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -84,17 +84,14 @@
(defcustom ses-initial-size '(1 . 1)
"Initial size of a new spreadsheet, as a cons (NUMROWS . NUMCOLS)."
- :group 'ses
:type '(cons (integer :tag "numrows") (integer :tag "numcols")))
(defcustom ses-initial-column-width 7
"Initial width of columns in a new spreadsheet."
- :group 'ses
:type '(integer :match (lambda (widget value) (> value 0))))
(defcustom ses-initial-default-printer "%.7g"
"Initial default printer for a new spreadsheet."
- :group 'ses
:type '(choice string
(list :tag "Parenthesized string" string)
function))
@@ -103,15 +100,30 @@
"Things to do after entering a value into a cell.
An abnormal hook that usually runs a cursor-movement function.
Each function is called with ARG=1."
- :group 'ses
:type 'hook
:options '(forward-char backward-char next-line previous-line))
(defcustom ses-mode-hook nil
"Hook functions to be run upon entering SES mode."
- :group 'ses
:type 'hook)
+(defcustom ses-jump-cell-name-function #'upcase
+ "Function to process the string passed to function `ses-jump'.
+Set it to `identity' to make no change.
+Set it to `upcase' to make cell name change case isensitive.
+
+ May return
+
+* a string, in this case this must be a cell name.
+* a (row . col) cons cell, in this case that must be valid cell coordinates."
+ :type 'function)
+
+(defcustom ses-jump-prefix-function #'ses-jump-prefix
+ "Function that takes the prefix argument passed to function `ses-jump'.
+It may return the same sort of thing as `ses-jump-cell-name-function'."
+ :type 'function)
+
+
;;----------------------------------------------------------------------------
;; Global variables and constants
@@ -227,26 +239,18 @@ Used for listing local printers or renamed cells.")
"w" ses-set-column-width
"x" ses-export-keymap
"\M-p" ses-read-column-printer))
- (repl '(;;We'll replace these wherever they appear in the keymap
- clipboard-kill-region ses-kill-override
- end-of-line ses-end-of-line
- kill-line ses-delete-row
- kill-region ses-kill-override
- open-line ses-insert-row))
(numeric "0123456789.-")
(newmap (make-keymap)))
;;Get rid of printables
(suppress-keymap newmap t)
;;These keys insert themselves as the beginning of a numeric value
(dotimes (x (length numeric))
- (define-key newmap (substring numeric x (1+ x)) 'ses-read-cell))
- ;;Override these global functions wherever they're bound
- (while repl
- (substitute-key-definition (car repl) (cadr repl) newmap
- (current-global-map))
- (setq repl (cddr repl)))
- ;;Apparently substitute-key-definition doesn't catch this?
- (define-key newmap [(menu-bar) edit cut] 'ses-kill-override)
+ (define-key newmap (substring numeric x (1+ x)) #'ses-read-cell))
+ (define-key newmap [remap clipboard-kill-region] #'ses-kill-override)
+ (define-key newmap [remap end-of-line] #'ses-end-of-line)
+ (define-key newmap [remap kill-line] #'ses-delete-row)
+ (define-key newmap [remap kill-region] #'ses-kill-override)
+ (define-key newmap [remap open-line] #'ses-insert-row)
;;Define our other local keys
(while keys
(define-key newmap (car keys) (cadr keys))
@@ -353,7 +357,7 @@ printer and then modify its output.")
(t (error "Unexpected elements `%S' in list `ses-localvars'" x)))))
;;; This variable is documented as being permitted in file-locals:
-(put 'ses--symbolic-formulas 'safe-local-variable 'consp)
+(put 'ses--symbolic-formulas 'safe-local-variable #'consp)
(defconst ses-paramlines-plist
'(ses--col-widths -5 ses--col-printers -4 ses--default-printer -3
@@ -1064,8 +1068,7 @@ the old and FORCE is nil."
(defcustom ses-self-reference-early-detection nil
"Non-nil if cycle detection is early for cells that refer to themselves."
:version "24.1"
- :type 'boolean
- :group 'ses)
+ :type 'boolean)
(defun ses-update-cells (list &optional force)
"Recalculate cells in LIST, checking for dependency loops.
@@ -2072,8 +2075,8 @@ formula:
;; Not to use tab characters for safe (tabs may do bad for column
;; calculation).
indent-tabs-mode nil)
- (1value (add-hook 'change-major-mode-hook 'ses-cleanup nil t))
- (1value (add-hook 'kill-buffer-hook 'ses-killbuffer-hook nil t))
+ (1value (add-hook 'change-major-mode-hook #'ses-cleanup nil t))
+ (1value (add-hook 'kill-buffer-hook #'ses-killbuffer-hook nil t))
(cl-pushnew (current-buffer) ses--ses-buffer-list :test 'eq)
;; This makes revert impossible if the buffer is read-only.
;; (1value (add-hook 'before-revert-hook 'ses-cleanup nil t))
@@ -2124,8 +2127,8 @@ formula:
;; find-alternate-file, post-command-hook doesn't get run for some reason,
;; so use an idle timer to make sure.
(setq ses--deferred-narrow 'ses-mode)
- (1value (add-hook 'post-command-hook 'ses-command-hook nil t))
- (run-with-idle-timer 0.01 nil 'ses-command-hook)
+ (1value (add-hook 'post-command-hook #'ses-command-hook nil t))
+ (run-with-idle-timer 0.01 nil #'ses-command-hook)
(run-mode-hooks 'ses-mode-hook)))
(put 'ses-mode 'mode-class 'special)
@@ -2241,24 +2244,43 @@ Based on the current set of columns and `window-hscroll' position."
;;----------------------------------------------------------------------------
;; Redisplay and recalculation
;;----------------------------------------------------------------------------
+(defun ses-jump-prefix (prefix-int)
+ "Convert an integer (unversal prefix) into a (ROW . COL).
+Does it by numbering cells starting from 0 from top left to bottom right,
+going row by row."
+ (and (>= prefix-int 0)
+ (< prefix-int (* ses--numcols ses--numrows))
+ (cons (/ prefix-int ses--numcols) (% prefix-int ses--numcols))))
+
-(defun ses-jump (sym)
+(defun ses-jump (&optional sym)
"Move point to cell SYM."
- (interactive (let* (names
- (s (completing-read
- "Jump to cell: "
- (and ses--named-cell-hashmap
- (progn (maphash (lambda (key _val)
- (push (symbol-name key) names))
- ses--named-cell-hashmap)
- names)))))
- (if (string= s "")
- (user-error "Invalid cell name")
- (list (intern s)))))
- (let ((rowcol (ses-sym-rowcol sym)))
+ (interactive "P")
+ (setq sym
+ (if current-prefix-arg
+ (funcall ses-jump-prefix-function (prefix-numeric-value sym))
+ (or sym
+ (completing-read
+ "Jump to cell: "
+ (and ses--named-cell-hashmap
+ (let (names)
+ (maphash (lambda (key _val)
+ (push (symbol-name key) names))
+ ses--named-cell-hashmap)
+ names))))))
+ (and (stringp sym)
+ (not (and ses--named-cell-hashmap (gethash (intern sym) ses--named-cell-hashmap)))
+ (setq sym (funcall ses-jump-cell-name-function sym)))
+ (if (stringp sym)
+ (if (string= sym "")
+ (user-error "Empty cell name")
+ (setq sym (intern sym))))
+ (let ((rowcol (if (consp sym)
+ (prog1 sym (setq sym (ses-cell-symbol (car sym) (cdr sym))))
+ (ses-sym-rowcol sym))))
(or rowcol (error "Invalid cell name"))
(if (eq (symbol-value sym) '*skip*)
- (error "Cell is covered by preceding cell"))
+ (error "Cell is covered by preceding cell"))
(ses-goto-print (car rowcol) (cdr rowcol))))
(defun ses-jump-safe (cell)
@@ -2309,7 +2331,7 @@ Narrow to print area if optional argument NONARROW is nil."
"Recalculate and reprint the current cell or range.
If CURCELL is non nil use it as current cell or range
-without any check, otherwise function (ses-check-curcell 'range)
+without any check, otherwise function (ses-check-curcell \\='range)
is called.
For an individual cell, shows the error if the formula or printer
@@ -2515,7 +2537,7 @@ Return nil if cell formula was unsafe and user declined confirmation."
;; 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))
+ (define-key ses-mode-edit-map key #'ses-edit-cell-complete-symbol))
;; make it globally visible, so that it can be visible from the minibuffer.
(setq ses--completion-table ses--named-cell-hashmap)
(list row col
@@ -2612,8 +2634,9 @@ With prefix, deletes several cells."
;;----------------------------------------------------------------------------
(defun ses-read-printer-complete-symbol ()
(interactive)
- (let ((completion-at-point-functions (cons 'ses--read-printer-completion-at-point-function
- completion-at-point-functions)))
+ (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 ()
@@ -2655,7 +2678,7 @@ canceled."
(setq default "")
(setq prompt (format-prompt prompt default)))
(dolist (key ses-completion-keys)
- (define-key ses-mode-edit-map key 'ses-read-printer-complete-symbol))
+ (define-key ses-mode-edit-map key #'ses-read-printer-complete-symbol))
;; make it globally visible, so that it can be visible from the minibuffer.
(setq ses--completion-table ses--local-printer-hashmap)
(let ((new (read-from-minibuffer prompt
@@ -3554,7 +3577,7 @@ With prefix, sorts in REVERSE order."
(push (cons (buffer-substring-no-properties (point) end)
(+ minrow x))
keys))
- (setq keys (sort keys #'(lambda (x y) (string< (car x) (car y)))))
+ (setq keys (sort keys (lambda (x y) (string< (car x) (car y)))))
;;Extract the lines in reverse sorted order
(or reverse
(setq keys (nreverse keys)))
@@ -3751,15 +3774,15 @@ DEFINITION shall be either a string formatter, e.g.:
\"%.2f\" or (\"%.2f\") for left alignment.
or a lambda expression, e.g. for formatting in ISO format dates
-created with a '(calcFunc-date YEAR MONTH DAY)' formula:
+created with a `(calcFunc-date YEAR MONTH DAY)' formula:
(lambda (x)
(cond
((null val) \"\")
- ((eq (car-safe x) 'date)
- (let ((calc-format-date '(X YYYY \"-\" MM \"-\" DD)))
+ ((eq (car-safe x) \\='date)
+ (let ((calc-format-date \\='(X YYYY \"-\" MM \"-\" DD)))
(math-format-date x)))
- (t (ses-center-span val ?# 'ses-prin1))))
+ (t (ses-center-span val ?# \\='ses-prin1))))
If NAME is already used to name a local printer function, then
the current definition is proposed as default value, and the
@@ -3774,7 +3797,9 @@ function is redefined."
(setq name (intern name))
(let* ((cur-printer (gethash name ses--local-printer-hashmap))
(default (and cur-printer (ses--locprn-def cur-printer))))
- (setq def (ses-read-printer (format "Enter definition of printer %S" name)
+ (setq def (ses-read-printer (format-prompt
+ "Enter definition of printer %S"
+ default name)
default)))
(list name def)))
@@ -4085,17 +4110,19 @@ SPAN indicates how many rightward columns to include in width (default = 0)."
(ses-center value span ?- printer))
(defun ses-dashfill-span (value &optional printer)
- "Print VALUE, centered using dashes within the span that starts in the
-current column and continues until the next nonblank column."
+ "Print VALUE, centered using dashes.
+Centers within the span that starts in the current column and continues
+until the next nonblank column."
(ses-center-span value ?- printer))
(defun ses-tildefill-span (value &optional printer)
- "Print VALUE, centered using tildes within the span that starts in the
-current column and continues until the next nonblank column."
+ "Print VALUE, centered using tildes.
+Centers within the span that starts in the current column and continues
+until the next nonblank column."
(ses-center-span value ?~ printer))
(defun ses-prin1 (value)
- "Shorthand for '(prin1-to-string VALUE t)'.
+ "Shorthand for `(prin1-to-string VALUE t)'.
Useful to handle the default behavior in custom lambda based
printer functions."
(prin1-to-string value t))