╭ changed ──────────╮ │src/ui/CloneUrl.zig│ ╰───────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 9 const Grid = xitui.grid.Grid; │ │10 const Focus = xitui.focus.Focus; │ │11 const inp = @import("input.zig"); │ │12 + │ │13 +const debug_ssh_prefix = "GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR' \\\r\n";│ │14 │ │15 pub const View = struct { │ │16 box: wgt.Box(ui.Widget), │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────╮ │21 │ │22 const Protocol = struct { │ │23 name: []const u8, │ │22 - url: []const u8, │ │24 + text: []const u8, │ │25 copyable_text: []const u8,│ │26 }; │ │27 │ ╰──────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │33 const url = try std.fmt.allocPrint(aa, "http://localhost:{d}/repo/{s}", .{ port, identity });│ │34 protocols[protocol_count] = .{ │ │35 .name = "http", │ │34 - .url = url, │ │36 + .text = url, │ │37 .copyable_text = try std.fmt.allocPrint(aa, "git clone {s}", .{url}), │ │38 }; │ │39 protocol_count += 1; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │40 } │ │41 if (session.data.clone_ssh_port) |port| { │ │40 - const debug_prefix = "GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR' \\\r\n";│ │42 const url = try std.fmt.allocPrint(aa, "ssh://localhost:{d}/repo/{s}", .{ port, identity }); │ │43 protocols[protocol_count] = .{ │ │44 .name = "ssh", │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │44 - .url = url, │ │45 - .copyable_text = try std.fmt.allocPrint(aa, "{s}git clone {s}", .{ if (builtin.mode == .Debug) debug_prefix else "", url }), │ │45 + .text = url, │ │46 + .copyable_text = try std.fmt.allocPrint(aa, "{s}git clone {s}", .{ if (builtin.mode == .Debug) debug_ssh_prefix else "", url }),│ │47 + }; │ │48 + protocol_count += 1; │ │49 + } │ │50 + return initProtocols(allocator, session, protocols, protocol_count, " clone "); │ │51 + } │ │52 + │ │53 + pub fn initPush(allocator: std.mem.Allocator, session: *ui.Session, identity: []const u8, id: []const u8, branch: []const u8) !View { │ │54 + const aa = session.page_arena.allocator(); │ │55 + var protocols: [2]Protocol = undefined; │ │56 + var protocol_count: usize = 0; │ │57 + if (session.data.clone_http_port) |port| { │ │58 + const url = try std.fmt.allocPrint(aa, "http://localhost:{d}/repo/{s}/patch:{s}/branch:{s}", .{ port, identity, id, branch }); │ │59 + const command = try std.fmt.allocPrint(aa, "git push {s} HEAD:patch", .{url}); │ │60 + protocols[protocol_count] = .{ .name = "http", .text = command, .copyable_text = command }; │ │61 + protocol_count += 1; │ │62 + } │ │63 + if (session.data.clone_ssh_port) |port| { │ │64 + const url = try std.fmt.allocPrint(aa, "ssh://localhost:{d}/repo/{s}/patch:{s}/branch:{s}", .{ port, identity, id, branch }); │ │65 + const command = try std.fmt.allocPrint(aa, "git push {s} HEAD:patch", .{url}); │ │66 + protocols[protocol_count] = .{ │ │67 + .name = "ssh", │ │68 + .text = command, │ │69 + .copyable_text = if (builtin.mode == .Debug) try std.fmt.allocPrint(aa, "{s}{s}", .{ debug_ssh_prefix, command }) else command, │ │70 }; │ │71 protocol_count += 1; │ │72 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │73 + return initProtocols(allocator, session, protocols, protocol_count, " push "); │ │74 + } │ │75 + │ │76 + fn initProtocols(allocator: std.mem.Allocator, session: *ui.Session, protocols: [2]Protocol, protocol_count: usize, input_label: []const u8) !View {│ │77 if (protocol_count == 0) return error.MissingClonePort; │ │78 │ │51 - var max_url_len: usize = 0; │ │52 - for (protocols[0..protocol_count]) |protocol| max_url_len = @max(max_url_len, protocol.url.len); │ │79 + var max_text_len: usize = 0; │ │80 + for (protocols[0..protocol_count]) |protocol| max_text_len = @max(max_text_len, protocol.text.len); │ │81 │ │82 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │83 errdefer box.deinit(allocator); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 90 try box.children.put(allocator, label.getFocus().id, .{ .widget = .{ .text_box = label }, .rect = null, .min_size = .{ .width = protocol.name.len + 2, .height = 3 } }); │ │ 91 } │ │ 92 │ │ 65 - var url_input = try wgt.TextInput(ui.Widget).init(allocator, .{ │ │ 93 + var text_input = try wgt.TextInput(ui.Widget).init(allocator, .{ │ │ 94 .border_style = .single, │ │ 67 - .label = " clone ", │ │ 95 + .label = input_label, │ │ 96 .render_content = session.is_terminal, │ │ 69 - .visible_width = max_url_len, │ │ 97 + .visible_width = max_text_len, │ │ 98 }); │ │ 71 - errdefer url_input.deinit(allocator); │ │ 72 - url_input.getFocus().focusable = true; │ │ 73 - try url_input.setContent(allocator, protocols[0].url); │ │ 74 - box.getFocus().child_id = url_input.getFocus().id; │ │ 75 - try box.children.put(allocator, url_input.getFocus().id, .{ .widget = .{ .text_input = url_input }, .rect = null, .min_size = .{ .width = max_url_len + 2, .height = 3 } }); │ │ 99 + errdefer text_input.deinit(allocator); │ │100 + text_input.getFocus().focusable = true; │ │101 + try text_input.setContent(allocator, protocols[0].text); │ │102 + box.getFocus().child_id = text_input.getFocus().id; │ │103 + try box.children.put(allocator, text_input.getFocus().id, .{ .widget = .{ .text_input = text_input }, .rect = null, .min_size = .{ .width = max_text_len + 2, .height = 3 } });│ │104 │ │105 return .{ .box = box, .session = session, .protocols = protocols, .protocol_count = protocol_count }; │ │106 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │107 │ │108 pub fn minWidth(self: *const View) usize { │ │109 var width: usize = 0; │ │ 82 - var max_url_len: usize = 0; │ │110 + var max_text_len: usize = 0; │ │111 for (self.protocols[0..self.protocol_count]) |protocol| { │ │112 width += protocol.name.len + 2; │ │ 85 - max_url_len = @max(max_url_len, protocol.url.len); │ │113 + max_text_len = @max(max_text_len, protocol.text.len); │ │114 } │ │ 87 - return width + max_url_len + 2; │ │115 + return width + max_text_len + 2; │ │116 } │ │117 │ │118 pub fn deinit(self: *View, allocator: std.mem.Allocator) void {│ ╰────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │130 if (clicked) |selected| { │ │131 if (selected != self.selected) { │ │132 self.selected = selected; │ │105 - try self.urlInput().setContent(allocator, self.protocols[selected].url); │ │133 + try self.textInput().setContent(allocator, self.protocols[selected].text);│ │134 } │ │107 - root_focus.setFocus(self.urlInput().getFocus().id); │ │135 + root_focus.setFocus(self.textInput().getFocus().id); │ │136 } │ │137 } │ │138 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │111 - const focused = root_focus.grandchild_id == self.urlInput().getFocus().id; │ │139 + const focused = root_focus.grandchild_id == self.textInput().getFocus().id;│ │140 for (0..self.protocol_count) |i| { │ │141 self.protocolLabel(i).options.border_style = if (i == self.selected) │ │142 (if (focused) .double else .single) │ ╰────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