Skip to content

Commit

Permalink
fix: dump setup() use vim.g.command
Browse files Browse the repository at this point in the history
also use subcommands for User commands istead of polluting the namespace
  • Loading branch information
cultab committed Oct 25, 2024
1 parent 82300b3 commit 676aa77
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 209 deletions.
138 changes: 77 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,110 @@
# command.nvim

command.nvim is a simple command runner. You give it a command and it runs it in a new or existing pane of your multiplexer (or a ToggleTerm terminal). It remembers the last command so it can repeat it. It can run the current file as is or a custom command depending on rules (see Rules section). If the current file is not executable, it asks if you want to make it executable.
command.nvim is a simple command runner. You give it a command and it runs it in a new or existing pane of your multiplexer (or a ToggleTerm terminal).
It remembers the last command so it can repeat it.
It can also run the current file as is or using a custom command depending on rules (see [Rules](#Rules) section). If the current file is not executable, it asks if you want to make it executable.

It supports the following multiplexers/backends:
# TOC

- [Installation](#Installation)
- [Usage](#Usage)
- [Configuration](#Configuration)
- [Backends](#Backends)
- [Rules](#Rules)
- [Defaults][#Defaults]
- [TODO](#TODO)

It supports the following multiplexers/terminal, refered to as backends hereafter:

- tmux
- wezterm
- toggleterm

# Installing
## Installation

With Lazy.nvim

```lua
{
'cultab/command.nvim',
opts = {},
init = function()
vim.g.command = { --[[ options go here ]]}
end,
dependencies = {
'MunifTanjim/nui.nvim',
'akinsho/toggleterm.nvim' -- optional, for the toggleterm backend
}
}
```

# Usage
## Usage

Setup keymaps for each action that you want to use. For example using lua:

```lua
local map = vim.keymap.set
map('n','<leader>ct', require('command').change_direction, { desc = '[c]ommand [t]oggle pane direction' })
map('n','<leader>cc', require('command').run_command, { desc = '[c]ommand shell [c]ommand' })
map('n','<leader>cr', require('command').run_current_file, { desc = '[c]ommand [r]un current file' })
map('n','<leader>cl', require('command').run_last_command, { desc = '[c]ommand repeat [l]ast command' })
map('n','<leader>ct', require('command').ChangeDirection, {
desc = 'Toggles direction of opening panes for running commands' })
map('n','<leader>cc', require('command').Run, {
desc = 'Show prompt for a command to run' })
map('n','<leader>cr', require('command').CurrentFile, {
desc = 'Run the current file, if not executable, ask whether to make executable and run' })
map('n','<leader>cl', require('command').LastCommand, {
desc = 'Repeat last action' })
```

## User Commands

You can also use the following user commands instead of the exported lua functions.

- `:CommandChangeDirection`
Toggles pane direction for running commands

- `:CommandRun`
Show prompt to ask for a command to run

- `:CommandFile`
Runs current file

- `:CommandLast`
Runs last command

## Multiplexers & Backends
Or use the user commands:

### tmux & wezterm
```vim
:Command ChangeDirection
:Command Run
:Command CurrentFile
:Command LastCommand
```

The tmux and wezterm backends both have 2 built in pane directions, right of the editor pane, and below the editor pane.
## Configuration

### ToggleTerm
Configurations is done by passing setting the `vim.g.command` table.

The ToggleTerm backend does not support toggling different pane directions, it uses the direction configured in ToggleTerm's setup.
```lua
vim.g.command = {--[[ options go here ]]} )
```

# Configuration
### Backends

Configurations is done by passing `opts` to the setup function.
The backend is the multiplexer or terminal to use. It's controlled by the `use` key in the options table.
If the `use` key is unset, as it is by default, heuristics are used to pick on of the supported backends.

```lua
require('command.nvim').setup( {--[[ your options here ]]} )
```
* If `$TMUX` is set, tmux is used.

## Backends
* Else if `wezterm(?.exe)` exists in `$PATH`, wezterm is used.

The backend is the multiplexer or terminal to use. It's controlled by the `use` key in the opts table.
* Else if toggleterm's module can be `require()`'ed, toggleterm is used.

```lua
opts = {
--- the backend to use, one of:
--- @alias backend_used
--- | 'auto' -- pick automatically by examining environment vars
--- | 'tmux'
--- | 'wezterm'
--- | 'toggleterm'
use = "auto",
}
use = nil
```

#### tmux & wezterm

The tmux and wezterm backends both have 2 built in pane directions, right of the editor pane, and below the editor pane.

#### ToggleTerm

The ToggleTerm backend does not support toggling different pane directions, it uses the direction configured in ToggleTerm's setup.


## Rules
### Rules

Rules are key-value pairs of lua patterns and functions.
They are passed into the `setup()` function through the opts table.

```lua
opts = {
--- @alias rule table<string, fun(string?):string>
rules = {
-- run the current file with `nvim -l` if it ends with '.lua'
[".*%.lua"] = function(filepath)
Expand All @@ -106,29 +118,30 @@ opts = {
}
```

The lua pattern is matched against the current filename. The function must accept an optional argument and return a string. The optional argument will contain the filepath to the current file. The return value will be the shell command to be run when the name of the current file matches the pattern.
The lua pattern is compared against the current filename, if it maches the function is run to get the shell command and run it.

The function can accept an optional argument that will contain the filepath to the current file.
The function shall return a shell command, as a string, to be run.

## Default Opts
### Defaults

The defaults options are as follows:

```lua
local default_opts = {
vim.g.command = {
--- the backend to use, one of:
--- optional, if unset heuristics are used to pick one
--- @alias backend_used
--- | 'auto' -- pick automatically by examining environment vars
--- | 'tmux'
--- | 'wezterm'
--- | 'toggleterm'
use = "auto",
use = nil

--- defines rules to overwrite the command to run when using the "run current file" behavior
--- keys are lua patterns (see :help lua-pattern)
---
--- values are functions that accept:
--- an optional argument containing the path to the current file
--- returns:
--- a string of the shell command to run
--- values are functions that accept an optional argument containing
--- the path to the current file and return a string of the shell command to run
--- @alias rule table<string, fun(string?):string>
rules = {
-- run the current file with `nvim -l` if it ends with '.lua'
Expand All @@ -141,17 +154,13 @@ local default_opts = {
end,
},

--- whether to check if keys in the opts passed to setup are valid
--- @type bool
validate = true,

--- an icon to use for prompts and notifications
--- @type string
icon = "$ ",
}
```

# TODO
## TODO

- [ ] slime-like behaviors
- [ ] send current line to pane
Expand All @@ -172,6 +181,13 @@ local default_opts = {
- [x] also in readme also
- [ ] history instead of just last command
- [x] add bugs
- [ ] user configured pane directions
- [ ] maybe fully custom
- [ ] maybe add every choice and make their availability configurable
- [x] remove bugs
- [ ] ~~user configured pane directions~~
- [ ] ~~maybe fully custom~~
- [ ] ~~maybe add every choice and make their availability configurable~~
- [ ] user backends
- [x] expunge `.setup()` all hail `vim.g`

## Similar Plugins

- [yeet.nvim](https://github.com/samharju/yeet.nvim), very similar, would not have *originaly* made this had I known yeet.nvim existed :^P
21 changes: 21 additions & 0 deletions lua/command/command-types.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--- @alias backend_used
--- | 'wezterm'
--- | 'tmux'
--- | 'toggleterm'
--- | 'auto' -- pick automatically by examining environment vars

--- @alias rule table<string, fun(string?):string>

--- @class direction
--- @field name string

--- @class backend
--- @field run fun(string)
--- @field directions direction[]|nil

--- @class opts
--- @field use backend_used?
--- @field rules rule[]?
--- @field validate boolean?
--- @field icon string?
--- @field backend backend?
Loading

0 comments on commit 676aa77

Please sign in to comment.