Thread: [Vimprobable-users] [Ticket #9] Edit text areas using $EDITOR
Vimprobable is a lean web browser optimised for full keyboard control
Brought to you by:
hanness
From: Hannes S. <ha...@yl...> - 2012-06-29 16:17:13
Attachments:
external_editor.patch
|
Hi, here is another patch which needs testing. The purpose is to edit text areas (or input type=text fields) using an external editor. The editor is read from $EDITOR. The function is called using Ctrl-t by default. If you plan to rebind it, make sure you use something involving Ctrl, because something else will not work in INSERT mode (which you should usually be in when a text area is active). Hannes |
From: Hannes S. <ha...@yl...> - 2012-06-29 17:32:09
Attachments:
external_editor.patch
|
Sorry, here is already another one: This escapes quotation marks correctly (hopefully). It supersedes the previous patch. Hannes |
From: Matthew C. <je...@gm...> - 2012-06-30 04:16:04
|
Hi all, Initial testing on Arch Linux (up to date). Code failed to compile, required changing the following on 1825: time_t id = time() to time_t id = time(NULL) Not sure if that is specific to my machine or what. Test results with 'vim' as $EDITOR: Calling vimprobable2 from the CLI causes it to properly pull up vim and take the text into the input after saving with :x Calling from a menu (dmenu) does nothing (no terminal is brought up with vim loaded). Test results with 'gvim' as $EDITOR: Editor pulls up fine in both cases, however text is never sent back to the input field. -Matt On Fri, Jun 29, 2012 at 07:32:21PM +0200, Hannes Schüller wrote: > Sorry, here is already another one: This escapes quotation marks > correctly (hopefully). It supersedes the previous patch. > > Hannes > > diff --git a/keymap.h b/keymap.h > index 7ba5d0b..86aea55 100644 > --- a/keymap.h > +++ b/keymap.h > @@ -114,6 +114,9 @@ Key keys[] = { > { 0, GDK_semicolon, GDK_T, input, {.s = ";T"} }, > { 0, GDK_semicolon, GDK_W, input, {.s = ";W"} }, > > + /* this needs to be a binding using CTRL for obvious reasons */ > + { GDK_CONTROL_MASK, 0, GDK_t, open_editor,{} }, > + > { 0, GDK_VoidSymbol, GDK_Escape, set, {ModeNormal} }, > { GDK_CONTROL_MASK, GDK_VoidSymbol, GDK_bracketleft,set, {ModeNormal} }, > { GDK_CONTROL_MASK, 0, GDK_z, set, {ModePassThrough} }, > diff --git a/main.c b/main.c > index 20a9925..810455c 100644 > --- a/main.c > +++ b/main.c > @@ -59,6 +59,7 @@ static gboolean complete(const Arg *arg); > static gboolean descend(const Arg *arg); > gboolean echo(const Arg *arg); > static gboolean focus_input(const Arg *arg); > +static gboolean open_editor(const Arg *arg); > static gboolean input(const Arg *arg); > static gboolean navigate(const Arg *arg); > static gboolean number(const Arg *arg); > @@ -419,6 +420,9 @@ webview_keypress_cb(WebKitWebView *webview, GdkEventKey *event) { > g_free(a.s); > a.i = ModeNormal; > return set(&a); > + } else if (CLEAN(event->state) & GDK_CONTROL_MASK) { > + /* keybindings of non-printable characters */ > + if (process_keypress(event) == TRUE) return TRUE; > } > case ModePassThrough: > if (IS_ESCAPE(event)) { > @@ -1809,6 +1813,112 @@ view_source(const Arg * arg) { > } > > static gboolean > +open_editor(const Arg *arg) { > + char *editor, *type, *text = NULL, *tempfile, *argv[2], s[255] = "", idstr[64] = ""; > + FILE *fp; > + gboolean success; > + GString *new_text = g_string_new(""); > + time_t id = time(); > + gchar *value = NULL, *message = NULL, *tag = NULL, *command = NULL; > + > + /* check if $EDITOR is set */ > + if (getenv("EDITOR")) > + editor = g_strdup_printf("%s", getenv("EDITOR")); > + else > + return FALSE; > + > + /* check if active element is suitable for text editing */ > + jsapi_evaluate_script("document.activeElement.tagName", &value, &message); > + if (value == NULL) > + return FALSE; > + tag = g_strdup(value); > + if (strcmp(tag, "INPUT") == 0) { > + /* extra check: type == text */ > + jsapi_evaluate_script("document.activeElement.type", &value, &message); > + if (strcmp(value, "text") != 0) { > + g_free(value); > + g_free(message); > + return FALSE; > + } > + } else if (strcmp(tag, "TEXTAREA") != 0) { > + g_free(value); > + g_free(message); > + return FALSE; > + } > + jsapi_evaluate_script("document.activeElement.value", &value, &message); > + text = g_strdup(value); > + if (text == NULL) { > + g_free(value); > + g_free(message); > + return FALSE; > + } > + > + /* write text into temporary file */ > + tempfile = g_strdup_printf(TEMPFILE); > + sprintf(idstr, "%d", id); > + tempfile = g_strconcat(tempfile, ".", idstr); > + fp = fopen(tempfile, "w"); > + if (fp == NULL) { > + g_free(value); > + g_free(message); > + g_free(text); > + return FALSE; > + } > + if (fputs(text, fp) < 0) { > + g_free(value); > + g_free(message); > + g_free(text); > + return FALSE; > + } > + fclose(fp); > + g_free(text); > + > + /* spawn editor */ > + command = g_strconcat(editor, " ", tempfile, NULL); > + success = g_spawn_command_line_sync(command, NULL, NULL, NULL, NULL); > + if (!success) { > + g_free(value); > + g_free(message); > + return FALSE; > + } > + > + /* re-read the new contents of the file and put it into the HTML element */ > + if (!access(tempfile, R_OK) == 0) { > + g_free(value); > + g_free(message); > + return FALSE; > + } > + fp = fopen(tempfile, "r"); > + if (fp == NULL) { > + g_free(value); > + g_free(message); > + return FALSE; > + } > + jsapi_evaluate_script("document.activeElement.value = '';", &value, &message); > + new_text = g_string_append(new_text, "\""); > + while (fgets(s, 254, fp)) { > + if (s[strlen(s)-1] == '\n') { > + /* encode line breaks into the string as Javascript does not like actual line breaks */ > + new_text = g_string_append_len(new_text, s, strlen(s) - 1); > + new_text = g_string_append(new_text, "\\n"); > + } else { > + new_text = g_string_append(new_text, s); > + } > + } > + new_text = g_string_append(new_text, "\""); > + fclose(fp); > + jsapi_evaluate_script(g_strconcat("document.activeElement.value = ", new_text->str, ";", NULL), &value, &message); > + > + /* done */ > + g_string_free(new_text, TRUE); > + g_free(value); > + g_free(message); > + g_free(tag); > + remove(tempfile); > + return TRUE; > +} > + > +static gboolean > focus_input(const Arg *arg) { > static Arg a; > > diff --git a/vimprobable.h b/vimprobable.h > index 5a6c2df..e2c647e 100644 > --- a/vimprobable.h > +++ b/vimprobable.h > @@ -181,6 +181,9 @@ enum ConfigFileError { > #define HISTORY_STORAGE_FILENAME "%s/vimprobable/history", config_base > #define CLOSED_URL_FILENAME "%s/vimprobable/closed", config_base > > +/* external editor - temporary file */ > +#define TEMPFILE "/tmp/vimprobable_edit" > + > /* Command size */ > #define COMMANDSIZE 1024 > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Vimprobable-users mailing list > Vim...@li... > https://lists.sourceforge.net/lists/listinfo/vimprobable-users -- Matthew Carter je...@gm... |
From: Jason R. <jas...@gm...> - 2012-06-30 04:53:06
|
On 30/06/12 at 12:15am, Matthew Carter wrote: > Hi all, > > Initial testing on Arch Linux (up to date). > > Code failed to compile, required changing the following on 1825: > > time_t id = time() > > to > > time_t id = time(NULL) > > Not sure if that is specific to my machine or what. > Confirmed here. > Test results with 'vim' as $EDITOR: > > Calling vimprobable2 from the CLI causes it to properly pull up vim and > take the text into the input after saving with :x > > Calling from a menu (dmenu) does nothing (no terminal is brought up with > vim loaded). > Also confirmed, although I start the browser from a keybind in dwm > Test results with 'gvim' as $EDITOR: > > Editor pulls up fine in both cases, however text is never sent back to > the input field. I changed $EDITOR to leafpad and it worked as expected only after saving the file to /tmp Also, this functionality is very cool - thanks Hannes. /J -- http://jasonwryan.com/ [GnuPG Key: B1BD4E40] |
From: Hannes S. <ha...@yl...> - 2012-06-30 08:12:33
|
Jason Ryan writes: > On 30/06/12 at 12:15am, Matthew Carter wrote: > > Initial testing on Arch Linux (up to date). > > > > Code failed to compile, required changing the following on 1825: > > > > time_t id = time() > > > > to > > > > time_t id = time(NULL) > > > > Not sure if that is specific to my machine or what. > > > Confirmed here. Please use the second version of the patch which should address this. Hannes |
From: Hannes S. <ha...@yl...> - 2012-06-30 08:26:09
Attachments:
external_editor.patch
|
Hannes Schüller writes: > Jason Ryan writes: >> On 30/06/12 at 12:15am, Matthew Carter wrote: >> > Initial testing on Arch Linux (up to date). >> > >> > Code failed to compile, required changing the following on 1825: >> > >> > time_t id = time() >> > >> > to >> > >> > time_t id = time(NULL) >> > >> > Not sure if that is specific to my machine or what. >> > >> Confirmed here. > > Please use the second version of the patch which should address this. The joke's on me, of course. For some reason, I seem to have attached the same patch twice yesterday. Sorry. This is the mysterious "second version". Hannes |
From: Daniel C. <dan...@gm...> - 2012-07-22 13:02:44
Attachments:
signature.asc
|
Hi Hannes! This patch is nice! But out of the reasons that also Matthew Carter mentioned this doesn't work if the EDITOR is vim and vimprobable is started via dmenu or as shortcut from tabbed. Until today I expected only cli tools to evaluate the EDITOR environment variable and I set it to vim. For a grafically tool like vimprobable I would preferable launch a grafical editor like gvim. But I'm averse to change the EDITOR to gvim, because I use many tools on cli that evaluates also the EDITOR variable and I don't want them to open gvim. Wouldn't it be a compromise to have a configuration for the editor in vimprobablerc and on runtime to set the editor in a way like: set editor="gvim %s"? This would allow the user to easily change the editor and also to launch a cli editor in a way like 'set editor="urxvt -e vim %s"'? If the configuration isn't set a fallback to the $EDITOR would be nice or we set the default value to 'vim' or better 'vi' (is posix conform an on most systems aliased to vim) which should be a good choice for a browser that aims to apply the usage paradigms from vim to a grafically browser. Daniel |
From: Hannes S. <ha...@yl...> - 2012-07-22 13:17:31
Attachments:
signature.asc
|
Agreed. My plan for this patch is this: - Have the editor command defined in a way like the external protocol handlers are (whether this will need to be run through :set will need to be decided; I'd say it's a fairly static setting). - Use asynchronous spawning; otherwise, some calls will return immediately (after sending the open command to the actual editor) and the browser will think editing is already done. This has to be avoided. Those are the issues I still see right now. Hannes |
From: Jason R. <jas...@gm...> - 2012-07-22 20:59:04
|
On 22/07/12 at 03:16pm, Hannes Schüller wrote: > Agreed. My plan for this patch is this: > > - Have the editor command defined in a way like the external protocol > handlers are (whether this will need to be run through :set will need > to be decided; I'd say it's a fairly static setting). FWIW, I haven't touched the external protocol handler since setting it up; I imagine the same would apply to $editor, I wouldn't expect to change it at runtime. Cheers, /J -- http://jasonwryan.com/ [GnuPG Key: B1BD4E40] |
From: Daniel C. <dan...@gm...> - 2012-09-10 11:12:15
|
Hi! Hannes Schüller <ha...@yl...> wrote: > Agreed. My plan for this patch is this: > > - Have the editor command defined in a way like the external protocol > handlers are (whether this will need to be run through :set will need > to be decided; I'd say it's a fairly static setting). I think it's nearly a static setting too. But in my opinion it's not a performance issue to have the ability to set it to the runtime via :set. Implementing it in as via :set, should be easier to implement, because we don't need to write more code and have not to introduce a new complicated way to set personal settings. I think to make this changeable via :set is also a good choice even if the setting is static (one time declared in vimprobablerc) and a default value via config.h Daniel |