Hugo Machet: 2 Rename mode.Mode to mode.UIMode Rename UIMode.nav to UIMode.normal 18 files changed, 166 insertions(+), 168 deletions(-)
nfm/patches/alpine.yml: SUCCESS in 51s [Rename mode.Mode to mode.UIMode][0] v2 from [Hugo Machet][1] [0]: https://lists.sr.ht/~leon_plickat/nfm/patches/37889 [1]: mailto:mail@hmachet.com ✓ #915055 SUCCESS nfm/patches/alpine.yml https://builds.sr.ht/~leon_plickat/job/915055
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~leon_plickat/nfm/patches/37889/mbox | git am -3Learn more about email & git
Rename Context.mode to Context.ui_mode --- src/Context.zig | 124 +++++++++++++++--------------- src/History.zig | 10 +-- src/UserInterface.zig | 20 ++--- src/key-operations/commit.zig | 14 ++-- src/key-operations/config.zig | 16 ++-- src/key-operations/cursor.zig | 30 ++++---- src/key-operations/marks.zig | 14 ++-- src/key-operations/misc.zig | 20 ++--- src/key-operations/user-input.zig | 8 +- src/mode.zig | 3 +- src/system/linux.zig | 4 +- src/view.zig | 4 +- 12 files changed, 133 insertions(+), 134 deletions(-) diff --git a/src/Context.zig b/src/Context.zig index b7409df523ab..4f2342628e43 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -31,7 +31,7 @@ const Config = @import("Config.zig"); const DirMap = @import("DirMap.zig"); const File = @import("File.zig"); const History = @import("History.zig"); -const Mode = @import("mode.zig").Mode; +const UIMode = @import("mode.zig").UIMode; const UserInterface = @import("UserInterface.zig"); const View = @import("view.zig").View; const CommandTokenizer = @import("CommandTokenizer.zig"); @@ -47,7 +47,7 @@ dirmap: DirMap = undefined, initial_cwd_path: []const u8 = undefined, view: View = .nav, -mode: Mode = .nav, +ui_mode: UIMode = .nav, completion_count: ?usize = null, selector_mode: bool = false, dump_cwd: bool = false, @@ -81,23 +81,23 @@ pub fn setCwd(self: *Self, path: []const u8) !void { self.dirmap.setCwd(path) catch |err| { switch (err) { error.DirNameTooLong => { - self.mode.setMessage(.err, "Directory name is too long"); + self.ui_mode.setMessage(.err, "Directory name is too long"); return; }, error.EnvMissingHome => { - self.mode.setMessage(.err, "$HOME is not set"); + self.ui_mode.setMessage(.err, "$HOME is not set"); return; }, error.AccessDenied => { - self.mode.setMessage(.err, "Access Denied"); + self.ui_mode.setMessage(.err, "Access Denied"); return; }, error.FileNotFound => { - self.mode.setMessage(.err, "Unknown directory"); + self.ui_mode.setMessage(.err, "Unknown directory"); return; }, error.NotDir => { - self.mode.setMessage(.err, "Not a directory"); + self.ui_mode.setMessage(.err, "Not a directory"); return; }, else => return err, @@ -133,40 +133,40 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void { var it = CommandTokenizer.from(command); const token = (it.next() catch { - self.mode.setMessage(.err, "Invalid command"); + self.ui_mode.setMessage(.err, "Invalid command"); return; }) orelse { - self.mode.setNav(); + self.ui_mode.setNav(); self.ui.list_dirty = true; return; }; if (mem.eql(u8, token, "cd")) { const arg = (it.next() catch { - self.mode.setMessage(.err, "Invalid command"); + self.ui_mode.setMessage(.err, "Invalid command"); return; }) orelse { - self.mode.setMessage(.err, "'cd' requires an argument"); + self.ui_mode.setMessage(.err, "'cd' requires an argument"); return; }; if (it.next() catch { - self.mode.setMessage(.err, "Invalid command"); + self.ui_mode.setMessage(.err, "Invalid command"); return; }) |_| { - self.mode.setMessage(.err, "too many arguments for 'cd'"); + self.ui_mode.setMessage(.err, "too many arguments for 'cd'"); return; } try self.setCwd(arg); - if (self.mode != .message) self.mode.setNav(); + if (self.ui_mode != .message) self.ui_mode.setNav(); self.ui.list_dirty = true; return; } else if (mem.eql(u8, token, "quit")) { if (it.next() catch { - self.mode.setMessage(.err, "Invalid command"); + self.ui_mode.setMessage(.err, "Invalid command"); return; }) |_| { - self.mode.setMessage(.err, "too many arguments for 'quit'"); + self.ui_mode.setMessage(.err, "too many arguments for 'quit'"); return; } @@ -179,21 +179,21 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void const ret = system.execForeground(command); - self.mode.setNav(); + self.ui_mode.setNav(); try self.ui.start(); ret catch |err| switch (err) { error.KilledBySignal => { - self.mode.setMessage(.err, name ++ " has been killed via signal"); + self.ui_mode.setMessage(.err, name ++ " has been killed via signal"); }, error.NonZeroExit => { // TODO For whatever unholy reason bash and /bin/sh have an exit // status of 1 when exited using `quit` or Ctrl-D. Maybe add // a way to silence these warnings for certain weird programs. - self.mode.setMessage(.err, name ++ " exited with a non-zero exit status"); + self.ui_mode.setMessage(.err, name ++ " exited with a non-zero exit status"); }, error.UnknownCommand => { - self.mode.setMessage(.err, "Unknown command"); + self.ui_mode.setMessage(.err, "Unknown command"); }, else => return err, }; @@ -203,7 +203,7 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void /// using $EDITOR. pub fn edit(self: *Self, dir: []const u8, file: []const u8) !void { const editor = os.getenv("EDITOR") orelse { - self.mode.setMessage(.err, "$EDITOR is not set"); + self.ui_mode.setMessage(.err, "$EDITOR is not set"); return; }; const alloc = self.gpa.allocator(); @@ -214,7 +214,7 @@ pub fn edit(self: *Self, dir: []const u8, file: []const u8) !void { pub fn open(self: *Self, dir: []const u8, file: []const u8) !void { if (self.config.opener == null) { - self.mode.setMessage(.err, "No opener configured"); + self.ui_mode.setMessage(.err, "No opener configured"); return; } const alloc = self.gpa.allocator(); @@ -238,12 +238,12 @@ pub fn getCursorSelectedName(self: *Self) ?[]const u8 { pub fn select(self: *Self, str: []const u8) !void { const fdv = self.dirmap.focusedDirView() orelse { - self.mode.setMessage(.err, "No files"); + self.ui_mode.setMessage(.err, "No files"); return; }; if (fdv.visible_files.items.len == 0) { - self.mode.setMessage(.err, "No visible files"); + self.ui_mode.setMessage(.err, "No visible files"); return; } @@ -252,7 +252,7 @@ pub fn select(self: *Self, str: []const u8) !void { const alloc = self.gpa.allocator(); var rex = Regex.compile(alloc, str) catch { // TODO find out the exact errors that indicate a bad regex - self.mode.setMessage(.err, "Invalid regex"); + self.ui_mode.setMessage(.err, "Invalid regex"); return; }; defer rex.deinit(); @@ -265,9 +265,9 @@ pub fn select(self: *Self, str: []const u8) !void { } } if (mark) { - self.mode.setNav(); + self.ui_mode.setNav(); } else { - self.mode.setMessage(.err, "No match"); + self.ui_mode.setMessage(.err, "No match"); } self.ui.list_dirty = true; @@ -275,18 +275,18 @@ pub fn select(self: *Self, str: []const u8) !void { pub fn keep(self: *Self, str: []const u8) !void { const fdv = self.dirmap.focusedDirView() orelse { - self.mode.setMessage(.err, "No files"); + self.ui_mode.setMessage(.err, "No files"); return; }; if (fdv.visible_files.items.len == 0) { - self.mode.setMessage(.err, "No visible files"); + self.ui_mode.setMessage(.err, "No visible files"); return; } const alloc = self.gpa.allocator(); var rex = Regex.compile(alloc, str) catch { - self.mode.setMessage(.err, "Invalid regex"); + self.ui_mode.setMessage(.err, "Invalid regex"); return; }; defer rex.deinit(); @@ -301,9 +301,9 @@ pub fn keep(self: *Self, str: []const u8) !void { } } if (mark) { - self.mode.setNav(); + self.ui_mode.setNav(); } else { - self.mode.setMessage(.err, "No marked files in this directory"); + self.ui_mode.setMessage(.err, "No marked files in this directory"); } self.ui.list_dirty = true; @@ -311,18 +311,18 @@ pub fn keep(self: *Self, str: []const u8) !void { pub fn discard(self: *Self, str: []const u8) !void { const fdv = self.dirmap.focusedDirView() orelse { - self.mode.setMessage(.err, "No files"); + self.ui_mode.setMessage(.err, "No files"); return; }; if (fdv.visible_files.items.len == 0) { - self.mode.setMessage(.err, "No visible files"); + self.ui_mode.setMessage(.err, "No visible files"); return; } const alloc = self.gpa.allocator(); var rex = Regex.compile(alloc, str) catch { - self.mode.setMessage(.err, "Invalid regex"); + self.ui_mode.setMessage(.err, "Invalid regex"); return; }; defer rex.deinit(); @@ -337,9 +337,9 @@ pub fn discard(self: *Self, str: []const u8) !void { } } if (mark) { - self.mode.setNav(); + self.ui_mode.setNav(); } else { - self.mode.setMessage(.err, "No marked files in this directory"); + self.ui_mode.setMessage(.err, "No marked files in this directory"); } self.ui.list_dirty = true; @@ -353,7 +353,7 @@ pub fn search(self: *Self, str: []const u8) !void { const alloc = self.gpa.allocator(); self.active_search = Regex.compile(alloc, str) catch { - self.mode.setMessage(.err, "Invalid regex"); + self.ui_mode.setMessage(.err, "Invalid regex"); return; }; @@ -364,7 +364,7 @@ pub fn search(self: *Self, str: []const u8) !void { /// Called by event loop implementation. pub fn handleSpoonInput(self: *Self, in: spoon.Input) !void { - switch (self.mode) { + switch (self.ui_mode) { .nav, .message => try self.handleSpoonInputNav(in), .user_input => try self.handleSpoonInputUserInput(in), } @@ -389,12 +389,12 @@ fn handleSpoonInputNav(self: *Self, in: spoon.Input) !void { if (self.config.keybinds.getEntry(in)) |entry| { try @call(.{}, entry.value_ptr.*.impl, .{entry.value_ptr}); } else { - self.mode.setMessage(.err, "Key not bound"); + self.ui_mode.setMessage(.err, "Key not bound"); } } fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { - debug.assert(self.mode == .user_input); + debug.assert(self.ui_mode == .user_input); self.ui.title_dirty = true; self.completion_count = null; @@ -404,8 +404,8 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { return; } - const buffer = &self.mode.user_input.buffer; - if (self.mode.user_input.history_index != null) { + const buffer = &self.ui_mode.user_input.buffer; + if (self.ui_mode.user_input.history_index != null) { // We are currently viewing command history if (in.eqlDescription("C-p") or in.eqlDescription("arrow-up")) { self.history.indexUp(); @@ -417,7 +417,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { try self.handleReturnUserInput(); return; } else if (in.eqlDescription("escape")) { - self.mode.setNav(); + self.ui_mode.setNav(); return; } @@ -425,9 +425,9 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { // item, so copy it into the edit buffer. buffer.deinit(); const index = self.history.command.items.len - - (self.mode.user_input.history_index.? + 1); + (self.ui_mode.user_input.history_index.? + 1); try buffer.insertSliceAtCursor(self.history.command.items[index]); - self.mode.user_input.history_index = null; + self.ui_mode.user_input.history_index = null; if (in.eqlDescription("arrow-left") or in.eqlDescription("C-b")) { return; @@ -442,7 +442,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { } else if (in.eqlDescription("C-n")) { self.history.indexDown(); } else if (in.eqlDescription("C-c") or in.eqlDescription("C-g")) { - self.mode.setNav(); + self.ui_mode.setNav(); } else if (in.eqlDescription("C-a")) { buffer.moveCursorToStart(); } else if (in.eqlDescription("C-e")) { @@ -490,7 +490,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { else => {}, } } else if (in.eqlDescription("escape")) { - self.mode.setNav(); + self.ui_mode.setNav(); } else if (in.eqlDescription("arrow-left")) { buffer.moveCursorOneBackward(); } else if (in.eqlDescription("arrow-right")) { @@ -518,11 +518,11 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { } }, 127 => { // Backspace. - if (self.mode.user_input.history_index != null) return; + if (self.ui_mode.user_input.history_index != null) return; buffer.deleteOneBackward(); }, else => { - if (self.mode.user_input.history_index != null) return; + if (self.ui_mode.user_input.history_index != null) return; try buffer.insertCodepointAtCursor(in.content.codepoint); }, } @@ -531,10 +531,10 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { fn handleReturnUserInput(self: *Self) !void { const alloc = self.gpa.allocator(); - const user_input = &self.mode.user_input; + const user_input = &self.ui_mode.user_input; switch (user_input.operation) { .command => { - if (self.mode.user_input.history_index) |index| { + if (self.ui_mode.user_input.history_index) |index| { const cmd = self.history.command.items[self.history.command.items.len - (index + 1)]; try self.history.append(cmd); try self.run(cmd, "/bin/sh or subprocess"); @@ -545,7 +545,7 @@ fn handleReturnUserInput(self: *Self) !void { } }, .search, .select, .keep, .discard => { - if (self.mode.user_input.history_index) |index| { + if (self.ui_mode.user_input.history_index) |index| { const str = self.history.search.items[self.history.search.items.len - (index + 1)]; switch (user_input.operation) { .search => try self.search(str), @@ -605,9 +605,9 @@ fn handleMouseClickNav(self: *Self, in: spoon.Input) !void { const scroll_offset = fdv.getScrollOffset(fdv.height); const selected_cursor = y - 1 + scroll_offset; if (fdv.cursor == selected_cursor) { - if (self.mode == .user_input) { + if (self.ui_mode == .user_input) { const name = fdv.visible_files.items[fdv.cursor].name; - const buffer = &self.mode.user_input.buffer; + const buffer = &self.ui_mode.user_input.buffer; try buffer.insertQuotedSliceAtCursor(name); try buffer.insertSliceAtCursor(" "); } else { @@ -615,14 +615,14 @@ fn handleMouseClickNav(self: *Self, in: spoon.Input) !void { } } else { fdv.setCursor(selected_cursor); - if (self.mode != .user_input) self.mode.setNav(); + if (self.ui_mode != .user_input) self.ui_mode.setNav(); } } else { const scroll_offset = dv.getScrollOffset(dv.height); const selected_cursor = y - 1 + scroll_offset; - if (self.mode == .user_input) { + if (self.ui_mode == .user_input) { const name = dv.visible_files.items[dv.cursor].name; - const buffer = &self.mode.user_input.buffer; + const buffer = &self.ui_mode.user_input.buffer; // TODO fix quoting try buffer.insertQuotedSliceAtCursor(dv.dir.name); @@ -632,7 +632,7 @@ fn handleMouseClickNav(self: *Self, in: spoon.Input) !void { } else { dv.setCursor(selected_cursor); try self.dirmap.setCwdRaw(dv.dir.name); - self.mode.setNav(); + self.ui_mode.setNav(); } } @@ -649,9 +649,9 @@ fn handleMouseClickFs(self: *Self, in: spoon.Input) !void { const selected_cursor = y - 2 + scroll_offset; if (self.view.fs.cursor == selected_cursor) { - if (self.mode == .user_input) { + if (self.ui_mode == .user_input) { if (self.getCursorSelectedName()) |name| { - const buffer = &self.mode.user_input.buffer; + const buffer = &self.ui_mode.user_input.buffer; try buffer.insertQuotedSliceAtCursor(name); try buffer.insertSliceAtCursor(" "); } @@ -660,7 +660,7 @@ fn handleMouseClickFs(self: *Self, in: spoon.Input) !void { } } else { self.view.setCursor(selected_cursor); - if (self.mode != .user_input) self.mode.setNav(); + if (self.ui_mode != .user_input) self.ui_mode.setNav(); } self.ui.list_dirty = true; diff --git a/src/History.zig b/src/History.zig index b75f6b4bad54..872a4c21f73c 100644 --- a/src/History.zig +++ b/src/History.zig @@ -45,8 +45,8 @@ pub fn deinit(self: *Self) void { pub fn append(self: *Self, item: []const u8) !void { if (item.len == 0) return; - debug.assert(context.mode == .user_input); - const list = switch (context.mode.user_input.operation) { + debug.assert(context.ui_mode == .user_input); + const list = switch (context.ui_mode.user_input.operation) { .command => &self.command, .search, .select, .keep, .discard => &self.search, }; @@ -60,7 +60,7 @@ pub fn append(self: *Self, item: []const u8) !void { } pub fn indexDown(_: *Self) void { - const index = &context.mode.user_input.history_index; + const index = &context.ui_mode.user_input.history_index; if (index.* == null) { return; @@ -72,8 +72,8 @@ pub fn indexDown(_: *Self) void { } pub fn indexUp(self: *Self) void { - const index = &context.mode.user_input.history_index; - const history = switch (context.mode.user_input.operation) { + const index = &context.ui_mode.user_input.history_index; + const history = switch (context.ui_mode.user_input.operation) { .command => &self.command, .search, .select, .keep, .discard => &self.search, }; diff --git a/src/UserInterface.zig b/src/UserInterface.zig index c9e1470f4c73..2d8660a78724 100644 --- a/src/UserInterface.zig +++ b/src/UserInterface.zig @@ -285,15 +285,15 @@ fn drawTitle(self: *Self, rc: *spoon.Term.RenderContext, title: []const u8) !voi const indicator = if (context.selector_mode) "[selector_mode]" else null; try rc.moveCursorTo(0, 0); - if (context.mode == .user_input) { + if (context.ui_mode == .user_input) { try rc.showCursor(); } else { try rc.hideCursor(); } - switch (context.mode) { + switch (context.ui_mode) { .user_input => { - const prefix = @tagName(context.mode.user_input.operation); + const prefix = @tagName(context.ui_mode.user_input.operation); const prefix_len = prefix.len + 4; debug.assert(prefix_len < min_width); @@ -306,8 +306,8 @@ fn drawTitle(self: *Self, rc: *spoon.Term.RenderContext, title: []const u8) !voi try writer.writeByte(' '); } - if (context.mode.user_input.history_index) |index| { - const history = switch (context.mode.user_input.operation) { + if (context.ui_mode.user_input.history_index) |index| { + const history = switch (context.ui_mode.user_input.operation) { .command => &context.history.command, .search, .select, .keep, .discard => &context.history.search, }; @@ -325,11 +325,11 @@ fn drawTitle(self: *Self, rc: *spoon.Term.RenderContext, title: []const u8) !voi try rc.moveCursorTo(0, prefix_len); // TODO input line scrolling var rpw = rc.restrictedPaddingWriter(self.term.width - prefix_len); - try rpw.writer().writeAll(context.mode.user_input.buffer.buffer.items); + try rpw.writer().writeAll(context.ui_mode.user_input.buffer.buffer.items); try rpw.pad(); if (context.completion_count) |cc| { - const pos = prefix_len + context.mode.user_input.buffer.cursor.codepoint + 1; + const pos = prefix_len + context.ui_mode.user_input.buffer.cursor.codepoint + 1; if (pos < self.term.width) { try rc.moveCursorTo(0, pos); rpw = rc.restrictedPaddingWriter(self.term.width - pos); @@ -339,18 +339,18 @@ fn drawTitle(self: *Self, rc: *spoon.Term.RenderContext, title: []const u8) !voi } } - try rc.moveCursorTo(0, prefix_len + context.mode.user_input.buffer.cursor.codepoint); + try rc.moveCursorTo(0, prefix_len + context.ui_mode.user_input.buffer.cursor.codepoint); } }, .message => { - try rc.setAttribute(switch (context.mode.message.level) { + try rc.setAttribute(switch (context.ui_mode.message.level) { .info => context.config.theme.getAttribute("title_info", .{ .bold = true }), .err => context.config.theme.getAttribute("title_error", .{ .bold = true, .blinking = true }), }); var rpw = rc.restrictedPaddingWriter(self.term.width); const writer = rpw.writer(); try writer.writeByte(' '); - try writer.writeAll(context.mode.message.message); + try writer.writeAll(context.ui_mode.message.message); try rpw.pad(); }, .nav => { diff --git a/src/key-operations/commit.zig b/src/key-operations/commit.zig index 2896b2fbee91..1e26fd398f15 100644 --- a/src/key-operations/commit.zig +++ b/src/key-operations/commit.zig @@ -29,7 +29,7 @@ pub fn commitFileAtCursor(_: *const KeyOperation) !void { switch (context.view) { .nav => try commitFileAtCursorImpl(), .fs => try commitFilesystem(), - else => context.mode.setMessage(.err, "Operation not supported in this view"), + else => context.ui_mode.setMessage(.err, "Operation not supported in this view"), } } @@ -59,7 +59,7 @@ fn commitFileAtCursorImpl() !void { return; } } else { - context.mode.setMessage(.err, "No operation implemented for this file type"); + context.ui_mode.setMessage(.err, "No operation implemented for this file type"); } context.ui.list_dirty = true; @@ -70,7 +70,7 @@ pub fn commitMarks(key_operation: *const KeyOperation) !void { switch (context.view) { .nav => try commitMarksImpl(key_operation), .fs => try commitFilesystem(), - else => context.mode.setMessage(.err, "Operation not supported in this view"), + else => context.ui_mode.setMessage(.err, "Operation not supported in this view"), } } @@ -101,7 +101,7 @@ pub fn commitMarksImpl(key_operation: *const KeyOperation) !void { if (is_text) { if (multi_editor == null) { const editor = os.getenv("EDITOR") orelse { - context.mode.setMessage(.err, "$EDITOR is not set"); + context.ui_mode.setMessage(.err, "$EDITOR is not set"); return; }; multi_editor = try MultiForeground.new(alloc, editor); @@ -129,15 +129,15 @@ pub fn commitMarksImpl(key_operation: *const KeyOperation) !void { fn isTextFileErrorMessage(err: anyerror) !void { switch (err) { error.AccessDenied => { - context.mode.setMessage(.err, "Access Denied"); + context.ui_mode.setMessage(.err, "Access Denied"); return; }, error.FileNotFound => { - context.mode.setMessage(.err, "File not found"); + context.ui_mode.setMessage(.err, "File not found"); return; }, error.Unseekable => { - context.mode.setMessage(.err, "Not a real file"); + context.ui_mode.setMessage(.err, "Not a real file"); return; }, else => return err, diff --git a/src/key-operations/config.zig b/src/key-operations/config.zig index 86eca42552c1..df6a69ccd539 100644 --- a/src/key-operations/config.zig +++ b/src/key-operations/config.zig @@ -26,7 +26,7 @@ const context = &@import("../nfm.zig").context; pub fn toggleHiddenFiles(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } @@ -37,7 +37,7 @@ pub fn toggleHiddenFiles(_: *const KeyOperation) !void { pub fn toggleDirectoriesFirst(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } @@ -48,7 +48,7 @@ pub fn toggleDirectoriesFirst(_: *const KeyOperation) !void { pub fn togglePermissionFormat(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } @@ -59,7 +59,7 @@ pub fn togglePermissionFormat(_: *const KeyOperation) !void { pub fn toggleSizeFormat(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } @@ -71,7 +71,7 @@ pub fn toggleSizeFormat(_: *const KeyOperation) !void { // TODO support setting this directly instead of just toggling it? pub fn toggleSortingScheme(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } @@ -82,9 +82,9 @@ pub fn toggleSortingScheme(_: *const KeyOperation) !void { fn infoMessageBool(comptime str: []const u8, val: bool) void { if (val) { - context.mode.setMessage(.info, str ++ ": true"); + context.ui_mode.setMessage(.info, str ++ ": true"); } else { - context.mode.setMessage(.info, str ++ ": false"); + context.ui_mode.setMessage(.info, str ++ ": false"); } } @@ -92,7 +92,7 @@ fn infoMessageEnum(comptime E: type, comptime str: []const u8, current: E) void const info = @typeInfo(E).Enum; inline for (info.fields) |field| { if (field.value == @enumToInt(current)) { - context.mode.setMessage(.info, str ++ ": " ++ field.name); + context.ui_mode.setMessage(.info, str ++ ": " ++ field.name); } } } diff --git a/src/key-operations/cursor.zig b/src/key-operations/cursor.zig index 80ba59de6fb1..dada4615b6a4 100644 --- a/src/key-operations/cursor.zig +++ b/src/key-operations/cursor.zig @@ -49,26 +49,26 @@ pub fn cursorMovePageDown(_: *const KeyOperation) !void { pub fn cursorMoveToNextMatch(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); const search = blk: { if (context.active_search) |*search| break :blk search; - context.mode.setMessage(.err, "No search pattern"); + context.ui_mode.setMessage(.err, "No search pattern"); context.ui.list_dirty = true; return; }; const fdv = context.dirmap.focusedDirView() orelse { - context.mode.setMessage(.err, "No files"); + context.ui_mode.setMessage(.err, "No files"); return; }; if (fdv.visible_files.items.len == 0) { - context.mode.setMessage(.err, "No visible files"); + context.ui_mode.setMessage(.err, "No visible files"); return; } @@ -96,24 +96,24 @@ pub fn cursorMoveToNextMatch(_: *const KeyOperation) !void { } } - context.mode.setMessage(.err, "No match"); + context.ui_mode.setMessage(.err, "No match"); } pub fn cursorMoveToNextMark(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); const fdv = context.dirmap.focusedDirView() orelse { - context.mode.setMessage(.err, "No files"); + context.ui_mode.setMessage(.err, "No files"); return; }; if (fdv.visible_files.items.len == 0) { - context.mode.setMessage(.err, "No visible files"); + context.ui_mode.setMessage(.err, "No visible files"); return; } @@ -141,7 +141,7 @@ pub fn cursorMoveToNextMark(_: *const KeyOperation) !void { } } - context.mode.setMessage(.err, "No marked files in this directory"); + context.ui_mode.setMessage(.err, "No marked files in this directory"); } pub fn cursorMoveToIndex(op: *const KeyOperation) !void { @@ -153,7 +153,7 @@ pub fn cursorMoveToRelativeIndex(op: *const KeyOperation) !void { .nav => (context.dirmap.focusedDirView() orelse return).scroll_offset, .fs => context.view.fs.scroll_offset, else => { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; }, }; @@ -163,8 +163,8 @@ pub fn cursorMoveToRelativeIndex(op: *const KeyOperation) !void { fn moveCursor(i: isize) void { // We need to take some care here, because cursor movement can also be // caused while in user input mode. - if (context.mode != .user_input) { - context.mode.setNav(); + if (context.ui_mode != .user_input) { + context.ui_mode.setNav(); } switch (context.view) { .nav => if (context.dirmap.focusedDirView()) |fdv| fdv.moveCursor(i), @@ -174,7 +174,7 @@ fn moveCursor(i: isize) void { } fn setCursor(i: usize) void { - context.mode.setNav(); + context.ui_mode.setNav(); switch (context.view) { .nav => if (context.dirmap.focusedDirView()) |fdv| fdv.setCursor(i), else => context.view.setCursor(i), diff --git a/src/key-operations/marks.zig b/src/key-operations/marks.zig index 1843e7c7e6f8..1e424a166a98 100644 --- a/src/key-operations/marks.zig +++ b/src/key-operations/marks.zig @@ -24,11 +24,11 @@ const context = &@import("../nfm.zig").context; pub fn markFileAtCursor(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); const file = context.dirmap.getCursorSelectedFile() orelse return; file.mark = !file.mark; context.ui.list_dirty = true; @@ -36,11 +36,11 @@ pub fn markFileAtCursor(_: *const KeyOperation) !void { pub fn invertMarks(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); const fdv = context.dirmap.focusedDirView() orelse return; for (fdv.visible_files.items) |file| file.mark = !file.mark; context.ui.list_dirty = true; @@ -48,11 +48,11 @@ pub fn invertMarks(_: *const KeyOperation) !void { pub fn clearMarks(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); // If this has been called two times with a delay of less than a second, // clear all marks. @@ -62,7 +62,7 @@ pub fn clearMarks(_: *const KeyOperation) !void { if (timespecDiffLessThanOneSecond(now, last)) { var it = context.dirmap.markIterator(); while (it.next()) |file| file.mark = false; - context.mode.setMessage(.info, "All marks cleared"); + context.ui_mode.setMessage(.info, "All marks cleared"); return; } } diff --git a/src/key-operations/misc.zig b/src/key-operations/misc.zig index 5f588dea562a..f35f4f4ec1f6 100644 --- a/src/key-operations/misc.zig +++ b/src/key-operations/misc.zig @@ -33,21 +33,21 @@ pub fn collapse(_: *const KeyOperation) !void { pub fn enterParentDir(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); try context.setCwd(".."); } pub fn jumpBack(_: *const KeyOperation) !void { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - context.mode.setNav(); + context.ui_mode.setNav(); try context.setCwd(context.initial_cwd_path); context.ui.list_dirty = true; } @@ -75,7 +75,7 @@ fn run(op: *const KeyOperation, foreground: bool) !void { } pub fn toggleViewFileSystems(_: *const KeyOperation) !void { - context.mode.setNav(); + context.ui_mode.setNav(); switch (context.view) { .fs => context.view.setNav(), else => try context.view.setFs(), @@ -83,7 +83,7 @@ pub fn toggleViewFileSystems(_: *const KeyOperation) !void { } pub fn toggleViewBookmarks(_: *const KeyOperation) !void { - context.mode.setNav(); + context.ui_mode.setNav(); switch (context.view) { .bm => context.view.setNav(), else => context.view.setBm(), @@ -91,7 +91,7 @@ pub fn toggleViewBookmarks(_: *const KeyOperation) !void { } pub fn setViewFiles(_: *const KeyOperation) !void { - context.mode.setNav(); + context.ui_mode.setNav(); if (context.view != .nav) context.view.setNav(); } @@ -121,15 +121,15 @@ pub fn discard(op: *const KeyOperation) !void { fn getFormattedBuffer(op: *const KeyOperation) !?[:0]const u8 { if (context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return null; } - context.mode.setNav(); + context.ui_mode.setNav(); return format.ownedSliceZFromFormat(op.payload.fmt.?) catch |err| switch (err) { error.NoSelection => { - context.mode.setMessage(.err, "No item selected by cursor"); + context.ui_mode.setMessage(.err, "No item selected by cursor"); return null; }, else => return err, diff --git a/src/key-operations/user-input.zig b/src/key-operations/user-input.zig index 27cf3b2403ab..d608db0191cd 100644 --- a/src/key-operations/user-input.zig +++ b/src/key-operations/user-input.zig @@ -44,17 +44,17 @@ pub fn openDiscard(op: *const KeyOperation) !void { fn setMode(kop: *const KeyOperation, comptime op: UserInputOperation) !void { if (op != .command and context.view != .nav) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } - try context.mode.setUserInput(op); + try context.ui_mode.setUserInput(op); switch (kop.payload) { .fmt => |ffmt| if (ffmt) |fmt| { - format.insertIntoEditableBuffer(fmt, &context.mode.user_input.buffer) catch |err| { + format.insertIntoEditableBuffer(fmt, &context.ui_mode.user_input.buffer) catch |err| { switch (err) { - error.NoSelection => context.mode.setMessage(.err, "No item selected by cursor"), + error.NoSelection => context.ui_mode.setMessage(.err, "No item selected by cursor"), else => return err, } }; diff --git a/src/mode.zig b/src/mode.zig index 9b83359a39b5..3a5dab3322fe 100644 --- a/src/mode.zig +++ b/src/mode.zig @@ -40,8 +40,7 @@ pub const UserInputOperation = enum { }; /// The mode controls the user interface. -/// TODO rename to UIMode for clearity -pub const Mode = union(enum) { +pub const UIMode = union(enum) { const Self = @This(); /// Nav mode: Normal title bar, keys map to user defined keybinds. diff --git a/src/system/linux.zig b/src/system/linux.zig index e065a8b2b994..00817c6e06e9 100644 --- a/src/system/linux.zig +++ b/src/system/linux.zig @@ -271,7 +271,7 @@ pub const EventLoop = struct { .to => try self.doTheInotifyMoveThing(m.name, m.wd, basename, ev.wd), } } else { - context.mode.setMessage(.err, "Bad inotify move events received. This should not happen."); + context.ui_mode.setMessage(.err, "Bad inotify move events received. This should not happen."); } return; @@ -425,7 +425,7 @@ pub const EventLoop = struct { // If the directory is visible, go to parent. if (dir.visible) { - context.mode.setMessage(.info, "working directory moved, moved up in tree (workaround, patches welcome)"); + context.ui_mode.setMessage(.info, "working directory moved, moved up in tree (workaround, patches welcome)"); const parent_path = fs.path.dirname(dir.name) orelse "/"; context.dirmap.setCwdRaw(parent_path) catch { try context.dirmap.setCwdRaw("/"); diff --git a/src/view.zig b/src/view.zig index 510327a7361f..7c18104a29f1 100644 --- a/src/view.zig +++ b/src/view.zig @@ -90,7 +90,7 @@ pub const View = union(enum) { pub fn setCursor(self: *Self, i: usize) void { if (self.* != .fs) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } @@ -101,7 +101,7 @@ pub const View = union(enum) { pub fn moveCursor(self: *Self, i: isize) void { if (self.* != .fs) { - context.mode.setMessage(.err, "Operation not supported in this view"); + context.ui_mode.setMessage(.err, "Operation not supported in this view"); return; } -- 2.39.0
Thanks! Friendly greetings, Leon Henrik Plickat
Rename UIMode.setNav() to UIMode.setNormal(); --- src/Context.zig | 28 ++++++++++++++-------------- src/UserInterface.zig | 2 +- src/key-operations/cursor.zig | 8 ++++---- src/key-operations/marks.zig | 6 +++--- src/key-operations/misc.zig | 12 ++++++------ src/mode.zig | 11 +++++------ 6 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Context.zig b/src/Context.zig index 4f2342628e43..05a17f0758f7 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -47,7 +47,7 @@ dirmap: DirMap = undefined, initial_cwd_path: []const u8 = undefined, view: View = .nav, -ui_mode: UIMode = .nav, +ui_mode: UIMode = .normal, completion_count: ?usize = null, selector_mode: bool = false, dump_cwd: bool = false, @@ -136,7 +136,7 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void self.ui_mode.setMessage(.err, "Invalid command"); return; }) orelse { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); self.ui.list_dirty = true; return; }; @@ -158,7 +158,7 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void } try self.setCwd(arg); - if (self.ui_mode != .message) self.ui_mode.setNav(); + if (self.ui_mode != .message) self.ui_mode.setNormal(); self.ui.list_dirty = true; return; } else if (mem.eql(u8, token, "quit")) { @@ -179,7 +179,7 @@ pub fn run(self: *Self, command: [:0]const u8, comptime name: []const u8) !void const ret = system.execForeground(command); - self.ui_mode.setNav(); + self.ui_mode.setNormal(); try self.ui.start(); ret catch |err| switch (err) { @@ -265,7 +265,7 @@ pub fn select(self: *Self, str: []const u8) !void { } } if (mark) { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); } else { self.ui_mode.setMessage(.err, "No match"); } @@ -301,7 +301,7 @@ pub fn keep(self: *Self, str: []const u8) !void { } } if (mark) { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); } else { self.ui_mode.setMessage(.err, "No marked files in this directory"); } @@ -337,7 +337,7 @@ pub fn discard(self: *Self, str: []const u8) !void { } } if (mark) { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); } else { self.ui_mode.setMessage(.err, "No marked files in this directory"); } @@ -365,7 +365,7 @@ pub fn search(self: *Self, str: []const u8) !void { /// Called by event loop implementation. pub fn handleSpoonInput(self: *Self, in: spoon.Input) !void { switch (self.ui_mode) { - .nav, .message => try self.handleSpoonInputNav(in), + .normal, .message => try self.handleSpoonInputNav(in), .user_input => try self.handleSpoonInputUserInput(in), } } @@ -417,7 +417,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { try self.handleReturnUserInput(); return; } else if (in.eqlDescription("escape")) { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); return; } @@ -442,7 +442,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { } else if (in.eqlDescription("C-n")) { self.history.indexDown(); } else if (in.eqlDescription("C-c") or in.eqlDescription("C-g")) { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); } else if (in.eqlDescription("C-a")) { buffer.moveCursorToStart(); } else if (in.eqlDescription("C-e")) { @@ -490,7 +490,7 @@ fn handleSpoonInputUserInput(self: *Self, in: spoon.Input) !void { else => {}, } } else if (in.eqlDescription("escape")) { - self.ui_mode.setNav(); + self.ui_mode.setNormal(); } else if (in.eqlDescription("arrow-left")) { buffer.moveCursorOneBackward(); } else if (in.eqlDescription("arrow-right")) { @@ -615,7 +615,7 @@ fn handleMouseClickNav(self: *Self, in: spoon.Input) !void { } } else { fdv.setCursor(selected_cursor); - if (self.ui_mode != .user_input) self.ui_mode.setNav(); + if (self.ui_mode != .user_input) self.ui_mode.setNormal(); } } else { const scroll_offset = dv.getScrollOffset(dv.height); @@ -632,7 +632,7 @@ fn handleMouseClickNav(self: *Self, in: spoon.Input) !void { } else { dv.setCursor(selected_cursor); try self.dirmap.setCwdRaw(dv.dir.name); - self.ui_mode.setNav(); + self.ui_mode.setNormal(); } } @@ -660,7 +660,7 @@ fn handleMouseClickFs(self: *Self, in: spoon.Input) !void { } } else { self.view.setCursor(selected_cursor); - if (self.ui_mode != .user_input) self.ui_mode.setNav(); + if (self.ui_mode != .user_input) self.ui_mode.setNormal(); } self.ui.list_dirty = true; diff --git a/src/UserInterface.zig b/src/UserInterface.zig index 2d8660a78724..ab748ae0e1c5 100644 --- a/src/UserInterface.zig +++ b/src/UserInterface.zig @@ -353,7 +353,7 @@ fn drawTitle(self: *Self, rc: *spoon.Term.RenderContext, title: []const u8) !voi try writer.writeAll(context.ui_mode.message.message); try rpw.pad(); }, - .nav => { + .normal => { try rc.setAttribute(context.config.theme.getAttribute("title", .{})); if (indicator) |indctr| { debug.assert(indctr.len < min_width); diff --git a/src/key-operations/cursor.zig b/src/key-operations/cursor.zig index dada4615b6a4..c9f748ab05b7 100644 --- a/src/key-operations/cursor.zig +++ b/src/key-operations/cursor.zig @@ -53,7 +53,7 @@ pub fn cursorMoveToNextMatch(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); const search = blk: { if (context.active_search) |*search| break :blk search; @@ -105,7 +105,7 @@ pub fn cursorMoveToNextMark(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); const fdv = context.dirmap.focusedDirView() orelse { context.ui_mode.setMessage(.err, "No files"); @@ -164,7 +164,7 @@ fn moveCursor(i: isize) void { // We need to take some care here, because cursor movement can also be // caused while in user input mode. if (context.ui_mode != .user_input) { - context.ui_mode.setNav(); + context.ui_mode.setNormal(); } switch (context.view) { .nav => if (context.dirmap.focusedDirView()) |fdv| fdv.moveCursor(i), @@ -174,7 +174,7 @@ fn moveCursor(i: isize) void { } fn setCursor(i: usize) void { - context.ui_mode.setNav(); + context.ui_mode.setNormal(); switch (context.view) { .nav => if (context.dirmap.focusedDirView()) |fdv| fdv.setCursor(i), else => context.view.setCursor(i), diff --git a/src/key-operations/marks.zig b/src/key-operations/marks.zig index 1e424a166a98..e80e00ea823c 100644 --- a/src/key-operations/marks.zig +++ b/src/key-operations/marks.zig @@ -28,7 +28,7 @@ pub fn markFileAtCursor(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); const file = context.dirmap.getCursorSelectedFile() orelse return; file.mark = !file.mark; context.ui.list_dirty = true; @@ -40,7 +40,7 @@ pub fn invertMarks(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); const fdv = context.dirmap.focusedDirView() orelse return; for (fdv.visible_files.items) |file| file.mark = !file.mark; context.ui.list_dirty = true; @@ -52,7 +52,7 @@ pub fn clearMarks(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); // If this has been called two times with a delay of less than a second, // clear all marks. diff --git a/src/key-operations/misc.zig b/src/key-operations/misc.zig index f35f4f4ec1f6..6c3374ed8b6e 100644 --- a/src/key-operations/misc.zig +++ b/src/key-operations/misc.zig @@ -37,7 +37,7 @@ pub fn enterParentDir(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); try context.setCwd(".."); } @@ -47,7 +47,7 @@ pub fn jumpBack(_: *const KeyOperation) !void { return; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); try context.setCwd(context.initial_cwd_path); context.ui.list_dirty = true; } @@ -75,7 +75,7 @@ fn run(op: *const KeyOperation, foreground: bool) !void { } pub fn toggleViewFileSystems(_: *const KeyOperation) !void { - context.ui_mode.setNav(); + context.ui_mode.setNormal(); switch (context.view) { .fs => context.view.setNav(), else => try context.view.setFs(), @@ -83,7 +83,7 @@ pub fn toggleViewFileSystems(_: *const KeyOperation) !void { } pub fn toggleViewBookmarks(_: *const KeyOperation) !void { - context.ui_mode.setNav(); + context.ui_mode.setNormal(); switch (context.view) { .bm => context.view.setNav(), else => context.view.setBm(), @@ -91,7 +91,7 @@ pub fn toggleViewBookmarks(_: *const KeyOperation) !void { } pub fn setViewFiles(_: *const KeyOperation) !void { - context.ui_mode.setNav(); + context.ui_mode.setNormal(); if (context.view != .nav) context.view.setNav(); } @@ -125,7 +125,7 @@ fn getFormattedBuffer(op: *const KeyOperation) !?[:0]const u8 { return null; } - context.ui_mode.setNav(); + context.ui_mode.setNormal(); return format.ownedSliceZFromFormat(op.payload.fmt.?) catch |err| switch (err) { error.NoSelection => { diff --git a/src/mode.zig b/src/mode.zig index 3a5dab3322fe..55154dc07e37 100644 --- a/src/mode.zig +++ b/src/mode.zig @@ -44,8 +44,7 @@ pub const UIMode = union(enum) { const Self = @This(); /// Nav mode: Normal title bar, keys map to user defined keybinds. - /// TODO rename to "normal", because nav is also taken in View - nav: void, + normal: void, /// Message mode: Message in title bar, keys map to user defined keybinds. message: struct { @@ -61,11 +60,11 @@ pub const UIMode = union(enum) { history_index: ?usize, }, - pub fn setNav(self: *Self) void { - if (self.* == .nav) return; - logger.debug("nav mode", .{}); + pub fn setNormal(self: *Self) void { + if (self.* == .normal) return; + logger.debug("normal mode", .{}); self.reset(); - self.* = .nav; + self.* = .normal; } pub fn setMessage(self: *Self, comptime level: MessageLevel, comptime message: []const u8) void { -- 2.39.0
builds.sr.ht <builds@sr.ht>nfm/patches/alpine.yml: SUCCESS in 51s [Rename mode.Mode to mode.UIMode][0] v2 from [Hugo Machet][1] [0]: https://lists.sr.ht/~leon_plickat/nfm/patches/37889 [1]: mailto:mail@hmachet.com ✓ #915055 SUCCESS nfm/patches/alpine.yml https://builds.sr.ht/~leon_plickat/job/915055