/stan-mode

Emacs mode for Stan.

Primary LanguageEmacs LispGNU General Public License v3.0GPL-3.0

Emacs support for Stan

Build Status License GPL 3

Example

This repository contains several Emacs packages and tools to make editing Stan files easier. For information on Stan itself, see its documentation and example models.

  • stan-mode is a major mode for editing Stan files. Its current features include:

    • syntax highlighting
    • indentation
    • imenu support for blocks, variables, and user-defined functions.
  • company-stan: Adds a company-mode completion backend.

  • eldoc-stan: Adds Stan support for the eldoc minor mode, which show the argument list of the function being written.

  • flycheck-stan adds a flycheck on-the-fly syntax checker.

  • stan-snippets: Adds Stan support for yasnippet. Yasnippet is a template system for Emacs. Snippets are defined for blocks, control structures, and all the built-in functions and distributions.

  • ac-stan: Adds a auto-complete stan dictionary.

  • indent-stan-files: A shell script that uses stan-mode to indent a file.

  • stan-language-definitions: The file stan_lang.json contains all keywords, functions (with their signatures and documentation) in the Stan modeling language. This is used to generate the keyword lists and snippets used by the modes. It could also be useful for developers designing tools for Stan, e.g. other editor modes.

Installing

Example configurations are available in the package-specific README.md file under each subfolder (linked above).

Via package.el

The recommended way to install these packages is using the built-in package manager: package.el. These packages are available from MELPA. If you're not already using MELPA, follow its installation instructions.

You can then install the packages using the following commands:

M-x package-install [RET] stan-mode [RET]
M-x package-install [RET] company-stan [RET]
M-x package-install [RET] eldoc-stan [RET]
M-x package-install [RET] flycheck-stan [RET]
M-x package-install [RET] stan-snippets [RET]

If you use auto-complete, also do the following:
M-x package-install [RET] stan-snippets [RET]

If the installation does not work, try refreshing the package list:

M-x package-refresh-contents [RET]

Or add the following to your init.el to ensure installation of these packages:

(package-refresh-contents)
(mapc
 (lambda (p)
   (unless (package-installed-p p)
     (package-install p)))
 '(stan-mode
   company-stan
   eldoc-stan
   flycheck-stan
   stan-snippets
   ;; If you use auto-complete, uncomment the line below.
   ;; ac-stan
   ))

Via Cask

Another way to manage dependencies is to to use Cask. See its docs for an argument as to why to use Cask to manage your configuration.

Simply add the following to your configuration Cask file:

(source melpa)
(depends-on "stan-mode")
(depends-on "company-stan")
(depends-on "eldoc-stan")
(depends-on "flycheck-stan")
(depends-on "stan-snippets")
;; If you use auto-complete, uncomment the line below.
;; (depends-on "ac-stan")

and from the command line in the same directory as the Cask file use cask to install the packages,

$ cask install

See the Cask documentation for more information.

Via Github

The package maintainer's current development version is available on Github. This can be cloned as follows. You can also use --recurse-submodules, but this will recurse more than one level, which is not necessary for our purpose.

# Clone the develop branch. Change as appropriate.
$ git clone --branch=develop https://github.com/stan-dev/stan-mode.git
$ cd stan-mode
# Clone submodules
$ git submodule update --init -- stan-language-definitions
$ git submodule update --init -- local-melpa
$ git submodule update --init -- rstanarm
$ git submodule update --init -- stan
# To run automated tests, do the following.
make clean; make all
# If just installing, do the following.
make local-melpa

Add the following to your init.el. The local development versions will be installed provided their version numbers are greater than the ones in MELPA.

