Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/emacsmirror/fennel-mode
A major-mode for editing Fennel code
https://github.com/emacsmirror/fennel-mode
Last synced: 8 days ago
JSON representation
A major-mode for editing Fennel code
- Host: GitHub
- URL: https://github.com/emacsmirror/fennel-mode
- Owner: emacsmirror
- License: gpl-3.0
- Created: 2018-06-05T23:05:50.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-03-13T22:24:59.000Z (8 months ago)
- Last Synced: 2024-04-16T02:18:40.537Z (7 months ago)
- Language: Emacs Lisp
- Homepage: https://git.sr.ht/~technomancy/fennel-mode
- Size: 164 KB
- Stars: 27
- Watchers: 4
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: changelog.md
- License: LICENSE
Awesome Lists containing this project
README
# Fennel Mode
Font-lock, indentation, navigation, documentation, and REPL support for the
[Fennel](https://fennel-lang.org) programming language.Supports `M-x imenu` for quick navigation to local definitions.
## Installation
Add this to your config:
```lisp
(autoload 'fennel-mode "/path/to/fennel-mode/fennel-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.fnl\\'" . fennel-mode))
```Note that `fennel-mode` doesn't inherit from `lisp-mode` since 0.4.0, and
instead switched to `prog-mode`. This means that there is no longer any way to
declare shared functionality (such as paredit) that you want to be applied to every
lisp you use; you have to add hooks specifically to `fennel-mode-hook`.You'll also probably want to use [fennel-ls][8], which works great
with [eglot][9]. In Emacs 30+, it will work automatically once
`fennel-ls` is installed; in earlier versions you need to add this to
your config:```lisp
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs '(fennel-mode . ("fennel-ls"))))
```## Interactivity
Run `M-x fennel-repl RET` to open a REPL buffer. Once a REPL is open,
you can send code from a `fennel-mode` buffer to be evaluated.### Bindings for `fennel-mode`
* `M-.` - Jump to the definition of a globally-visible function
* `M-,` - Jump back to where you were before jumping to definition
* `M-'` - Jump to the definition of a function in a module
* `C-c C-k` - Reload the module for the current file (requires `fennel.seacher`)
* `C-c C-l` - Display compilation output for the current file
* `C-c C-z` - Start or switch to REPL buffer
* `C-c C-t` - Reformat current buffer with [fnlfmt][1] (separate install)
* `C-c C-d` - Ask for a value and show its docstring in the REPL (also `C-c C-f`)
* `C-c C-v` - Show docstring of variable at point
* `C-c C-p` - Print macro expansion of expression at point in the REPL
* `C-x C-e` - Evaluate last expression before the point
* `C-c C-e` - Evaluate current top-level form (also `C-M-x`)
* `C-c C-n` - Evaluate current top-level form, then move to the next
* `C-c C-r` - Evaluate the region
* `C-c C-z` - Start or switch to REPL buffer### Bindings for `fennel-repl-mode`
* `TAB` - Completion at point
* `C-c M-o` - Clear the REPL output
* `C-c C-d` - Ask for a value and show its docstring in the REPL (also `C-c C-f`)
* `C-c C-v` - Show docstring of variable at point
* `M-.` - Jump to the definition of a globally-visible function
* `C-c C-z` - Toggle back to previous `fennel-mode` buffer
* `C-c C-q` - Quit the REPLThese functions assume a `fennel` executable is present on your
path. You can override the location by setting `inferior-lisp-program`
or invoking `C-u M-x fennel-repl`. For instance, if you have [a stdio
REPL][2] in a [LÖVE][3] game, you can set this to `love .`.Note that finding the definition of a function with `M-.` only works when the
function is in scope for the REPL, which means it's usually best to
load a module and set it as a global if you want to use it this way.## Antifennel
This repo also contains `antifennel.el` which allows you to compile
Lua code to Fennel straight from a `lua-mode` buffer. It requires
installing [antifennel][6] first. Install it with:```lisp
(autoload 'antifennel-mode "/path/to/fennel-mode/antifennel.el" nil t)
(add-hook 'lua-mode-hook 'antifennel-mode)
```Now when `antifennel-mode` is active in a Lua buffer, you can press
`C-c C-f` to open a new buffer containing the Fennel equivalent of the
Lua code.## Protocol-based REPL
A separate REPL integration is provided via the `fennel-proto-repl`
module. This module provides a client that can connect to a regular
Fennel REPL, *upgrade* it with the [protocol][7] code, and provides a
more robust interactive experience. Advantages over the default
`fennel-repl` are:* IO and evaluation results are separated.
* Stack traces in Errors can be used to jump to the error location.
* Evaluation results are shown in the echo area - no need to keep the
REPL window open.
* Running multiple REPLs is easier, and different buffers can be
linked to different REPLs.
* Synchronous and Asynchronous API.
* Support for Eldoc and Xref.Installation is similar to the other modules:
```lisp
(autoload 'fennel-proto-repl "/path/to/fennel-mode/fennel-proto-repl.el" nil t)
(add-hook 'fennel-mode-hook 'fennel-proto-repl-minor-mode)
```The `fennel-proto-repl-minor-mode` re-binds all of the default REPL
interaction keys available in `fennel-mode` to use `fennel-proto-repl`
instead of a regular `fennel-repl`. In addition to the usual
`fennel-mode` mappings listed above, additional commands are
available:* `C-c C-S-l` - link the current buffer to a specific REPL session
* `C-c C-b` - Evaluate the whole buffer
* `C-c C-a` - Ask for a function and show its argument list in the REPLStarting the REPL or switching to the existing one is done via the
same `C-c C-z` shortcut, and the new REPL session can be started at
any moment with the `fennel-proto-repl` command. The buffer is
automatically linked to the newly created REPL.Note that `fennel-proto-repl` requires a Fennel version recent enough
to include the `___repl___` variable. If the Fennel doesn't have the
`___repl___` variable the Proto REPL won't be started.## Org Babel support
Installation is similar to the other modules:
```lisp
(autoload 'ob-fennel "/path/to/fennel-mode/ob-fennel.el" nil t)
```Then, the support for Fennel in Org buffers can be activated by adding
the following code to the Emacs init file:```lisp
(with-eval-after-load 'org
(require 'ob-fennel))
```After that, the `#+begin_src fennel` code blocks can be executed in
Org buffers. The integration requires the `fennel-proto-repl` module
to be available and operational.The `ob-fennel` module supports evaluating code from the regular "src
blocks", and "inline src blocks" (`src_fennel[]{...}`), with the
ability to access variables and tables defined elsewhere in the file.
Multiple sessions can be used, and a different command to start the
REPL process can be passed via the `:fennel-cmd` header argument.## Contributing
Send patches to the [Fennel mailing list][4]. If you prefer not to
use email you can send a pull request on the [Codeberg mirror][5].
Please byte-compile to check for warnings.### Testing
This package has tests stored in the `test/` directory. When
developing new functionality consider writing a test for it.You can run the tests with `make`. By default this runs the tests for
`fennel-mode` alone; for `fennel-proto-repl` and `ob-fennel` you can
override the `TESTS` argument.Use `make EMACS=emacs29` to test against a different Emacs version.
During development it may be more convenient to use `M-x
ert-run-tests-interactively` but try to make sure the tests pass with
a fresh Emacs using `make` before committing.## Copyright
Copyright © 2018-2024 Phil Hagelberg and contributors
Licensed under the same license as Emacs (GPL v3 or later); see LICENSE
[1]: https://git.sr.ht/~technomancy/fnlfmt
[2]: https://gitlab.com/alexjgriffith/min-love2d-fennel/blob/master/lib/stdio.fnl
[3]: https://love2d.org
[4]: https://lists.sr.ht/%7Etechnomancy/fennel
[5]: https://codeberg.org/technomancy/fennel-mode
[6]: https://git.sr.ht/~technomancy/antifennel
[7]: https://gitlab.com/andreyorst/fennel-proto-repl-protocol
[8]: https://git.sr.ht/~xerool/fennel-ls
[9]: https://www.gnu.org/software/emacs/manual/html_mono/eglot.html