Skip to content
Draft
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
397 commits
Select commit Hold shift + click to select a range
a9d5557
merge from master
mattwparas Jan 11, 2025
28383ea
Optionally load init.scm and helix.scm from env var
RatCornu Jan 14, 2025
90488cb
start working on language configuration
mattwparas Jan 21, 2025
7294983
use selection did change
mattwparas Jan 26, 2025
374389e
adding hooks
mattwparas Jan 28, 2025
9c11585
upgrade steel
mattwparas Feb 2, 2025
d17dd31
merge from master
mattwparas Feb 27, 2025
d00294c
fix arg parsing
mattwparas Feb 27, 2025
cfb7a58
merge latest changes in
mattwparas Feb 27, 2025
21f7a7b
Merge pull request #18 from mattwparas/language-configuration
mattwparas Feb 27, 2025
f407a04
cleanup
mattwparas Feb 27, 2025
fffa86e
merge from master
mattwparas Mar 26, 2025
14316ae
Merge pull request #19 from mattwparas/language-configuration
mattwparas Mar 26, 2025
2d16a86
update steel submodule
mattwparas Mar 26, 2025
60c0882
remove old document open/close events
mattwparas Mar 26, 2025
7143dd4
use new mutex guard
mattwparas Mar 26, 2025
05f4352
bump steel
mattwparas Mar 27, 2025
c9b5276
unpark the interrupt handler after resuming
mattwparas Mar 27, 2025
43b9dd3
remove erroneous no such command when the command succeeds
mattwparas Apr 9, 2025
6e8fa50
bump steel to fix windows
mattwparas Apr 17, 2025
85eab83
fix command and arg parsing with typed commands
mattwparas Apr 19, 2025
9bb634a
Merge pull request #16 from RatCornu/steel
mattwparas Apr 19, 2025
170e506
wip
mattwparas Apr 26, 2025
35c9a3d
start working on some docs
mattwparas Apr 27, 2025
82ad9c1
update steel
mattwparas Apr 27, 2025
416642d
update
mattwparas Apr 27, 2025
e684c7d
setup embedding
mattwparas Apr 27, 2025
5c6620b
remove debug prints
mattwparas Apr 27, 2025
0c96732
Merge pull request #21 from mattwparas/mwp-embedded-modules
mattwparas Apr 27, 2025
c69f11b
fix merge
mattwparas Apr 27, 2025
85f99f8
Merge pull request #22 from mattwparas/mwp-improving-docs
mattwparas Apr 27, 2025
63086ee
feat: allow to get a register value from scheme
piotrkwarcinski May 4, 2025
edcb630
cleanup
piotrkwarcinski May 10, 2025
0b5741f
attempt to get nix working
mattwparas May 10, 2025
e8614ce
use embedded dependencies instead of depending on external code gener…
mattwparas May 10, 2025
75bf1a7
update steel to have fixed language server
mattwparas May 10, 2025
c0c3d69
Merge remote-tracking branch 'plugin-steel/steel-event-system' into h…
piotrkwarcinski May 11, 2025
d9ec722
Add documentation
piotrkwarcinski May 11, 2025
ec53eb4
dots
piotrkwarcinski May 11, 2025
de2496d
formatting
piotrkwarcinski May 11, 2025
ef4fe80
Merge pull request #24 from piotrkwarcinski/helix-plugin-register-value
mattwparas May 12, 2025
81ee8ef
test experimental picker callback, use at your own risk (do not use u…
mattwparas May 14, 2025
3f062fa
bring rust version back in line
mattwparas May 17, 2025
848f2e2
instrument proper components module, start documentation
mattwparas May 17, 2025
3b534ac
finish documenting component api
mattwparas May 17, 2025
a48abb7
just kidding, actually finish documenting the component api
mattwparas May 17, 2025
56a083a
more documentation of configuration
mattwparas May 18, 2025
64e4826
more documentation
mattwparas May 18, 2025
d04c95d
more docs
mattwparas May 18, 2025
e6b0bad
fix polluting the command palette with global steel functions
mattwparas May 19, 2025
9492771
make sure docs don't show up for globals that aren't commands
mattwparas May 19, 2025
c0bb7c2
rename workspace function
mattwparas May 19, 2025
54b3033
clean up, don't error on bootup if the helix file is missing
mattwparas May 20, 2025
39f7244
fix init file and set up language configs
mattwparas May 20, 2025
770d4d3
refresh language configs for open docs after update
mattwparas May 20, 2025
d3fb156
manually merge each field in the language config
mattwparas May 20, 2025
a2a97f1
properly handle lsp configs as well
mattwparas May 20, 2025
d451258
insert unknown lsps on update
mattwparas May 20, 2025
f9d83ac
remove some logging
mattwparas May 20, 2025
2922687
allow writing registers from steel
tobiaskohlbau May 20, 2025
3147f98
fix typo in find-workspace
tobiaskohlbau May 20, 2025
f249949
address warning nix build
tobiaskohlbau May 20, 2025
9504a50
Merge pull request #27 from tobiaskohlbau/fixTypo
mattwparas May 20, 2025
6de4235
have docs properly generate on code-gen
mattwparas May 20, 2025
85bd47c
fix arity for ctx functions in components
mattwparas May 20, 2025
39614b2
typo in theme-scope
mattwparas May 20, 2025
9f0501d
when encountering an error in a dynamic component, pop off the stack …
mattwparas May 21, 2025
67c5a2a
add function to check for key event
mattwparas May 21, 2025
6ec0410
apply suggested naming
tobiaskohlbau May 21, 2025
aada3b5
add ability to ignore the command and close the component
mattwparas May 21, 2025
9d88ce3
Merge pull request #28 from tobiaskohlbau/addressNixWarning
mattwparas May 22, 2025
04697d6
Merge pull request #26 from tobiaskohlbau/writeRegisters
mattwparas May 22, 2025
aefdab6
fix arity on acquire-context-lock
mattwparas May 23, 2025
3e57105
bundle ext library, upgrade steel, fix block on task
mattwparas May 23, 2025
fda1bbf
add macros for language configuration and lsp configuration
mattwparas May 25, 2025
85e83d9
Fix call to exp-picker callback
piotrkwarcinski May 26, 2025
c5bd451
Merge pull request #29 from piotrkwarcinski/exp-picker-fix
mattwparas May 26, 2025
863cf60
speed up the keymap api
mattwparas May 28, 2025
b3d55c0
clean up
mattwparas May 28, 2025
0d509d6
update steel
mattwparas May 28, 2025
c1da27b
add missing bufferline option
mattwparas May 28, 2025
977fc9e
add dynamic option config
mattwparas May 28, 2025
d7bdac1
add generated docs
mattwparas May 28, 2025
b321252
update steel
mattwparas May 29, 2025
c7273d7
add document saved hook
mattwparas May 30, 2025
9f581f8
update steel, add new time primitives
mattwparas May 31, 2025
01cfd2e
update steel
mattwparas May 31, 2025
bc01dda
check if a document has been modified
mattwparas May 31, 2025
f032f18
no longer install via git submodule, just use cargo install
mattwparas Jun 1, 2025
3149754
bake in a high level theme api
mattwparas Jun 1, 2025
fe2ab35
fix theme api
mattwparas Jun 1, 2025
ba1fdac
use inferred steel lsp home location
mattwparas Jun 3, 2025
e2b81a2
punch out some more docs
mattwparas Jun 5, 2025
82dce7a
ViewID equality (#30)
piotrkwarcinski Jun 5, 2025
6f4b41c
keep component functions alive for the duration of the life cycle, sk…
mattwparas Jun 5, 2025
f40100a
dont lock the engine when grabbing the docs
mattwparas Jun 6, 2025
8eae56f
merge latest from master
mattwparas Jun 6, 2025
67f5b70
implement equality for some more types
mattwparas Jun 9, 2025
cae10b8
create init and helix files if they don't exist
mattwparas Jun 10, 2025
3311c4e
update steel
mattwparas Jun 11, 2025
7a006f7
clean up
mattwparas Jun 13, 2025
bf22478
clean up doc fetching
mattwparas Jun 13, 2025
b6b02c8
add docs for ropes
mattwparas Jun 14, 2025
1eecadb
merge from master
mattwparas Jun 14, 2025
2fe135c
set up integration to listen to lsp notifications that aren't handled…
mattwparas Jun 14, 2025
c1b5ff2
address warnings
mattwparas Jun 14, 2025
7e0c438
remove some newlines
mattwparas Jun 14, 2025
bb1d8af
update steel docs and add more rope functions
mattwparas Jun 14, 2025
1301c93
add rope docs
mattwparas Jun 14, 2025
d4fe0a0
update steel
mattwparas Jun 15, 2025
f582c8b
feat: add API for selection and ranges (#33)
nik-rev Jun 15, 2025
629bb38
adjust inlay hint api to remove just based on character index and not…
mattwparas Jun 16, 2025
ec38807
add removing inlay hints by id to remove all invalidated inlay hints
mattwparas Jun 16, 2025
a35388a
add return value for the inlay hints removal
mattwparas Jun 16, 2025
47b3ab8
update steel
mattwparas Jun 17, 2025
b858f9f
typos
mattwparas Jun 18, 2025
d4958e4
expose paste events in components
mattwparas Jun 20, 2025
b2c28b8
bump steel version
mattwparas Jun 21, 2025
1393d14
set default name to be the id
mattwparas Jun 21, 2025
081f9e8
update install instructions
mattwparas Jun 21, 2025
45480fc
add range and selection conversions
mattwparas Jun 21, 2025
ef244de
don't set the status as void when the return value is void
mattwparas Jun 21, 2025
3ee0e81
special case strings when setting the status to eliminate the quotes
mattwparas Jun 21, 2025
ef7ea0f
auto convert values to strings when logging
mattwparas Jun 21, 2025
557aa9c
add warning and error
mattwparas Jun 21, 2025
7e800e3
bump toolchain version for weird windows c abi incompatibility that i…
mattwparas Jun 23, 2025
7a8db55
add key-modifier-super function (#46)
thomasschafer Jul 8, 2025
8218db6
fix windows paths for registering additional search paths
mattwparas Jul 9, 2025
46abe80
Add more fns to update selection ranges (#38)
meepleek Jul 9, 2025
f377c1c
added a selected-register! function for the plugin system for use wit…
mjkpolo Jul 9, 2025
e79005e
update steel
mattwparas Jul 13, 2025
bafe5bd
merge master
mattwparas Jul 16, 2025
81e8ba8
address most of the comments
mattwparas Jul 18, 2025
69c16ea
remove comment from toml
mattwparas Jul 18, 2025
28bdf66
Add key-event-end? function (#51)
thomasschafer Jul 20, 2025
faaf0b8
update steel
mattwparas Jul 21, 2025
2411202
update steel to fix regression with ffi-function creation
mattwparas Jul 21, 2025
8d0a19a
fix bug with path function
mattwparas Jul 25, 2025
152bf02
check equality on mode
mattwparas Jul 28, 2025
9734ea3
add function to get the current column number (#49)
quantonganh Jul 29, 2025
ce21547
add function to get language for document (#53)
jdrst Jul 29, 2025
ec8971a
update steel
mattwparas Jul 29, 2025
3f6d6fb
Add integration for handling LSP method calls (#45)
nikolaiser Jul 29, 2025
2aad9cf
make notifications not take an id
mattwparas Jul 29, 2025
8d11ab2
add accessors for event mode switch event
mattwparas Jul 29, 2025
6990052
dont pass in context
mattwparas Jul 29, 2025
96358f9
make adjustments to client non standard lsp implementation
mattwparas Jul 29, 2025
d0c4939
better name for a function
mattwparas Jul 30, 2025
dd42ed5
customize the cursor kind from dynamic components
mattwparas Jul 30, 2025
d426226
slot more things behind the feature flag
mattwparas Aug 1, 2025
db98b3e
merge from master
mattwparas Aug 1, 2025
1e7d1b2
update to include rainbow brackets
mattwparas Aug 1, 2025
16ebbce
add back lock file
mattwparas Aug 1, 2025
d8c27f2
fix sleep function
mattwparas Aug 1, 2025
f1403d5
Add send-lsp-notification Steel binding (#55)
npupko Aug 5, 2025
e137965
clean up
mattwparas Aug 5, 2025
8cdb8af
move files around
mattwparas Aug 5, 2025
055b2ea
clean up
mattwparas Aug 5, 2025
14014cd
address comments
mattwparas Aug 5, 2025
626d5e0
move steel out of default, use the xtask to install, otherwise manual…
mattwparas Aug 5, 2025
069456e
gobbledy
mattwparas Aug 5, 2025
f8bc328
typo
mattwparas Aug 5, 2025
374412a
fix post event dispatching
mattwparas Aug 9, 2025
580702a
set the engine to be in a safepoint while idle
mattwparas Aug 13, 2025
ec24bef
properly check arity of typed commands
mattwparas Aug 23, 2025
81a2f2e
Reload documents by ID (#50)
thomasschafer Aug 23, 2025
dbe0b76
create new (get-current-line-character) to give columns with encoding…
m4rch3n1ng Aug 23, 2025
1454311
Add extra config options (#54)
gerblesh Sep 9, 2025
f94c9b2
Regex match on ropes (#57)
gerblesh Sep 9, 2025
b15b62d
fix some clippy warnings (#66)
m4rch3n1ng Sep 9, 2025
9be9ad6
update steel
mattwparas Sep 9, 2025
7bd8530
add some functions to get lsp clients and info from them (#64)
m4rch3n1ng Sep 9, 2025
2270457
update steel
mattwparas Sep 15, 2025
04c313f
add lsp-client-initialized?, check if client is init in offset-encodi…
m4rch3n1ng Sep 20, 2025
fc71806
merge from master
mattwparas Sep 21, 2025
14c37a4
add back missing files from merge
mattwparas Sep 21, 2025
f44862e
add custom commands to command palette
mattwparas Sep 23, 2025
0372e0a
don't unwrap language_server_name when it is None (#71)
m4rch3n1ng Sep 23, 2025
a853eaa
add ability to completely override keybindings
mattwparas Sep 24, 2025
a651517
move initialization up to avoid lsps starting with old config
mattwparas Sep 24, 2025
b57c48a
make the default not steel, again
mattwparas Oct 6, 2025
17ecf38
merge from master
mattwparas Oct 6, 2025
1c8de92
add missing inline diagnostics configs
mattwparas Oct 7, 2025
03754b3
fix typo
mattwparas Oct 8, 2025
d04369a
have get-language-config return the actual configuration as a seriali…
mattwparas Oct 8, 2025
edd5f3a
update steel
mattwparas Oct 9, 2025
7d7648f
handle deserializing values better
mattwparas Oct 9, 2025
02b4281
move rust tool chain back down
mattwparas Oct 10, 2025
00f73bb
downgrade imbl
mattwparas Oct 11, 2025
cea193b
downgrade archery version to get things behaving
mattwparas Oct 11, 2025
c6c7ba5
fix bad merge
mattwparas Oct 11, 2025
990f1fd
undoing more bad merge stuff from termina
mattwparas Oct 11, 2025
f319b81
one step closer to windows fix
mattwparas Oct 11, 2025
86f3efb
attempt to fix windows
mattwparas Oct 11, 2025
42b1047
one more try
mattwparas Oct 11, 2025
a18c989
okay for real
mattwparas Oct 11, 2025
4f4b356
(finally) add module for handling keymaps
mattwparas Oct 12, 2025
e872a19
don't crash if value doesn't exist
mattwparas Oct 12, 2025
506bc71
add proper keywords to the keymaps macro
mattwparas Oct 12, 2025
b51143d
attempt merging keybinds
mattwparas Oct 13, 2025
56e8658
fix integration build
mattwparas Oct 13, 2025
cde3d6c
update steel to fix init time regression
mattwparas Oct 13, 2025
af1a0ad
try to initialize the engine in the background
mattwparas Oct 13, 2025
5ca50c8
fix keymaps macro
mattwparas Oct 13, 2025
2e04ae5
add runtime flag for steel as well
mattwparas Oct 13, 2025
571d241
merge from master
mattwparas Oct 13, 2025
060e1d4
fix issue with xtask and generating sources
mattwparas Oct 19, 2025
9fdc8ec
add support for reloading the whole engine, should work now
mattwparas Oct 24, 2025
2e4c1db
add goto-col function:
mattwparas Oct 30, 2025
4c7d951
query keybindings api
mattwparas Oct 30, 2025
d69b0c4
add goto-line
mattwparas Oct 30, 2025
5bf9e04
add optional param to extend
mattwparas Oct 30, 2025
50b3ec1
create mode from string
mattwparas Oct 30, 2025
ad81a9d
fix build for language server
mattwparas Nov 4, 2025
01d2e73
fix bugs in keymap macro
mattwparas Nov 4, 2025
0e286d1
fix keymap macro again
mattwparas Nov 5, 2025
71cc471
change how keymaps are stored with length explanation
mattwparas Nov 5, 2025
33f53f0
add another function for language server updating
mattwparas Nov 5, 2025
ce421e4
document a bunch of more configs
mattwparas Nov 5, 2025
8d05b78
more config options
mattwparas Nov 5, 2025
4b41b67
add statusline configuration
mattwparas Nov 5, 2025
23b90f7
add more docs for statusline
mattwparas Nov 5, 2025
9221623
union missing conf in keymaps
mattwparas Nov 5, 2025
c361b79
include additional docs
mattwparas Nov 8, 2025
c9b5e72
update docs
mattwparas Nov 8, 2025
53786e4
fix callbacks on static commands
mattwparas Nov 9, 2025
ce7e90c
add one more patch
mattwparas Nov 9, 2025
e9e7bc2
update steel
mattwparas Nov 12, 2025
5ef8dbd
fix some bugs with how keymaps get overlaid on to the global
mattwparas Nov 12, 2025
86430a9
fix statusline function
mattwparas Nov 13, 2025
148311c
add on key callback
mattwparas Nov 13, 2025
66db9c9
on key event function
mattwparas Nov 13, 2025
37807cc
decrease polling timeout in interrupt handler
mattwparas Nov 13, 2025
1b948bd
trigger on key callbacks
mattwparas Nov 13, 2025
e151f16
merge from master
mattwparas Nov 14, 2025
59f601e
updated STEEL.md to fix invalid function for helix.scm example (#78)
Cooksey99 Nov 14, 2025
17aecbd
add missing function
mattwparas Nov 14, 2025
e00034c
force re install
mattwparas Nov 14, 2025
40f4b88
check engine bindings first for typed commands
mattwparas Nov 18, 2025
b366862
fix typed command calling
mattwparas Nov 20, 2025
9044221
Push auto pairs config down to editor on change
mattwparas Nov 21, 2025
92bc3db
implement equality for key events
mattwparas Nov 24, 2025
4a9569c
fix string->editor-mode binding
mattwparas Nov 30, 2025
c87abc1
attempt to fetch the editor count
mattwparas Dec 1, 2025
8e6f66a
add another check on if line is in bounds
mattwparas Dec 2, 2025
ae4fed2
update steel core
mattwparas Dec 3, 2025
35229a6
update steel
mattwparas Dec 4, 2025
a7d6f79
set the error object when a callback to the main thread fails
mattwparas Dec 4, 2025
2574e42
update steel
mattwparas Dec 4, 2025
a01f45b
update docs for buffer clear
mattwparas Dec 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,764 changes: 1,376 additions & 388 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ package.helix-term.opt-level = 2
tree-house = { version = "0.3.0", default-features = false }
nucleo = "0.5.0"
slotmap = "1.0.7"
steel-core = { git = "https://github.com/mattwparas/steel.git", version = "0.7.0", features = ["anyhow", "dylibs", "sync", "triomphe", "imbl"] }
thiserror = "2.0"
tempfile = "3.23.0"
bitflags = "2.9"
Expand Down
265 changes: 265 additions & 0 deletions STEEL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# Building

You will need:

* A clone of this fork, on the branch `steel-event-system`

## Installing helix

Just run

`cargo xtask steel`

To install the `hx` executable, with steel as a plugin language. This also includes:

The `steel` executable, the steel language server, the steel dylib installer, and the steel package manager `forge`.

## Developing

The easiest way to contribute would be to adjust the default features on the `helix-term` crate:

```toml
[features]
features = ["git", "steel"]
```

## Setting up configurations for helix

There are 2 important files you'll want, which should be auto generated during the installation process if they don't already exist:

* `~/.config/helix/helix.scm`
* `~/.config/helix/init.scm`

Note - these both live inside the same directory that helix sets up for runtime configurations.

### `helix.scm`

The `helix.scm` module will be loaded first before anything else, the runtime will `require` this module, and any functions exported will now be available
to be used as typed commands. For example:


```scheme
# helix.scm
(require "helix/editor.scm")
(require (prefix-in helix. "helix/commands.scm"))
(require (prefix-in helix.static. "helix/static.scm"))

(provide shell git-add open-helix-scm open-init-scm)

;;@doc
;; Specialized shell implementation, where % is a wildcard for the current file
(define (shell cx . args)
;; Replace the % with the current file
(define expanded (map (lambda (x) (if (equal? x "%") (current-path cx) x)) args))
(apply helix.run-shell-command expanded))

;;@doc
;; Adds the current file to git
(define (git-add cx)
(shell cx "git" "add" "%"))

(define (current-path)
(let* ([focus (editor-focus)]
[focus-doc-id (editor->doc-id focus)])
(editor-document->path focus-doc-id)))

;;@doc
;; Open the helix.scm file
(define (open-helix-scm)
(helix.open (helix.static.get-helix-scm-path)))

;;@doc
;; Opens the init.scm file
(define (open-init-scm)
(helix.open (helix.static.get-init-scm-path)))


```

Now, if you'd like to add the current file you're editing to git, simply type `:git-add` - you'll see the doc pop up with it since we've annotated the function
with the `@doc` symbol. Hitting enter will execute the command.

You can also conveniently open the `helix.scm` file by using the typed command `:open-helix-scm`.


### `init.scm`

The `init.scm` file is run at the top level, immediately after the `helix.scm` module is `require`d. The helix context is available here, so you can interact with the editor.

The helix context is bound to the top level variable `*helix.cx*`.

For example, if we wanted to select a random theme at startup:

```scheme
# init.scm

(require-builtin steel/random as rand::)
(require (prefix-in helix. "helix/commands.scm"))
(require (prefix-in helix.static. "helix/static.scm"))

;; Picking one from the possible themes
(define possible-themes '("ayu_mirage" "tokyonight_storm" "catppuccin_macchiato"))

(define (select-random lst)
(let ([index (rand::rng->gen-range 0 (length lst))]) (list-ref lst index)))

(define (randomly-pick-theme options)
;; Randomly select the theme from the possible themes list
(helix.theme (select-random options)))

(randomly-pick-theme possible-themes)

```

### Libraries for helix

There are a handful of extra libraries in development for extending helix, and can be found here https://github.com/mattwparas/helix-config.

If you'd like to use them, create a directory called `cogs` in your `.config/helix` directory, and copy the files in there.

### options.scm

If you'd like to override configurations from your toml config:


```scheme
# init.scm

(require "helix/configuration.scm")

(file-picker (fp-hidden #f))
(cursorline #t)
(soft-wrap (sw-enable #t))

```


### keymaps.scm

Applying custom keybindings for certain file extensions:

```scheme
# init.scm

(require "cogs/keymaps.scm")
(require (only-in "cogs/file-tree.scm" FILE-TREE-KEYBINDINGS FILE-TREE))
(require (only-in "cogs/recentf.scm" recentf-open-files get-recent-files recentf-snapshot))

;; Set the global keybinding for now
(add-global-keybinding (hash "normal" (hash "C-r" (hash "f" ":recentf-open-files"))))

(define scm-keybindings (hash "insert" (hash "ret" ':scheme-indent "C-l" ':insert-lambda)))

;; Grab whatever the existing keybinding map is
(define standard-keybindings (deep-copy-global-keybindings))

(define file-tree-base (deep-copy-global-keybindings))

(merge-keybindings standard-keybindings scm-keybindings)
(merge-keybindings file-tree-base FILE-TREE-KEYBINDINGS)

(set-global-buffer-or-extension-keymap (hash "scm" standard-keybindings FILE-TREE file-tree-base))

```

In insert mode, this overrides the `ret` keybinding to instead use a custom scheme indent function. Functions _must_ be available as typed commands, and are referred to
as symbols. So in this case, the `scheme-indent` function was exported by my `helix.scm` module.


## Writing a plugin

### Getting setup

Before you start, you should make sure that your configuration for the steel lsp is wired up correctly. This will give you
access to the documentation that will help you as you write your plugin. To configure the LSP, you can add this to your
`init.scm`:

```scheme
(require "helix/configuration.scm")
(define-lsp "steel-language-server" (command "steel-language-server") (args '()))
(define-language "scheme"
(language-servers '("steel-language-server")))
```

This will give you an interactive setup that can help you run plugins as you go. I also like to evaluate commands
via the buffer, by either typing them in to the command prompt or by loading the current buffer. To load the current
buffer, you can type `:eval-buffer`, or to evaluate an individual command, you can run `:evalp` - note, in your init.scm, you
may need to add:

```scheme
(require (only-in "helix/ext" evalp eval-buffer))
```

This brings those functions to the top level scope so that you can interact with them. You may also be keen to peruse all of the steel
functions and modules available. Those can be found in `steel-docs.md`.


### Command API

There are two levels of the functionality exposed to plugins. The first is simply based around
chaining builtin commands, as if you're a lightning fast human typing commands very quickly. The other level
is a bit lower, and deals directly with the component API that helix uses to draw the text editor and various
popups, like the file picker or buffer selection.

To understand the first level, which is accessing typed commands and static commands, i.e. commands that you
typically type via `:`, or static commands, commands which are bound to keybindings, you can look at the modules:

* helix/commands.scm
* helix/static.scm

Every function here implicitly has access to a context, the helix context. This assumes that you're focused onto
some buffer, and any actions are assumed to be done within that context. For example, calling `vsplit` will
split the currently focused into a second, and move your focus to that window. Keeping track of that is important
to understand where your focus is.

In general, these functions do not return anything, given that they're purely for side effects. There are some functions
that do, and they should be documented as such. The API will need to be improved to return useful things where relevant.

### The UI

A good rule of thumb is to not block the UI. During the execution of a steel function, the helix context is exclusively
available to that executing function. As a result, you should not have long running functions there (note - if you end
up having an infinite loop of some kind, `ctrl-c` should break you out).

Luckily, there are a handful of ways we can accomplish more sophisticated plugins:

* Futures
* Threads

There are a handful of primitives that accept a future + a callback, where the callback will get executed once the future
is complete. The future will get scheduled on to the helix event loop, so the UI won't be blocked. (TODO: Document this more!)

Another way we can accomplish this is with native threads. Steel supports native threads, which means we can spawn a function
off on to another thread to run some code. Consider the following example which won't work:


```scheme
(spawn-native-thread (lambda () (time/sleep-ms 1000) (theme "focus_nova"))) ;; Note, this won't work!
```

This appears to spawn a thread, sleep for 1 second, and then change the theme. The issue here is that this thread does not
have control over the helix context. So what we'll have to do instead, is schedule a function to be run on the main thread:


```scheme
(require "helix/ext.scm")
(require-builtin steel/time)

(spawn-native-thread
(lambda ()
(hx.block-on-task
(lambda ()
(time/sleep-ms 1000)
(theme "focus_nova")))))
```

`hx.block-on-task` will check if we're running on the main thread. If we are already, it doesn't do anything - but otherwise,
it enqueues a callback that schedules itself onto the main thread, and waits till it can acquire the helix context. The function
is then run, and the value returned back to this thread of control.


There is also `hx.with-context` which does a similar thing, except it does _not_ block the current thread.

### Components

Coming soon!
2 changes: 2 additions & 0 deletions helix-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ homepage.workspace = true
[features]
unicode-lines = ["ropey/unicode_lines"]
integration = []
steel = ["dep:steel-core"]

[dependencies]
helix-stdx = { path = "../helix-stdx" }
Expand Down Expand Up @@ -53,6 +54,7 @@ chrono = { version = "0.4", default-features = false, features = ["alloc", "std"

textwrap = "0.16.2"

steel-core = { workspace = true, optional = true }
nucleo.workspace = true
parking_lot.workspace = true
globset = "0.4.16"
Expand Down
11 changes: 9 additions & 2 deletions helix-core/src/command_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,13 @@ impl<'a> Args<'a> {
}
}

pub fn raw(positionals: Vec<Cow<'a, str>>) -> Self {
Self {
positionals,
..Self::default()
}
}

/// Reads the next token out of the given parser.
///
/// If the command's signature sets a maximum number of positionals (via `raw_after`) then
Expand Down Expand Up @@ -872,7 +879,7 @@ impl<'a> Args<'a> {

/// Performs any validations that must be done after the input args are finished being pushed
/// with `Self::push`.
fn finish(&self) -> Result<(), ParseArgsError<'a>> {
pub fn finish(&self) -> Result<(), ParseArgsError<'a>> {
if !self.validate {
return Ok(());
};
Expand Down Expand Up @@ -1123,7 +1130,7 @@ mod test {
assert_incomplete_tokens(r#"echo %{hello {{} world}"#, &["echo", "hello {{} world}"]);
}

fn parse_signature<'a>(
pub fn parse_signature<'a>(
input: &'a str,
signature: Signature,
) -> Result<Args<'a>, Box<dyn std::error::Error + 'a>> {
Expand Down
Loading