summaryrefslogtreecommitdiff
path: root/src/main.zig
blob: fd1c30402c0b549bfe4ff59fa5587a5b05dd569a (plain) (blame)
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
pub const Buffer = @import("Buffer.zig");
pub const c = @import("c.zig");
pub const conf = @import("es-config");
pub const Config = @import("Config.zig");
pub const Editor = @import("Editor.zig");
pub const files = @import("files.zig");
pub const Highlight = @import("highlight.zig").Highlight;
pub const Key = @import("key.zig").Key;
pub const KeyMap = @import("KeyMap.zig");
pub const KeyReader = @import("KeyReader.zig");
pub const RawMode = @import("RawMode.zig");
pub const Row = @import("Row.zig");
pub const search = @import("search.zig").search;
pub const StringBuilder = @import("StringBuilder.zig");
pub const Syntax = @import("Syntax.zig");

const builtin = @import("builtin");
const std = @import("std");

const Allocator = std.mem.Allocator;
const File = std.fs.File;
const GPA = std.heap.GeneralPurposeAllocator(.{});

var log_file: ?File = null;

// TODO[zigbug]: Why isn't getpid defined for Darwin?
const getpid = switch (builtin.os.tag) {
    .macos, .ios, .tvos, .watchos => c.getpid,
    else => std.os.system.getpid,
};

pub fn log(
    comptime level: std.log.Level,
    comptime scope: @TypeOf(.EnumLiteral),
    comptime format: []const u8,
    args: anytype,
) void {
    const file = if (log_file) |f| f else std.io.getStdErr();

    const writer = file.writer();

    nosuspend writer.print(
        "[" ++ @tagName(scope) ++ ":" ++ level.asText() ++ "] " ++ format ++ "\n",
        args,
    ) catch return;
}

pub fn main() !void {
    var gpa = GPA{};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const log_file_name = try std.fmt.allocPrint(
        allocator,
        "/tmp/es.{}.log",
        .{getpid()},
    );
    defer {
        std.log.info("Logs in {s}", .{log_file_name});
        allocator.free(log_file_name);
    }

    log_file = try std.fs.createFileAbsolute(
        log_file_name,
        .{ .exclusive = true, .truncate = true },
    );
    defer {
        log_file.?.close();
        log_file = null;
    }

    const raw_mode = try RawMode.init();
    defer raw_mode.deinit();

    var editor = try Editor.init(allocator);
    defer editor.deinit();

    try processCommandLineArgs(allocator, &editor);

    try editor.setStatusMessage("C-x C-s = Save | C-x C-c = Quit | C-s = Search", .{});

    while (!editor.should_exit) {
        try editor.refreshScreen();
        try editor.processKeypress();
    }
}

fn processCommandLineArgs(allocator: Allocator, editor: *Editor) !void {
    const args = try std.process.argsAlloc(allocator);
    defer std.process.argsFree(allocator, args);
    if (args.len <= 1) {
        // Do nothing
    } else if (args.len == 2) {
        try editor.open(args[1]);
    } else {
        std.log.err("What am I to do with {} arguments?", .{args.len});
        return error.CommandLineArgs;
    }
}