*conjure* ______ _ ~ / ____/___ ____ (_)_ __________ ~ / / / __ \/ __ \ / / / / / ___/ _ \~ / /___/ /_/ / / / / / / /_/ / / / __/~ \____/\____/_/ /_/_/ /\__,_/_/ \___/ ~ /___/ ~ ============================================================================== CONTENTS *conjure-contents* 1. Introduction ............................. |conjure-introduction| 2. Mappings ..................................... |conjure-mappings| 3. Completion ................................. |conjure-completion| 4. Configuration ........................... |conjure-configuration| 5. Log ............................................... |conjure-log| 6. Autocmds ..................................... |conjure-autocmds| 7. Clients ....................................... |conjure-clients| 8. Hooks ........................................... |conjure-hooks| ============================================================================== INTRODUCTION *conjure-introduction* Conjure allows you to evaluate code and perform actions in various languages. The results of your actions are stored in a log buffer that you can view and edit at any time. If you don't have the log buffer open the results will be shown temporarily in the heads up display (HUD), a floating window that vanishes after you move your cursor. The HUD can be turned off entirely if you would rather check for results in your own time. This documentation will show you which mappings are available by default and how to configure them to suit you. You'll also learn about the extra features and mappings that are provided by each language specific client. You can execute `:ConjureSchool` to begin the interactive tutorial which will introduce you to Conjure's workflow and mappings. ============================================================================== MAPPINGS *conjure-mappings* These are the default mappings, |conjure-configuration| will show you how to remap them to keys that suit you if required. The default prefix key for almost all of the mappings is `` (|maplocalleader|). If you already have a buffer open and you change a mapping's configuration it won't update right away. Mappings are defined as you open a buffer, so be sure to set up your mappings in your Neovim configuration or at least before you open a buffer. I've also included some commands since they're related to the mappings. *:ConjureSchool* :ConjureSchool Start the interactive tutorial which will walk you through the workflow and mappings Conjure provides. *:ConjureEval* :ConjureEval [code] Evaluates the given code in the current buffer's language and context. Accepts a range so `:%ConjureEval` would evaluate the entire buffer, this also works with visual selections. *:ConjureConnect* :ConjureConnect [host] [port] Connect to the given host and port. Both arguments tend to be optional but this can vary depending on the client. Only clients with network based REPL connections will provide implementations for this. `:ConjureConnect` `:ConjureConnect 5678` `:ConjureConnect staging.my-app.com 5678` *:ConjureClientState* :ConjureClientState [state-key] Get or set (if an argument is provided) the current client state key. This defaults to `default` and can be used to have a connection per current working directory (or any other unique string of your choice!). Set up auto commands to suit your needs. > augroup conjure_set_state_key_on_dir_changed autocmd! autocmd DirChanged * execute "ConjureClientState " . getcwd() augroup END < ls Open the log buffer in a new horizontal split window. The direction can be controlled with |splitbelow|. lv Open the log buffer in a new vertical split window. The direction can be controlled with |splitright|. lt Open the log buffer in a new tab. Great for viewing large output. Just close the window to close the tab when you're done and return to your previous layout. le Open the log buffer in your current window. Just jump back (with e.g. |Ctrl-O|) when you're done and return to your previous buffer. lq Close all visible log windows in your current tab. Other tabs will remain unaffected. lr Soft reset the log buffer by deleting the lines while leaving any wider buffer state intact. This will leave any open log windows open. lR Hard reset the log buffer, completely deleting the buffer, mappings and buffer local settings. This will close any open log windows. ll Set cursor to top of latest evaluation result. E When in visual mode, evaluate the current selection. E[motion] Evaluate any given motion following this mapping such as `E2j` to evaluate this line and the two below it. ee Evaluate the current form under the cursor. This is the innermost pair (ignoring those in comments or strings). `g:conjure#extract#form_pairs` controls the character pairs. ece Evaluates the form under the cursor and displays the result as a comment at the end of the line or below the current line if you already have a comment there. er Evaluate the root form under the cursor. This is the outermost pair. Great for evaluating a function you're editing if your cursor is within a few nested forms. `g:conjure#extract#form_pairs` controls the character pairs. ecr Evaluates the root form under the cursor and displays the result as a comment at the end of the line or below the current line if you already have a comment there. ew Evaluate the word under the cursor, good for peeking inside vars defined in your file. ecw Evaluates the word under the cursor and displays the result as a comment at the end of the line or below the current line if you already have a comment there. e! Evaluate the form under the cursor and replace it with the result of the evaluation. Using this on the form `(+ 10 20)` would replace the form with `30`. em[mark] Evaluate the form under the cursor at the given |mark|. Set a regular Neovim mark on a form using `mF` for example in any file, then jump to another file. You can evaluate that form at any time with `emF`. ef Evaluate the current file from disk. This may be different to what's currently in your buffer if you haven't saved! eb Evaluate the current buffer contents. This may be different to what's on disk if you've edited it without saving. gd Go to the definition of the word under the cursor. Support for this may vary between languages. K Look up documentation for the word under the cursor. Support for this may vary between languages. Language clients will provide their own extra mappings on top of these, you can find links to their help in |conjure-clients|. ============================================================================== COMPLETION *conjure-completion* Conjure sets the |omnifunc| for all supported languages, the language clients must implement completion for it to actually provide results. Some languages will provide rich completion, others will provide simpler completions based on the syntax file of the language and the current symbols visible in the buffer. You can get completions through the normal mapping of ``, nothing else needs to be configured for this to work. The |omnifunc| used is configurable via the `g:conjure#completion...` options. Automatic completion as you type is provided by external plugins. Deoplete support is built into the Conjure plugin, so if you have Deoplete installed it should be working already. * https://github.com/Shougo/deoplete.nvim Conquerer of Completion support is provided by coc-conjure. * https://github.com/neoclide/coc.nvim * https://github.com/jlesquembre/coc-conjure asyncomplete.vim support is provided by asyncomplete-conjure.vim. * https://github.com/prabirshrestha/asyncomplete.vim * https://github.com/thecontinium/asyncomplete-conjure.vim nvim-cmp support is provided by cmp-conjure. * https://github.com/hrsh7th/nvim-cmp * https://github.com/PaterJason/cmp-conjure ============================================================================== CONFIGURATION *conjure-configuration* Conjure is configured through global vars such as `g:conjure#debug`, you can set these with normal VimL `let` expressions. Here's the full list of options available in the core plugin. Each language client also has its own set of mappings and settings you can alter. You can also set `b:` prefixed versions of all configuration values for buffer local settings that override their global counterparts. As an example, we can change the default prefix from `` to `,c` with the following command: > :let g:conjure#mapping#prefix = ",c" All mappings are prefixed by this by default. To have a mapping work without the prefix simply wrap the string in a list. > :let g:conjure#mapping#log_split = ["ClS"] Now you can hit `ClS` without a prefix in any buffer Conjure has a client for. You can disable a mapping entirely by setting it to `v:false` like so. > :let g:conjure#mapping#doc_word = v:false These need to be set before you enter a relevant buffer since the mappings are defined as you enter a buffer and can't be altered after the fact. Conjure sets up filetype-specific mappings for each of the filetypes listed in `g:conjure#filetypes`. These mappings are determined by the client filetype and set when that filetype is loaded. You can disable all of the filetype code by setting `g:conjure#mapping#enable_ft_mappings` to `v:false` like so (the name is a little misleading, it will prevent Conjure from doing ANY filetype autocommand specific work, including setting up mappings). `:let g:conjure#mapping#enable_ft_mappings = v:false` Tip: Booleans in Vim Script are written as `v:true` and `v:false`. If you're configuring these values from Lua it's just `true` and `false`. If you want to set all of the default mappings to `false` so you can just configure the ones you care about one at a time you can set: > :let g:conjure#mapping#enable_defaults = v:false vim.g["conjure#mapping#enable_defaults"] = false < *g:conjure#filetypes* `g:conjure#filetypes` A list of filetypes Conjure should be associated with. Conjure will then look up which client module to use for this filetype using `g:conjure#filetype#[filetype]`, which should be a string that resolves to a Lua module that adheres to the |conjure-clients| interface. Conjure will only initialise for filetypes in this list. It also will not load if the file type is in this list but there isn't an equivalent `g:conjure#filetype#[filetype]` configuration value. Default: > ["clojure", "fennel", "janet", "hy", "julia", "racket", "scheme", "lua", "lisp", "python", "rust", "sql"] < *g:conjure#filetype#clojure* `g:conjure#filetype#clojure` Client to use for `clojure` buffers. Help: |conjure-client-clojure-nrepl| Default: `"conjure.client.clojure.nrepl"` *g:conjure#filetype#fennel* `g:conjure#filetype#fennel` Client to use for `fennel` buffers. Conjure also ships with an alternative `"conjure.client.fennel.stdio"` client which allows you to work with Fennel (without Aniseed) outside of Neovim in an external Lua process. This default Fennel client implementation uses a vendored copy of Aniseed (which contains a vendored Fennel compiler) for all evaluations. Help: |conjure-client-fennel-aniseed|, |conjure-client-fennel-stdio| Default: `"conjure.client.fennel.aniseed"` *g:conjure#filetype#janet* `g:conjure#filetype#janet` Client to use for `janet` buffers. Conjure also ships with an alternative `"conjure.client.janet.stdio"` client which allows you to work with Janet without installing and running a netrepl server. Help: |conjure-client-janet-netrepl|, |conjure-client-janet-stdio| Default: `"conjure.client.janet.netrepl"` *g:conjure#filetype#hy* `g:conjure#filetype#hy` Client to use for `hy` buffers. Help: |conjure-client-hy-stdio| Default: `"conjure.client.hy.stdio"` *g:conjure#filetype#scheme* `g:conjure#filetype#scheme` Client to use for `scheme` buffers. You can use Guile over a socket file instead by setting this to `"conjure.client.guile.socket"`. To edit scripts for the snd/s7 sound editor, set this to `"conjure.client.snd-s7.stdio"`. Help: |conjure-client-scheme-stdio|, |conjure-client-guile-socket|, or |conjure-client-snd-s7-stdio. Default: `"conjure.client.scheme.stdio"` *g:conjure#filetype#racket* `g:conjure#filetype#racket` Client to use for `racket` buffers. Help: |conjure-client-racket-stdio| Default: `"conjure.client.racket.stdio"` *g:conjure#filetype#sql* `g:conjure#filetype#sql` Client to use for `SQL` buffers. Help: |conjure-client-sql-stdio| Default: `"conjure.client.sql.stdio"` *g:conjure#filetype_suffixes#[filetype]* `g:conjure#filetype_suffixes#[filetype]` If a client is loading when it shouldn't we can configure that filetype to match a specific set of file extensions. This is useful in the Scheme / Racket / Guile world where they share filetype strings and extentions in a lot of places, making it difficult to determine which client we should use. If you wish to disable a suffix filter for any specific client, set the value to `v:false` in VimL and `false` in Lua. Default: `nil` *g:conjure#filetype_suffixes#racket* `g:conjure#filetype_suffixes#racket` Racket filetype support cycles between the `scheme` and `racket` filetypes at times, this list restricts the Racket client to the right paths as well as filetypes. Default: `["rkt"]` *g:conjure#filetype_suffixes#scheme* `g:conjure#filetype_suffixes#scheme` We don't want the Scheme client to activate for Racket or Guile buffers, which both sometimes flick their filetype to `scheme` just to try and confuse us. But we're ready for it! Default: `["scm"]` *g:conjure#eval#result_register* `g:conjure#eval#result_register` Every evaluation captures the result and places it in a Neovim register for you to use however you want. By default, if you evaluate a form, you can then hit `"cp` to paste the result into your buffer or `c` in insert mode. Some suggestions of other registers you can set this to: * `"\""` or `"*"` the default register for easy access. * `"C"` if you want to keep your lower case registers clear. * `"_"` the black hole when you don't want this at all. Default: `"c"` *g:conjure#eval#inline_results* `g:conjure#eval#inline_results` Displays the results of evaluations inline as virtual text at the end of the line where the evaluation was initiated. Example: `(+ 10 20) => 30` Default: `true` *g:conjure#eval#inline#highlight* `g:conjure#eval#inline#highlight` Sets the highlight group used for the inline results Example: `"EndOfBuffer"` Default: `"Comment"` *g:conjure#eval#inline#prefix* `g:conjure#eval#inline#prefix` Sets the prefix used in the inline results Example: `"-> "` Default: `"=> "` *g:conjure#eval#comment_prefix* `g:conjure#eval#comment_prefix` The comment prefix to use for "eval and insert result as comment" mappings. Defaults to whatever comment character (normally singular) the language uses, such as `"; "`, if you would like two character comments, you can set this to `";; "` (note the trailing space!). Default: `nil` (whatever comment character the language uses) *g:conjure#eval#gsubs* `g:conjure#eval#gsubs` Lua `string.gsub` modifications to make to code before it's evaluated. For example, the following will mean you can evaluate `comment` forms as `do` forms. > let g:conjure#eval#gsubs = {'do-comment': ['^%(comment[%s%c]', '(do ']} < The first value in the list is a Lua pattern to match against and the second is the replacement value. When using the root form eval within a comment form Conjure will now execute all forms contained within it. The keys of your value pairs are purely for documentation, you'll only see them in error messages if something goes wrong. If a pattern throws an error for some reason Conjure will still proceed with the evaluation (without the substitution) but will log the error. More on Lua patterns: https://www.lua.org/pil/20.2.html *g:conjure#mapping#prefix* `g:conjure#mapping#prefix` The key that proceeds most mappings. Default: `""` *g:conjure#mapping#enable_ft_mappings* `g:conjure#mapping#enable_ft_mappings` Toggles the `on-filetype` callback that is fired for the `Filetype` autocommand fired for each supported language. By disabling this you opt out of ALL Conjure mapping code and must manually configure your mappings, the mapping configuration options listed here will no longer work because they're entirely disabled. Default: `true` *g:conjure#mapping#enable_defaults* `g:conjure#mapping#enable_defaults` Setting this to `false` will prevent all of the `g:conjure#mapping#*` defaults from being configured, which means you need to set the mappings you care about, Conjure will then hook them up with it's mapping code but using your keys. This is a good way to disable Conjure's mappings and opt into the ones you care about gradually. This must be set BEFORE you first load a buffer for a language you're working with because the configuration is read at `Filetype` autocommand time. Default: `true` *g:conjure#mapping#log_split* `g:conjure#mapping#log_split` Opens the log in a horizontal split. Default: `"ls"` *g:conjure#mapping#log_vsplit* `g:conjure#mapping#log_vsplit` Opens the log in a vertical split. Default: `"lv"` *g:conjure#mapping#log_tab* `g:conjure#mapping#log_tab` Opens the log in a new tab. Default: `"lt"` *g:conjure#mapping#log_buf* `g:conjure#mapping#log_buf` Opens the log in the current window. Default: `"le"` *g:conjure#mapping#log_toggle* `g:conjure#mapping#log_toggle` Toggles open or closed the log, using the last used log open command. This will only work for vertical or horizontal split log windows. Default: `"lg"` *g:conjure#mapping#log_reset_soft* `g:conjure#mapping#log_reset_soft` Soft reset the log buffer by wiping the contents. Default: `"lr"` *g:conjure#mapping#log_reset_hard* `g:conjure#mapping#log_reset_hard` Hard reset the log buffer by deleting the entire buffer. Default: `"lR"` *g:conjure#mapping#log_jump_to_latest* `g:conjure#mapping#log_jump_to_latest` Set cursor to top of latest evaluation result. Default: `"ll"` *g:conjure#mapping#log_close_visible* `g:conjure#mapping#log_close_visible` Close all visible log windows. Default: `"lq"` *g:conjure#mapping#eval_current_form* `g:conjure#mapping#eval_current_form` Evaluates the form under the cursor. Default: `"ee"` *g:conjure#mapping#eval_comment_current_form* `g:conjure#mapping#eval_comment_current_form` Evaluates the form under the cursor and inserts the result as a comment. Default: `"ece"` *g:conjure#mapping#eval_root_form* `g:conjure#mapping#eval_root_form` Evaluates the root form under the cursor. Default: `"er"` *g:conjure#mapping#eval_comment_root_form* `g:conjure#mapping#eval_comment_root_form` Evaluates the root form under the cursor and inserts the result as a comment. Default: `"ecr"` *g:conjure#mapping#eval_word* `g:conjure#mapping#eval_word` Evaluates the word under the cursor. Default: `"ew"` *g:conjure#mapping#eval_previous* `g:conjure#mapping#eval_previous` Evaluates the previous evaluation again. Default: `"ep"` *g:conjure#mapping#eval_comment_word* `g:conjure#mapping#eval_comment_word` Evaluates the word under the cursor and inserts the result as a comment. Default: `"ecw"` *g:conjure#mapping#eval_replace_form* `g:conjure#mapping#eval_replace_form` Evaluates the form under the cursor and replace with the result. Default: `"e!"` *g:conjure#mapping#eval_marked_form* `g:conjure#mapping#eval_marked_form` Evaluates the form at the marks location. Default: `"em"` *g:conjure#mapping#eval_file* `g:conjure#mapping#eval_file` Evaluates the file from disk. Default: `"ef"` *g:conjure#mapping#eval_buf* `g:conjure#mapping#eval_buf` Evaluates the buffer from memory. Default: `"eb"` *g:conjure#mapping#eval_visual* `g:conjure#mapping#eval_visual` Evaluates the visual selection. Default: `"E"` *g:conjure#mapping#eval_motion* `g:conjure#mapping#eval_motion` Evaluates the following motion. Default: `"E"` *g:conjure#mapping#def_word* `g:conjure#mapping#def_word` Goes to the definition of the word under the cursor. Default: `"gd"` *g:conjure#mapping#doc_word* `g:conjure#mapping#doc_word` Looks up documentation for the word under the cursor. Default: `["K"]` *g:conjure#completion#omnifunc* `g:conjure#completion#omnifunc` |omnifunc| to set for supported Conjure clients. No omnicompletion will be provided if you set this to `v:false`. Default: `"ConjureOmnifunc"` *g:conjure#completion#fallback* `g:conjure#completion#fallback` |omnifunc| to use if the client isn't returning completions, requires `completion#omnifunc` to be set to `"ConjureOmnifunc"`. For Janet and Racket, this is the main completion method, for Clojure this kicks in if you don't have an nREPL connection yet. Default: `"syntaxcomplete#Complete"` *g:conjure#highlight#enabled* `g:conjure#highlight#enabled` Enable highlighting of evaluated forms. Requires support for the highlight API, so you'll need Neovim 0.5+. Default: `false` *g:conjure#highlight#group* `g:conjure#highlight#group` Which syntax group should the form be highlighted with. Default: `"IncSearch"` *g:conjure#highlight#timeout* `g:conjure#highlight#timeout` How long should the highlight last in milliseconds. Default: `500` *g:conjure#log#hud#width* `g:conjure#log#hud#width` Width of the HUD as a percentage of the editor width. A float between 0.0 and 1.0. Default: `0.42` *g:conjure#log#hud#height* `g:conjure#log#hud#height` Height of the HUD as a percentage of the editor height. A float between 0.0 and 1.0. Default: `0.3` *g:conjure#log#hud#zindex* `g:conjure#log#hud#zindex` The zindex of the HUD window, you may need to tweak this to get the HUD to play nicely with other plugins that create floating windows. The zindex must be a positive integer. Default: `1` *g:conjure#log#hud#enabled* `g:conjure#log#hud#enabled` Should the HUD be displayed at all. Default: `true` *g:conjure#log#hud#passive_close_delay* `g:conjure#log#hud#passive_close_delay` Delay to introduce (in milliseconds) when closing the HUD passively such as after you move the cursor. Set it to `0` to disable the mechanic entirely and close instantly. Default: `0` *g:conjure#log#hud#minimum_lifetime_ms* `g:conjure#log#hud#minimum_lifetime_ms` A minimum amount of milliseconds that must have passed since the HUD opened before it'll be passively closed from cursor movement. This delay means evaluations that involve cursor movement etc won't close the HUD the moment it displays. Default: `20` *g:conjure#log#hud#overlap_padding* `g:conjure#log#hud#overlap_padding` Extra space checked around the HUD window for the cursor. If it's within this padded boundary (too close to the HUD) it'll move to the opposite side of the screen to stay out of the way. A float between 0.0 and 1.0. Default: `0.1` *g:conjure#log#hud#anchor* `g:conjure#log#hud#anchor` Preferred corner position for the HUD. This is not guaranteed, it will try to move out of the way to avoid covering your cursor and the code you're reading. Example: Set this to `"SE"` and the width to `1.0` to get a full window width HUD at the bottom of the screen. Default: `"NE"` *g:conjure#log#hud#border* `g:conjure#log#hud#border` Preferred border style for the HUD. Possible values are the same as the `border` parameter in `:h nvim_open_win()`. Set this to `"none"` if you don't want a border. Default: `"single"` *g:conjure#log#hud#ignore_low_priority* `g:conjure#log#hud#ignore_low_priority` Don't display the HUD for "low priority" messages. This includes `stdout` and `stderr` for Clojure, this support varies from language to language drastically depending on the information each REPL can offer Conjure. Most languages only have standard priority messages, there is no distinction between low and anything else. If your HUD is constantly displaying because of low priority messages you'll see a warning, once, telling you about this option. You can then set the option during a session to improve your experience with particularly noisy REPLs. The following snippet will set this to true and suppress low priority output from the HUD, just in case you're in a rush: > :let g:conjure#log#hud#ignore_low_priority = v:true < Default: `false` *g:conjure#log#botright* `g:conjure#log#botright` Force the log to always open at the bottom or far right of the editor, taking up the full width or height respectively. Default: `false` *g:conjure#log#diagnostics* `g:conjure#log#diagnostics` Enables diagnostics in the log buffer. This should hide the warnings you would normally see from your LSP setup if switched off. Default: `false` *g:conjure#log#treesitter* `g:conjure#log#treesitter` Enables treesitter in the log buffer. You may want this off if you notice large logs slowing down your editor. Default: `true` *g:conjure#log#break_length* `g:conjure#log#break_length` Length of the break comment (`; ---------...`) between log results in characters. Used in trimming to avoid cutting forms in half. Default: `80` *g:conjure#log#trim#at* `g:conjure#log#trim#at` Trim the log once the line count passes the value. Default: `10000` *g:conjure#log#trim#to* `g:conjure#log#trim#to` Trim the log down to this many lines when it gets too long. Default: `7000` *g:conjure#log#strip_ansi_escape_sequences_line_limit* `g:conjure#log#strip_ansi_escape_sequences_line_limit` If the chunk of text being appended to the log is less than this many lines in length, strip all ANSI escape sequences from it. If you set this to `0` it'll never apply, you can then use an ANSI escape sequence highlight plugin to display the colours in the buffer. A line limit is used to prevent massive output (which probably doesn't contain escape sequences) from slowing down your log. Default: `100` *g:conjure#log#wrap* `g:conjure#log#wrap` Enable line wrapping in the HUD and log. Default: `false` *g:conjure#log#fold#enabled* `g:conjure#log#fold#enabled` Enable or disable folding of results. Default: `false` *g:conjure#log#fold#lines* `g:conjure#log#fold#lines` Fold results that have a line count >= this value. Default: `10` *g:conjure#log#fold#marker#start* `g:conjure#log#fold#marker#start` Marker to use to represent the start of a log fold. Default: `"~~~%{"` *g:conjure#log#fold#marker#end* `g:conjure#log#fold#marker#end` Marker to use to represent the end of a log fold. Default: `"}%~~~"` *g:conjure#log#jump_to_latest#enabled* `g:conjure#log#jump_to_latest#enabled` Should the log buffer always set cursor to the top of the latest evaluation output? Default: `false` *g:conjure#log#jump_to_latest#cursor_scroll_position* `g:conjure#log#jump_to_latest#cursor_scroll_position` After jumping to the latest log entry, this decides where your cursor should appear on the screen by adjusting the scroll. Your options are `top`, `center`, `bottom` and `none`. `none` will just leave the scroll wherever it naturally lands after moving the cursor to the latest log entry. Default: `"top"` *g:conjure#extract#context_header_lines* `g:conjure#extract#context_header_lines` How many lines of the file should be checked for a context (namespace name) such as `(module foo.bar)` or `(ns foo.bar)` which is used for setting the right context for evaluations. If you have buffers with huge comment headers you may want to set this higher. If a specific buffer isn't extracting the context correctly, you can override it by setting `b:conjure#context`. Default: `24` *g:conjure#extract#form_pairs* `g:conjure#extract#form_pairs` Character pairs to search for when evaluating forms. The closest matching pair is used when evaluating the current form but the furthest matching pair is used for root forms. The structure of each item is `[start end escape?]` where the first two are characters and the third is an optional boolean to enable escaping for use in |searchpairpos()|. Default: `[["(" ")"] ["{" "}"] ["[" "]" true]]` *g:conjure#extract#tree_sitter#enabled* `g:conjure#extract#tree_sitter#enabled` Enable tree-sitter support for extracting code from the buffer. This is used by non-Lisp clients to find the appropriate chunk of code under the cursor to evaluate. This is experimental and requires the following: * Neovim 0.5+ with tree-sitter support * https://github.com/nvim-treesitter/nvim-treesitter * The appropriate `:TSInstall [filetype]` to have already been run. * This flag to be `true`. If any of these conditions are not met it'll fall back to looking for matching parenthesis in the buffer from the cursors current location. Beware trying to use TreeSitter to highlight your buffer while simultaneously asking Conjure to use the legacy regex based form extraction by setting this to `false`. It will not work! More information: https://github.com/Olical/conjure/issues/246 Default: `true` *g:conjure#preview#sample_limit* `g:conjure#preview#sample_limit` Most evaluation actions create a line in the log buffer with a preview of the code that was evaluated as a reminder. This setting controls how long that preview should be before it trails off into ellipsis. It is a percentage value based on the width of the editor. This is so you can align it with the width of your HUD. This also affects the preview in folded results. A float between 0.0 and 1.0. Default: `0.3` *g:conjure#relative_file_root* `g:conjure#relative_file_root` If set, Conjure will attempt to resolve absolute file paths to a relative path based on this value. This means you can evaluate files on other machines or inside Docker containers that share a common file structure for the project but may be stored in different parts of the overall file system. Here's how you could resolve all file paths relative to a sub-directory under your Neovim current working directory. `:let g:conjure#relative_file_root = getcwd() . "/sub-proj"` Now `/foo/bar/sub-proj/baz.clj` would be `baz.clj` if your Neovim CWD was `/foo/bar`. See also `g:conjure#path_subs`. Default: `undefined` *g:conjure#path_subs* `g:conjure#path_subs` If set Conjure will modify paths on "go to definition" as well as "eval file". The path will be substituted using Lua's `string.gsub` function. The keys of the `path_subs` table are the patterns and the values are the replacements. Lua pattern documentation: https://www.lua.org/pil/20.2.html > {"/root/.m2" "/home/ollie/.m2" "/src/app" "." "^(/home)/foo" "%1/bar"} < This can be used when connecting to REPLs outside of your local machine or within Docker containers where the filesystems don't quite match up. See also `g:conjure#relative_file_root`. Default: `undefined` *g:conjure#client_on_load* `g:conjure#client_on_load` Call the relevant client's `on-load` function when you enter a relevant buffer for the first time. This normally automatically starts or connects to a REPL for you. If you don't want Conjure to automatically connect you can switch this off. The client will still set up it's mappings and commands but it shouldn't start any REPLs or connect to anything. Default: `true` *g:conjure#debug* `g:conjure#debug` Display debug information in any client you're using. Default: `false` *b:conjure#context* `b:conjure#context` Override the context name for a specific buffer, preventing Conjure from attempting to extract it from the first few lines defined by the `g:conjure#extract#context_header_lines` configuration value. Default: `undefined` ============================================================================== LOG *conjure-log* The log buffer is a regular buffer that you can edit and interact with as you normally would. You can even insert new code and evaluate it, seeing the results at the bottom of the buffer, kind of like a regular REPL. The log buffer will scroll along with new results if you leave your cursor on the last line, like a terminal following along with new output. If you'd like to stop it scrolling and just see a specific result for a while you can move your cursor to it. Conjure will then leave that cursor where it is, it'll only follow along if left on the last line of the buffer. To continue following new output you can press `G` to go to the bottom. If a result is appended to the end of the log and you don't currently have a log on your screen with the cursor following along, the HUD will appear (unless you've disabled it through config). This is to ensure you always see new entries, even if you're looking at something further up in the log. The HUD is a floating window that shows you the current tail of the log. It tries to show you the top of extremely large results since the top of a data structure tends to be more interesting than the bottom. It'll vanish when you move the cursor and can be turned off entirely through configuration. The log will be automatically trimmed when it gets too long, this can be tweaked with configuration. It will attempt to trim to a known good break point so as to not cut a large data structure or string in half resulting in broken highlighting in the rest of the log buffer. Note: The HUD may be unreadable if your theme defines odd colours for the `Pmenu` highlight group. You can set a different background colour by theming `NormalFloat` or `Pmenu` with something like the following. ============================================================================== AUTOCMDS *conjure-autocmds* Conjure emits custom |User| |autocmds| when certain things happen, such as when you perform an evaluation. You can use these to trigger other behaviour or plugins as you see fit. > autocmd User ConjureEval if expand("%:t") =~ "^conjure-log-" | exec "normal G" | endif This example will cause all evaluations inside the Conjure log to jump the cursor to the bottom of the buffer, providing a slightly more REPL like experience. If there's an event you need and think would be a good general fit for the project, feel free to raise an issue to discuss it (and potentially submit a pull request if we agree!). *ConjureEval* `ConjureEval` After an evaluation of any kind. *ConjureEvalFile* `ConjureEvalFile` After an evaluation of a file from disk. *ConjureEvalStr* `ConjureEvalStr` After an evaluation of an arbitrary string (from evaluating a form, buffer, range, command etc). *ConjureDoc* `ConjureDoc` After requesting documentation. *ConjureDef* `ConjureDef` After requesting definition lookup. ============================================================================== CLIENTS *conjure-clients* Conjure comes bundled with a set of built in clients, you can access their documentation below or through the `:help conjure-client-*` command. You can install more clients through 3rd party plugins or simply write your own within your dotfiles. - |conjure-client-fennel-aniseed| - |conjure-client-fennel-stdio| - |conjure-client-clojure-nrepl| - |conjure-client-janet-netrepl| - |conjure-client-janet-stdio| - |conjure-client-hy-stdio| - |conjure-client-racket-stdio| - |conjure-client-scheme-stdio| - |conjure-client-guile-socket| - |conjure-client-julia-stdio| - |conjure-client-lua-stdio| - |conjure-client-python-stdio| - |conjure-client-snd-s7-stdio| - |conjure-client-sql-stdio| - |conjure-client-rust-evcxr| - |conjure-client-common-lisp-swank| Language clients are simply Lua modules (which can be compiled from Fennel using Aniseed) that have a few essential properties and functions in them. The module doesn't have to be within Conjure's source tree, it can be inside a 3rd party plugin repository, you can connect a filetype to it with the `g:conjure#filetype#[filetype]` configuration option. When implementing a new language client you'll need to provide the following values and functions at the top level of your module. You can split your client up into separate modules and just build this API into your init module. See `fnl/conjure/client/clojure/nrepl/init.fnl` for an example of this. You can read more about the current state of clients and their feature support on the wiki. This is also a good place for client implementers to learn about the various features Conjure allows you to provide with links to examples: https://github.com/Olical/conjure/wiki/Client-features `buf-suffix` String Last part of the log buffer name which helps with setting the filetype among other things depending on what plugins a user may have installed. For example, Fennel's is `".fnl"` and Clojure's is `".cljc"`. Whatever suits your language, it's up to you! `context-pattern` String Lua pattern to identify the module or namespace name from the first few lines of the buffer. Used to set the context for each user evaluation. Clojure's is `%(%s*ns%s*(.-)[%s){]`, alter as you see fit for your language. The value in the first capture group is passed into later functions as `opts.context`. If this doesn't suit your needs, leave it `nil` and define a `context` function instead. `context` Function(header) Called instead of `context-pattern` if it's not defined. Is passed the first few lines of the buffer as it's only argument. You can parse out the context string in any way you see fit. The return value is passed into later functions as `opts.context`. `comment-prefix` String Proceeds lines that describe what kind of evaluation has taken place (among other things), you don't want those to be highlighted as code so they're turned into comments by placing this string before them. For Lisps you probably want to use `"; "`, notice the trailing space! `eval-str` Function(opts) Takes a single argument table `opts` which contains the following: - `opts.code` String to be embedded in your evaluation. You can wrap it with whatever padding code you require. This is what the user selected for evaluation. - `opts.context` String extracted using `context-pattern` or `nil` if nothing could be found. At that point you should default it to something sensible or not set the context of your evaluation at all. - `opts.action` Always `"eval"` in this case. - `opts.file-path` Path to the buffer the user is evaluating from. - `opts.origin` What the evaluation originated from such as `"current-form"`. - `opts.preview` A comment that's appended to the log for you describing what action the user just took for future reference. It lends context to your follow up log entries with results. - `opts.range` Contains `start` and `end` tuples that mark the starting and ending row and column for the code that was extracted from the buffer. - `opts.on-result` An optional function, when it's present you should call it with the result of the evaluation as a string. This is used when evaluating code and replacing it in the buffer it came from. Such as evaluating `(+ 10 20)` and replacing the original form with `30`. `doc-str` Function(opts) Almost identical to `eval-str` even down to taking the same arguments. Instead of just evaluating `opts.code` though it should wrap it in whatever code necessary to produce documentation output for the given code. `opts.code` will probably be a single keyword. In the case of Clojure it's wrapped in `(doc ...)`, if your language doesn't implement documentation lookup you can skip this function or have it print a warning. The Clojure implementation actually leans on it's own `eval-str`. `def-str` Function(opts) Similar to `doc-str` but it should jump the user to the definition of the value in `opts.code` using the `conjure.editor/go-to` function (or similar, it's up to you how you implement it). If your language doesn't support looking up definitions you can leave the function out or print a warning. `completions` Function(opts) Called with a single argument table called `opts`, containing the following values. - `opts.prefix` The string you should be completing for the user. - `opts.cb` A callback function to be invoked with the results. Completion results should conform to what |complete-functions| return in a normal |omnifunc|. - `opts.context` Same as the context in `eval-str`, can be used to calculate completions based on the file the user is working on. If you don't provide this function all completion attempts will work, they'll just default to returning no results, it shouldn't produce errors or warnings. Asynchronous completion plugins that have Conjure support will call this function, so you'll get automatic completions as you type right away. `eval-file` Function(opts) Again, similar to `eval-str`, you should just perform an appropriate evaluation (maybe using your own `eval-str`) to load `opts.file-path` from disk, however that should be done in your language. `on-filetype` Function() Called when the filetype your client is associated with is opened. This is the time for you to set up your own mappings and buffer local commands using the `conjure.mapping` module where required. You can create your own mappings based on your own configuration, just like the Fennel + Aniseed module. It's called every time a file associated with your client is opened. `on-load` Function() Much like `on-filetype` but it's only called as the client is loaded for the first time. You can use this to register autocommands or perform one off actions the first time a user opens a file of a relevant filetype. In the case of Clojure, this is when it attempts to connect to a `.nrepl-port` file and hooks up an autocommand to clean up any existing nREPL connection before Neovim exits. `on-exit` Function() Called by the |ExitPre| autocommand, use this hook to tidy up child processes, close non-essential windows and destroy connections. This can help Neovim exit cleanly in some situations. `connect` Function(opts) Called with an `opts` table that contains the following when the user uses the `:ConjureConnect` command. - `opts.host` First argument to `:ConjureConnect` or `nil` if there was only one argument. - `opts.port` Second argument to `:ConjureConnect` or `nil` if there were zero arguments. In this case you can error or try to "do the right thing" for your given context. You do not need to provide this if there are no connection steps for your client such as a purely stdio based client running within Neovim as a sub-process. `form-node?` Function(node) When tree-sitter is in use this will be called with each node considered when looking for the "current form under the cursor". Your client can then (optionally) accept or reject the node by returning `true` or `false`. For example, Lisp clients probably want to reject any form that doesn't start with an opening parenthesis. `symbol-node?` Function(node) When tree-sitter is in use this will be called with each node considered when looking for "symbol" nodes under the cursor with the "eval word" pneumonic mapping. returning `true` or `false`. For example, the Clojure client is looking for nodes with "sym" in their type (part of the built in shared behaviour between clients) and additionally "kwd" (short for keyword and specialised for Clojure). `get-form-modifier` Function(node) The second iteration of `form-node?`, allows the client to return an instruction for Conjure to handle. The return values look like this: * `nil` or `{:modifier :none}` if you're happy with the node. * `{:modifier :parent}` if you want to go up one level and try the parent instead. This is the same as returning false from `form-node?`. * `{:modifier :node :node X}` uses the specified node `X`. * `{:modifier :raw :node-table {:content "" :range {:start [0 0] :end [0 0]}}}` Skips all of the tree-sitter things and takes your content and range at face value. This is for rare edge cases. It's also mixing up the return types of this system and may cause deep regret at a later date but for now, it's pretty darn useful when we really need it. `comment-node?` Function(node) When tree-sitter is in use this will be called with each node considered when looking for the "root form under the cursor". Your client can then (optionally) accept or reject the node by returning `true` or `false`. For example, Lisp clients probably want to reject any form that begins with `(comment)` which means the user can use "eval root form" inside comment blocks to evaluate each entry in the comment. ============================================================================== HOOKS *conjure-hooks* Hooks allow you to override parts of Conjure's functionality with more Lua code, allowing you to completely override behaviour or integrate other systems in ways that the original design ever anticipated. You manipulate hooks with the `conjure.hook` module, so you'll need to require that into your own Lua configuration code (probably aliased as `hook`) to continue. From there you may execute the `(hook.override *name* *fn*)` function to define your own hook overrides. If you need to also call the original code you can use `(hook.get *name*)` to fetch the original Conjure internal function which you may call at your discretion. So here's an example of overriding the HUD with a simple `print` statement: > (module my.config {autoload {hook conjure.hook}}) (hook.override :display-hud (fn [opts] (print "There's something new in the log, you might want to look.")) See below for all of the possible hooks and their default implementations and arguments when executed, this list can be extended upon request and consideration. `(display-hud opts)` Creates and displays the HUD floating window, scrolling the latest lines into focus. The `opts` table may contain the key `low-priority?` which indicates that this isn't so essential to display right away. stdout and stderr should count as low priority most of the time when it comes from clients that support this feature. This is because some programs may spit out lots of stdio and we want to back off from HUD spam if there is a LOT of low priority traffic. You can probably get away with ignoring this feature though. `(close-hud)` Called when the HUD should close, either by direct user interaction or because the user did something indirect like moving their cursor after a while. The passive and active closing behaviour is identical from the perspective of this function. vim:tw=78:sw=2:ts=2:ft=help:norl:et:listchars=