-;;;_* sage-mode.el --- Major mode for editing S~~AGE~~ code

+;;;_* sage-mode.el --- Major mode for editing Sage code

;; Copyright (C) 2007, 2008 Nick Alexander

-;;;_ + S~~AGE~~ mode key bindings

+;;;_ + Sage mode key bindings

(let ((map (make-keymap))) ;`sparse' doesn't allow binding to charsets.

"Keymap for `inferior-sage-mode'.")

-;;;_* Inferior S~~AGE~~ major mode for interacting with a slave S~~AGE~~ process

+;;;_* Inferior Sage major mode for interacting with a slave Sage process

- "Major mode for interacting with an inferior SAGE process."

+ "Major mode for interacting with an inferior Sage process."

(when (and (markerp comint-last-output-start)

(not (marker-buffer comint-last-output-start)))

(defun inferior-sage-wait-for-prompt ()

- "Wait until the S~~AGE~~ process is ready for input."

+ "Wait until the Sage process is ready for input."

(message "Waiting for sage: prompt...")

(with-current-buffer sage-buffer

(let* ((sprocess (get-buffer-process sage-buffer))

(if (not (eq (process-status sprocess) 'run))

- (error "S~~AGE~~ process has died unexpectedly.")

+ (error "Sage process has died unexpectedly.")

(if (> (setq timeout (1+ timeout)) inferior-sage-timeout)

- (error "Timeout waiting for S~~AGE~~ prompt. Check inferior-sage-timeout."))

+ (error "Timeout waiting for Sage prompt. Check inferior-sage-timeout."))

(accept-process-output nil 0 1)

(defun sage-apropos (symbol)

- (interactive "sApropos S~~AGE~~ command: ")

+ (interactive "sApropos Sage command: ")

(when (or (null symbol) (equal "" symbol))

(with-output-to-temp-buffer "*sage-apropos*"

(defun ipython-handle-magic-**? (proc string &optional match)

- "Handle S~~AGE~~ apropos **?."

+ "Handle Sage apropos **?."

(when (string-match "\\(.*?\\)\\*\\*\\?" string)

(sage-apropos (match-string 1 string))))

(if (with-current-buffer output-buffer (> (point-max) (point-min)))

(display-buffer output-buffer))))))

-;;;_* S~~AGE~~ process management

+;;;_* Sage process management

(if (boundp 'python-shell-internal-buffer)

(defvaralias 'sage-buffer 'python-shell-internal-buffer)

(defvaralias 'sage-buffer 'python-buffer))

;; (defvar sage-buffer nil

-;; "*The current S~~AGE~~ process buffer.

+;; "*The current Sage process buffer.

-;; Commands that send text from source buffers to S~~AGE~~ processes have

+;; Commands that send text from source buffers to Sage processes have

;; to choose a process to send to. This is determined by buffer-local

;; value of `sage-buffer'. If its value in the current buffer,

;; i.e. both any local value and the default one, is nil, `run-sage'

;; Whenever \\[run-sage] starts a new process, it resets the default

;; value of `sage-buffer' to be the new process's buffer and sets the

-;; buffer-local value similarly if the current buffer is in SAGE mode

-;; or Inferior SAGE mode, so that source buffer stays associated with a

+;; buffer-local value similarly if the current buffer is in Sage mode

+;; or Inferior Sage mode, so that source buffer stays associated with a

;; Use \\[sage-set-proc] to set the default value from a buffer with a

;; (error "Not in a sage-mode buffer!"))

- "S~~AGE~~ buffer: " (sage-all-inferior-sage-buffers) nil nil

+ "Sage buffer: " (sage-all-inferior-sage-buffers) nil nil

(car (sage-all-inferior-sage-buffers))))))

(let ((chosen-buffer (with-current-buffer buffer (current-buffer))))

(setq sage-buffer chosen-buffer)

- (let* ((sage-buffer-base-name (format "*S~~AGE~~-%s*" (sage-current-branch)))

+ (let* ((sage-buffer-base-name (format "*Sage-%s*" (sage-current-branch)))

(sage-buffer-name (if new (generate-new-buffer sage-buffer-base-name) sage-buffer-base-name))

(cmdlist (sage-args-to-list cmd))

;; Set PYTHONPATH to import module emacs from emacs.py,

(data-path (concat "PYTHONPATH=" orig-path path-sep data-directory))

(cons data-path process-environment)))

- (apply 'make-comint-in-buffer "S~~AGE~~"

+ (apply 'make-comint-in-buffer "Sage"

(car cmdlist) nil (cdr cmdlist)))))

(defalias 'sage-run 'run-sage)

(defun run-sage (&optional new cmd noshow)

- "Run an inferior S~~AGE~~ process, input and output via buffer *S~~AGE~~*.

+ "Run an inferior Sage process, input and output via buffer *Sage*.

-NEW non-nil means always create a new buffer and SAGE process.

-CMD is the SAGE command to run.

+NEW non-nil means always create a new buffer and Sage process.

+CMD is the Sage command to run.

NOSHOW non-nil means don't show the buffer automatically.

Normally, if there is a process already running in `sage-buffer',

buffer for a list of commands.)"

;; Fixme: Consider making `sage-buffer' buffer-local as a buffer

- ;; (not a name) in S~~AGE~~ buffers from which `run-sage' &c is

+ ;; (not a name) in Sage buffers from which `run-sage' &c is

;; invoked. Would support multiple processes better.

(if (not (or new (sage-new-sage-p)))

(unless noshow (pop-to-buffer sage-buffer))

(defun sage-set-buffer-name ()

- "Change the current S~~AGE~~ buffer name to include the current branch."

+ "Change the current Sage buffer name to include the current branch."

(when (sage-current-branch)

- (generate-new-buffer-name (format "*S~~AGE~~-%s*" (sage-current-branch))))))

+ (generate-new-buffer-name (format "*Sage-%s*" (sage-current-branch))))))

(defun sage-current-branch-link ()

- "Return the current S~~AGE~~ branch link, i.e., the target of devel/sage."

+ "Return the current Sage branch link, i.e., the target of devel/sage."

(let ((lst (split-string (shell-command-to-string (concat sage-command " -branch")))))

(defun sage-current-branch ()

- "Return the current S~~AGE~~ branch name."

+ "Return the current Sage branch name."

(if (and (inferior-sage-mode-p)

- (string-match "\\*S~~AGE~~-\\(.*\\)\\*" (buffer-name)))

+ (string-match "\\*Sage-\\(.*\\)\\*" (buffer-name)))

(match-string 1 (buffer-name))

(sage-current-branch-link))))

(defun sage-current-devel-root ()

- "Return the current S~~AGE~~ branch directory."

+ "Return the current Sage branch directory."

(format "%s/devel/sage-%s" (sage-root) (sage-current-branch)))

-;;;_* S~~AGE~~ major mode for editing S~~AGE~~ library code

+;;;_* Sage major mode for editing Sage library code

- "Major mode for editing SAGE files.

+ "Major mode for editing Sage files.

The major entry points are:

;; `(("\\(\\*\\*\\)test\\(\\*\\*\\)" . 'font-lock-comment-face)))

-;;;_* Treat S~~AGE~~ code as Python source code

+;;;_* Treat Sage code as Python source code

(add-to-list 'interpreter-mode-alist '("sage" . sage-mode))

(sage-send-command (format "attach(r'''%s''')" buffer-file-name) nil)

(error "This buffer is not associated with a file. Please save it first.")))

-;;;_* Integrate S~~AGE~~ mode with Emacs

+;;;_* Integrate Sage mode with Emacs

(defun sage-pcomplete-or-help ()

(when (python-current-word)

(ipython-describe-symbol (python-current-word))))))

-;;;_ + Set better grep defaults for S~~AGE~~ and Pyrex code

+;;;_ + Set better grep defaults for Sage and Pyrex code

;; (eval-after-load "grep"

"^\\(.*\\):\\([0-9]+\\):\\([0-9]+\\):"

-;; To add support for S~~AGE~~ build and test errors to *compilation* buffers by

+;; To add support for Sage build and test errors to *compilation* buffers by

;; default, evaluate the following four lines.

;; (add-to-list 'compilation-error-regexp-alist-alist sage-test-compilation-regexp)

;; (add-to-list 'compilation-error-regexp-alist 'sage-build-compilation)

(defun eshell-sage-command-hook (command args)

- "Handle some S~~AGE~~ invocations specially.

+ "Handle some Sage invocations specially.

-Without ARGS, run S~~AGE~~ in an emacs `sage-mode' buffer.

+Without ARGS, run Sage in an emacs `sage-mode' buffer.

-With first ARGS starting with \"-b\" or \"-t\", run S~~AGE~~ in an

+With first ARGS starting with \"-b\" or \"-t\", run Sage in an

emacs `compilation-mode' buffer.

-Otherwise (for example, with ARGS \"-hg\", run S~~AGE~~ at the eshell

+Otherwise (for example, with ARGS \"-hg\", run Sage at the eshell

This is an `eshell-named-command-hook' because only some parameters modify the

;; the t makes current-word strict: returns nil if point is not in the word

-;;;_* IPython and S~~AGE~~ completing reads

+;;;_* IPython and Sage completing reads

;;;_ + `ipython-completing-read-symbol' is `completing-read' for python symbols

;;; using IPython's *? mechanism

;; make it easy to send doctests from a help buffer, for example

(run-hooks 'sage-after-help-hook))))

-;;;_ + `sage-find-symbol' is `find-function' for S~~AGE~~.

+;;;_ + `sage-find-symbol' is `find-function' for Sage.

(defun sage-find-symbol-command (symbol)

- "Return S~~AGE~~ command to fetch position of SYMBOL."

+ "Return Sage command to fetch position of SYMBOL."

(concat "sage.misc.sageinspect.sage_getfile(%s), "

"sage.misc.sageinspect.sage_getsourcelines(%s)[-1] + 1")

(defun sage-find-symbol-noselect (symbol)

"Return a pair (BUFFER . POINT) pointing to the definition of SYMBOL.

-Queries S~~AGE~~ to find the source file containing the definition of

+Queries Sage to find the source file containing the definition of

FUNCTION in a buffer and the point of the definition. The buffer

(sage-find-symbol-do-it symbol 'switch-to-buffer-other-frame))

-;;;_ + `try-complete-sage-symbol-partially' is a `hippie-expand' function for S~~AGE~~

+;;;_ + `try-complete-sage-symbol-partially' is a `hippie-expand' function for Sage

(defun he-sage-symbol-beg ()

(defun try-complete-sage-symbol-partially (old)

- "Try to complete as a S~~AGE~~ symbol, as many characters as unique.

+ "Try to complete as a Sage symbol, as many characters as unique.

The argument OLD is nil if this is the first call to this

function, non-nil if this is a subsequent call.

;;;_* Make it easy to sagetest files and methods

(defun sage-test-file-inline (file-name &optional method)

- "Run sage-test on file FILE-NAME, with output to underlying the S~~AGE~~ buffer.

+ "Run sage-test on file FILE-NAME, with output to underlying the Sage buffer.

We take pains to test the correct module.

Interactively, try to find current method at point."

- (comint-get-source "Load S~~AGE~~ file: "

+ (comint-get-source "Load Sage file: "

python-prev-dir/file python-source-modes t)

(list current-prefix-arg)))

(comint-check-source file-name) ; Check to see if buffer needs saving.

Interactively, try to find current method at point."

- (comint-get-source "Load S~~AGE~~ file: "

+ (comint-get-source "Load Sage file: "

python-prev-dir/file python-source-modes t)

(list current-prefix-arg)))

(comint-check-source file-name) ; Check to see if buffer needs saving.