summaryrefslogtreecommitdiff
path: root/src/builtins.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/builtins.zig')
-rw-r--r--src/builtins.zig44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index 4d257a9e..edeb7ac8 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -38,6 +38,29 @@ pub const capabilities: config.Runtime.Capabilities = .{
/// ctl; pardes's root `ctl` takes the session builtins and a pane's `ctl`
/// the pane ones. A builtin says `pub const scope: Scope = .session;`,
/// and every setting is one; the rest act on their pane.
+/// The kinds of pane a builtin may be for alone (registry.needs).
+pub const PaneKind = enum {
+ terminal,
+ pdf,
+ image,
+
+ pub fn has(kind: PaneKind, pane: *const panes.Pane) bool {
+ return switch (kind) {
+ .terminal => pane.isTerminal(),
+ .pdf => pane.hasPdf(),
+ .image => pane.image != null,
+ };
+ }
+
+ pub fn noun(kind: PaneKind) []const u8 {
+ return switch (kind) {
+ .terminal => "a terminal",
+ .pdf => "a PDF",
+ .image => "an image",
+ };
+ }
+};
+
pub const Scope = enum { pane, session };
pub const Ctx = struct {
@@ -181,6 +204,15 @@ pub const registry = struct {
/// `Msg`, a setting's value), or would ask for it at a prompt (`Find`):
/// a ctl refuses it bare before any line of the write runs. A builtin
/// says `pub const requires_arg = true;` beside `takes_arg`.
+ /// The one kind of pane a builtin means something on, or null for any:
+ /// it says `pub const needs: PaneKind = .terminal;`, and on any other
+ /// pane it is refused (exec.runBuiltinFrom), as Repl and Edit are.
+ pub fn needs(b: Builtin()) ?PaneKind {
+ inline for (manualBuiltinList(), 0..) |T, i|
+ if (@intFromEnum(b) == i) return if (@hasDecl(T, "needs")) T.needs else null;
+ return null;
+ }
+
pub fn requiresArg(b: Builtin()) bool {
inline for (manualBuiltinList(), 0..) |T, i|
if (@intFromEnum(b) == i) return @hasDecl(T, "requires_arg") and T.requires_arg;
@@ -869,7 +901,7 @@ pub const TreeContext = struct {
pub fn run(c: Ctx) void {
if (comptime !enabled) unreachable;
- if (!panes.File.supportsContext(c.pane)) return;
+ if (!panes.File.supportsContext(c.pane)) return c.p.reportFailure(c.id, "TreeContext: only a source file the parser knows has context");
const file = &c.pane.file.?;
const arg = std.mem.trim(u8, c.arg orelse "", " \t\r\n");
const on = if (arg.len == 0) !file.tree_context else if (std.mem.eql(u8, arg, "on")) true else if (std.mem.eql(u8, arg, "off")) false else {
@@ -889,6 +921,7 @@ pub const TreeContext = struct {
/// Fit the PDF page to the pane by width or by height, flipping between them.
pub const PdfFit = struct {
+ pub const needs: PaneKind = .pdf;
pub const enabled = pardes.pdf_enabled;
pub fn run(c: Ctx) void {
if (comptime enabled) apply(c) else unreachable;
@@ -900,6 +933,7 @@ pub const PdfFit = struct {
/// Tint the PDF page to the theme, or show it as printed, flipping between them.
pub const PdfTint = struct {
+ pub const needs: PaneKind = .pdf;
pub const enabled = pardes.pdf_enabled;
pub fn run(c: Ctx) void {
if (comptime enabled) apply(c) else unreachable;
@@ -911,6 +945,7 @@ pub const PdfTint = struct {
/// List the PDF's sections in a pane, each a place to go.
pub const PdfSections = struct {
+ pub const needs: PaneKind = .pdf;
pub const output: OutputTraits = .{ .name = config.pdf_sections_buffer, .steps = true, .locations = true };
pub const enabled = pardes.pdf_enabled;
pub fn run(c: Ctx) void {
@@ -923,6 +958,7 @@ pub const PdfSections = struct {
/// glyph art over the host's pixels
pub const Petscii = struct {
+ pub const needs: PaneKind = .image;
pub fn run(c: Ctx) void {
if (c.pane.image) |*state| panes.Image.toggleGlyphArt(state);
}
@@ -930,6 +966,7 @@ pub const Petscii = struct {
/// the C64 palette or the terminal's own 16
pub const Palette = struct {
+ pub const needs: PaneKind = .image;
pub fn run(c: Ctx) void {
if (c.pane.image) |*state| panes.Image.togglePalette(state);
}
@@ -937,6 +974,7 @@ pub const Palette = struct {
/// add the printable ASCII bitmaps to the matcher's glyph set
pub const Ascii = struct {
+ pub const needs: PaneKind = .image;
pub fn run(c: Ctx) void {
if (c.pane.image) |*state| panes.Image.toggleAscii(state);
}
@@ -1057,8 +1095,8 @@ pub const Del = struct {
/// Recolour a terminal's program colours to the theme, or show them as sent, flipping between them.
pub const Filter = struct {
+ pub const needs: PaneKind = .terminal;
pub fn run(c: Ctx) void {
- if (!c.pane.isTerminal()) return;
c.pane.tty_filter = !c.pane.tty_filter;
}
};
@@ -1066,12 +1104,14 @@ pub const Filter = struct {
/// Cycle the pane's input modes: terminals add raw tty mode to normal/insert.
pub const Mode = struct {
pub fn run(c: Ctx) void {
+ if (c.pane.file == null and !c.pane.isTerminal()) return c.p.reportFailure(c.id, "Mode: only a text or terminal pane has modes");
c.p.cycleMode(c.id);
}
};
/// Switch this terminal between raw program input and normal editor mode.
pub const Togglettymode = struct {
+ pub const needs: PaneKind = .terminal;
pub fn run(c: Ctx) void {
c.p.toggleTty(c.id);
}