diff --git a/librz/core/cmd/cmd.c b/librz/core/cmd/cmd.c index eb950ed426b..1d6870e792c 100644 --- a/librz/core/cmd/cmd.c +++ b/librz/core/cmd/cmd.c @@ -44,15 +44,6 @@ static const char *help_msg_vertical_bar[] = { NULL }; -static const char *help_msg_v[] = { - "Usage:", "v[*i]", "", - "v", "", "open visual panels", - "v", " test", "load saved layout with name test", - "v=", " test", "save current layout with name test", - "vi", " test", "open the file test in 'cfg.editor'", - NULL -}; - RZ_API void rz_core_cmd_help(const RzCore *core, const char *help[]) { rz_cons_cmd_help(help, core->print->flags & RZ_PRINT_FLAGS_COLOR); } @@ -385,60 +376,6 @@ RZ_IPI void rz_core_kuery_print(RzCore *core, const char *k) { free(out); } -RZ_IPI int rz_cmd_panels(void *data, const char *input) { - RzCore *core = (RzCore *)data; - RzCoreVisual *visual = core->visual; - if (core->vmode) { - return false; - } - if (!rz_cons_is_interactive()) { - RZ_LOG_ERROR("core: Panel mode requires scr.interactive=true.\n"); - return false; - } - char *sp = strchr(input, ' '); - switch (input[0]) { - case ' ': // "v [name]" - if (visual->panels_root->active_tab) { - rz_load_panels_layout(core, input + 1); - } - rz_config_set(core->config, "scr.layout", input + 1); - return true; - case '=': // "v= [name]" - rz_save_panels_layout(core, input + 1); - rz_config_set(core->config, "scr.layout", input + 1); - return true; - case 'i': // "vi [file]" - if (sp) { - char *r = rz_core_editor(core, sp + 1, NULL); - if (r) { - free(r); - } else { - RZ_LOG_ERROR("core: Cannot open file (%s)\n", sp + 1); - } - } - ////rz_sys_cmdf ("v%s", input); - return false; - case 0: - rz_core_visual_panels_root(core, visual->panels_root); - return true; - default: - rz_core_cmd_help(core, help_msg_v); - return false; - } -} - -RZ_IPI int rz_cmd_visual(void *data, const char *input) { - RzCore *core = (RzCore *)data; - if (core->http_up) { - return false; - } - if (!rz_cons_is_interactive()) { - RZ_LOG_ERROR("core: Visual mode requires scr.interactive=true.\n"); - return false; - } - return rz_core_visual((RzCore *)data, input); -} - RZ_IPI RzCmdStatus rz_push_escaped_handler(RzCore *core, int argc, const char **argv) { char *input = rz_str_array_join(argv + 1, argc - 1, " "); int len = rz_str_unescape(input); @@ -5282,8 +5219,6 @@ RZ_API void rz_core_cmd_init(RzCore *core) { } cmds[] = { { "/", "search kw, pattern aes", rz_cmd_search }, { "p", "print current block", rz_cmd_print }, - { "V", "enter visual mode", rz_cmd_visual }, - { "v", "enter visual mode", rz_cmd_panels }, { "x", "alias for px", rz_cmd_hexdump }, }; diff --git a/librz/core/cmd/cmd_api.c b/librz/core/cmd/cmd_api.c index e6742234025..4d3e07e2d03 100644 --- a/librz/core/cmd/cmd_api.c +++ b/librz/core/cmd/cmd_api.c @@ -162,12 +162,14 @@ static RzCmdDesc *create_cmd_desc(RzCmd *cmd, RzCmdDesc *parent, RzCmdDescType t res->type = type; res->name = rz_str_dup(name); if (!res->name) { + RZ_LOG_ERROR("Failed to duplicate cmd name.\n"); goto err; } res->n_children = 0; res->help = help ? help : ¬_defined_help; rz_pvector_init(&res->children, (RzPVectorFree)cmd_desc_free); if (ht_insert && !ht_sp_insert(cmd->ht_cmds, name, res)) { + RZ_LOG_WARN("Command already in hash table. Previous command has been replaced.\n"); goto err; } cmd_desc_set_parent(cmd, res, parent); diff --git a/librz/core/cmd/cmd_interactive.c b/librz/core/cmd/cmd_interactive.c new file mode 100644 index 00000000000..bfde788f894 --- /dev/null +++ b/librz/core/cmd/cmd_interactive.c @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2024 Rot127 +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include +#include + +#include "../core_private.h" + +RZ_IPI RzCmdStatus rz_interactive_visual_handler(RzCore *core, int argc, const char **argv) { + if (core->http_up) { + RZ_LOG_ERROR("core->http_up=false.\n"); + return RZ_CMD_STATUS_ERROR; + } + if (!rz_cons_is_interactive()) { + RZ_LOG_ERROR("Visual mode requires scr.interactive=true.\n"); + return RZ_CMD_STATUS_ERROR; + } + const char *v_commands = argc > 1 ? argv[1] : ""; + rz_core_visual(core, v_commands); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_interactive_visual_disas_handler(RzCore *core, int argc, const char **argv) { + rz_core_visual(core, "p"); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_interactive_visual_emu_handler(RzCore *core, int argc, const char **argv) { + rz_core_visual(core, "pp"); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_interactive_visual_help_handler(RzCore *core, int argc, const char **argv) { + rz_core_cmd_help(core, rz_core_visual_get_short_help()); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_interactive_visual_help_detail_handler(RzCore *core, int argc, const char **argv) { + rz_core_cmd_help(core, rz_core_visual_get_long_help()); + rz_cons_printf("%s\n", "Function Keys: (See 'e key.'), defaults to"); + rz_core_cmd_help(core, rz_core_visual_get_fcn_help()); + return RZ_CMD_STATUS_OK; +} diff --git a/librz/core/cmd/cmd_interactive_panel.c b/librz/core/cmd/cmd_interactive_panel.c new file mode 100644 index 00000000000..d6dd9a7e8c5 --- /dev/null +++ b/librz/core/cmd/cmd_interactive_panel.c @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2024 Rot127 +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include +#include + +#include "../core_private.h" + +RZ_IPI RzCmdStatus rz_interactive_panel_handler(RzCore *core, int argc, const char **argv) { + if (core->vmode) { + RZ_LOG_ERROR("core->vmode == false.\n"); + return RZ_CMD_STATUS_ERROR; + } + if (!rz_cons_is_interactive()) { + RZ_LOG_ERROR("Panel mode requires scr.interactive=true.\n"); + return RZ_CMD_STATUS_ERROR; + } + + RzCoreVisual *visual = core->visual; + if (rz_core_visual_panels_root(core, visual->panels_root)) { + return RZ_CMD_STATUS_OK; + } + RZ_LOG_ERROR("rz_core_visual_panels_root() failed\n"); + return RZ_CMD_STATUS_ERROR; +} + +RZ_IPI RzCmdStatus rz_interactive_panel_load_handler(RzCore *core, int argc, const char **argv) { + RzCoreVisual *visual = core->visual; + + if (visual && visual->panels_root && visual->panels_root->active_tab) { + rz_load_panels_layout(core, argv[1]); + } + rz_config_set(core->config, "scr.layout", argv[1]); + RZ_LOG_INFO("Set scr.layout = %s", argv[1]); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_interactive_panel_store_handler(RzCore *core, int argc, const char **argv) { + rz_save_panels_layout(core, argv[1]); + + rz_return_val_if_fail(core->config, RZ_CMD_STATUS_ERROR); + rz_config_set(core->config, "scr.layout", argv[1]); + return RZ_CMD_STATUS_OK; +} diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index 31ac8f5a8e6..5ee50914cf6 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -66,6 +66,7 @@ static const RzCmdDescDetail query_sdb_get_set_details[2]; static const RzCmdDescDetail cmd_print_byte_array_details[3]; static const RzCmdDescDetail pf_details[3]; static const RzCmdDescDetail print_rising_and_falling_entropy_details[2]; +static const RzCmdDescDetail interactive_visual_details[2]; static const RzCmdDescDetail write_details[3]; static const RzCmdDescDetail write_bits_details[2]; static const RzCmdDescDetail wv_details[2]; @@ -789,6 +790,9 @@ static const RzCmdDescArg type_union_c_args[2]; static const RzCmdDescArg type_union_c_nl_args[2]; static const RzCmdDescArg type_xrefs_list_args[2]; static const RzCmdDescArg type_xrefs_function_args[2]; +static const RzCmdDescArg interactive_visual_args[2]; +static const RzCmdDescArg interactive_panel_load_args[2]; +static const RzCmdDescArg interactive_panel_store_args[2]; static const RzCmdDescArg write_args[2]; static const RzCmdDescArg write_bits_args[2]; static const RzCmdDescArg write_unset_bits_args[2]; @@ -17435,12 +17439,103 @@ static const RzCmdDescHelp type_xrefs_list_all_help = { .args = type_xrefs_list_all_args, }; -static const RzCmdDescHelp cmd_visual_help = { - .summary = "Enter visual mode", +static const RzCmdDescHelp V_help = { + .summary = "Interactive mode", }; +static const RzCmdDescDetailEntry interactive_visual_Parameters_detail_entries[] = { + { .text = "V", .arg_str = " ", .comment = "The argument is a string of keys to press directly after entering the visual mode. See 'VH' or 'VHH' for a full list of valid keys." }, + { 0 }, +}; +static const RzCmdDescDetail interactive_visual_details[] = { + { .name = "Parameters", .entries = interactive_visual_Parameters_detail_entries }, + { 0 }, +}; +static const RzCmdDescArg interactive_visual_args[] = { + { + .name = "key-sequence", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp interactive_visual_help = { + .summary = "Enter interactive visual mode", + .description = "Use Rizin (mostly) without shell. Scrolling disassembly, debugging, searching or graph views. All with a few keyboard shortcuts.", + .details = interactive_visual_details, + .args = interactive_visual_args, +}; + +static const RzCmdDescArg interactive_visual_help_args[] = { + { 0 }, +}; +static const RzCmdDescHelp interactive_visual_help_help = { + .summary = "Show most common keys shortcuts of the visual mode.", + .args = interactive_visual_help_args, +}; + +static const RzCmdDescArg interactive_visual_help_detail_args[] = { + { 0 }, +}; +static const RzCmdDescHelp interactive_visual_help_detail_help = { + .summary = "Show all keys shortcuts of the visual mode.", + .args = interactive_visual_help_detail_args, +}; + +static const RzCmdDescArg interactive_visual_disas_args[] = { + { 0 }, +}; +static const RzCmdDescHelp interactive_visual_disas_help = { + .summary = "Enter interactive visual mode and select next mode (alias for 'V p').", + .args = interactive_visual_disas_args, +}; + +static const RzCmdDescArg interactive_visual_emu_args[] = { + { 0 }, +}; +static const RzCmdDescHelp interactive_visual_emu_help = { + .summary = "Enter interactive visual mode and select the mode after next (alias for 'V pp').", + .args = interactive_visual_emu_args, +}; + +static const RzCmdDescHelp v_help = { + .summary = "Interactive panel mode", +}; +static const RzCmdDescArg interactive_panel_args[] = { + { 0 }, +}; +static const RzCmdDescHelp interactive_panel_help = { + .summary = "Enter interactive panel mode", + .args = interactive_panel_args, +}; + +static const RzCmdDescArg interactive_panel_load_args[] = { + { + .name = "name", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp interactive_panel_load_help = { + .summary = "Load panel layout", + .args = interactive_panel_load_args, +}; + +static const RzCmdDescArg interactive_panel_store_args[] = { + { + .name = "name", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, -static const RzCmdDescHelp cmd_panels_help = { - .summary = "Enter visual panel mode", + }, + { 0 }, +}; +static const RzCmdDescHelp interactive_panel_store_help = { + .summary = "Store panel layout", + .args = interactive_panel_store_args, }; static const RzCmdDescHelp w_help = { @@ -22950,11 +23045,27 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *type_xrefs_list_all_cd = rz_cmd_desc_argv_new(core->rcmd, tx_cd, "txl", rz_type_xrefs_list_all_handler, &type_xrefs_list_all_help); rz_warn_if_fail(type_xrefs_list_all_cd); - RzCmdDesc *cmd_visual_cd = rz_cmd_desc_oldinput_new(core->rcmd, root_cd, "V", rz_cmd_visual, &cmd_visual_help); - rz_warn_if_fail(cmd_visual_cd); + RzCmdDesc *V_cd = rz_cmd_desc_group_new(core->rcmd, root_cd, "V", rz_interactive_visual_handler, &interactive_visual_help, &V_help); + rz_warn_if_fail(V_cd); + RzCmdDesc *interactive_visual_help_cd = rz_cmd_desc_argv_new(core->rcmd, V_cd, "VH", rz_interactive_visual_help_handler, &interactive_visual_help_help); + rz_warn_if_fail(interactive_visual_help_cd); + + RzCmdDesc *interactive_visual_help_detail_cd = rz_cmd_desc_argv_new(core->rcmd, V_cd, "VHH", rz_interactive_visual_help_detail_handler, &interactive_visual_help_detail_help); + rz_warn_if_fail(interactive_visual_help_detail_cd); + + RzCmdDesc *interactive_visual_disas_cd = rz_cmd_desc_argv_new(core->rcmd, V_cd, "Vp", rz_interactive_visual_disas_handler, &interactive_visual_disas_help); + rz_warn_if_fail(interactive_visual_disas_cd); + + RzCmdDesc *interactive_visual_emu_cd = rz_cmd_desc_argv_new(core->rcmd, V_cd, "Vpp", rz_interactive_visual_emu_handler, &interactive_visual_emu_help); + rz_warn_if_fail(interactive_visual_emu_cd); + + RzCmdDesc *v_cd = rz_cmd_desc_group_new(core->rcmd, root_cd, "v", rz_interactive_panel_handler, &interactive_panel_help, &v_help); + rz_warn_if_fail(v_cd); + RzCmdDesc *interactive_panel_load_cd = rz_cmd_desc_argv_new(core->rcmd, v_cd, "vl", rz_interactive_panel_load_handler, &interactive_panel_load_help); + rz_warn_if_fail(interactive_panel_load_cd); - RzCmdDesc *cmd_panels_cd = rz_cmd_desc_oldinput_new(core->rcmd, root_cd, "v", rz_cmd_panels, &cmd_panels_help); - rz_warn_if_fail(cmd_panels_cd); + RzCmdDesc *interactive_panel_store_cd = rz_cmd_desc_argv_new(core->rcmd, v_cd, "vs", rz_interactive_panel_store_handler, &interactive_panel_store_help); + rz_warn_if_fail(interactive_panel_store_cd); RzCmdDesc *w_cd = rz_cmd_desc_group_new(core->rcmd, root_cd, "w", rz_write_handler, &write_help, &w_help); rz_warn_if_fail(w_cd); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index 89268862deb..1c01565171b 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -2371,9 +2371,21 @@ RZ_IPI RzCmdStatus rz_type_xrefs_graph_handler(RzCore *core, int argc, const cha // "txl" RZ_IPI RzCmdStatus rz_type_xrefs_list_all_handler(RzCore *core, int argc, const char **argv); // "V" -RZ_IPI int rz_cmd_visual(void *data, const char *input); +RZ_IPI RzCmdStatus rz_interactive_visual_handler(RzCore *core, int argc, const char **argv); +// "VH" +RZ_IPI RzCmdStatus rz_interactive_visual_help_handler(RzCore *core, int argc, const char **argv); +// "VHH" +RZ_IPI RzCmdStatus rz_interactive_visual_help_detail_handler(RzCore *core, int argc, const char **argv); +// "Vp" +RZ_IPI RzCmdStatus rz_interactive_visual_disas_handler(RzCore *core, int argc, const char **argv); +// "Vpp" +RZ_IPI RzCmdStatus rz_interactive_visual_emu_handler(RzCore *core, int argc, const char **argv); // "v" -RZ_IPI int rz_cmd_panels(void *data, const char *input); +RZ_IPI RzCmdStatus rz_interactive_panel_handler(RzCore *core, int argc, const char **argv); +// "vl" +RZ_IPI RzCmdStatus rz_interactive_panel_load_handler(RzCore *core, int argc, const char **argv); +// "vs" +RZ_IPI RzCmdStatus rz_interactive_panel_store_handler(RzCore *core, int argc, const char **argv); // "w" RZ_IPI RzCmdStatus rz_write_handler(RzCore *core, int argc, const char **argv); // "wB" diff --git a/librz/core/cmd_descs/cmd_descs.yaml b/librz/core/cmd_descs/cmd_descs.yaml index 46d58916db7..5a0c71bc2d2 100644 --- a/librz/core/cmd_descs/cmd_descs.yaml +++ b/librz/core/cmd_descs/cmd_descs.yaml @@ -263,13 +263,11 @@ commands: summary: Types, noreturn, signatures, C parser and more subcommands: cmd_type - name: V - cname: cmd_visual - summary: Enter visual mode - type: RZ_CMD_DESC_TYPE_OLDINPUT + summary: Interactive mode + subcommands: cmd_interactive - name: v - cname: cmd_panels - summary: Enter visual panel mode - type: RZ_CMD_DESC_TYPE_OLDINPUT + summary: Interactive panel mode + subcommands: cmd_interactive_panel - name: w summary: Write commands subcommands: cmd_write diff --git a/librz/core/cmd_descs/cmd_interactive.yaml b/librz/core/cmd_descs/cmd_interactive.yaml new file mode 100644 index 00000000000..1306423d79a --- /dev/null +++ b/librz/core/cmd_descs/cmd_interactive.yaml @@ -0,0 +1,40 @@ +# SPDX-FileCopyrightText: 2024 RizinOrg +# SPDX-License-Identifier: LGPL-3.0-only +--- +name: cmd_interactive +commands: + - name: V + cname: interactive_visual + summary: Enter interactive visual mode + description: > + Use Rizin (mostly) without shell. + Scrolling disassembly, debugging, searching or graph views. + All with a few keyboard shortcuts. + args: + - name: key-sequence + type: RZ_CMD_ARG_TYPE_STRING + optional: true + details: + - name: Parameters + entries: + - text: "V" + arg_str: " " + comment: > + The argument is a string of keys to press directly after entering the visual mode. + See 'VH' or 'VHH' for a full list of valid keys. + - name: VH + cname: interactive_visual_help + summary: Show most common keys shortcuts of the visual mode. + args: [] + - name: VHH + cname: interactive_visual_help_detail + summary: Show all keys shortcuts of the visual mode. + args: [] + - name: Vp + cname: interactive_visual_disas + summary: Enter interactive visual mode and select next mode (alias for 'V p'). + args: [] + - name: Vpp + cname: interactive_visual_emu + summary: Enter interactive visual mode and select the mode after next (alias for 'V pp'). + args: [] diff --git a/librz/core/cmd_descs/cmd_interactive_panel.yaml b/librz/core/cmd_descs/cmd_interactive_panel.yaml new file mode 100644 index 00000000000..5c805441f2e --- /dev/null +++ b/librz/core/cmd_descs/cmd_interactive_panel.yaml @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2024 RizinOrg +# SPDX-License-Identifier: LGPL-3.0-only +--- +name: cmd_interactive_panel +commands: + - name: v + summary: Enter interactive panel mode + cname: interactive_panel + args: [] + - name: vl + summary: Load panel layout + cname: interactive_panel_load + args: + - name: name + type: RZ_CMD_ARG_TYPE_STRING + - name: vs + summary: Store panel layout + cname: interactive_panel_store + args: + - name: name + type: RZ_CMD_ARG_TYPE_STRING + diff --git a/librz/core/cmd_descs/meson.build b/librz/core/cmd_descs/meson.build index bd3d7373e16..beacf2d42d4 100644 --- a/librz/core/cmd_descs/meson.build +++ b/librz/core/cmd_descs/meson.build @@ -13,6 +13,8 @@ cmd_descs_yaml = files( 'cmd_heap_glibc.yaml', 'cmd_history.yaml', 'cmd_info.yaml', + 'cmd_interactive.yaml', + 'cmd_interactive_panel.yaml', 'cmd_interpret.yaml', 'cmd_macro.yaml', 'cmd_math.yaml', diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 5fd2918a79e..01807187a34 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -444,6 +444,9 @@ RZ_IPI void rz_core_visual_nexttab(RzCore *core); RZ_IPI void rz_core_visual_prevtab(RzCore *core); RZ_IPI void rz_core_visual_closetab(RzCore *core); +RZ_IPI const char **rz_core_visual_get_short_help(); +RZ_IPI const char **rz_core_visual_get_long_help(); +RZ_IPI const char **rz_core_visual_get_fcn_help(); RZ_IPI int rz_core_visual(RzCore *core, const char *input); RZ_IPI int rz_core_visual_graph(RzCore *core, RzAGraph *g, RzAnalysisFunction *_fcn, int is_interactive); RZ_IPI bool rz_core_visual_panels_root(RzCore *core, RzPanelsRoot *panels_root); diff --git a/librz/core/meson.build b/librz/core/meson.build index 22208a2ee72..296b0df3b5b 100644 --- a/librz/core/meson.build +++ b/librz/core/meson.build @@ -83,6 +83,8 @@ rz_core_sources = [ #'cmd/cmd_help.c', 'cmd/cmd_history.c', 'cmd/cmd_info.c', + 'cmd/cmd_interactive.c', + 'cmd/cmd_interactive_panel.c', 'cmd/cmd_interpret.c', 'cmd/cmd_macro.c', #'cmd/cmd_magic.c', diff --git a/librz/core/tui/panels.c b/librz/core/tui/panels.c index 28a480eb0ab..ca9797719a8 100644 --- a/librz/core/tui/panels.c +++ b/librz/core/tui/panels.c @@ -366,8 +366,6 @@ static void __panel_prompt(const char *prompt, char *buf, int len); static void __panels_layout_refresh(RzCore *core); static void __panels_layout(RzPanelsTab *tab); static void __layout_default(RzPanelsTab *tab); -RZ_IPI void rz_save_panels_layout(RzCore *core, const char *_name); -RZ_IPI bool rz_load_panels_layout(RzCore *core, const char *_name); static void __split_panel_vertical(RzCore *core, RzPanel *p, const char *name, const char *cmd); static void __split_panel_horizontal(RzCore *core, RzPanel *p, const char *name, const char *cmd); static void __panel_print(RzCore *core, RzConsCanvas *can, RzPanel *panel, int color); diff --git a/librz/core/tui/visual.c b/librz/core/tui/visual.c index 100bf442aad..cdbc038cd8a 100644 --- a/librz/core/tui/visual.c +++ b/librz/core/tui/visual.c @@ -254,85 +254,97 @@ static bool __core_visual_gogo(RzCore *core, int ch) { } static const char *help_visual[] = { - "?", "full help", - "!", "enter panels", - "a", "code analysis", - "b", "browse mode", - "c", "toggle cursor", - "d", "debugger / emulator", - "e", "toggle configurations", - "i", "insert / write", - "m", "moving around (seeking)", - "p", "print commands and modes", - "v", "view management", + "?", "", "full help", + "!", "", "enter panels", + "a", "", "code analysis", + "b", "", "browse mode", + "c", "", "toggle cursor", + "d", "", "debugger / emulator", + "e", "", "toggle configurations", + "i", "", "insert / write", + "m", "", "moving around (seeking)", + "p", "", "print commands and modes", + "v", "", "view management", NULL }; static const char *help_msg_visual[] = { - "?", "show visual help menu", - "??", "show this help", - "$", "set the program counter to the current offset + cursor", - "&", "rotate asm.bits between 8, 16, 32 and 64 applying hints", - "%", "in cursor mode finds matching pair, otherwise toggle autoblocksz", - "^", "seek to the beginning of the function", - "!", "enter into the visual panels mode", - "TAB", "switch to the next print mode (or element in cursor mode)", - "_", "enter the flag/comment/functions/.. hud (same as VF_)", - "=", "set cmd.vprompt (top row)", - "|", "set cmd.cprompt (right column)", - ".", "seek to program counter", - "#", "toggle decompiler comments in disasm (see pdd* from jsdec)", - "\\", "toggle visual split mode", - "\"", "toggle the column mode (uses pC..)", - "/", "in cursor mode search in current block", - ")", "toggle emu.str", - ":cmd", "run rizin command", - ";[-]cmt", "add/remove comment", - "0", "seek to beginning of current function", - "[1-9]", "follow jmp/call identified by shortcut (like ;[1])", - ",file", "add a link to the text file", - "/*+-[]", "change block size, [] = resize hex.cols", - "<,>", "seek aligned to block size (in cursor slurp or dump files)", - "a/A", "(a)ssemble code, visual (A)ssembler", - "b", "browse evals, symbols, flags, evals, classes, ...", - "B", "toggle breakpoint", - "c/C", "toggle (c)ursor and (C)olors", - "d[f?]", "define function, data, code, ..", - "D", "enter visual diff mode (set diff.from/to)", - "f/F", "set/unset or browse flags. f- to unset, F to browse, ..", - "hjkl", "move around (left-down-up-right)", - "HJKL", "select in cursor mode (left-down-up-right)", - "i", "insert hex or string (in hexdump) use tab to toggle", - "I", "insert hexpair block ", - "mK/'K", "mark/go to Key (any key)", - "n/N", "seek next/prev function/flag/hit (scr.nkey)", - "g", "go/seek to given offset (g[g/G] to seek begin/end of file)", - "o/O", "rotate between different formats (next/prev)", - "p/P", "rotate print modes (hex, disasm, debug, words, buf)", - "q", "back to rizin shell", - "r", "toggle call/jmp/lea hints", - "R", "changes the theme or randomizes colors if scr.randpal option is true.", - "sS", "step / step over", - "tT", "tt new tab, t[1-9] switch to nth tab, t= name tab, t- close tab", - "uU", "undo/redo seek", - "v", "visual function/vars code analysis menu", - "V", "(V)iew interactive ascii art graph (agfv)", - "wW", "seek cursor to next/prev word", - "xX", "show xrefs/refs of current function from/to data/code", - "yY", "copy and paste selection", - "Enter", "follow address of jump/call", + "?", "", "show visual help menu", + "??", "", "show this help", + "$", "", "set the program counter to the current offset + cursor", + "&", "", "rotate asm.bits between 8, 16, 32 and 64 applying hints", + "%", "", "in cursor mode finds matching pair, otherwise toggle autoblocksz", + "^", "", "seek to the beginning of the function", + "!", "", "enter into the visual panels mode", + "TAB", "", "switch to the next print mode (or element in cursor mode)", + "_", "", "enter the flag/comment/functions/.. hud (same as VF_)", + "=", "", "set cmd.vprompt (top row)", + "|", "", "set cmd.cprompt (right column)", + ".", "", "seek to program counter", + "#", "", "toggle decompiler comments in disasm (see pdd* from jsdec)", + "\\", "", "toggle visual split mode", + "\"", "", "toggle the column mode (uses pC..)", + "/", "", "in cursor mode search in current block", + ")", "", "toggle emu.str", + ":cmd", "", "run rizin command", + ";[-]cmt", "", "add/remove comment", + "0", "", "seek to beginning of current function", + "[1-9]", "", "follow jmp/call identified by shortcut (like ;[1])", + ",file", "", "add a link to the text file", + "/*+-[]", "", "change block size, [] = resize hex.cols", + "<,>", "", "seek aligned to block size (in cursor slurp or dump files)", + "a/A", "", "(a)ssemble code, visual (A)ssembler", + "b", "", "browse evals, symbols, flags, evals, classes, ...", + "B", "", "toggle breakpoint", + "c/C", "", "toggle (c)ursor and (C)olors", + "d[f?]", "", "define function, data, code, ..", + "D", "", "enter visual diff mode (set diff.from/to)", + "f/F", "", "set/unset or browse flags. f- to unset, F to browse, ..", + "hjkl", "", "move around (left-down-up-right)", + "HJKL", "", "select in cursor mode (left-down-up-right)", + "i", "", "insert hex or string (in hexdump) use tab to toggle", + "I", "", "insert hexpair block", + "mK/'K", "", "mark/go to Key (any key)", + "n/N", "", "seek next/prev function/flag/hit (scr.nkey)", + "g", "", "go/seek to given offset (g[g/G] to seek begin/end of file)", + "o/O", "", "rotate between different formats (next/prev)", + "p/P", "", "rotate print modes (hex, disasm, debug, words, buf)", + "q", "", "back to rizin shell", + "r", "", "toggle call/jmp/lea hints", + "R", "", "changes the theme or randomizes colors if scr.randpal option is true.", + "sS", "", "step / step over", + "tT", "", "tt new tab, t[1-9] switch to nth tab, t= name tab, t- close tab", + "uU", "", "undo/redo seek", + "v", "", "visual function/vars code analysis menu", + "V", "", "(V)iew interactive ascii art graph (agfv)", + "wW", "", "seek cursor to next/prev word", + "xX", "", "show xrefs/refs of current function from/to data/code", + "yY", "", "copy and paste selection", + "Enter", "", "follow address of jump/call", NULL }; static const char *help_msg_visual_fn[] = { - "F2", "toggle breakpoint", - "F4", "run to cursor", - "F7", "single step", - "F8", "step over", - "F9", "continue", + "F2", "", "toggle breakpoint", + "F4", "", "run to cursor", + "F7", "", "single step", + "F8", "", "step over", + "F9", "", "continue", NULL }; +RZ_IPI const char **rz_core_visual_get_short_help() { + return help_visual; +} + +RZ_IPI const char **rz_core_visual_get_long_help() { + return help_msg_visual; +} + +RZ_IPI const char **rz_core_visual_get_fcn_help() { + return help_msg_visual_fn; +} + static void rotateAsmBits(RzCore *core) { RzAnalysisHint *hint = rz_analysis_hint_get(core->analysis, core->offset); int bits = hint ? hint->bits : rz_config_get_i(core->config, "asm.bits"); @@ -443,17 +455,17 @@ RZ_IPI void rz_core_visual_append_help(RzStrBuf *p, const char *title, const cha const char *pal_args_color = cons_ctx->color_mode ? cons_ctx->pal.args : "", *pal_help_color = cons_ctx->color_mode ? cons_ctx->pal.help : "", *pal_reset = cons_ctx->color_mode ? cons_ctx->pal.reset : ""; - for (i = 0; help[i]; i += 2) { + for (i = 0; help[i]; i += 3) { max_length = RZ_MAX(max_length, strlen(help[i])); } rz_strbuf_appendf(p, "|%s:\n", title); - for (i = 0; help[i]; i += 2) { + for (i = 0; help[i]; i += 3) { padding = max_length - (strlen(help[i])); rz_strbuf_appendf(p, "| %s%s%*s %s%s%s\n", pal_args_color, help[i], padding, "", - pal_help_color, help[i + 1], pal_reset); + pal_help_color, help[i + 2], pal_reset); } } @@ -3813,16 +3825,8 @@ RZ_IPI int rz_core_visual(RzCore *core, const char *input) { return 0; } visual->obs = core->blocksize; - // rz_cons_set_cup (true); core->vmode = false; - /* honor vim */ - if (!strncmp(input, "im", 2)) { - char *cmd = rz_str_newf("!v%s", input); - int ret = rz_core_cmd0(core, cmd); - free(cmd); - return ret; - } while (*input) { int len = *input == 'd' ? 2 : 1; if (!rz_core_visual_cmd(core, input)) { diff --git a/librz/include/rz_util/rz_panels.h b/librz/include/rz_util/rz_panels.h index aa42772f336..20d8aaf3d5d 100644 --- a/librz/include/rz_util/rz_panels.h +++ b/librz/include/rz_util/rz_panels.h @@ -73,6 +73,8 @@ typedef struct rz_panel_t { typedef void (*RzPanelAlmightyCallback)(void *user, RzPanel *panel, const RzPanelLayout dir, RZ_NULLABLE const char *title); RZ_IPI void rz_panel_free(RZ_NULLABLE RzPanel *panel); +RZ_IPI void rz_save_panels_layout(RzCore *core, const char *_name); +RZ_IPI bool rz_load_panels_layout(RzCore *core, const char *_name); #ifdef __cplusplus } diff --git a/test/db/analysis/arm b/test/db/analysis/arm index 02a75f05d73..ca74e495a31 100644 --- a/test/db/analysis/arm +++ b/test/db/analysis/arm @@ -178,7 +178,7 @@ FILE=bins/mach0/arm-or-thumb CMDS=< seek aligned to block size (in cursor slurp or dump files) +| a/A (a)ssemble code, visual (A)ssembler +| b browse evals, symbols, flags, evals, classes, ... +| B toggle breakpoint +| c/C toggle (c)ursor and (C)olors +| d[f?] define function, data, code, .. +| D enter visual diff mode (set diff.from/to) +| f/F set/unset or browse flags. f- to unset, F to browse, .. +| hjkl move around (left-down-up-right) +| HJKL select in cursor mode (left-down-up-right) +| i insert hex or string (in hexdump) use tab to toggle +| I insert hexpair block +| mK/'K mark/go to Key (any key) +| n/N seek next/prev function/flag/hit (scr.nkey) +| g go/seek to given offset (g[g/G] to seek begin/end of file) +| o/O rotate between different formats (next/prev) +| p/P rotate print modes (hex, disasm, debug, words, buf) +| q back to rizin shell +| r toggle call/jmp/lea hints +| R changes the theme or randomizes colors if scr.randpal option is true. +| sS step / step over +| tT tt new tab, t[1-9] switch to nth tab, t= name tab, t- close tab +| uU undo/redo seek +| v visual function/vars code analysis menu +| V (V)iew interactive ascii art graph (agfv) +| wW seek cursor to next/prev word +| xX show xrefs/refs of current function from/to data/code +| yY copy and paste selection +| Enter follow address of jump/call +Function Keys: (See 'e key.'), defaults to +| F2 toggle breakpoint +| F4 run to cursor +| F7 single step +| F8 step over +| F9 continue +EOF +RUN + +NAME=panels vl/vs +FILE== +CMDS=< /dev/null +V c10dwq @e:scr.interactive=true > /dev/null pd 20~dword? EOF EXPECT=<