conjure
Interactive evaluation for Neovim (Clojure, Fennel, Janet, Racket, Hy, MIT Scheme, Guile, Python and more!)
Top Related Projects
Native, fast starting Clojure interpreter for scripting
fireplace.vim: Clojure REPL support
The Clojure Interactive Development Environment that Rocks for Emacs
Quick Overview
Conjure is a Neovim plugin that provides a powerful and flexible way to manage and interact with external processes, such as language servers, linters, and other tools, within the Neovim editor. It aims to simplify the setup and configuration of these tools, making it easier for developers to integrate them into their workflow.
Pros
- Flexible Configuration: Conjure allows users to easily configure and customize the behavior of external processes, including their command-line arguments, environment variables, and more.
- Seamless Integration: The plugin integrates closely with Neovim, providing a smooth and efficient way to interact with external tools without leaving the editor.
- Asynchronous Execution: Conjure runs external processes asynchronously, allowing users to continue working in Neovim while the processes are running.
- Robust Error Handling: The plugin provides detailed error reporting and logging, making it easier to troubleshoot issues with external tools.
Cons
- Learning Curve: Conjure has a relatively steep learning curve, especially for users who are not familiar with Neovim's configuration system.
- Dependency on Neovim: Conjure is a Neovim-specific plugin and does not work with the original Vim editor.
- Limited Documentation: While the project has a README file, the documentation could be more comprehensive, especially for advanced use cases.
- Performance Overhead: Depending on the number and complexity of external processes being managed, Conjure may introduce some performance overhead to Neovim.
Code Examples
-- Example configuration for a language server
local conjure = require("conjure")
conjure.setup({
servers = {
["my-language-server"] = {
command = { "path/to/language-server", "--stdio" },
filetypes = { "my-language" },
settings = {
-- Language server-specific settings
}
}
}
})
-- Example of running a command and capturing its output
local conjure = require("conjure")
local output = conjure.run_command({ "ls", "-l" })
print(output)
-- Example of attaching a callback to a running process
local conjure = require("conjure")
local process = conjure.run_command({ "my-long-running-process" })
process:on_stdout(function(_, data)
print("Received output:", data)
end)
process:on_stderr(function(_, data)
print("Received error:", data)
end)
process:on_exit(function(_, code, _)
print("Process exited with code:", code)
end)
Getting Started
To get started with Conjure, follow these steps:
-
Install the Conjure plugin in your Neovim configuration. You can use a plugin manager like vim-plug or packer.nvim to do this.
-
Configure Conjure by creating a
conjure.lua
file in your Neovim configuration directory (usually~/.config/nvim/
) and adding your desired configuration. Here's a basic example:
local conjure = require("conjure")
conjure.setup({
servers = {
["my-language-server"] = {
command = { "path/to/language-server", "--stdio" },
filetypes = { "my-language" },
settings = {
-- Language server-specific settings
}
}
}
})
- Restart Neovim, and you should now be able to use Conjure to manage your external processes. You can use Conjure's commands and mappings to interact with the configured processes.
For more advanced usage and configuration options, please refer to the Conjure README.
Competitor Comparisons
Native, fast starting Clojure interpreter for scripting
Pros of babashka
- Fast startup time and low memory footprint
- Native executables for easy distribution
- Extensive standard library and compatibility with Clojure
Cons of babashka
- Limited to scripting and command-line tasks
- Not suitable for interactive REPL-driven development
- Lacks support for certain Clojure features and libraries
Code comparison
Babashka example:
#!/usr/bin/env bb
(require '[babashka.fs :as fs])
(doseq [file (fs/glob "." "*.txt")]
(println (str file)))
Conjure example (used within a Neovim session):
(ns example.core
(:require [clojure.string :as str]))
(defn greet [name]
(str "Hello, " name "!"))
Summary
Babashka is designed for fast Clojure scripting and command-line tasks, offering quick startup times and native executables. Conjure, on the other hand, focuses on interactive REPL-driven development within Neovim, providing a more comprehensive Clojure development environment. While Babashka excels in scripting scenarios, Conjure is better suited for larger Clojure projects and interactive development workflows.
fireplace.vim: Clojure REPL support
Pros of vim-fireplace
- Mature and stable project with a long history
- Seamless integration with Vim's built-in features
- Lightweight and fast, with minimal dependencies
Cons of vim-fireplace
- Limited support for newer Clojure tools and workflows
- Less active development and fewer recent updates
- Steeper learning curve for beginners
Code Comparison
vim-fireplace:
:Require
:Eval (+ 1 2 3)
:FireplaceConnect
Conjure:
:ConjureEval (+ 1 2 3)
:ConjureConnect clj
:ConjureLogSplit
Key Differences
- Conjure offers broader language support beyond Clojure
- Conjure provides a more interactive and visual REPL experience
- vim-fireplace focuses on tight Vim integration and simplicity
- Conjure has more active development and frequent updates
Conclusion
Both vim-fireplace and Conjure are excellent tools for Clojure development in Vim. vim-fireplace excels in its maturity and seamless Vim integration, while Conjure offers a more modern, feature-rich experience with broader language support. The choice between them depends on personal preferences, workflow requirements, and desired level of interactivity.
The Clojure Interactive Development Environment that Rocks for Emacs
Pros of CIDER
- More mature and feature-rich, with a longer development history
- Extensive documentation and larger community support
- Tighter integration with Emacs and its ecosystem
Cons of CIDER
- Heavier and more complex setup, especially for newcomers
- Limited to Emacs, not available for other editors
- Can be slower to start up and consume more resources
Code Comparison
CIDER:
(cider-connect '(:host "localhost" :port 7888))
(cider-eval-buffer)
(cider-test-run-project-tests)
Conjure:
:ConjureConnect
:ConjureEval (+ 1 2 3)
:ConjureEvalFile
Conjure is a Neovim plugin for interactive development in Clojure and other languages, while CIDER is an Emacs package specifically for Clojure development. Conjure aims to be lightweight and editor-agnostic, whereas CIDER provides a more comprehensive, Emacs-centric experience.
Conjure offers a simpler setup process and works across multiple editors that support Lua plugins. It's designed to be minimal and fast, making it appealing for users who prefer a leaner development environment or work with multiple editors.
CIDER, on the other hand, provides a more integrated and feature-rich experience within Emacs. It offers advanced debugging capabilities, test running, and deeper integration with Clojure tools and libraries. However, this comes at the cost of increased complexity and resource usage.
Both tools support essential features like REPL integration, code evaluation, and autocomplete, but their approaches and target audiences differ. The choice between them often comes down to personal preference, editor choice, and specific project requirements.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
++++
++++== https://oli.me.uk/conversational-software-development/[Conversational software development] for https://neovim.io[Neovim] + https://discord.gg/wXAMr8F[image:https://img.shields.io/discord/732957595249410108.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2[Discord]]
Conjure is an interactive environment for evaluating code within your running program.
The core features of Conjure are language agnostic (although it's targeted at Lisps for now), with each language client providing their own extra tools. Here's the currently supported languages, contributions and 3rd party plugins that add clients are highly encouraged! You can find a https://github.com/Olical/conjure/wiki/Client-features[comparison table for all clients and supported features] in the wiki.
- https://clojure.org/[Clojure] over https://nrepl.org/[nREPL] (https://github.com/Olical/conjure/wiki/Quick-start:-Clojure[quickstart])
- https://fennel-lang.org/[Fennel] inside Neovim via Lua and https://github.com/Olical/nfnl[nfnl] (https://github.com/Olical/conjure/wiki/Quick-start:-Fennel-(nfnl)[quickstart])
- https://fennel-lang.org[Fennel] outside of Neovim within any Lua process through an stdio REPL (https://github.com/Olical/conjure/wiki/Quick-start:-Fennel-(stdio)[quickstart])
- https://janet-lang.org/[Janet] over https://github.com/janet-lang/spork/#networked-repl[spork/netrepl] (https://github.com/Olical/conjure/wiki/Quick-start:-Janet-(netrepl)[quickstart])
- https://janet-lang.org/[Janet] over stdio (https://github.com/Olical/conjure/wiki/Quick-start:-Janet-(stdio)[quickstart])
- https://racket-lang.org/[Racket] over stdio (https://github.com/Olical/conjure/wiki/Quick-start:-Racket-(stdio)[quickstart])
- https://docs.hylang.org[Hy] over stdio (https://github.com/Olical/conjure/wiki/Quick-start:-Hy-(stdio)[quickstart])
- https://www.gnu.org/software/mit-scheme/[Scheme] (MIT by default) over stdio (https://github.com/Olical/conjure/wiki/Quick-start:-Scheme-(stdio)[quickstart])
- https://www.gnu.org/software/guile/[Guile] over a socket file (https://github.com/Olical/conjure/wiki/Quick-start:-Guile-(socket)[quickstart])
- https://lisp-lang.org/[Common Lisp] over https://www.cliki.net/SWANK[Swank] (https://github.com/Olical/conjure/wiki/Quick-start:-Common-Lisp-(Swank)[quickstart])
- https://julialang.org/[Julia] over stdio (https://github.com/Olical/conjure/wiki/Quick-start:-Julia-(stdio)[quickstart])
- https://www.rust-lang.org/[Rust] over stdio with https://github.com/google/evcxr[evcxr] (https://github.com/Olical/conjure/wiki/Quick-start:-Rust-(evcxr)[quickstart])
- https://www.lua.org/[Lua] inside Neovim (https://github.com/Olical/conjure/wiki/Quick-start:-Lua-(neovim)[quickstart])
- https://www.python.org/[Python] over stdio (https://github.com/Olical/conjure/wiki/Quick-start:-Python-(stdio)[quickstart])
You can learn more about the mappings and configuration inside Neovim with :help conjure
. Each language client also has it's own specific help text under :help conjure-client-{LANGUAGE}-{TRANSPORT}
, such as :help conjure-client-clojure-nrepl
, which contains specific mappings and configuration for that client.
You can also get an interactive guide to the core principals and mappings by executing :ConjureSchool
or by using the "try before you install" script as described further down this page.
== User experience
What does wielding Conjure actually look like? What can you do with it?
- YouTube: https://youtu.be/ZSwbiZhvMdQ[How I use Conjure and Neovim to interact with Clojure (and more!)]
- Asciinema (see below)
https://asciinema.org/a/325517[image:https://asciinema.org/a/325517.svg[asciicast]]
- Open a file of a supported file type such as
clojure
orracket
. - Some languages, such as Clojure, will automatically connect to your REPL or give you the commands and mappings to do so yourself.
- Use various mappings to execute the code you're interested in such as the current form, file, buffer or even form at a Neovim mark.
- Every result is kept in a log buffer that you can access at any time.
- Support for multiple asynchronous autocompletion frameworks, with https://github.com/Shougo/deoplete.nvim/[deoplete] built in (
<C-x><C-o>
also works!). ** You can also use https://github.com/hrsh7th/nvim-cmp[nvim-cmp] with https://github.com/PaterJason/cmp-conjure[cmp-conjure]. (which I actually recommend!)
Conjure allows you to send the right part of your code off for evaluation, see the results, wrap the results in more code and evaluate that. It keeps a log of your actions and results so you don't have to remember them, that context is extremely helpful when you're down the rabbit hole of a bug hunt.
Evaluating a form under your cursor is as simple as <prefix>ee
, where <prefix>
defaults to <localleader>
. Be sure to set your your <localleader>
key or configure Conjure to use a different mapping prefix, see :h maplocalleader
and :h g:conjure#mapping#prefix
for more information.
The goal is to give you a tool that lets you effortlessly run whatever you need to while keeping out of your way (but there with context and more information if you need it).
Once installed you can run :ConjureSchool
to begin an interactive tutorial.
== Try without installing
You can trial run Conjure with the interactive :ConjureSchool
tutorial without actually installing it! The only prerequisites are curl
and an up to date nvim
.
[source,bash]
curl -fL conjure.oli.me.uk/school | sh
This will temporarily download the plugin, launch Neovim with :ConjureSchool
running and then clean up after itself. You get to try out what Conjure has to offer without having to edit your Neovim configuration.
== Installation
Requires Neovim 0.8 or newer.
Alternatively you can use https://github.com/Olical/magic-kit[Magic Kit], an opinionated starter kit that includes all sorts of essential tools.
=== https://github.com/wbthomason/packer.nvim[packer.nvim]
[source,lua]
use 'Olical/conjure'
=== https://github.com/junegunn/vim-plug[vim-plug]
[source,viml]
Plug 'Olical/conjure'
=== https://github.com/folke/lazy.nvim[lazy.nvim]
[source,lua]
return { "Olical/conjure" }
To take advantage of lazy loading, a bit more involved configuration is required: [%collapsible]
[source,lua]
return { { "Olical/conjure", ft = { "clojure", "fennel", "python" }, -- etc lazy = true, init = function() -- Set configuration options here -- Uncomment this to get verbose logging to help diagnose internal Conjure issues -- This is VERY helpful when reporting an issue with the project -- vim.g["conjure#debug"] = true end,
-- Optional cmp-conjure integration
dependencies = { "PaterJason/cmp-conjure" },
}, { "PaterJason/cmp-conjure", lazy = true, config = function() local cmp = require("cmp") local config = cmp.get_config() table.insert(config.sources, { name = "conjure" }) return cmp.setup(config) end, }, }
====
== Configuration
All configuration is performed through global Neovim variables, this may change to a .setup(...)
Lua first approach some day but for now you can configure things by setting variables early, before Conjure loads. For example, if you wish to rebind or disable the default documentation lookup key (K
) because you don't need it or it conflicts with your LSP configuration you can do so like this:
-- Disable the documentation mapping
vim.g["conjure#mapping#doc_word"] = false
-- Rebind it from K to <prefix>gk
vim.g["conjure#mapping#doc_word"] = "gk"
-- Reset it to the default unprefixed K (note the special table wrapped syntax)
vim.g["conjure#mapping#doc_word"] = {"K"}
# And the same disabling but in Vim Script
# Note the v:false in Vim Script!
let g:conjure#mapping#doc_word = v:false
Please see :help conjure
for the full list of possible configuration variables and values.
== Mods
Modifications or mods are extra plugins that improve Conjure in various ways. They may add completion plugin support, entire language clients or new mappings that do fun and interesting things. You can learn about creating your own by reading the source code of the projects listed below as well as https://github.com/Olical/conjure/wiki/Using-Conjure-programatically-(API)["Using Conjure programatically (API)"] and https://github.com/Olical/conjure/wiki/Client-features["Client features"].
- https://github.com/jlesquembre/coc-conjure[jlesquembre/coc-conjure]: Conjure completion support for https://github.com/neoclide/coc.nvim[coc.nvim].
- https://github.com/PaterJason/cmp-conjure[PaterJason/cmp-conjure]: https://github.com/hrsh7th/nvim-cmp[nvim-cmp] source for Conjure.
- https://gitlab.com/invertisment/conjure-clj-additions-cider-nrepl-mw[Invertisment/conjure-clj-additions-nrepl]: Jump to failing Clojure test and more.
- https://gitlab.com/invertisment/conjure-clj-additions-vanilla[Invertisment/conjure-clj-additions-vanilla]: Jump to failing Clojure test for Conjure when not using nREPL.
== Tree sitter support
Warning! If you want to work with ANY language that isn't a Lisp dialect you will need to use tree sitter. If you do not use tree sitter only visual selection and vim motion based evaluations will work. You need tree sitter if you wish to evaluate non Lisp languages with <prefix>ee
and other such form based evaluation mappings.
When you ask Conjure to evaluate the form under your cursor it has to understand the code enough to be able to find the boundaries and extract the right characters from the buffer. This used to be done using Neovim's built in findpairpos
, syntax highlighting regexes and exhaustive searching of the buffer. This is error prone, gets slow as the buffer grows and doesn't work with non-Lisp languages which lack clear boundaries.
I highly recommend you set up tree sitter inside your Neovim configuration and :TSInstall [language]
every language you're interested in working with. You should then keep those tree sitter modules up to date as you upgrade Neovim since the API seems to change slightly over time.
Tree sitter allows you to work with non-Lisp languages like Julia as well as get far more accurate, smart and performant evaluations in languages like Clojure. You can learn more and get everything set up using the https://github.com/nvim-treesitter/nvim-treesitter[nvim-treesitter] repository.
It's technically optional since Conjure contains legacy fallback code, but I highly recommend tree sitter when using Conjure, it's how you get cool things like smart comment block evaluations in Clojure and form based evaluations in Julia and Lua.
== Getting started
The majority of the documentation can be found within link:doc/conjure.txt[:help conjure
]. You can also use :ConjureSchool
to get an interactive introduction to the workflow and mappings Conjure provides. Refer to the list at the top of this file for links to the various quickstart guides for each language.
Please do get in touch via https://discord.gg/wXAMr8F[Discord] or https://twitter.com/OliverCaldwell[Twitter] if you have any questions or issues.
Broader documentation can be found in the https://github.com/Olical/conjure/wiki[Conjure wiki], there you'll find blog posts and guides that will help you get common workflows up and running. Contributions are encouraged!
== Behind the curtain
Conjure is written entirely in Lua (no VimL or external processes!) which is compiled from https://fennel-lang.org/[Fennel] by https://github.com/Olical/nfnl[nfnl] ahead of time. Check out link:CONTRIBUTING.md[CONTRIBUTING.md
] for more on how to work on Conjure using itself.
Historically, Conjure was Clojure specific with an entirely different implementation, you can still find that version on the https://github.com/Olical/conjure/tree/legacy-jvm[legacy-jvm branch].
== Unlicenced
Find the full http://unlicense.org/[unlicense] in the UNLICENSE
file, but here's a snippet.
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
Top Related Projects
Native, fast starting Clojure interpreter for scripting
fireplace.vim: Clojure REPL support
The Clojure Interactive Development Environment that Rocks for Emacs
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot