ad-editor 0.4.0

An adaptable text editor
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
>> Using the ad text editor

+-------------------------------------------------------------------------------------+
| Welcome to the help page for the ad text editor. Viewing this file within ad itself |
| is recommended as it will allow you to use Load and Execute the text it contains    |
| in order to navigate the contents and explore the functionality of the editor.      |
+-------------------------------------------------------------------------------------+
              \  ,,  __
                ("\ ( (
                -)>\ )/
                ('( )'
                -'-'

You can either read things from top to bottom or make use of the Index below to jump
to a particular section that you care about. To do this, highlight one of the lines
in the Index below by placing the cursor on it and pressing "x" in NORMAL mode. Once
the line is highlighted, hit enter to jump to that section of the file. (See the
"Loading Text" section for more information on how this works.)

  NOTE: pressing "gg" while you are in NORMAL mode will jump you to back to the top
        of the file so you can quickly find the index again.

---

>> Index
About
The Tour
Configuration
Editor Modes
Selecting Text
Loading Text
Executing Text
Key Bindings
Mouse Interactions
The Minibuffer
Windows and Columns
Virtual Buffers
The Jump List
Running Built In Commands
Running External Commands
Running Edit Commands
The Filesystem Interface
Plumbing
LSP support
Syntax Highlighting
Debugging and Troubleshooting

---

>> About

"ad" is a text oriented user interface and editor for programmers. Getting the most out
of ad involves writing your own scripts and helper programs to customise its behaviour
to your needs. The design of ad is heavily inspired by the text editors "acme" and "sam"
from the Plan 9 operating system along with the modal interface of vi and the dmenu tool
from suckless.

    http://acme.cat-v.org/
    http://doc.cat-v.org/plan_9/4th_edition/papers/acme/
    http://sam.cat-v.org/
    http://doc.cat-v.org/plan_9/4th_edition/papers/sam/
    https://en.wikipedia.org/wiki/Vi_(text_editor)
    https://tools.suckless.org/dmenu/

  NOTE: Right clicking on the URLs above will open them in your browser

Rather than attempt to provide built-in implementations of all the functionality you might
need (or be used to) from other editors, ad instead makes it easy for your existing tools
to interact with the state of the editor directly. Approaching things this way round
turns ad into a "glue layer" for the tooling you already have. In the words of Russ Cox
describing acme, it is an IDE done right: an integratING development environment instead
of an integratED one.

At its simplest ad is a minimal text editor with a modal interface inspired by vi, but
within ad text is something you can read, edit, load and execute. An ad buffer can be a
file you are working on, the output of commands you are running, a custom user interface
you have written or even all three at once. If you've used acme before then you should feel
right at home, and if not you'll quickly discover that you have a lot of power and control
over the contents of your buffers as you read through the rest of this guide.

---

>> The Tour

The ad git repo contains a tour that can be run using the Slide script located in data/bin.
The tour does not aim to cover every aspect of ad in detail but it is a good place to start
if you are wanting to learn a bit about how everything works in a more guided setting.

You can clone the repo and start the tour by running the following from your shell (assuming
that you already have ad installed):

  git clone https://github.com/sminez/ad.git
  cd ad
  ad docs/tour/intro

Once ad is open the "intro" file will instruct you on how to start the tour. Middle clicking
(or pressing the "@" key) on the PrevSlide and NextSlide "buttons" on each slide will
navigate through the tour. Refer to the "Executing Text" section of this help file to learn
more about how that works.

---

>> Configuration

Your config file is located at {{CONFIG_PATH}}

You can right click on this path to open your current config file. The default configuration
will be written to that file on startup if it is currently missing.

---

>> Editor Modes

ad provides a number of distinct "modes" for interacting with the editor. Depending on the
mode you are in you will find that the keys that you press have a different effect. See the
"Key Bindings" section for more details.

  NORMAL mode
    This is the default mode that ad will open in. Key bindings in this mode are primarily
    focused on selecting and manipulating text but you are also able to specify your own
    key bindings that will run external commands. If you are familiar with the NORMAL mode
    of editors like Vim and Kakoune then things should feel broadly familiar.

    Note that ad follows the "noun verb" approach to motions used in Kakoune rather than the
    traditional "verb noun" approach used by Vi and its descendants. So you will "select a word
    to delete" (Wd) rather than "delete a word" (dw). As a general rule pressing a key on
    its own will set the dot based on the motion used and pressing the same key while holding
    down shift will extend the existing dot to that position instead.

    The default key map for NORMAL mode can be viewed here:
      https://github.com/sminez/ad/blob/develop/src/mode/normal.rs

    To return to NORMAL mode from any other mode, press Escape.

  INSERT mode
    For the most part, key presses in INSERT mode will directly insert and remove text from
    current buffer at the current cursor position. There are also some convenience bindings
    for quickly jumping to the start and end of the current line as well as support for using
    Alt-h/j/k/l to move the cursor while simultaneously returning to NORMAL mode.

    The default key map for INSERT mode can be viewed here:
      https://github.com/sminez/ad/blob/develop/src/mode/insert.rs

    To enter INSERT mode from NORMAL mode,
      press "i" to keep the cursor at its current position
      press "a" to place the cursor one character after its current position
      press "I" to place the cursor at the start of the current line
      press "A" to place the cursor at the end of the current line 

  COMMAND mode
    This is a special mode that focuses the status line instead of the active buffer, allowing
    you to execute built in editor commands. For the list of supported commands please refer
    to the "Running Built In Commands" section below.

    To enter COMMAND mode from NORMAL mode, type ":"

  RUN mode
    Another special mode that focuses the status line. In this mode you are able to execute
    external commands as if you had typed them at a shell prompt. Standard output and error
    from commands run in this way will be redirected to a buffer named "$DIR/+output" where
    "$DIR" is the directory containing the active buffer.

    You can place scripts and binaries that you wish to execute only from inside of ad within
    the ~/.ad/bin directory which is automatically added to $PATH for all commands executed
    from within the editor.

    To enter RUN mode from NORMAL mode, type "!"

  EDIT mode
    The last special mode is focused around applying structural regular expressions to the
    contents of the current buffer. The "Running Edit Commands" section below provides more
    information on the syntax and functionality of Edit commands and the following links are
    a useful reference for the history behind the concept of structural regular expressions
    and their implementation within the Sam text editor:

    https://doc.cat-v.org/bell_labs/structural_regexps/se.pdf
    https://doc.cat-v.org/bell_labs/sam_lang_tutorial/sam_tut.pdf

    To enter EDIT mode from NORMAL mode, type "."

---

>> Selecting Text

ad is built around the idea of making and refining text selections within a buffer before
applying an editing action to that selection. While you can always move into INSERT mode
and use ad as any other text editor, you will quickly find that you are missing a lot of
what makes ad unique if you don't take the time to learn about selecting text.

Each buffer in ad has an active selection that is known as "dot". This can be a single
character (a "cursor") or a continuous range of characters (a "range"). The current dot
for a given buffer can be set and manipulated in a number of different ways, the most
obvious being through clicking and dragging the mouse or using the arrow keys. However,
there are more advanced ways of manipulating the current dot that can help you to perform
more complex editing and automation tasks once you get the hang of them.

  Extending and Setting Dot
    The first and most commonly used way of altering your selection within a buffer is to
    use the built-in NORMAL mode key bindings. As a general rule, lowercase keys will *set*
    the current dot and uppercase keys will *extend* it. For example, j/k moves up and down
    lines while J/K starts and extends a selection up or down one line from the current
    active cursor position.
    
    See the "Keybindings" section for all of the available actions.

  Selecting Within Delimiters
    You can quickly select text within matching delimiters by using Alt-i followed by the
    delimiter character. For example, Alt-i " will select the text within the nearest pair
    of double quotes, and Alt-i ( will select the text within the nearest pair of parentheses.

    The following delimiters are supported: ( ) [ ] { } < > " ' /

  "Smart" expansion
    Pressing "*" in NORMAL mode while dot is a cursor will attempt to smart-expand to select
    the filepath, URL or word under that cursor. This is a best-effort convenience that is
    typically then followed by loading or executing that selection rather than being used in
    conjunction with other dot manipulation techniques.

  Flipping and Collapsing Ranges
    When you have a range dot you will notice that you still have a visual marker for the
    cursor at one end of your selection. This is your "active" cursor, and it is where all
    actions that extend or set the current dot are applied. If you want to instead work with
    the other end of your selected range you can press ";" in NORMAL mode to flip which
    cursor is active. (This is particularly useful for refining selections from both ends
    with additional NORMAL mode key bindings for extending dot).

    If instead you want to quickly collapse a range down to a single cursor, you can press ","
    to collapse to the start of the selection or Alt-, to collapse to the end.

  Edit Mode and Structural Regular Expressions
    ad contains a powerful editing language known as "structural regular expressions" that is
    exposed through its EDIT mode. See the "Running Edit Commands" section for details on how
    this works and how it can be used to both manipulate dot and directly apply editing actions.

---

>> Loading Text

Along with "Executing" text, the idea of "Loading" text is taken from the Plan 9 text editor
acme as a way of providing a form of programmable hyperlinking within arbitrary text files.
Unlike HTML links where the target of the link is defined within the source text, ad Loading
makes use of centrally defined "plumbing" rules in order to determine what the outcome of a
given Load should be.

To "Load" text, highlight the text you wish to Load and hit Enter from within NORMAL mode.
Alternatively, right clicking the mouse within your current selection will work in any mode.
If your current selection is a single character cursor, Loading will first expand to the
surrounding word, filepath or URL before attempting to interpret the selected text.

By default, if no rules are matched then a Load of a file path is defined to be opening that
file within ad and a Load of any other text will search for the next occurrence of that text
within the current buffer. Rules are defined in ~/.ad/plumbing.rules with the default ruleset
being viewable here:

  https://github.com/sminez/ad/blob/develop/data/plumbing.rules


The structure of the 'plumbing.rules' file is as follows:

  Comments
    Any line beginning with a '#' is a comment and is ignored when parsing the file.

  Variable declarations
    At the top of the file you may have any number of 'var = value' lines that declare a
    variable that may be used as '$var' in the rest of your rules file. Variables declared
    in this way are replaced when the rules file is parsed. When a message is being processed
    by your rules, there are several built in variables that are always available:

      $0     The result of the most recent 'matches' pattern ($1, $2, ... for submatches)
      $src   The 'src' field of the message being processed
      $dst   The 'dst' field of the message being processed
      $wdir  The 'wdir' field of the message being processed
      $data  The 'data' field of the message being processed
      $file  The matched file name from a successful 'isfile' pattern
      $dir   The matched directory name from a successful 'isdir' pattern

  Rule sets
    After any variable declarations your rules file consists of one or more rule blocks that
    define a set of patterns that must hold for an incoming message in order for the paired
    action to be run. Every rule set must contain at least one pattern and one action. Rule
    sets are terminated by a blank line or end of file.

  Patterns
    The following pattern lines are supported as part of a Rule set:

      $field is $value    If the specified field exactly matches the given value, then
                          the rule matches.

      arg isfile $value   If the given value is a valid file path for an existing file
                          then the rule matches.

      arg isdir $value    If the given value is a valid directory path for an existing
                          file then the rule matches.

      $field matches $re  If the specified field matches the provided regex then the
                          rule matches. (You must specify ^$ anchors to match against
                          the full contents of the field if that is what you want)

      data narrows $re    If the provided regex matches the message's data field at the
                          offset specified by its cur field (defaulting to 0) then data
                          is replaced with that match.

      data from $cmd      Replaces the current contents of 'data' with the stdout of
                          the provided shell command.

      $field set $value   Replace the specified field with a new value.

      attr add $attr=$val Set or replace the $attr attribute on the message. Multiple
                          attributes may be set at once in a single 'attr add' line if
                          desired. Message attributes are ignored by the plumber but
                          can be used to pass additional information to the program that
                          receives the resulting plumbing message from a 'plumb to' action.
                          For ad, the following attributes are currently supported:

                            action=showdata  causes ad to open a new window showing a
                                             virtual buffer containing the contents of
                                             the 'data' field.
                            filename=$fname  sets the file name of a virtual buffer
                                             opened using 'showdata' (defaults to
                                             '+plumbing-message' if not set).
                            addr=$addr       parses $addr as an Edit Command address
                                             and sets the current dot to that range
                                             after opening 'data' as a new file.

      attr delete $attr   Delete the $attr attribute from the message.

  Actions
    The following actions are supported as part of a Rule set:

      plumb to $port      Send the message to the specified port for handling by the
                          program listening on it. Currently only the 'edit' port is
                          supported where plumbed messages will be handled internally
                          by ad itself.
      plumb start $cmd    Discard the message and run the provided shell command instead.
                          Typically this is used with variables to control how a command
                          is executed (such as opening a picture in an image viewer, or
                          a URL in a browser). 

---

>> Executing Text

Executing text within ad is a way of running both built in and external commands by name
from within a buffer. ad will prefer internal commands over external ones in the event of
duplicate command names. Standard output and error from commands run in this way will be
redirected to a buffer named "$DIR/+output" where "$DIR" is the directory containing the
active buffer.

To "Execute" text, highlight the text you wish to Execute and hit "@" from within NORMAL
mode. Alternatively, middle clicking the mouse within your current selection will work in
any mode. If your current selection is a single character cursor, Loading will first
expand to the surrounding whitespace delimited word before attempting to interpret the
selected text.

If the selection being executed begins with a "<" character then the output of running
the command will replace the selection within the buffer it was executed in rather than
being redirected to a +output buffer.

  <date

---

>> Key Bindings

The following key bindings are built into ad. You can specify additional key bindings as
part of your config file under the [keys.normal] and [keys.insert] sections like so:

    [keys.normal]
    # Window & Column management
    "<space> w /" = { run = "new-column" }
    "<space> w -" = { run = "new-window" }
    "<space> w h" = { run = "prev-column" }
    "<space> w j" = { run = "next-window" }
    "<space> w k" = { run = "prev-window" }
    "<space> w l" = { run = "next-column" }

    [keys.insert]
    # Custom escape sequence to return to normal mode
    "f d" = { send_keys = "<esc>" }

Any key bindings that you specify need to be distinct from the ones shown below in the
default key maps.

{{KEY_BINDINGS}}

---

>> Mouse Interactions

ad supports using the mouse for navigation, selection and interaction with text. The mouse
bindings are inspired by those found in the acme text editor from Plan 9, providing a
consistent way to Load and Execute text alongside the keyboard shortcuts described in the
previous section.

  Left Click
    The left mouse button is used to select text. A single click positions the cursor, and a
    drag will select a continuous range of text (as you would expect from pretty much any text
    editor you have used previously). Double clicking will expand to select the word you are
    clicking inside of, or if you click just inside of a standard delimiter as shown below,
    expand to contain all of the text within the delimiters.

      "Double click just after the opening quote or before the closing one"
      (same for parentheses) [and brackets] {and curly brackets} <and angle brackets>

    Double clicking at the start or end of a line will select the entire line.

  Right Click
    The right mouse button is used for Loading text (see the "Loading Text" section for
    more details). Right clicking will Load the text at the current cursor position after
    first expanding to a word, file path or URL if the cursor is not already part of a
    selection. If you click and drag with the right button held down you will Load the
    selected range when you release the button.

  Middle Click
    The middle mouse button is used for Executing text (see the "Executing Text" section for
    more details). Middle clicking will Execute the text under the current cursor position,
    after first expanding to a whitespace delimited word if the cursor is not already
    part of a selection. If you click and drag with the middle button held down you will
    Execute the selected range when you release the button.

You can also use the mouse to resize windows and columns by clicking and dragging on the
border between them. This allows you to quickly adjust your layout without having to run
the resize commands described in the "Running Built In Commands" section.

---

>> The Minibuffer

The minibuffer is ad's interactive selection interface. It is presented at the bottom of
the screen whenever you need to select from a list of options (such as searching within a
buffer, selecting a file to open or reviewing LSP diagnostics).

When the minibuffer is visible you can use the up and down arrow keys (or Alt-j/k) to move
the highlighted line up and down through the available options. Pressing Enter will select
the currently highlighted line and apply the associated action based on the mode that opened
the minibuffer. Pressing Escape will cancel the operation and close the minibuffer without
making a selection.

Try pressing the "/" key in normal mode to fuzzy search through the contents of the active
buffer. Hitting enter will jump you to that line within the buffer.

The number of lines displayed in the minibuffer can be configured by setting the
'minibuffer_lines' property in your config.toml file (see the "Configuration" section for
more details). The default is to show up to 8 lines at a time.

---

>> Windows and Columns

The ad user interface is inspired by the acme text editor and is made up of a array of
columns, each containing one or more windows that are arranged vertically one above the
other. This setup doesn't support arbitrary arrangements of windows but it is more than
sufficient for arranging multiple buffers alongside one another for editing.

Windows in the UI layout are permitted to contain any open buffer within the editor, allowing
you to have multiple copies of the same buffer side by side in order to view different parts
of the file at once.

  Creating Windows and Columns
    You can create a new window within the current column by running the 'new-window' command,
    which will clone the current window and place it at the end of the column. Similarly, the
    'new-column' command will create a new column containing a clone of the current window. See
    the "Running Built In Commands" section for the full list of available commands.

  Navigating Between Windows and Columns
    In NORMAL mode you can use Alt-w/a/s/d to move focus between open windows.

  Moving Windows Around
    In NORMAL mode you can use Alt-W/A/S/D to drag the focused window between columns and within
    the column it is currently in.

    You can move the currently focused window by holding down Alt and pressing W, A, S or D to
    drag it up, left, down or right respectively. Moving a window left or right will move it to
    the adjacent column, while moving it up or down will swap it with the window above or below.

  Resizing
    Windows and columns can be resized either by clicking and dragging on the border between
    them with the mouse (see the "Mouse Interactions" section) or by using the 'resize-window'
    and 'resize-column' commands. The 'balance-all', 'balance-column', 'balance-columns' and
    'balance-windows' commands can be used to reset windows and columns to equal sizes.

  Closing Windows and Columns
    The 'delete-window' and 'delete-column' commands (along with their forced variants) can be
    used to close windows and columns. If you close the last window displaying a buffer with
    unsaved changes you will be prompted to save before the window is closed.

See the "Key Bindings" section for details of available shortcuts for running some of the more
common layout manipulation commands.

---

>> Virtual Buffers

In addition to buffers that are backed by files on disk, ad makes use of several virtual
buffers that exist only within the editor. Typically the name for these buffers start with
a "+" character but that is simply a naming convention.

  +scratch
    The scratch buffer is a place for you to quickly write and run commands or keep notes.
    You can toggle the scratch buffer open and closed by pressing Alt-; in either NORMAL or
    INSERT mode. Commands executed from the scratch buffer act as if they were executed from
    within the currently active buffer.

  +output
    When you run external commands from within ad (either using RUN mode or by Executing text),
    the standard output and error from those commands will be redirected to an output buffer
    named after the directory containing the active buffer. For example, if you run a command
    while editing a file in /home/innes/example/hello.txt, the output will be written to a buffer
    named '/home/innes/example/+output'.

  +help
    The built-in help documentation (this file!) is displayed in a buffer named '+help' when you
    run the 'help' command.

  +logs
    Internal editor logs can be viewed by running the 'view-logs' command or pressing Alt-= in
    NORMAL mode. This can be useful for debugging issues with your config files and the editor
    itself. You can increase the verbosity of the logs by setting the AD_LOG environment variable
    to "debug" or "trace".

  NOTE: Unlike file-backed buffers, virtual buffers are not saved to disk and their contents
        will be lost when you close the editor unless you explicitly save them to a file.

---

>> The Jump List

ad maintains a "jump list" that tracks your navigation history as you move between buffers.
The jump list automatically records your position whenever you set the buffer Dot via a
command (such as searching or switching buffers) or make an edit to a buffer. Navigating
back through the jump list and then making further edits will clear any "stale" entries
that are now invalid beyond that point in the list.

To make use of the jump list, you need to be in NORMAL mode. From there, you can press
Alt-[ or Ctrl-o to move backwards through the list, and Alt-] or Ctrl-i to move forward.

---

>> Running Built In Commands

The following commands are all built into ad and are runnable via the COMMAND mode
which can be opened using the ":" key from NORMAL mode. Each of the commands can also
be executed directly from any buffer (including this one) or written as a command
string to the "ctl" file in the filesystem interface.

{{BUILT_IN_COMMANDS}}

---

>> Running External Commands

All commands available on the user's $PATH are executable from within ad in addition to anything
located in the ~/.ad/bin directory. The $bufid environment variable will be set to the id of the
buffer that the command was run from (the active buffer if run from RUN mode) and the working
directory will be set to the directory containing the active buffer. Output from running commands
is redirected to the appropriate +output buffer as described in the "Virtual Buffers" section.

  Managing Running Processes
    When you execute external commands from within ad, those commands run as child processes
    of the editor. If you need to terminate a long-running command, you can use the 'kill'
    command from COMMAND mode which will present you with a list of currently running processes
    in the minibuffer. Select the process you wish to terminate and press Enter to send it a
    SIGTERM signal.

---

>> Running Edit Commands

ad supports running a form of the structural regular expression syntax first introduced in the
Sam text editor as part of the Plan 9 operating system. The current supported syntax covers most
use cases but it does not include some of the features found within Sam and Acme. Editing
expressions are composed of an optional "address" (defaulting to the current buffer Dot) followed
by a chain of operators, ending in an action.

The following operators are supported by the engine:

  n/re/                  narrow to the first match of re
  x/re/                  extract all matches of re
  y/re/                  extract between matches of re ("split on re")
  g/re/                  require re to match
  v/re/                  require re to not match

The following actions are supported by the engine:

  i/template/            template and insert before match
  a/template/            template and insert after match
  c/template/            template and replace match
  p/template/            template and print print

  d                      delete match

Templating supports injecting the contents of the full match and submatches via '{n}' variable
references, with '{0}' denoting the full match and '{1}' denoting the first submatch etc. It
is also possible to reference '{FILENAME}', '{ROW}' and '{COL}' which will have their values
set by the location of the match being templated.

---

>> The Filesystem Interface

ad uses the 9p protocol to present a virtual filesystem interface as an API for extending
the functionality of the editor, allowing you to read and manipulate the state of the editor
using any language you wish.

  http://man.cat-v.org/plan_9/5/

ad itself can be used as a simple 9p client to explore the filesystem (run 'ad --help' in
your terminal for details of each of the available commands):

  $ ad -9p ls ad
  log                # read only log of events in the editor
  minibuffer         # control file for selecting text using the minibuffer
  scratch            # control file for reading and appending to the scratch buffer
  ctl                # control file for issuing commands to ad
  buffers            # directory of control files for open buffers

  $ ad -9p ls ad/buffers
  1                  # directory of control files for buffer id=1
  current            # the id of the current buffer
  index              # a line per open buffer in the format 'id\tpath'

  $ ad -9p ls ad/buffers/1
  addr               # the row:col,row:col address of the current buffer dot
  body               # the string content of the buffer
  dot                # the currently selected text within the buffer
  event              # control file for intercepting user input events to the buffer
  filename           # the current filename for the buffer
  filetype           # the filetype used by ad for this buffer (as set in your config.toml)
  output             # output from stdout/err of commands run within the buffer
  xaddr              # the row:col,row:col address of the current buffer xdot
  xdot               # the currently selected xdot content

If you have the fusermount(1) and 9pfuse(4) programs installed then you can set the "auto_mount"
property in ~/.ad/config.toml to true and mount the filesystem directly at ~/.ad/mnt when ad starts.
The default scripts provided in the ad GitHub repo serve as a useful reference for the sorts of
interactions that are possible through this interface:

  https://github.com/sminez/ad/tree/develop/data/bin
  https://github.com/sminez/ad/blob/develop/data/lib/ad.sh

---

>> LSP support

ad has minimal support for the Language Server Protocol for the pieces of functionality that fit
within the feature set of the editor itself. See the "Running Built In Commands" section for
details of which features are supported.

Configuration of LSP servers is currently supported through the '[[languages]]' section of your
config.toml configuration file. There you may specify the command to run to start the language
server along with any arguments that need to be passed and a list of files that should be searched
for in parent directories in order to determine the root of the project.

Example config.toml section:
  [[languages]]
  name = "rust"
  extensions = ["rs"]
  lsp.command = "rust-analyzer"
  lsp.args = []
  lsp.roots = ["Cargo.toml"]


By default, ad will automatically start an available LSP server if one is configured when
documents are opened. To prevent this behaviour you can set the `lsp_autostart` property
of your main editor config to false:

[editor]
lsp_autostart = false

---

>> Syntax Highlighting

ad supports syntax highlighting via tree-sitter. In order to enable syntax highlighting for a given
filetype you will need to ensure that you have:

  - a compiled '$ftype.so' file in your configured 'parser_dir' directory
  - a 'highlights.scm' file for that filetype in your configured 'syntax_query_dir' directory.
  - a '[filetypes]' entry for the filetype in your 'config.toml'


Example config.toml sections:
  [tree_sitter]
  parser_dir = "~/.ad/tree-sitter/parsers"
  syntax_query_dir = "~/.ad/tree-sitter/queries"

  [filetypes.rust]
  extensions = ["rs"]
  first_lines = []


Example directory structure and contents:

  ~/.ad/tree-sitter
    ├── parsers
    │    └── rust.so
    └── queries
        └── rust
           └── highlights.scm


For additional information on how to write tree-sitter queries see the official documentation here:
  https://tree-sitter.github.io/tree-sitter/syntax-highlighting#queries

For a quick way of re-using parsers and queries from neovim, see the following from the nvim-treesitter
project:
  https://github.com/nvim-treesitter/nvim-treesitter/blob/master/lua/nvim-treesitter/parsers.lua
  https://github.com/nvim-treesitter/nvim-treesitter/tree/master/queries

---

>> Debugging and Troubleshooting

ad provides several commands and key bindings for inspecting the internal state of the editor
and debugging issues with your configuration or the editor itself.

  Viewing Internal Logs
    You can view the internal editor logs by running the 'view-logs' command from COMMAND mode
    or by pressing Alt-= in NORMAL mode. This will open a buffer named '+logs' containing log
    messages from the editor.

    The verbosity of the logs can be increased by setting the AD_LOG environment variable to
    "debug" or "trace" before starting ad. This can be useful when tracking down issues with
    configuration files or unexpected behavior.

  Viewing the Edit Log
    The edit log tracks all changes made to the current buffer as a series of transactions.
    You can view this log by pressing Alt-# in NORMAL mode, which can help you understand the
    undo/redo history and diagnose issues with editing operations.

  Tree-Sitter Parse Trees
    If you have tree-sitter syntax highlighting enabled for the current buffer, you can view
    the parse tree by running the 'ts-show-tree' command. This will open a buffer showing the
    hierarchical structure of the parsed syntax tree, which can be useful for debugging syntax
    highlighting issues or understanding how tree-sitter is interpreting your code.

---