sage-shell-mode

Emacs front end for SageMath

  • Owner: sagemath/sage-shell-mode
  • Platform:
  • License:: GNU General Public License v3.0
  • Category::
  • Topic:
  • Like:
    1
      Compare:

Github stars Tracking Chart

  • sage-shell-mode
    [[http://melpa.org/#/sage-shell-mode][file:http://melpa.org/packages/sage-shell-mode-badge.svg]]
    [[http://stable.melpa.org/#/sage-shell-mode][file:http://stable.melpa.org/packages/sage-shell-mode-badge.svg]]
    [[https://travis-ci.org/sagemath/sage-shell-mode][https://travis-ci.org/sagemath/sage-shell-mode.svg]]

** Overview

=sage-shell-mode= is an elisp package and provides an Emacs front
end for [[http://www.sagemath.org/][Sage]].

=sage-shell-mode= provides two main features:

  1. =sage-shell-mode= to run the Sage terminal inside Emacs.

  2. =sage-shell:sage-mode= for editing =.sage= source files and sending their contents directly to the Sage terminal. This major mode is derived from =python-mode=.

The package supports extensions with [[https://github.com/stakemori/auto-complete-sage][auto-complete-sage]], [[https://github.com/stakemori/helm-sage][helm-sage]],
[[https://github.com/stakemori/anything-sage][anything-sage]] and [[https://github.com/stakemori/ob-sagemath][ob-sagemath]].

** Table of Contents :TOC:

  • [[#requirements][Requirements]]
  • [[#installation-and-setup][Installation and Setup]]
  • [[#aliases][Aliases]]
  • [[#basic-usage][Basic Usage]]
  • [[#input-history][Input History]]
  • [[#emulating-worksheets-code-blocks][Emulating Worksheets: code blocks]]
  • [[#inline-display-of-latex-outputs-and-plots-a-port-of-sage-view][Inline display of LaTeX outputs and plots (a port of =sage-view=)]]
  • [[#sagetex][SageTeX]]
  • [[#customization][Customization]]
  • [[#extensions][Extensions]]
  • [[#screenshots][Screenshots]]
  • [[#workaround-for-flycheck][Workaround for Flycheck]]
  • [[#license][License]]

** Requirements

  1. GNU Emacs 24.4 later.

  2. Local installation of [[http://www.sagemath.org/][Sage]].

  3. The Emacs package [[https://github.com/kiwanami/emacs-deferred][deferred]]. This will be installed automatically if you follow the guide below.

** Installation and Setup

The most convenient is to use the Emacs package manager to install =sage-shell-mode= from [[https://github.com/milkypostman/melpa.git][MELPA]]:

  1. See http://melpa.org/#/getting-started if you do not have a
    configuration for MELPA.

  2. Install =sage-shell-mode= by

    • =M-x package-refresh-contents=
    • =M-x package-install RET sage-shell-mode=.
  3. If you have Sage 7.3 or earlier, then add the following to your Emacs init file (=~/.emacs.d/init.el=):

    #+BEGIN_SRC elisp
    (setq sage-shell:use-prompt-toolkit nil)
    #+END_SRC

  4. You can now run Sage inside Emacs by =M-x sage-shell:run-sage=, if Emacs
    can find the executable file of Sage.

    If Emacs cannot find the executable file, add the following line to your Emacs init file:

    #+BEGIN_SRC elisp
    (setq sage-shell:sage-root "/path/to/sage/root_directory")
    #+END_SRC

    And replace =/path/to/sage_root_directory= by the root directory of
    Sage, i.e. =$SAGE_ROOT=. If you do not know the root directory of
    Sage, evaluate the following code in a Sage terminal:

    #+BEGIN_SRC python
    import os; print os.environ["SAGE_ROOT"]
    #+END_SRC

    Alternatively, instead of setting =sage-shell:sage-root=, you may
    set the variable =sage-shell:sage-executable=.

    #+BEGIN_SRC elisp
    (setq sage-shell:sage-executable "/path/to/sage/executable")
    #+END_SRC

    Here =/path/to/sage/executable= is the path of the executable file
    of Sage. This may be a symbolic link.

*** Sample configuration
Here is a sample configuration.

#+BEGIN_SRC elisp
  ;; Run SageMath by M-x run-sage instead of M-x sage-shell:run-sage
  (sage-shell:define-alias)

  ;; Turn on eldoc-mode in Sage terminal and in Sage source files
  (add-hook 'sage-shell-mode-hook #'eldoc-mode)
  (add-hook 'sage-shell:sage-mode-hook #'eldoc-mode)
#+END_SRC

** Aliases

The official Emacs major mode for Sage used to be [[https://bitbucket.org/gvol/sage-mode/src][sage-mode]]. To avoid name conflicts
with this package, =sage-shell-mode= prefixes all names with =sage-shell=.

If you are not using =sage-mode= at all, you can define more convenient
aliases for =sage-shell-mode= by adding the following to your Emacs init file
after the line =(require 'sage-shell-mode)=:

#+BEGIN_SRC elisp
(sage-shell:define-alias)
#+END_SRC

The following aliases will be defined:, Original name, Alias, ---------------------------+----------------, sage-shell:run-sage, run-sage, sage-shell:run-new-sage, run-new-sage, sage-shell:sage-mode, sage-mode, sage-shell:sage-mode-map, sage-mode-map, sage-shell:sage-mode-hook, sage-mode-hook, This means e.g. that you can do =M-x run-sage= to run Sage, instead of =M-x
sage-shell:run-sage=.

** Basic Usage

*** Running a Sage Process

You can start a Sage process by =M-x sage-shell:run-sage=. If you need
to open multiple Sage processes simultaneously, you can start new ones by
=M-x sage-shell:run-new-sage=. You can restart the current process by
=M-x sage-shell:restart-sage=., Command, Alias, Description, -------------------------+--------------+-----------------------------------, sage-shell:run-sage, run-sage, Run a Sage process., sage-shell:run-new-sage, run-new-sage, Run another Sage process., sage-shell:restart-sage, None, Restart the current Sage process., The major-mode of the Sage process buffer is =sage-shell-mode=.

*** The Sage Process as a terminal

The primary element of =sage-shell-mode= is interacting with the Sage process
you just started. The Sage process buffer communicates directly with a Sage
shell in the background and behaves very much like it. You just type and send
the command with ==:

#+BEGIN_SRC python
sage: 2+2
4
sage: (x^2 + 2*x + 1).factor()
(x + 1)^2
sage:
#+END_SRC

The buffer behaves like an Emacs shell:

  • =M-p= or =C-up= goes through earlier input.
  • Previous input and output is retained earlier in the buffer. You can move
    around just as usual and e.g. copy from it or search.
  • To exit, you can enter =quit= at the prompt or type =C-d= (bound to =sage-shell:delchar-or-maybe-eof=) at a blank line.

The buffer also behaves much like the Sage terminal:

**** Tab completion
== at the prompt completes the current word. It understands all Sage and
Python functions currently in scope, and it also completes attributes of
objects. If there are multiple possibilities, they are presented in another
window.

#+BEGIN_SRC python
sage: G = graphs.PetersenGraph()
sage: G.

sage: G.charp
<G.charp is completed uniquely to G.charpoly>
#+END_SRC

By default, Tab completion uses =completion-at-point=. Alternatively, you can
use =pcomplete= by adding the following to your Emacs init file:

#+BEGIN_SRC elisp
(setq sage-shell:completion-function 'pcomplete)
#+END_SRC

You can also use =auto-complete=, =anything= or =helm= for
completion. This requires installing those extensions, see [[#extensions][Extensions]].

**** =?= Help

By writing the name of an object at the prompt, followed by =?= and then =RET=,
you are shown the documentation of that object:

#+BEGIN_SRC python
sage: G = graphs.PetersenGraph()
sage: G.charpoly?

#+END_SRC

This is identical to running =C-c C-h= and then typing the name of the object.

**** =??= Source Lookup

If you use =??= instead =?= after a Sage object, then the source code for that object will be opened in a new buffer:

#+BEGIN_SRC python
sage: G = graphs.PetersenGraph()
sage: G.charpoly??
<The file src/sage/graphs/generic_graph.py is opened at "def characteristic_polynomial(...):">
#+END_SRC

**** Most important key-bindings, Key Stroke, Command, Description, ------------+----------------------------------------------+----------------------------------------------------------------------------, RET, sage-shell:send-input, Evaluate the expression written at the prompt., TAB, sage-shell-tab-command, Complete a partially written word or indent a line., C-d, sage-shell:delchar-or-maybe-eof, Delete the next input character. End the Sage process if nothing is input., C-c C-c, sage-shell:interrupt-subjob, Interrupt the current computation., M-p, comint-previous-input, Go backward through input history., M-n, sage-shell:next-input, Go forward through input history., C-c C-o, sage-shell:delete-output, Remove all output from Sage since last input prompt., C-c M-o, sage-shell:clear-current-buffer, Clear the entire Sage process buffer, leaving just the prompt., C-c C-l, sage-shell:load-file, Asks for a file and loads it into Sage, C-c C-h, sage-shell:help, Ask for the name of a Sage object and show its documentation., ? RET, sage-shell-help::describe-symbol, Show the documentation of the object directly preceding the =?=., ?? RET, sage-shell:find-source-in-view-mode, Visits the source code of the object directly preceding the =??=., C-c o, sage-shell:list-outputs, List inputs and outputs in a buffer., C-c M-w, sage-shell:copy-previous-output-to-kill-ring, Copy the previous output to =kill-ring=, For more commands and key-bindings see the help using =M-x describe-mode
sage-shell-mode=.

*** Editing a Sage File

When you visit a file with the suffix =.sage=, then
=sage-shell:sage-mode= will be the major-mode of the buffer
automatically.

To switch to =sage-shell:sage-mode= on a =.py= file, run =M-x
sage-shell:sage-mode=. To use =sage-shell:sage-mode= every time you visit
that file, you can add the following magic comment at the first line of the
file:

#+BEGIN_SRC python
# -- mode: sage-shell:sage --
#+END_SRC

If you've activated [[#aliases][Aliases]] you can instead use the following magic comment:

#+BEGIN_SRC python
# -- mode: sage --
#+END_SRC

The major mode =sage-shell:sage-mode= is almost the same as
=python-mode=. The following new key-bindings are added:, Key, Command, Description, ---------+---------------------------------------+------------------------------------------------------------------, C-c C-c, sage-shell-edit:send-buffer, Evaluate the contents of the current buffer in the Sage process., C-c C-r, sage-shell-edit:send-region, Evaluate the currently marked region in the Sage process., C-c C-j, sage-shell-edit:send-line*, Evaluate the current line in the Sage process., C-c C-l, sage-shell-edit:load-file, Load the current file in the Sage process., C-c C-z, sage-shell-edit:pop-to-process-buffer, Select the Sage process buffer., If you run multiple Sage processes, use =M-x sage-shell:set-process-buffer=
to change which one will be used for the above functions.

** Input History

To save the history of input evaluated in a Sage process and use in future
Sage process (using the =M-p= keybinding), add the following to your Emacs
init file:

#+BEGIN_SRC elisp
(setq sage-shell:input-history-cache-file "~/.emacs.d/.sage_shell_input_history")
#+END_SRC

The file name in the above line is the path for storing the inputs and you can
change it to what you prefer.

** Emulating Worksheets: code blocks

Worksheets is a popular paradigm for structuring experiments in computer algebra systems, seen in Jupyter, the Sage Notebook, Maple and many other softwares.
=sage-shell-mode= supports a lightweight type of this workflow using "code blocks".

Essentially, you structure your source file in logical blocks of code, representing both your library code and your experiments.
For instance:

#+BEGIN_SRC python

Implement the new algorithm

def my_helper(a):
return a*2

def my_new_algorithm(x, y):
return my_helper(x) + my_helper(y)

Check the new algorithm on small input

print my_new_algorithm(1, 2)

Check the new algorithm on big input

print my_new_algorithm(100, 300)

Check that my algorithm is commutative using random input

def my_random_number():
return randint(100, 200)

a, b = my_random_number(), my_random_number()
assert my_new_algorithm(a, b) == my_new_algorithm(b, a)

#+END_SRC

The blocks of code are logically delimited by lines starting with =###=.
In this case =load(experiment.sage)= is not a good alternative to the way one works with the Jupyter Notebook: rather, you want to evaluate the code block by block.
You also want to be able to modifying an earlier or later block, run that, and then return to the block in the middle, etc.

=sage-shell-mode= comes with a small set of functions for accommodating this. In =sage-shell:sage-mode=, the following functions are provided:, Key, Command, Description, ------------+--------------------------------+-------------------------------------------------------------------, C-M-{, sage-shell-blocks:backward, Move backward one block, i.e. to previous =###= delimiter., C-M-}, sage-shell-blocks:forward, Move forward one block, i.e. to next =###= delimiter., C-, sage-shell-blocks:send-current, Send the block that the point is currently in to the Sage process, In the Sage process buffer, the following functions are provided:, Key, Command, Description, ------------+-----------------------------+------------------------------------------------------------, C-, sage-shell-blocks:pull-next, Take the block from the last visited =sage-shell:sage-mode= buffer and send to the Sage process., As an example, if the point is in the body of =my_new_algorithm=, then =C-= (or =M-x sage-shell-blocks:send-current=) would send the definitions of =my_helper= and =my_new_algorithm= to the Sage shell. Furthermore, it would print the "title" of the block:

#+BEGIN_SRC python
sage: load('/tmp/sage_shell_mode3946wC1/sage_shell_mode_temp.sage')
--- Implement the new algorithm ---
sage:
#+END_SRC

The delimiter =###= can be changed by =setq= the variable =sage-shell-blocs:delimiter=.

** Inline display of LaTeX outputs and plots (a port of =sage-view=)
This feature is a port of [[https://bitbucket.org/gvol/sage-mode/src/44eb95cb6b27a05af68e11253649ddf8ae364a5b/emacs/sage-view.el?at=default&fileviewer=file-view-default][sage-view]]. This requires [[https://www.ctan.org/pkg/dvipng][dvipng]] and [[https://www.ctan.org/tex-archive/macros/latex/contrib/preview][preview.sty]].

To enable inline display of LaTeX outputs and plots in =sage-shell-mode= buffer,
add the following code to your Emacs init file:

#+BEGIN_SRC elisp
  ;; If you want to enable inline display of LaTeX outputs only,
  ;; uncomment the following line.
  ;; (setq sage-shell-view-default-commands 'output)

  ;; If you want to enable inline display of plots only,
  ;; uncomment the following line.
  ;; (setq sage-shell-view-default-commands 'plot)

  (add-hook 'sage-shell-after-prompt-hook #'sage-shell-view-mode)
#+END_SRC

You can use the following commands to enable/disable inline display of LaTeX outputs and plots., Command, Description, -----------------------------------------+---------------------------------------------------------------------------, =sage-shell-view-toggle-inline-output=, Toggle inline display of LaTeX outputs while SageMath process is running., =sage-shell-view-toggle-inline-plots=, Toggle inline display of plots while SageMath process is running., The following table shows some of customizable variables for =sage-shell-view-mode=.
For further customization, run =M-x customize-group RET sage-shell-view RET=., Customizable variable, Description, Default value, =sage-shell-view-default-commands=, If equal to the symbol =plots= then will start inline plotting. If equal to the symbol =output= then will start typesetting output. Otherwise, if non-nil will start both., =t=, =sage-shell-view-default-resolution=, Resolution used when converting from PDF to PNG. This value is passed to the =-r= option of the ghostscript command., 125, =sage-shell-view-latex-foreground-color=, Foreground color used in LaTeX image as string (e.g. "black", "white", "#de935f") or =nil=. If it is =nil=, then the default foreground color will be used., =nil=, =sage-shell-view-latex-background-color=, Similar to =sage-shell-view-latex-foreground-color= for background color., =nil=, ** SageTeX

=sage-shell-mode= can be conveniently used when writing Sage-powered LaTeX files
using [[https://github.com/dandrake/sagetex][SageTeX]].

*** TEXINPUTS

When a Sage process is spawned by =sage-shell:run-sage= or
=sage-shell:run-new-sage=, then =sage-shell-mode= adds
=$SAGE_ROOT/local/share/texmf/tex/generic/sagetex/= to the
environment variable =TEXINPUTS= in Emacs. If you do not want to
change the environment variable, set
=sage-shell-sagetex:add-to-texinputs-p= to =nil=.

*** Commands for SageTeX

Here is a list of commands for =SageTeX=. These commands load a
=.sagetex.sage= file generated by =SageTeX= to the existing Sage
process., Command, Run =latex= before loading, Run =latex= after loading, --------------------------------------------+----------------------------+---------------------------, sage-shell-sagetex:load-file, No, No, sage-shell-sagetex:run-latex-and-load-file, Yes, No, sage-shell-sagetex:compile-file, Yes, Yes, There are similar commands to above,
=sage-shell-sagetex:load-current-file=,
=sage-shell-sagetex:run-latex-and-load-current-file= and
=sage-shell-sagetex:compile-current-file=.

Here is a sample setting for =AUCTeX= users.

#+BEGIN_SRC elisp
(eval-after-load "latex"
'(mapc (lambda (key-cmd) (define-key LaTeX-mode-map (car key-cmd) (cdr key-cmd)))
`((,(kbd "C-c s c") . sage-shell-sagetex:compile-current-file)
(,(kbd "C-c s C") . sage-shell-sagetex:compile-file)
(,(kbd "C-c s r") . sage-shell-sagetex:run-latex-and-load-current-file)
(,(kbd "C-c s R") . sage-shell-sagetex:run-latex-and-load-file)
(,(kbd "C-c s l") . sage-shell-sagetex:load-current-file)
(,(kbd "C-c s L") . sage-shell-sagetex:load-file)
(,(kbd "C-c C-z") . sage-shell-edit:pop-to-process-buffer))))
#+END_SRC

For example, you can run =sage-shell-sagetex:compile-current-file=
by =C-c s c= in a =LaTeX-mode= buffer with this setting.

*** Customize the =latex= Command

You can change a =latex= command used by
=sage-shell-sagetex:compile-file= and
=sage-shell-sagetex:compile-current-file= by setting
=sage-shell-sagetex:latex-command= or
=sage-shell-sagetex:auctex-command-name=.

If you are an =AUCTeX= user, then customize
=sage-shell-sagetex:auctex-command-name= to change the =latex=
command. The value of =sage-shell-sagetex:auctex-command-name=
should be a =name= of a command in =TeX-command-list= (i.e =car= of
an element of the list =TeX-command-list=), e.g.:

#+BEGIN_SRC elisp
(setq sage-shell-sagetex:auctex-command-name "LaTeX")
#+END_SRC

You can also use the variable =sage-shell-sagetex:latex-command= to
change the =latex= command. For example, if you want to run
=latexmk= after loading a =.sagetex.sage= file, then use the
following setting:

#+BEGIN_SRC elisp
(setq sage-shell-sagetex:latex-command "latexmk")
#+END_SRC

The default value of =sage-shell-sagetex:latex-command= is =latex
-interaction=nonstopmode=. If
=sage-shell-sagetex:auctex-command-name= is =non-nil=, then the
value of =sage-shell-sagetex:latex-command= is ignored.

** Customization

To customize =sage-shell-mode=, =M-x customize-group RET sage-shell=,
=M-x customize-group RET sage-shell-sagetex= or
=M-x customize-group RET sage-shell-view=.

** Extensions

  • [[https://github.com/stakemori/auto-complete-sage][auto-complete-sage]] provides an [[https://github.com/auto-complete/auto-complete][auto-complete]] source for
    =sage-shell-mode=.

  • [[https://github.com/stakemori/helm-sage][helm-sage]] provides a [[https://github.com/emacs-helm/helm][helm]] source for =sage-shell-mode=.

  • [[https://github.com/stakemori/anything-sage][anything-sage]] provides an [[http://www.emacswiki.org/Anything][anything]] source for =sage-shell-mode=.

  • [[https://github.com/stakemori/ob-sagemath][ob-sagemath]] provides [[http://orgmode.org/worg/org-contrib/babel/][org-babel]] functions for Sage.

** Screenshots

Automatic indentation and syntax highlighting work.

#+CAPTION: alt text

Completion with [[https://github.com/stakemori/auto-complete-sage][auto-complete-sage]].

#+CAPTION: alt text

Completion with [[https://github.com/stakemori/helm-sage][helm-sage]].

#+CAPTION: alt text

#+CAPTION: alt text

** Workaround for Flycheck

To use =flycheck-mode= in a =sage-shell:sage-mode= buffer and a
=python-mode= buffer, try the following code.

#+BEGIN_SRC elisp

(dolist (ckr '(python-pylint python-flake8))
  (flycheck-add-mode ckr 'sage-shell:sage-mode))

(defun sage-shell:flycheck-turn-on ()
  "Enable flycheck-mode only in a file ended with py."
  (when (let ((bfn (buffer-file-name)))
          (and bfn (string-match (rx ".py" eol) bfn)))
    (flycheck-mode 1)))

(add-hook 'python-mode-hook 'sage-shell:flycheck-turn-on)

#+END_SRC

** License

Licensed under the [[http://www.gnu.org/licenses/gpl.html][GPL]].

Main metrics

Overview
Name With Ownersagemath/sage-shell-mode
Primary LanguageEmacs Lisp
Program languageEmacs Lisp (Language Count: 3)
Platform
License:GNU General Public License v3.0
所有者活动
Created At2013-03-13 13:15:45
Pushed At2024-05-04 07:26:16
Last Commit At2024-05-04 09:26:15
Release Count36
Last Release Name0.3 (Posted on )
First Release Name0.0.2 (Posted on )
用户参与
Stargazers Count106
Watchers Count9
Fork Count17
Commits Count1.1k
Has Issues Enabled
Issues Count68
Issue Open Count38
Pull Requests Count12
Pull Requests Open Count2
Pull Requests Close Count3
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private