VbResult input_open_editor(Client *c) { char **argv, *file_path = NULL; const char *text = NULL, *editor_command; int argc; GPid pid; gboolean success; GVariant *jsreturn; g_assert(c); /* get the editor command */ editor_command = GET_CHAR(c, "editor-command"); if (!editor_command || !*editor_command) { vb_echo(c, MSG_ERROR, TRUE, "No editor-command configured"); return RESULT_ERROR; } /* get the selected input element */ jsreturn = ext_proxy_eval_script_sync(c, "vimb_input_mode_element.value"); g_variant_get(jsreturn, "(bs)", &success, &text); if (!success || !text) { return RESULT_ERROR; } /* create a temp file to pass text to and from editor */ if (!util_create_tmp_file(text, &file_path)) { return RESULT_ERROR; } /* spawn editor */ char* command = g_strdup_printf(editor_command, file_path); if (!g_shell_parse_argv(command, &argc, &argv, NULL)) { g_critical("Could not parse editor-command '%s'", command); g_free(command); return RESULT_ERROR; } g_free(command); success = g_spawn_async( NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL ); g_strfreev(argv); if (!success) { unlink(file_path); g_free(file_path); g_warning("Could not spawn editor-command"); return RESULT_ERROR; } /* disable the active element */ ext_proxy_eval_script(c, "vimb_input_mode_element.disabled=true", NULL); /* watch the editor process */ EditorData *data = g_slice_new0(EditorData); data->file = file_path; data->c = c; g_child_watch_add(pid, (GChildWatchFunc)resume_editor, data); return RESULT_COMPLETE; }
VbResult input_open_editor(void) { char **argv, *file_path = NULL; const char *text, *editor_command; int argc; GPid pid; gboolean success; editor_command = GET_CHAR("editor-command"); if (!editor_command || !*editor_command) { vb_echo(VB_MSG_ERROR, true, "No editor-command configured"); return RESULT_ERROR; } Element* active = dom_get_active_element(vb.gui.webview); /* check if element is suitable for editing */ if (!active || !dom_is_editable(active)) { return RESULT_ERROR; } text = dom_editable_element_get_value(active); if (!text) { return RESULT_ERROR; } if (!util_create_tmp_file(text, &file_path)) { return RESULT_ERROR; } /* spawn editor */ char* command = g_strdup_printf(editor_command, file_path); if (!g_shell_parse_argv(command, &argc, &argv, NULL)) { g_critical("Could not parse editor-command '%s'", command); g_free(command); return RESULT_ERROR; } g_free(command); success = g_spawn_async( NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL ); g_strfreev(argv); if (!success) { unlink(file_path); g_free(file_path); g_warning("Could not spawn editor-command"); return RESULT_ERROR; } /* disable the active element */ dom_editable_element_set_disable(active, true); EditorData *data = g_slice_new0(EditorData); data->file = file_path; data->element = active; g_child_watch_add(pid, (GChildWatchFunc)resume_editor, data); return RESULT_COMPLETE; }