地圖 (Jido) is a lightweight Unix TUI file explorer designed for speed and simplicity.
at v1.3.0 26 kB view raw
1const std = @import("std"); 2const App = @import("./app.zig"); 3const config = &@import("./config.zig").config; 4const zuid = @import("zuid"); 5const environment = @import("./environment.zig"); 6const vaxis = @import("vaxis"); 7 8pub fn delete(app: *App) error{OutOfMemory}!void { 9 var message: ?[]const u8 = null; 10 defer if (message) |msg| app.alloc.free(msg); 11 12 const entry = (app.directories.getSelected() catch { 13 app.notification.write("Can not to delete item - no item selected.", .warn) catch {}; 14 return; 15 }) orelse return; 16 17 var prev_path_buf: [std.fs.max_path_bytes]u8 = undefined; 18 const prev_path = app.directories.dir.realpath(entry.name, &prev_path_buf) catch { 19 message = try std.fmt.allocPrint(app.alloc, "Failed to delete '{s}' - unable to retrieve absolute path.", .{entry.name}); 20 app.notification.write(message.?, .err) catch {}; 21 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 22 return; 23 }; 24 const prev_path_alloc = try app.alloc.dupe(u8, prev_path); 25 26 var trash_dir = dir: { 27 notfound: { 28 break :dir (config.trashDir() catch break :notfound) orelse break :notfound; 29 } 30 app.alloc.free(prev_path_alloc); 31 message = try std.fmt.allocPrint(app.alloc, "Failed to delete '{s}' - unable to retrieve trash directory.", .{entry.name}); 32 app.notification.write(message.?, .err) catch {}; 33 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 34 return; 35 }; 36 defer trash_dir.close(); 37 38 var trash_dir_path_buf: [std.fs.max_path_bytes]u8 = undefined; 39 const trash_dir_path = trash_dir.realpath(".", &trash_dir_path_buf) catch { 40 message = try std.fmt.allocPrint(app.alloc, "Failed to delete '{s}' - unable to retrieve absolute path for trash directory.", .{entry.name}); 41 app.notification.write(message.?, .err) catch {}; 42 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 43 return; 44 }; 45 46 if (std.mem.eql(u8, prev_path_alloc, trash_dir_path)) { 47 app.notification.write("Can not delete trash directory.", .warn) catch {}; 48 app.alloc.free(prev_path_alloc); 49 return; 50 } 51 52 const tmp_path = try std.fmt.allocPrint(app.alloc, "{s}/{s}-{s}", .{ trash_dir_path, entry.name, zuid.new.v4() }); 53 if (app.directories.dir.rename(entry.name, tmp_path)) { 54 if (app.actions.push(.{ 55 .delete = .{ .prev_path = prev_path_alloc, .new_path = tmp_path }, 56 })) |prev_elem| { 57 app.alloc.free(prev_elem.delete.prev_path); 58 app.alloc.free(prev_elem.delete.new_path); 59 } 60 message = try std.fmt.allocPrint(app.alloc, "Deleted '{s}'.", .{entry.name}); 61 app.notification.write(message.?, .info) catch {}; 62 63 app.directories.removeSelected(); 64 } else |err| { 65 app.alloc.free(prev_path_alloc); 66 app.alloc.free(tmp_path); 67 68 message = try std.fmt.allocPrint(app.alloc, "Failed to delete '{s}' - {}.", .{ entry.name, err }); 69 app.notification.write(message.?, .err) catch {}; 70 } 71} 72 73pub fn rename(app: *App) error{OutOfMemory}!void { 74 var message: ?[]const u8 = null; 75 defer if (message) |msg| app.alloc.free(msg); 76 77 const entry = (app.directories.getSelected() catch { 78 app.notification.write("Can not to rename item - no item selected.", .warn) catch {}; 79 return; 80 }) orelse return; 81 82 var dir_prefix_buf: [std.fs.max_path_bytes]u8 = undefined; 83 const dir_prefix = app.directories.dir.realpath(".", &dir_prefix_buf) catch { 84 message = try std.fmt.allocPrint(app.alloc, "Failed to rename '{s}' - unable to retrieve absolute path.", .{entry.name}); 85 app.notification.write(message.?, .err) catch {}; 86 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 87 return; 88 }; 89 90 const new_path = app.inputToSlice(); 91 92 if (environment.fileExists(app.directories.dir, new_path)) { 93 message = try std.fmt.allocPrint(app.alloc, "Can not rename file - '{s}' already exists.", .{new_path}); 94 app.notification.write(message.?, .warn) catch {}; 95 } else { 96 app.directories.dir.rename(entry.name, new_path) catch |err| { 97 message = try std.fmt.allocPrint(app.alloc, "Failed to rename '{s}' - {}.", .{ new_path, err }); 98 app.notification.write(message.?, .err) catch {}; 99 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 100 return; 101 }; 102 103 if (app.actions.push(.{ 104 .rename = .{ 105 .prev_path = try std.fs.path.join(app.alloc, &.{ dir_prefix, entry.name }), 106 .new_path = try std.fs.path.join(app.alloc, &.{ dir_prefix, new_path }), 107 }, 108 })) |prev_elem| { 109 app.alloc.free(prev_elem.rename.prev_path); 110 app.alloc.free(prev_elem.rename.new_path); 111 } 112 113 try app.repopulateDirectory(""); 114 app.text_input.clearAndFree(); 115 116 message = try std.fmt.allocPrint(app.alloc, "Renamed '{s}' to '{s}'.", .{ entry.name, new_path }); 117 app.notification.write(message.?, .info) catch {}; 118 } 119 120 app.text_input.clearAndFree(); 121} 122 123pub fn forceDelete(app: *App) error{OutOfMemory}!void { 124 const entry = (app.directories.getSelected() catch { 125 app.notification.write("Can not force delete item - no item selected.", .warn) catch {}; 126 return; 127 }) orelse return; 128 129 app.directories.dir.deleteTree(entry.name) catch |err| { 130 const error_message = try std.fmt.allocPrint(app.alloc, "Failed to force delete '{s}' - {}.", .{ entry.name, err }); 131 app.notification.write(error_message, .err) catch {}; 132 return; 133 }; 134 135 app.directories.removeSelected(); 136} 137 138pub fn toggleHiddenFiles(app: *App) error{OutOfMemory}!void { 139 config.show_hidden = !config.show_hidden; 140 141 const prev_selected_name: []const u8, const prev_selected_err: bool = lbl: { 142 const selected = app.directories.getSelected() catch break :lbl .{ "", true }; 143 if (selected == null) break :lbl .{ "", true }; 144 145 break :lbl .{ try app.alloc.dupe(u8, selected.?.name), false }; 146 }; 147 defer if (!prev_selected_err) app.alloc.free(prev_selected_name); 148 149 try app.repopulateDirectory(""); 150 app.text_input.clearAndFree(); 151 152 for (app.directories.entries.all()) |entry| { 153 if (std.mem.eql(u8, entry.name, prev_selected_name)) return; 154 app.directories.entries.selected += 1; 155 } 156 157 // If it didn't find entry, reset selected. 158 app.directories.entries.selected = 0; 159} 160 161pub fn yank(app: *App) error{OutOfMemory}!void { 162 var message: ?[]const u8 = null; 163 defer if (message) |msg| app.alloc.free(msg); 164 165 if (app.yanked) |yanked| { 166 app.alloc.free(yanked.dir); 167 app.alloc.free(yanked.entry.name); 168 } 169 170 app.yanked = lbl: { 171 const entry = (app.directories.getSelected() catch { 172 app.notification.write("Can not yank item - no item selected.", .warn) catch {}; 173 break :lbl null; 174 }) orelse break :lbl null; 175 176 switch (entry.kind) { 177 .file, .directory, .sym_link => { 178 break :lbl .{ 179 .dir = try app.alloc.dupe(u8, app.directories.fullPath(".") catch { 180 message = try std.fmt.allocPrint( 181 app.alloc, 182 "Failed to yank '{s}' - unable to retrieve directory path.", 183 .{entry.name}, 184 ); 185 app.notification.write(message.?, .err) catch {}; 186 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 187 break :lbl null; 188 }), 189 .entry = .{ 190 .kind = entry.kind, 191 .name = try app.alloc.dupe(u8, entry.name), 192 }, 193 }; 194 }, 195 else => { 196 message = try std.fmt.allocPrint(app.alloc, "Can not yank '{s}' - unsupported file type '{s}'.", .{ entry.name, @tagName(entry.kind) }); 197 app.notification.write(message.?, .warn) catch {}; 198 break :lbl null; 199 }, 200 } 201 }; 202 203 if (app.yanked) |y| { 204 message = try std.fmt.allocPrint(app.alloc, "Yanked '{s}'.", .{y.entry.name}); 205 app.notification.write(message.?, .info) catch {}; 206 } 207} 208 209pub fn paste(app: *App) error{ OutOfMemory, NoSpaceLeft }!void { 210 var message: ?[]const u8 = null; 211 defer if (message) |msg| app.alloc.free(msg); 212 213 const yanked = if (app.yanked) |y| y else return; 214 215 var new_path_buf: [std.fs.max_path_bytes]u8 = undefined; 216 const new_path_res = environment.checkDuplicatePath(&new_path_buf, app.directories.dir, yanked.entry.name) catch { 217 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - path too long.", .{yanked.entry.name}); 218 app.notification.write(message.?, .err) catch {}; 219 return; 220 }; 221 222 switch (yanked.entry.kind) { 223 .directory => { 224 var source_dir = std.fs.openDirAbsolute(yanked.dir, .{ .iterate = true }) catch { 225 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unable to open directory '{s}'.", .{ yanked.entry.name, yanked.dir }); 226 app.notification.write(message.?, .err) catch {}; 227 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 228 return; 229 }; 230 defer source_dir.close(); 231 232 var selected_dir = source_dir.openDir(yanked.entry.name, .{ .iterate = true }) catch { 233 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unable to open directory '{s}'.", .{ yanked.entry.name, yanked.entry.name }); 234 app.notification.write(message.?, .err) catch {}; 235 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 236 return; 237 }; 238 defer selected_dir.close(); 239 240 var walker = selected_dir.walk(app.alloc) catch |err| { 241 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unable to walk directory tree due to {}.", .{ yanked.entry.name, err }); 242 app.notification.write(message.?, .err) catch {}; 243 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 244 return; 245 }; 246 defer walker.deinit(); 247 248 // Make initial dir. 249 app.directories.dir.makeDir(new_path_res.path) catch |err| { 250 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unable to create new directory due to {}.", .{ yanked.entry.name, err }); 251 app.notification.write(message.?, .err) catch {}; 252 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 253 return; 254 }; 255 256 var errored = false; 257 var inner_path_buf: [std.fs.max_path_bytes]u8 = undefined; 258 while (walker.next() catch |err| { 259 message = try std.fmt.allocPrint(app.alloc, "Failed to copy one or more files - {}. A partial copy may have taken place.", .{err}); 260 app.notification.write(message.?, .err) catch {}; 261 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 262 return; 263 }) |entry| { 264 const path = try std.fmt.bufPrint(&inner_path_buf, "{s}{s}{s}", .{ new_path_res.path, std.fs.path.sep_str, entry.path }); 265 switch (entry.kind) { 266 .directory => { 267 app.directories.dir.makeDir(path) catch { 268 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unable to create containing directory '{s}'.", .{ entry.basename, path }); 269 app.notification.write(message.?, .err) catch {}; 270 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 271 errored = true; 272 }; 273 }, 274 .file, .sym_link => { 275 entry.dir.copyFile(entry.basename, app.directories.dir, path, .{}) catch |err| switch (err) { 276 error.FileNotFound => { 277 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - the original file was deleted or moved.", .{entry.path}); 278 app.notification.write(message.?, .err) catch {}; 279 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 280 errored = true; 281 }, 282 else => { 283 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - {}.", .{ entry.path, err }); 284 app.notification.write(message.?, .err) catch {}; 285 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 286 errored = true; 287 }, 288 }; 289 }, 290 else => { 291 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unsupported file type '{s}'.", .{ entry.path, @tagName(entry.kind) }); 292 app.notification.write(message.?, .err) catch {}; 293 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 294 errored = true; 295 }, 296 } 297 } 298 299 if (errored) { 300 app.notification.write("Failed to copy some items, check the log file for more details.", .err) catch {}; 301 } else { 302 message = try std.fmt.allocPrint(app.alloc, "Copied '{s}'.", .{yanked.entry.name}); 303 app.notification.write(message.?, .info) catch {}; 304 } 305 }, 306 .file, .sym_link => { 307 var source_dir = std.fs.openDirAbsolute(yanked.dir, .{ .iterate = true }) catch { 308 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - unable to open directory '{s}'.", .{ yanked.entry.name, yanked.dir }); 309 app.notification.write(message.?, .err) catch {}; 310 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 311 return; 312 }; 313 defer source_dir.close(); 314 315 std.fs.Dir.copyFile( 316 source_dir, 317 yanked.entry.name, 318 app.directories.dir, 319 new_path_res.path, 320 .{}, 321 ) catch |err| switch (err) { 322 error.FileNotFound => { 323 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - the original file was deleted or moved.", .{yanked.entry.name}); 324 app.notification.write(message.?, .err) catch {}; 325 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 326 return; 327 }, 328 else => { 329 message = try std.fmt.allocPrint(app.alloc, "Failed to copy '{s}' - {}.", .{ yanked.entry.name, err }); 330 app.notification.write(message.?, .err) catch {}; 331 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 332 return; 333 }, 334 }; 335 336 message = try std.fmt.allocPrint(app.alloc, "Copied '{s}'.", .{yanked.entry.name}); 337 app.notification.write(message.?, .info) catch {}; 338 }, 339 else => { 340 message = try std.fmt.allocPrint(app.alloc, "Can not copy '{s}' - unsupported file type '{s}'.", .{ yanked.entry.name, @tagName(yanked.entry.kind) }); 341 app.notification.write(message.?, .warn) catch {}; 342 return; 343 }, 344 } 345 346 // Append action to undo history. 347 var new_path_abs_buf: [std.fs.max_path_bytes]u8 = undefined; 348 const new_path_abs = app.directories.dir.realpath(new_path_res.path, &new_path_abs_buf) catch { 349 message = try std.fmt.allocPrint( 350 app.alloc, 351 "Failed to push copy action for '{s}' to undo history - unable to retrieve absolute directory path for '{s}'. This action will not be able to be undone via the `undo` keybind.", 352 .{ new_path_res.path, yanked.entry.name }, 353 ); 354 app.notification.write(message.?, .err) catch {}; 355 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 356 return; 357 }; 358 359 if (app.actions.push(.{ 360 .paste = try app.alloc.dupe(u8, new_path_abs), 361 })) |prev_elem| { 362 app.alloc.free(prev_elem.delete.prev_path); 363 app.alloc.free(prev_elem.delete.new_path); 364 } 365 366 try app.repopulateDirectory(""); 367 app.text_input.clearAndFree(); 368} 369 370pub fn traverseLeft(app: *App) error{OutOfMemory}!void { 371 app.text_input.clearAndFree(); 372 373 const dir = app.directories.dir.openDir("../", .{ .iterate = true }) catch |err| { 374 const message = try std.fmt.allocPrint(app.alloc, "Failed to read directory entries - {}.", .{err}); 375 defer app.alloc.free(message); 376 app.notification.write(message, .err) catch {}; 377 if (app.file_logger) |file_logger| file_logger.write(message, .err) catch {}; 378 return; 379 }; 380 381 app.directories.dir.close(); 382 app.directories.dir = dir; 383 384 try app.repopulateDirectory(""); 385 app.text_input.clearAndFree(); 386 387 if (app.directories.history.pop()) |history| { 388 if (history < app.directories.entries.len()) { 389 app.directories.entries.selected = history; 390 } 391 } 392} 393 394pub fn traverseRight(app: *App) !void { 395 var message: ?[]const u8 = null; 396 defer if (message) |msg| app.alloc.free(msg); 397 398 const entry = (app.directories.getSelected() catch { 399 app.notification.write("Can not rename item - no item selected.", .warn) catch {}; 400 return; 401 }) orelse return; 402 403 switch (entry.kind) { 404 .directory => { 405 app.text_input.clearAndFree(); 406 407 const dir = app.directories.dir.openDir(entry.name, .{ .iterate = true }) catch |err| { 408 message = try std.fmt.allocPrint(app.alloc, "Failed to read directory entries - {}.", .{err}); 409 app.notification.write(message.?, .err) catch {}; 410 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 411 return; 412 }; 413 414 app.directories.dir.close(); 415 app.directories.dir = dir; 416 _ = app.directories.history.push(app.directories.entries.selected); 417 try app.repopulateDirectory(""); 418 app.text_input.clearAndFree(); 419 }, 420 .file => { 421 if (environment.getEditor()) |editor| { 422 try app.vx.exitAltScreen(app.tty.anyWriter()); 423 try app.vx.resetState(app.tty.anyWriter()); 424 app.loop.stop(); 425 426 environment.openFile(app.alloc, app.directories.dir, entry.name, editor) catch |err| { 427 message = try std.fmt.allocPrint(app.alloc, "Failed to open file '{s}' - {}.", .{ entry.name, err }); 428 app.notification.write(message.?, .err) catch {}; 429 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 430 }; 431 432 try app.loop.start(); 433 try app.vx.enterAltScreen(app.tty.anyWriter()); 434 try app.vx.enableDetectedFeatures(app.tty.anyWriter()); 435 app.vx.queueRefresh(); 436 } else { 437 app.notification.write("Can not open file - $EDITOR not set.", .warn) catch {}; 438 } 439 }, 440 else => {}, 441 } 442} 443 444pub fn createNewDir(app: *App) error{OutOfMemory}!void { 445 var message: ?[]const u8 = null; 446 defer if (message) |msg| app.alloc.free(msg); 447 448 const dir = app.inputToSlice(); 449 450 app.directories.dir.makeDir(dir) catch |err| { 451 message = try std.fmt.allocPrint(app.alloc, "Failed to create directory '{s}' - {}", .{ dir, err }); 452 app.notification.write(message.?, .err) catch {}; 453 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 454 app.text_input.clearAndFree(); 455 return; 456 }; 457 458 try app.repopulateDirectory(""); 459 app.text_input.clearAndFree(); 460 461 message = try std.fmt.allocPrint(app.alloc, "Created new directory '{s}'.", .{dir}); 462 app.notification.write(message.?, .info) catch {}; 463} 464 465pub fn createNewFile(app: *App) error{OutOfMemory}!void { 466 var message: ?[]const u8 = null; 467 defer if (message) |msg| app.alloc.free(msg); 468 469 const file = app.inputToSlice(); 470 471 if (environment.fileExists(app.directories.dir, file)) { 472 message = try std.fmt.allocPrint(app.alloc, "Can not create file - '{s}' already exists.", .{file}); 473 app.notification.write(message.?, .warn) catch {}; 474 } else { 475 _ = app.directories.dir.createFile(file, .{}) catch |err| { 476 message = try std.fmt.allocPrint(app.alloc, "Failed to create file '{s}' - {}", .{ file, err }); 477 app.notification.write(message.?, .err) catch {}; 478 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 479 app.text_input.clearAndFree(); 480 return; 481 }; 482 483 try app.repopulateDirectory(""); 484 app.text_input.clearAndFree(); 485 486 message = try std.fmt.allocPrint(app.alloc, "Created new file '{s}'.", .{file}); 487 app.notification.write(message.?, .info) catch {}; 488 } 489 490 app.text_input.clearAndFree(); 491} 492 493pub fn undo(app: *App) error{OutOfMemory}!void { 494 var message: ?[]const u8 = null; 495 defer if (message) |msg| app.alloc.free(msg); 496 497 const action = app.actions.pop() orelse { 498 app.notification.write("There is nothing to undo.", .info) catch {}; 499 return; 500 }; 501 502 const selected = app.directories.entries.selected; 503 504 switch (action) { 505 .delete => |a| { 506 defer app.alloc.free(a.new_path); 507 defer app.alloc.free(a.prev_path); 508 509 var new_path_buf: [std.fs.max_path_bytes]u8 = undefined; 510 const new_path_res = environment.checkDuplicatePath(&new_path_buf, app.directories.dir, a.prev_path) catch { 511 message = try std.fmt.allocPrint(app.alloc, "Failed to undo delete '{s}' - path too long.", .{a.prev_path}); 512 app.notification.write(message.?, .err) catch {}; 513 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 514 return; 515 }; 516 517 app.directories.dir.rename(a.new_path, new_path_res.path) catch |err| { 518 message = try std.fmt.allocPrint(app.alloc, "Failed to undo delete for '{s}' - {}.", .{ a.prev_path, err }); 519 app.notification.write(message.?, .err) catch {}; 520 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 521 return; 522 }; 523 524 try app.repopulateDirectory(""); 525 app.text_input.clearAndFree(); 526 527 message = try std.fmt.allocPrint(app.alloc, "Restored '{s}' as '{s}'.", .{ a.prev_path, new_path_res.path }); 528 app.notification.write(message.?, .info) catch {}; 529 }, 530 .rename => |a| { 531 defer app.alloc.free(a.new_path); 532 defer app.alloc.free(a.prev_path); 533 534 var new_path_buf: [std.fs.max_path_bytes]u8 = undefined; 535 const new_path_res = environment.checkDuplicatePath(&new_path_buf, app.directories.dir, a.prev_path) catch { 536 message = try std.fmt.allocPrint(app.alloc, "Failed to undo rename '{s}' - path too long.", .{a.prev_path}); 537 app.notification.write(message.?, .err) catch {}; 538 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 539 return; 540 }; 541 542 app.directories.dir.rename(a.new_path, new_path_res.path) catch |err| { 543 message = try std.fmt.allocPrint(app.alloc, "Failed to undo rename for '{s}' - {}.", .{ a.new_path, err }); 544 app.notification.write(message.?, .err) catch {}; 545 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 546 return; 547 }; 548 549 try app.repopulateDirectory(""); 550 app.text_input.clearAndFree(); 551 552 message = try std.fmt.allocPrint(app.alloc, "Reverted renaming of '{s}', now '{s}'.", .{ a.new_path, new_path_res.path }); 553 app.notification.write(message.?, .info) catch {}; 554 }, 555 .paste => |path| { 556 defer app.alloc.free(path); 557 558 app.directories.dir.deleteTree(path) catch |err| { 559 message = try std.fmt.allocPrint(app.alloc, "Failed to delete '{s}' - {}.", .{ path, err }); 560 app.notification.write(message.?, .err) catch {}; 561 if (app.file_logger) |file_logger| file_logger.write(message.?, .err) catch {}; 562 return; 563 }; 564 565 try app.repopulateDirectory(""); 566 app.text_input.clearAndFree(); 567 }, 568 } 569 570 app.directories.entries.selected = selected; 571}