;; To make the local package archive visible.
(let ((local-melpa-stan
       "your-path/stan-mode/local-melpa/packages"))
  (when (file-exists-p local-melpa-stan)
    (add-to-list 'package-archives
                 `("local-melpa-stan" . ,local-melpa-stan) t)))
;; Installation
(package-refresh-contents)
(mapc
 (lambda (p)
   (unless (package-installed-p p)
     (package-install p)))
 '(stan-mode
   company-stan
   eldoc-stan
   flycheck-stan
   stan-snippets
   ;; If you use auto-complete, uncomment the line below.
   ;; ac-stan
   ))

Configuration

The recommended mode of configuration is via the use-package. One example of configuration is included below. Please the package-specific README files for configuration without use-package.

;; Uncomment the line below if not required elsewhere.
;; (require 'use-package)

;;; stan-mode.el
(use-package stan-mode
  ;; Uncomment if directly loading from your development repo
  ;; :load-path "your-path/stan-mode/stan-mode"
  :mode ("\\.stan\\'" . stan-mode)
  :hook (stan-mode . stan-mode-setup)
  ;;
  :config
  ;; The officially recommended offset is 2.
  (setq stan-indentation-offset 2))

;;; company-stan.el
(use-package company-stan
  ;; Uncomment if directly loading from your development repo
  ;; :load-path "your-path/stan-mode/company-stan/"
  :hook (stan-mode . company-stan-setup)
  ;;
  :config
  ;; Whether to use fuzzy matching in `company-stan'
  (setq company-stan-fuzzy nil))

;;; eldoc-stan.el
(use-package eldoc-stan
  ;; Uncomment if directly loading from your development repo
  ;; :load-path "your-path/stan-mode/eldoc-stan/"
  :hook (stan-mode . eldoc-stan-setup)
  ;;
  :config
  ;; No configuration options as of now.
  )

;;; flycheck-stan.el
(use-package flycheck-stan
  ;; Uncomment if directly loading from your development repo
  ;; :load-path "your-path/stan-mode/flycheck-stan/"
  :hook (stan-mode . flycheck-stan-setup)
  ;;
  :config
  ;; No configuration options as of now.
  )

;;; stan-snippets.el
(use-package stan-snippets
  ;; Uncomment if directly loading from your development repo
  ;; :load-path "your-path/stan-mode/stan-snippets/"
  :hook (stan-mode . stan-snippets-initialize)
  ;;
  :config
  ;; No configuration options as of now.
  )

;;; ac-stan.el
(use-package ac-stan
  ;; Uncomment if directly loading from your development repo
  ;; :load-path "path-to-your-repo/stan-mode/ac-stan/"
  ;; Delete the line below if using.
  :disabled t
  :hook (stan-mode . stan-ac-mode-setup)
  ;;
  :config
  ;; No configuration options as of now.
  )

For Developers

Updating packages for a new Stan version

To update stan-mode when a new version of the Stan language comes out:

  1. Replace stan-lang/stan-functions-2.19.0.txt with the newest version of the stan-functions.txt file in the rstan repo. The version string must exist in the file name and it is the Stan version.
  2. Clean and rebuild all generated files. Fix issues in testing and linting as necessary.
$ make clean
$ make all
  1. Save and commit the changes.
  2. Bump the version number of the emacs packages. For example, to bump to 10.0.0. This is the emacs stan-mode package version, which is different than the Stan language version.
$ ./update-versions.sh 10.0.0
  1. If the changes are minor, tag the commit and push the tag for MELPA Stable. If making major changes, it is better to create a pull request on Github to document and discuss.
$ git tag v10.0.0
$ git push --tags

Emacs lisp good practices

The packages must meet the MELPA standards. See "Making your package ready for inclusion". The packages ensure these standards through the following automated examinations, which are mandated in make all.

For testing only, use make test at the top-level or in a subfolder. For linting only, use make lint at the top-level (both types) or make lint-package and make lint-elisp in a subfolder.

Available top-level make commands

The following make commands are available at the top-level Makefile. Each package has its own Makefile and common included file common.mk, allowing us to work on them individually.

Command Cleaning Equivalent Action
all clean Run stan-lang deps build-src local-melpa compile test lint
stan-lang clean-stan-lang Create the stan-lang.json definition file in stan-language-definitions.
deps clean-deps Run cask install for each package to manage dependencies.
build-src clean-src Build data files for each package.
local-melpa clean-local-melpa Create a local archive local-melpa to manage package installability in testing.
compile clean-elc Byte-compile *.elc files for each package.
test Run buttercup.el tests for each package.
lint Run both linting for each package.
lint-package Run package-lint.el to examine package metadata.
lint-elisp Run elisp-lint.el to examine elisp coding practice.
dist clean-dist Run cask package to build package files under dist for each package.
show Show elisp files designated for byte-compilation for each package.
snippets clean-snippets Move snippet files under stan-snippets/snippets/ to snippets

Submodules

  • stan-language-definitions: Provides language definitions. All packages depend on this for definitions.
  • local-melpa: Provides a local version of MELPA to make the current development version available via the package.el interface. Used to avoid installability issue during linting. Also allows package installation checking.
  • rstanarm: Used to provide examples of complicated stan code in indentation and syntax highlighting tests for the stan-mode package.
  • stan: Used to provide error message patterns for flycheck-stan.

License

All packages are free software under the GPL v3.