Closed sminez closed 2 months ago
On the subject of +errors
buffers: I've never liked that acme calls it this when it contains the output of any and all external programs run within the editor (most of which is not errors), so something like +output
might be better. I do like the idea of combining things per directory though as it means there are less virtual buffers clogging up the buffer list. If that's the way I end up going then it's probably a good idea to include them in fsys as aliases and update the Buffers
struct to also track +output
buffers so they can be opened nicely.
The current single-window setup is going to quickly become annoying with this for helper programs like test loops so it might be a good idea to sort out #9 first.
Rather than follow the event format and semantics of acme exactly I'm initially planning on having a simpler structure like this (so omitting the various flags acme provides around what it thinks about the event in question):
# Source Kind Start End Content (up to some max number of characters, 256 in acme)
K I 14 16 foo
M X 0 9 git status
From my experience with working with the Acme API, it only prevents mouse events from being handled in the body without being handed back (the man page explain the behaviour but without trying things out by hand its a little hard to fully understand the semantics. Not being able to capture and prevent keyboard input was annoying when I was trying to get keyboard shortcuts working but I'm handling that differently in ad already. Instead I think having the event file simply being:
for both the mouse and keyboard, with intercepted events being dropped by ad unless they are passed back (minus the text) is a good starting point. The ctl
file already allows for executing commands within the editor using [!><]$command
which replaces the thing I used to do of spoofing a click in the tag and modal editing plus defining your own keybindings means that you don't need to worry about using the event file for implementing custom keybindings.
Something like the following is the structure I'm thinking of for the internal data for the events file:
macro_rules! impl_charconv {
($name:ident, $($variant:ident <=> $ch:expr,)+) => {
impl $name {
fn to_char(&self) -> char {
match self {
$($name::$variant => $ch,)+
}
}
fn try_from_char(ch: char) -> Option<Self> {
match ch {
$($ch => Some($name::$variant),)+
_ => None,
}
}
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum Source {
Keyboard,
Mouse,
Fsys,
// acme makes a distinction between direct writes to /body and /tag vs
// text entering the buffer via one of the other fsys files but I'm not
// sure if I need that initially? As and when it looks useful I can add it.
}
impl_charconv! {
Source,
Keyboard <=> 'K',
Mouse <=> 'M',
Fsys <=> 'F',
}
#[derive(Debug, PartialEq, Eq)]
pub enum Kind {
InsertBody,
DeleteBody,
ExecuteBody,
LoadBody,
InsertTag,
DeleteTag,
ExecuteTag,
LoadTag,
}
impl_charconv! {
Kind,
InsertBody <=> 'I',
DeleteBody <=> 'D',
ExecuteBody <=> 'X',
LoadBody <=> 'L',
InsertTag <=> 'i',
DeleteTag <=> 'd',
ExecuteTag <=> 'x',
LoadTag <=> 'l',
}
#[derive(Debug, PartialEq, Eq)]
pub struct Event {
source: Source,
kind: Kind,
from: usize,
to: usize,
txt: String,
}
Implemented as of ceeccbf448f5efe8889c19a8c3267f7a5f77895c
Scripts like the following are now possible:
#!/usr/bin/env bash
# A simple ad helper script to lint Rust files on change
clearBuffer() {
echo -n "," | 9p write "ad/buffers/$1/xaddr"
echo -n "" | 9p write "ad/buffers/$1/xdot"
}
updateCargoOutput() {
clearBuffer "$1"
output="$(cargo check --message-format=short 2>&1)"
echo -n "$output" | 9p write "ad/buffers/$1/body"
echo -n "mark-clean $1" | 9p write ad/ctl
if [[ "$output" =~ "error" ]]; then
echo -n "buffer $1" | 9p write ad/ctl
echo -n 'Edit x/.*/ s/(.+):(\d+):\d+:/$1:$2/' | 9p write ad/ctl
fi
}
# Open the +cargo output buffer (would really need to track multiple?)
CURRENT_ID="$(9p read ad/buffers/current | cut -f1)"
echo -n "open +cargo" | 9p write ad/ctl
echo -n "buffer $CURRENT_ID" | 9p write ad/ctl
ID="$(9p read ad/buffers/index | grep "+cargo" | cut -f1)"
9p read ad/log | while read -r line; do
action="$(echo "$line" | cut -d' ' -f2)"
if [ "$action" = "save" ]; then
updateCargoOutput "$ID"
fi
done
The filesystem interface supports a decent subset of the functionality provided by acme but it is currently missing several important elements:
+errors
style virtual buffers for displaying output associated with the given buffer.In addition to this, I'd like to expose more functionality of the editor through the filesystem in order to make writing programs that interact with
ad
richer. As a starting point, being able to use the mini-buffer like dmenu would be interesting to look into.See http://man.cat-v.org/plan_9/4/acme for the man page on the acme filesystem