Skip to documentation
SLOP

tiny.smg.command.search

Reference tiny.smg command search

Defined in command.

API (5)

Actions

Public operations.

No direct callersNo direct callscommandsearch
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callerscli.optionspositionalcli.outputwriteClickUsageErrorcli.outputwriteOutFmtcommand.searchindex
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallsNo direct callerscli.optionsflagValuecli.optionshasFlagcli.optionshasJsoncli.optionspositionalcli.optionssearchLimitValue+6 morecommand.searchrun
Static calls · unresolved targets: 0 · external targets: 5.
Called byCallsNo direct callscommand.searchruntest; no linktools.smg.src.command.searchtest: search renders table and full t...command.searchwriteFull
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallscommand.searchruncli.outputwriteOutcommand.searchwriteJson
Static calls · unresolved targets: 1 · external targets: 10.
Called byCallscommand.searchruntest; no linktools.smg.src.command.searchtest: search renders table and full t...private sourcelib.markdown.src.tableappendRowcommand.searchwriteTable
Static calls · unresolved targets: 1 · external targets: 4.

Source: tools/smg/src/command/root.zig:20

zig
pub const search = @import("search.zig");

Source: tools/smg/src/command/search.zig

zig
const std = @import("std");const pretty_json = @import("pretty").json;const smg = @import("../root.zig");const options = smg.cli.options;const output = smg.cli.output;const search_mod = smg.search;const session = smg.command.session;const storage = smg.storage;const table = smg.cli.table;const validation = smg.cli.validation;pub fn run(allocator: std.mem.Allocator, _: std.mem.Allocator, args: []const []const u8, limits: smg.Limits, boundary: session.PhaseBoundary) !u8 {    const pos = try options.positional(allocator, args);    if (pos.len < 1) return error.MissingArgument;    const root = try storage.requireRoot(allocator);    try session.noteGraphAge(allocator, root);    const kind = options.flagValue(args, "--kind");    const limit = options.searchLimitValue(args);    const result = search_mod.searchStored(        allocator,        root,        pos[0],        kind,        limit,        limits.storage,    ) catch |err| switch (err) {        search_mod.Error.InvalidSearchQuery => {            try output.writeErrFmt(allocator, "Error: invalid search query: '{s}'\n", .{pos[0]});            return 2;        },        else => return err,    };    boundary.seal();    defer boundary.beginTeardown();    if (options.hasJson(args)) return try writeJson(allocator, result, limit);    if (result.hits.len == 0) return try output.writeOut("No results.\n");    var out: std.Io.Writer.Allocating = .init(allocator);    if (options.hasFlag(args, "--full")) {        try writeFull(allocator, &out.writer, result);    } else {        try writeTable(allocator, &out.writer, result);    }    return try output.writeOut(out.written());}pub fn index(allocator: std.mem.Allocator, phases: std.mem.Allocator, args: []const []const u8, limits: smg.Limits) !u8 {    if (try validation.rejectUnexpectedOptionsPlain(allocator, "index", "[OPTIONS]", args, &.{})) return 2;    const pos = try options.positional(allocator, args);    if (pos.len != 0) {        try output.writeClickUsageError(allocator, "index", "[OPTIONS]", try validation.unexpectedArgumentMessage(allocator, pos));        return 2;    }    const root = try storage.requireRoot(allocator);    const count = try search_mod.rebuildStored(phases, root, limits);    return try output.writeOutFmt(allocator, "Indexed {d} nodes into search cache\n", .{count});}pub fn writeJson(allocator: std.mem.Allocator, result: search_mod.Result, limit: i64) !u8 {    var out: std.Io.Writer.Allocating = .init(allocator);    var writer = pretty_json.Writer.init(&out.writer, .minified);    try writer.beginObject();    try writer.objectField("rows");    try writer.beginArray();    for (result.hits) |hit| {        try writer.beginObject();        try writer.objectField("rank");        try writer.write(hit.rank);        try writer.objectField("kind");        try writer.write(hit.kind);        try writer.objectField("name");        try writer.write(hit.name);        try writer.objectField("location");        try writer.write(try search_mod.location(allocator, hit));        try writer.objectField("snippet");        try writer.write(search_mod.snippet(hit));        try writer.endObject();    }    try writer.endArray();    try writer.objectField("total");    try writer.write(result.total);    try writer.objectField("displayed");    try writer.write(result.hits.len);    try writer.objectField("truncated");    try writer.write(result.total > @as(i64, @intCast(result.hits.len)));    try writer.objectField("limit");    try writer.write(limit);    try writer.endObject();    try out.writer.writeByte('\n');    return try output.writeOut(out.written());}pub fn writeTable(allocator: std.mem.Allocator, writer: *std.Io.Writer, result: search_mod.Result) !void {    const columns = [_]table.Column{        .{ .header = "rank", .alignment = .right, .max_width = 6 },        .{ .header = "kind", .max_width = 12 },        .{ .header = "name", .max_width = 40 },        .{ .header = "location", .max_width = 30 },        .{ .header = "snippet", .max_width = 40 },    };    var scratch_state = std.heap.ArenaAllocator.init(allocator);    defer scratch_state.deinit();    const scratch = scratch_state.allocator();    var rows: std.ArrayList([]const []const u8) = .empty;    for (result.hits) |hit| {        try table.appendRow(scratch, &rows, &.{            try std.fmt.allocPrint(scratch, "{d}", .{hit.rank}),            hit.kind,            hit.name,            try search_mod.location(scratch, hit),            search_mod.snippet(hit),        });    }    const total = if (result.total > 0) @as(usize, @intCast(result.total)) else result.hits.len;    try table.write(allocator, writer, &columns, rows.items, total);}pub fn writeFull(allocator: std.mem.Allocator, writer: *std.Io.Writer, result: search_mod.Result) !void {    for (result.hits) |hit| {        try writer.print("{d}. [{s}] {s}\n", .{ hit.rank, hit.kind, hit.name });        try writer.print("   {s}\n", .{try search_mod.location(allocator, hit)});        if (hit.docstring) |doc| {            if (doc.len != 0) {                var lines = std.mem.splitScalar(u8, doc, '\n');                var count: usize = 0;                while (count < 5) : (count += 1) {                    const line = lines.next() orelse break;                    try writer.print("   {s}\n", .{line});                }            }        }        try writer.writeByte('\n');    }    if (result.total > @as(i64, @intCast(result.hits.len))) try writer.print("(showing {d} of {d} -- use --limit 0 for all, --json for exact records)\n", .{ result.hits.len, result.total });}test "search renders table and full text" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    const hits = [_]search_mod.Hit{        .{            .rank = 1,            .name = "app.handler",            .kind = "function",            .file = "src/app.py",            .line_start = 12,            .line_end = 14,            .docstring = "first line\nsecond line",            .score = 10,        },        .{            .rank = 2,            .name = "app.module",            .kind = "module",            .file = null,            .line_start = null,            .line_end = null,            .docstring = null,            .score = 5,        },    };    const result: search_mod.Result = .{ .hits = &hits, .total = 3 };    var table_out: std.Io.Writer.Allocating = .init(allocator);    try writeTable(allocator, &table_out.writer, result);    try std.testing.expect(std.mem.indexOf(u8, table_out.written(), "rank") != null);    try std.testing.expect(std.mem.indexOf(u8, table_out.written(), "app.handler") != null);    try std.testing.expect(std.mem.indexOf(u8, table_out.written(), "src/app.py:12") != null);    try std.testing.expect(std.mem.indexOf(u8, table_out.written(), "first line") != null);    try std.testing.expect(std.mem.indexOf(u8, table_out.written(), "showing 2 of 3") != null);    var full_out: std.Io.Writer.Allocating = .init(allocator);    try writeFull(allocator, &full_out.writer, result);    try std.testing.expect(std.mem.indexOf(u8, full_out.written(), "1. [function] app.handler\n") != null);    try std.testing.expect(std.mem.indexOf(u8, full_out.written(), "   src/app.py:12\n") != null);    try std.testing.expect(std.mem.indexOf(u8, full_out.written(), "   first line\n") != null);    try std.testing.expect(std.mem.indexOf(u8, full_out.written(), "(showing 2 of 3 -- use --limit 0 for all, --json for exact records)\n") != null);}

Complete call list for command.search.run

11 direct calls.

Audit

Definitions6
Public names6
Members0
Version26.7.0
Revisiondaab053ee433