## 1. Project Overview & Quickstart (bbatsov/prelude)

## File: README.md

# Emacs Prelude

[
[](https://github.com/bbatsov/prelude/actions/workflows/ci.yml)

Prelude is an Emacs distribution that aims to enhance the default
Emacs experience.  Prelude alters a lot of the default settings,
bundles a plethora of additional packages and adds its own core
library to the mix. The final product offers an easy to use Emacs
configuration for Emacs newcomers and lots of additional power for
Emacs power users.



Prelude is compatible **ONLY with GNU Emacs 29.1+**. In general
you're advised to always run Prelude with the latest stable
Emacs release.

-----------
[](https://github.com/sponsors/bbatsov)
[](https://www.patreon.com/bbatsov)
[](https://www.paypal.me/bbatsov)

I've been developing and maintaining Prelude in my free time for well over
a decade. That's a lot of work, and not all of it is fun!

**Please consider [supporting Prelude's ongoing development](#funding).**

## Features

- Improved UX, that's still in line with Emacs traditions
- Sane defaults of baseline Emacs functionality
- Automatic installation of many major programming modes on demand
- A curated set of 3rd party packages to enhance the base
  functionality
- Simple modular architecture
- Easy customization

Check out our [user manual](https://prelude.emacsredux.com)
for more information.

## Fast Forward

Assuming you're using an Unix-like OS (`*BSD`, `GNU/Linux`,
`macOS`, `Solaris`, etc), you already have a recent version of
Emacs installed, as well as `git` & `curl` you can skip the
whole manual and just type in your favorite shell the
following command:

```shell
curl -L https://git.io/epre | sh
```

You can now power up your Emacs, sit back and enjoy Prelude.

There are two environment variables you can use to control the
source repository and the installation directory. To change the
installation directory:

```shell
export PRELUDE_INSTALL_DIR="$HOME/.emacs.d" && \
  curl -L https://github.com/bbatsov/prelude/raw/master/utils/installer.sh | sh
```

To change the source repository:

```shell
export PRELUDE_URL="https://github.com/yourname/prelude.git" && \
  curl -L https://github.com/bbatsov/prelude/raw/master/utils/installer.sh | sh
```

Note that the installer will back up any existing `.emacs` file or
`.emacs.d` since it will unpack Prelude's code in `.emacs.d`. If
you're doing a manual install make sure you don't have a `.emacs`
file or back up your existing `.emacs.d` directory manually.

**Important:** Don't forget to adjust your
`prelude-modules.el` file in your personal directory
once the installation is done. By default most of the modules
that ship with Prelude are **not** loaded.

## Try Before You "Buy"

If you're using Emacs 29+ there's a simple way to try Prelude
(or any other Emacs distro for that matter).
Just clone Prelude's repo somewhere and do the following:

```shell
emacs --init-dir ~/path/to/prelude
```

## Philosophy

Prelude's philosophy is quite simple:

- simple
- easy to understand and extend
- stable
- a foundation for you to build upon, as opposed to some
  end-user product

This means that it intentionally doesn't pack all the bells
and whistles that it could. Prelude aims to enhance the classic
Emacs experience without deviating a lot from it - e.g.
it would never enable something like `evil-mode`
(vim keybindings) by default and so on.

All the third-party packages that it bundles are carefully
vetted and are known to be of good quality and to have reliable
maintainers. That generally means that Prelude's unlikely
to immediate adopt some shiny new package, that has established
tried and true alternatives.

In practice this translates to the following:

- Prelude is less opinionated than distros like Spacemacs and
  Doom Emacs (meaning it's closer to the standard Emacs
  experience)
- Prelude installs relatively few additional packages by default
- Most modules in Prelude are opt-in instead of opt-out
  (you'll notice the default config enables only a handful of
  modules)
- Most modules (e.g. modules for programming languages) are
  pretty short and feature setup only for essential packages
  (in some cases that be just the major mode for the language
  in question)
- You don't really need to track Prelude's upstream - you're
  encouraged to just fork it and use it as the basis for your
  own configuration.

Remember that the ultimate goal of every Emacs user is to
create an Emacs setup that reflects their own experience,
needs, goals and ideas. Just like Lisp, Emacs is nothing but a
raw building material for the perfect editing experience.

More installation options are discussed in the
[installation guide](https://prelude.emacsredux.com/en/latest/installation/).

## User Manual

While Emacs Prelude is pretty simple at its core, it does have
some specifics that are worth learning - e.g. configuration
options, load order of modules and personal settings and so on.

Check out our [user manual](https://prelude.emacsredux.com)
for more information.

You can also find a lot of information about specific Prelude
features and the rationale behind them on my Emacs blog
[Emacs Redux](https://emacsredux.com).

## crux and super-save

A lot of utility commands that used to be part of Prelude were
eventually extracted to the [crux][crux-url] package, so they'd
be easily available to more people.
These days Prelude simply depends on that package.

The [super-save][super-save-url] package also used to be part
of Prelude in the past.

[crux-url]: https://github.com/bbatsov/crux
[super-save-url]: https://github.com/bbatsov/super-save

## Upgrading to Prelude 2.0

Prelude 2.0 is a major release that modernizes the entire
distribution around Emacs 29+ features. Here's what you need to know:

## Emacs 29.1 is now required

Prelude no longer supports Emacs 28 or older. If you haven't
upgraded yet, now's the time. Emacs 29 brings built-in tree-sitter,
Eglot (LSP client), `use-package`, and many other improvements that
Prelude 2.0 takes full advantage of.

## Tree-sitter support

For built-in modes that ship both classic and tree-sitter variants
(e.g., `python-mode` / `python-ts-mode`), Prelude automatically
selects the tree-sitter version when a grammar is available and falls
back to the classic mode when it isn't. Some modules use tree-sitter
modes unconditionally (e.g., `prelude-ocaml` uses `neocaml` which is
tree-sitter-only), though such modes typically auto-install their
grammars.

To install tree-sitter grammars, use
`M-x treesit-install-language-grammar`. See the
[Emacs manual][ts-grammar] for details.

[ts-grammar]: https://www.gnu.org/software/emacs/manual/html_node/emacs/Language-Grammar.html

## Built-in LSP via Eglot

Prelude 2.0 adds LSP support to most language modules using Eglot
(built-in since Emacs 29) as the default client. If you were
previously using `prelude-lsp` with lsp-mode, note that:

- The module has been renamed to `prelude-lsp-mode`.
- Set `(setq prelude-lsp-client 'lsp-mode)` in your personal
  config to keep using lsp-mode.
- The default is now Eglot -- no extra packages needed.
- Eglot keybindings live under `C-c C-l` (rename, code
  actions, format, etc.).

## Removed packages and modules

Several outdated packages have been replaced by built-in alternatives:

| Removed             | Replacement                          |
|---------------------|--------------------------------------|
| `nlinum`            | Built-in `display-line-numbers-mode` |
| `anzu`              | Built-in `isearch-lazy-count`        |
| `epl`               | Built-in `package-upgrade-all`       |
| `smex` (binding)    | `execute-extended-command`           |
| `anaconda-mode`     | LSP (Eglot/lsp-mode)                 |
| `js2-mode`          | `js-ts-mode` + LSP                   |
| `tide`              | `typescript-ts-mode` + LSP           |
| `alchemist`         | LSP                                  |
| `go-projectile`     | Removed (unmaintained)               |
| `prelude-selectrum` | Use `prelude-vertico` instead        |

## Keybinding changes

- `C-x p` no longer opens `proced` (reserved for `project.el`).
- `C-x C-m` runs `execute-extended-command` instead of `smex`.
- `C-c c` is bound to `org-capture`.
- `C-c C-l` prefix is used for Eglot commands in programming
  modes.

## What you should do

1. **Update Emacs** to 29.1 or newer.
2. **Pull the latest Prelude** and restart Emacs. Packages will
   be updated automatically.
3. **Review your `prelude-modules.el`** -- if you had
   `prelude-lsp` enabled, rename it to `prelude-lsp-mode`. If
   you want Eglot (recommended), you don't need any LSP module
   enabled.
4. **Install tree-sitter grammars** for your languages of choice
   (optional but recommended).
5. **Check your personal config** for references to removed
   packages (`nlinum`, `anzu`, `epl`, `anaconda-mode`,
   `js2-mode`, `tide`, `alchemist`).

## Known issues

Check out the project's
[issue list](https://github.com/bbatsov/prelude/issues?sort=created&direction=desc&state=open)
a list of unresolved issues. By the way - feel free to fix any
of them and send me a pull request. :-)

## Funding

While Prelude is free software and will always be, the project would
benefit immensely from some funding. If Prelude improves your daily Emacs
experience, please consider supporting its ongoing development.

You can support the development of Prelude via:

- [GitHub Sponsors](https://github.com/sponsors/bbatsov)
- [Patreon](https://www.patreon.com/bbatsov)
- [ko-fi](https://ko-fi.com/bbatsov)
- [PayPal](https://www.paypal.me/bbatsov)

## Support

Support is available via several channels:

- Prelude's Google Group 
- [GitHub Discussions](https://github.com/bbatsov/prelude/discussions)

## Contributors

Here's a [list](https://github.com/bbatsov/prelude/contributors)
of all the people who have contributed to the development of
Emacs Prelude.

## Bugs & Improvements

Bug reports and suggestions for improvements are always
welcome. GitHub pull requests are even better! :-)

## License

Copyright © 2011-2026 Bozhidar Batsov and
[contributors](https://github.com/bbatsov/prelude/contributors).

Distributed under the GNU General Public License, version 3

[badge-license]: https://img.shields.io/badge/license-GPL_3-green.svg

---

## File: docs/modules/ai.md

# Prelude AI

## Overview

[gptel](https://github.com/karthink/gptel) is a simple, multi-backend
LLM client for Emacs. This module installs it and provides a single
global keybinding so you can drive it from anywhere.

gptel supports many providers, including:

- **Anthropic** (Claude)
- **OpenAI** (GPT-4, GPT-5, etc.)
- **Google** (Gemini)
- **Ollama** (local models)
- **Azure OpenAI**, **OpenRouter**, **Perplexity**, and more

## Key Bindings

| Key | Command | Description |
| --- | ------- | ----------- |
| <kbd>C-c q</kbd> | `gptel-menu` | Transient menu (entry to gptel) |

Inside a gptel chat buffer, <kbd>C-c RET</kbd> sends the current
prompt and <kbd>C-c C-c</kbd> sends the region (these are gptel's
own defaults).

## Configuring a backend

You need to configure a backend and an API key in your personal
config (e.g. `~/.emacs.d/personal/ai.el`).  Some examples:

### Anthropic (Claude)

```emacs-lisp
(setq gptel-backend (gptel-make-anthropic "Claude"
                      :stream t
                      :key (getenv "ANTHROPIC_API_KEY"))
      gptel-model 'claude-sonnet-4-6)
```

### OpenAI

OpenAI is gptel's default backend, so you only need to set the key
and the model:

```emacs-lisp
(setq gptel-api-key (getenv "OPENAI_API_KEY")
      gptel-model 'gpt-4o)
```

### Local Ollama

```emacs-lisp
(setq gptel-backend (gptel-make-ollama "Ollama"
                      :host "localhost:11434"
                      :stream t
                      :models '(llama3.1:8b qwen2.5-coder:7b))
      gptel-model 'qwen2.5-coder:7b)
```

See the [gptel README](https://github.com/karthink/gptel) for
backend-specific options and the full list of supported providers.

## Tips

- `auth-source` is supported for API keys — pass
  `:key 'gptel-api-key-from-auth-source` or use a function — so you
  don't have to keep the key in environment variables.
- `gptel-add` (available from the transient menu) lets you attach
  buffers, regions, or files to the chat context.
- For agentic editing workflows, take a look at
  [aidermacs](https://github.com/MatthewZMD/aidermacs) — it's not
  bundled here but pairs naturally with this module.

---

## File: docs/modules/apheleia.md

# Prelude Apheleia

## Overview

[Apheleia](https://github.com/radian-software/apheleia) is a
unified format-on-save framework for Emacs. On save, it runs the
appropriate external formatter (Prettier, Black, Ruff, gofmt,
rustfmt, ...) asynchronously, then patches the buffer with the
result. The patching is point-preserving and flicker-free -- it
feels like the formatter ran instantly with no visible buffer
churn.

Apheleia ships with sensible defaults for dozens of formatters and
many major modes out of the box. Look at `apheleia-formatters` and
`apheleia-mode-alist` for the full list.

## What this module does

Just two things:

1. Installs the `apheleia` package.
2. Enables `apheleia-global-mode`.

That's it -- no further setup required for the languages Apheleia
already knows about.

## Relationship to language modules

Several Prelude language modules install their own format-on-save
hooks (e.g. `rust-format-on-save` in `prelude-rust`,
`gofmt-before-save` in `prelude-go`). These keep working with
Apheleia enabled -- they just run redundantly. If you enable this
module you can safely drop them from your personal config, or
disable them with hooks like:

```emacs-lisp
(with-eval-after-load 'rust-ts-mode
  (setq rust-format-on-save nil))

(with-eval-after-load 'go-mode
  (remove-hook 'before-save-hook 'gofmt-before-save))
```

## Adding a formatter

For languages or tools Apheleia doesn't know about, register a
formatter and tell Apheleia which mode it applies to:

```emacs-lisp
(with-eval-after-load 'apheleia
  (setf (alist-get 'shfmt apheleia-formatters)
        '("shfmt" "-i" "2" "-ci"))
  (setf (alist-get 'sh-mode apheleia-mode-alist) 'shfmt))
```

See the [Apheleia README](https://github.com/radian-software/apheleia)
for the formatter spec and built-in entries you can copy from.

## Disabling per buffer

If you need to skip formatting for a specific buffer, run
`M-x apheleia-mode` to toggle it off locally. To skip a whole
project, set a directory-local `apheleia-inhibit` to `t`.

---

## File: docs/modules/c.md

# Prelude C/C++

!!! Note

    This module builds on top of the shared [Programming](programming.md) module.

## cc-mode

Emacs comes with powerful C/C++ programming support through the built-in
`cc-mode`. This module provides sensible defaults for `cc-mode` and all modes
derived from it (e.g. `java-mode`, `php-mode`, etc.).

Prelude configures the following defaults:

- **Indentation style**: K&R (`c-default-style` set to `"k&r"`)
- **Indent offset**: 4 spaces (`c-basic-offset` set to `4`)
- **Substatement opening braces** are not indented
  (`substatement-open` offset set to `0`)

You can override any of these in your personal config:

```emacs-lisp
(setq prelude-c-mode-common-hook
      (lambda ()
        (setq c-default-style "linux"
              c-basic-offset 8)))
```

## Makefile Mode

The module also provides configuration for `makefile-mode`:

- Tabs are allowed in Makefiles (since they are syntactically required)
- `indent-tabs-mode` is enabled

## Key Bindings

Run <kbd>C-h m</kbd> in any C/C++ buffer to see all available key bindings.

---

## File: docs/modules/clojure.md

# Prelude Clojure

!!! Note

    This module builds on top of the shared [Lisp Base](lisp.md) module.

## Clojure Mode

This module bundles `clojure-mode`, a major mode for programming in Clojure,
and some sensible defaults for it.

Prelude uses `clojure-mode` rather than the newer `clojure-ts-mode` because:

- `clojure-ts-mode` requires Emacs 30+, while Prelude supports Emacs 29.1+.
- CIDER and `clj-refactor` still depend on `clojure-mode` for some APIs.
- `clojure-ts-mode` is still under active development and not yet at full
  feature parity with `clojure-mode`.

### Using clojure-ts-mode (Emacs 30+)

If you're on Emacs 30+ and want to try tree-sitter based Clojure
support, install `clojure-ts-mode` in your personal config:

```emacs-lisp
(use-package clojure-ts-mode
  :ensure t)
```

`clojure-ts-mode` auto-remaps `clojure-mode` buffers when installed,
so no additional configuration is needed. It will also auto-install
the required tree-sitter grammar on first use. See the
[clojure-ts-mode documentation](https://github.com/clojure-emacs/clojure-ts-mode)
for details.

## CIDER

This module also bundles [CIDER](https://docs.cider.mx), a popular interactive
programming environment for Clojure.

Intentionally, Prelude doesn't install by default popular CIDER plugins like
`clj-refactor`, `sayid`, etc, as those can be overwhelming to newcomers and
are easy to setup if you need them.

## CIDER Alternatives

Depending on your preferences you might want to use `inf-clojure` or `clojure-lsp`
alongside/instead of CIDER, but you'll have to set them up yourselves.

## Fun trivia

I'm the author of CIDER and `inf-clojure` and the primary
maintainer of `clojure-mode`. I'm also a co-maintainer of
`clj-refactor`. I guess I love Clojure! :-)

---

## File: docs/modules/common_lisp.md

# Prelude Common Lisp

!!! Note

    This module builds on top of the shared [Lisp Base](lisp.md) module.

## lisp-mode

Not much to say here, as `lisp-mode` is configured in the "Lisp Base" module.

## SLIME

This module bundles [SLIME](https://common-lisp.net/project/slime/), a popular interactive
programming environment for Common Lisp, and enables many of its essential features.

SLIME supports many Common Lisp implementations. Prelude defaults to
[SBCL](http://www.sbcl.org/) on all platforms. You can change this via
`slime-default-lisp`, or use `M-- M-x slime` to pick an implementation
interactively.

You can start SLIME with `M-x slime`.

## Alternatives

If you prefer [Sly](https://github.com/joaotavora/sly), a modernized fork
of SLIME with features like stickers (non-disruptive value tracing),
multiple REPLs, flex completion out of the box, and a more polished
inspector, you can install it in your personal config instead. Note that
SLIME and Sly conflict with each other -- use one or the other, not both.

To switch, drop something like this into a file under
`~/.emacs.d/personal/` (and remove `prelude-common-lisp` from your
`prelude-modules.el`, or skip loading SLIME some other way):

```emacs-lisp
(use-package sly
  :ensure t
  :config
  (setq inferior-lisp-program "sbcl"))
```

Then start it with `M-x sly`.

---

## File: docs/modules/company.md

# Prelude Company

!!! Note

    This module is enabled by default.

[company](https://company-mode.github.io/) is a completion library.

This module simply provides some reasonable defaults for it and enables `company-mode`:

```emacs-lisp
(setq company-idle-delay 0.5)
(setq company-show-numbers t)
(setq company-tooltip-limit 10)
(setq company-minimum-prefix-length 2)
(setq company-tooltip-align-annotations t)
;; invert the navigation direction if the the completion popup-isearch-match
;; is displayed on top (happens near the bottom of windows)
(setq company-tooltip-flip-when-above t)

(global-company-mode 1)
```

You can adjust the configuration further in your personal config.

`company-mode` has [many extensions](https://github.com/company-mode/company-mode/wiki/Third-Party-Packages)
for various programming languages.
Some of Prelude's modules will install and enable the relevant extensions when necessary.

---

## File: docs/modules/corfu.md

# Prelude Corfu

## Overview

[Corfu](https://github.com/minad/corfu) is a minimal in-buffer
completion UI for Emacs -- a modern, lightweight alternative to
Company. It uses Emacs' built-in `completion-at-point` infrastructure
and the standard completion styles (so it cooperates with
`orderless` from `prelude-vertico`), instead of providing its own
backend abstraction the way Company does.

[Cape](https://github.com/minad/cape) extends
`completion-at-point-functions` with extra sources -- file paths,
dabbrev, keywords, ispell, abbrevs, etc. -- so they show up in the
Corfu popup alongside the language-specific completions provided by
LSP servers, Eglot, etc.

!!! Note

    This module is mutually exclusive with the
    [Company](company.md) module -- enable one or the other, not
    both.

## Packages

- [corfu](https://github.com/minad/corfu) - the completion popup
- [cape](https://github.com/minad/cape) - completion-at-point extensions

## Defaults

Corfu auto-pops after typing 2 characters (with a 200 ms debounce)
and cycles through candidates with <kbd>TAB</kbd>:

| Variable | Value | Effect |
| -------- | ----- | ------ |
| `corfu-auto` | `t` | Open the popup automatically as you type |
| `corfu-auto-prefix` | `2` | Minimum prefix length to trigger |
| `corfu-auto-delay` | `0.2` | Delay (seconds) before popup |
| `corfu-cycle` | `t` | Wrap around at end of list |

`corfu-popupinfo-mode` is enabled by default -- it shows
documentation for the highlighted candidate in a side popup.

## Default Cape sources

The following completion-at-point sources are added globally:

- `cape-dabbrev` - completes from words in open buffers
- `cape-file` - completes file paths

Add more from your personal config:

```emacs-lisp
(with-eval-after-load 'cape
  (add-hook 'completion-at-point-functions #'cape-keyword)
  (add-hook 'completion-at-point-functions #'cape-elisp-block))
```

## Tips

- Press <kbd>M-SPC</kbd> in the popup to insert a space without
  dismissing it (useful with orderless).
- <kbd>M-g</kbd> opens the candidate at point (e.g. jumps to the
  function definition); <kbd>M-h</kbd> shows its documentation in a
  separate buffer.
- For language-specific completions to feel snappy, configure your
  LSP setup (Eglot or `lsp-mode`) to expose richer
  `completion-at-point-functions` -- both already do this out of
  the box.

---

## File: docs/modules/css.md

# Prelude CSS

## CSS Mode

Emacs comes with CSS editing support through the built-in
`css-mode`. This module
adds a couple of enhancements on top of it:

- **Indent offset**: 2 spaces (`css-indent-offset` set to `2`)
- **Rainbow mode**:
  [rainbow-mode](https://elpa.gnu.org/packages/rainbow-mode.html)
  is enabled, which colorizes color strings (like `#ff0000` or
  `rgb(255, 0, 0)`) with the color they represent

The module also runs the `prelude-prog-mode-hook`, so you get the same baseline
programming features (whitespace visualization, smartparens, etc.) as in other
programming modes.

---

## File: docs/modules/dart.md

# Prelude Dart

!!! Note

    This module builds on top of the lsp-module.

The dart module is powered by [lsp-dart](https://emacs-lsp.github.io/lsp-dart/).

Some features it provides:

- Flutter integration
- Tree views
- Run pub
- Debug
- Run tests

Some essential commands:

- `lsp-dart-pub-get` - Run pub get or flutter pub get on
  project root.
- `lsp-dart-pub-upgrade` - Run pub upgrade or flutter pub
  upgrade on project root.
- `lsp-dart-pub-outdated` - Run pub outdated or flutter pub
  outdated on project root.
- `lsp-dart-run-all-tests` - Run all tests from project.
- `lsp-dart-run-test-file` - Run all tests from current
  test buffer.

## 2. Official Technical Reference & Guides (bbatsov/docs)

## File: README.md

# Introduction

Volt is a Ruby web framework where your ruby code runs on both the server and the client (via [opal](https://github.com/opal/opal)).  The DOM automatically updates as the user interacts with the page. Page state can be stored in the URL. If the user hits a URL directly, the HTML will first be rendered on the server for faster load times and easier indexing by search engines.

Instead of syncing data between the client and server via HTTP, Volt uses a persistent connection between the client and server. When data is updated on one client, it is updated in the database and any other listening clients (with almost no setup code needed).

Pages HTML is written in a template language where you can put ruby between ```{{``` and ```}}```.  Volt uses data flow/reactive programming to automatically and intelligently propagate changes to the DOM (or any other code wanting to know when a value updates).  When something in the DOM changes, Volt intelligently updates only the nodes that need to be changed.

See some demo videos here:
- [Volt Todos Example](https://www.youtube.com/watch?v=Tg-EtRnMz7o)
- [Pagination Example](https://www.youtube.com/watch?v=1uanfzMLP9g)
- [Build a Blog with Volt](https://www.youtube.com/watch?v=c478sMlhx1o)
** Note: The blog video is outdated, expect an updated version soon.

Check out demo apps:
 - https://github.com/voltrb/todos3
 - https://github.com/voltrb/contactsdemo

---

## File: en/contributing/README.md

# Contributing

You want to contribute?  Great!  Thanks for being awesome!  We have full docs on how to contribute here:
https://github.com/voltrb/volt/blob/master/CONTRIBUTING.md

---

## File: en/deployment/README.md

# Volt Deployment

This chapter highlights various deployment options for Volt on popular cloud providers.

---

## File: en/docs/arraymodel_events.md

## ArrayModel Events

Models trigger events when their data is updated.  Currently, models emit two events: ```added``` and ```removed```.  For example:

```ruby
    model = Volt::Model.new

    model._items.on('added') { puts 'item added' }
    model._items << 1
    # => item added

    model._items.on('removed') { puts 'item removed' }
    model._items.delete_at(0)
    # => item removed
```

---

## File: en/docs/assets.md

## Assets

**Note, asset management is still early, and likely will change quite a bit**

In Volt, assets such as JavaScript and CSS (or sass) are automatically included on the page for you.  Anything placed inside of a components asset/js or assets/css folder is served at /assets/{js,css} (via [Sprockets](https://github.com/sstephenson/sprockets)).  Link and script tags are automatically added for each css and js file in assets/css and assets/js respectively.  Files are included in their lexical order, so you can add numbers in front if you need to change the load order.

Any JS/CSS from an included component or component gem will be included as well.  By default [bootstrap](http://getbootstrap.com/) is provided by the volt-bootstrap gem.

**Note: asset bundling is on the TODO list**

---

## File: en/docs/attribute_bindings.md

# Attribute Bindings

Bindings can also be placed inside of attributes.

```html
Text
```

There are some special features provided to make elements work as "two way bindings":

```html

```

## CheckBoxes

In the example above, if ```_name``` changes, the field will update, and if the field is updated, ```_name``` will be changed:

```html

```

If the value of a checked attribute is ```true```, the checkbox will be shown checked. If it's checked or unchecked, the value will be updated to ```true``` or ```false``` respectively.

## Radio Buttons

Radio buttons bind to a checked state as well, except instead of setting the value to true or false, they set it to a supplied field value.

```html


```

When a radio button is checked, whatever checked is bound to is set to the field's value.  When the checked binding value is changed, any radio buttons where the binding's value matches the fields value are checked.  NOTE: This seems to be the most useful behavior for radio buttons.

## Select Boxes

Select boxes can be bound to a value (while not technically a DOM property, this is another convenient behavior Volt adds).

```html
<select value="{{ _rating }}">
  <option value="1">*</option>
  <option value="2">**</option>
  <option value="3">***</option>
  <option value="4">****</option>
  <option value="5">*****</option>
</select>
```

When the selected option of the select above changes, ```_rating``` is changed to match.  When ```_rating``` is changed, the selected value is changed to the first option with a matching value.  If no matching values are found, the select box is unselected.

---

## File: en/docs/automatic_model_conversion.md

## Automatic Model Conversion

### Hash -> Model

For convenience, when placing a hash inside of another model, it is automatically converted into a model.  Models are similar to hashes, but provide support for things like persistence and triggering reactive events.

```ruby
    user = Volt::Model.new
    user._name = 'Ryan'
    user._profiles = {
      twitter: 'http://www.twitter.com/ryanstout',
      dribbble: 'http://dribbble.com/ryanstout'
    }

    user._name
    # => "Ryan"
    user._profiles._twitter
    # => "http://www.twitter.com/ryanstout"
    user._profiles.class
    # => Volt::Model
```

Models are accessed differently from hashes.  Instead of using `model[:symbol]` to access, you call a method `model.method_name`.  This provides a dynamic unified store where setters and getters can be added without changing any access code.

You can get a Ruby hash back out by calling `#to_h` on a Model.

### Array -> ArrayModel

Arrays inside of models are automatically converted to an instance of ArrayModel.  ArrayModels behave the same as a normal Array except that they can handle things like being bound to backend data and triggering reactive events.

```ruby
    model = Volt::Model.new
    model._items << {name: 'item 1'}
    model._items.class
    # => Volt::ArrayModel

    model._items[0].class
    # => Volt::Model
    model._items[0]
```


To convert a Volt::Model or a Volt::ArrayModel back to a normal hash, call .to_h or .to_a respectively.
To convert them to a JavaScript Object (for passing to some JavaScript code), call `#to_n` (to native).

```ruby
    user = Volt::Model.new
    user._name = 'Ryan'
    user._profiles = {
      _twitter: 'http://www.twitter.com/ryanstout',
      _dribbble: 'http://dribbble.com/ryanstout'
    }

    user._profiles.to_h
    # => {twitter: 'http://www.twitter.com/ryanstout', dribbble: 'http://dribbble.com/ryanstout'}

    items = Volt::ArrayModel.new([1,2,3,4])
    # => #<Volt::ArrayModel:70226521081980 [1, 2, 3, 4]>

    items.to_a
    # => [1,2,3,4]
```

You can get a normal array again by calling .to_a on a Volt::ArrayModel.

---

## File: en/docs/buffers.md

## Buffers

Because the store collection is automatically synced to the backend, any change to a model's property will result in all other clients seeing the change immediately.  Often this is not the desired behavior.  To facilitate building [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete) apps, Volt provides the concept of a "buffer".  A buffer can be created from one model and will not save data back to its backing model until .save! is called on it.  This lets you create a form thats not saved until a submit button is pressed.

```ruby
    store._items << {name: 'Item 1'}

    item1 = store._items[0]

    item1_buffer = item1.buffer

    item1_buffer._name = 'Updated Item 1'
    item1_buffer._name
    # => 'Updated Item 1'

    item1._name
    # => 'Item 1'

    item1_buffer.save!

    item1_buffer._name
    # => 'Updated Item 1'

    item1._name
    # => 'Updated Item 1'
```

```#save!``` on buffer also returns a [promise](http://opalrb.org/blog/2014/05/07/promises-in-opal/) that will resolve when the data has been saved back to the server.

```ruby
    item1_buffer.save!.then do
      puts "Item 1 saved"
    end.fail do |err|
      puts "Unable to save because #{err}"
    end
```

Calling .buffer on an existing model will return a buffer for that model instance.  If you call .buffer on a Volt::ArrayModel (plural sub-collection), you will get a buffer for a new item in that collection.  Calling .save! will then add the item to that sub-collection as if you had done << to push the item into the collection.

---

## File: en/docs/callbacks_and_actions.md

# Controller Actions

When a template binding or tag renders a view, it first loads a controller.  There are four callbacks around the rendering.  The ```{action}``` is the same as the view file's name.  So if you were rendering ```about.html```, ```about``` would be the action.  Simply create the correct method in the controller and it will called at the time.

| action name           | description |
|-----------------------|-----------------------------------------------------|
| ```{action}``` | called before anything renders.  Setup data you need       |
| ```{action}_ready``` | called after the view renders.  Run any code where you need to bind directly to the dom.  jQuery setup code for example (bootstrap components) |
| ```before_{action}_remove``` | called before the view is removed (unrendered).  Cleanup any dom bindings here. |
| ```after_{action}_remove``` | called after the view is removed from the dom.  Cleanup anything in the controller that needs to be cleaned up. |

Most of the time all you will need is the action method to setup the controller, model, etc...

---

## File: en/docs/channel.md

# Channel

Controllers provide a `#channel` method, that you can use to get the status of the connection to the backend.  Channel's access methods are reactive and when the status changes, the watching computations will be re-triggered.  It provides the following:

| method      | description                                               |
|-------------|-----------------------------------------------------------|
| connected?  | true if it is connected to the backend                    |
| status      | possible values: :opening, :open, :closed, :reconnecting  |
| error       | the error message for the last failed connection          |
| retry_count | the number of reconnection attempts that have been made without a successful connection |
| reconnect_interval | the time until the next reconnection attempt (in seconds) |