From b70083a5f4404e2422ff0a0aadd023a661164fae Mon Sep 17 00:00:00 2001 From: Juhani Krekelä Date: Fri, 25 Jun 2021 17:59:53 +0300 Subject: Add feature to open a new terminal Add ability to open a new weltschmerz terminal, either from context menu or with a key combination. The new terminal is opened in the directory indicated with OSC 7, allowing quickly opening additional terminals while working. Preferably this would launch the user's preferred terminal, as defined in per-user settings, but this is not possible with glib[1]. For this reason the option always launches another weltschmerz. weltschmerz is launched using bare Process.spawn_async() on the name of the program as defined in weltschmerz.vala. We considered using the AppInfo database to retrieve the name of executable instead, but as there is no way to query the database for terminal emulators we would have to go through every single program installed on the computer and try to find one called weltschmerz. As the change would merely replace the requirement of having weltschmerz in PATH with the requirement of having a .desktop file with the name in one of the standardized locations, this would not be worth it. [1] https://gitlab.gnome.org/GNOME/glib/-/issues/338 --- terminal.ui | 18 ++++++++++++++++++ terminal.vala | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ weltschmerz.1 | 8 +++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/terminal.ui b/terminal.ui index c22fbec..345c543 100644 --- a/terminal.ui +++ b/terminal.ui @@ -52,6 +52,11 @@ False document-open + + True + False + utilities-terminal + True False @@ -92,6 +97,19 @@ False + + + Open _terminal + True + False + Open new terminal window in the current directory + True + open_terminal_item_image + False + + + + _Open directory diff --git a/terminal.vala b/terminal.vala index 4a2e676..dfe8130 100644 --- a/terminal.vala +++ b/terminal.vala @@ -28,6 +28,7 @@ class Terminal : Gtk.Overlay { [GtkChild] unowned Gtk.Menu hyperlink_context_menu; [GtkChild] unowned Gtk.MenuItem copy_item_text; [GtkChild] unowned Gtk.MenuItem copy_item_html; + [GtkChild] unowned Gtk.MenuItem open_terminal_item; [GtkChild] unowned Gtk.MenuItem open_directory_item; [GtkChild] unowned Gtk.Revealer search_revealer; [GtkChild] unowned Gtk.ScrolledWindow scrolled_window; @@ -329,6 +330,48 @@ class Terminal : Gtk.Overlay { adjust_font_scale(vte.get_font_scale() / FONT_SCALE_FACTOR); } + string? get_local_directory_path() { + var uri = vte.get_current_directory_uri(); + if (uri == null) + return null; + + string uri_hostname; + string path = null; + try { + path = Filename.from_uri(uri, out uri_hostname); + } catch (Error e) { + warning(e.message); + return null; + } + + char hostname[256]; // SUSv2 says 255 is max length, +1 for terminator + Posix.gethostname(hostname); + + // If the path URI points to another computer, return null + if (uri_hostname != (string)hostname) + return null; + + return path; + } + + [GtkCallback] + void open_terminal() { + var cwd = get_local_directory_path(); + if (cwd == null) + return; + + Pid child; + + try { + Process.spawn_async(cwd, {PROGRAM_NAME}, Environ.get(), SpawnFlags.SEARCH_PATH, null, out child); + } catch (Error e) { + warning(e.message); + infobar_show(e.message, Gtk.MessageType.ERROR); + } + + Process.close_pid(child); + } + [GtkCallback] void open_directory() { uri_open(vte.get_current_directory_uri()); @@ -358,6 +401,7 @@ class Terminal : Gtk.Overlay { } else { copy_item_text.set_sensitive(vte.get_has_selection()); copy_item_html.set_sensitive(vte.get_has_selection()); + open_terminal_item.set_sensitive(get_local_directory_path() != null); open_directory_item.set_sensitive(vte.get_current_directory_uri() != null); standard_context_menu.popup_at_pointer(event); } @@ -408,6 +452,11 @@ class Terminal : Gtk.Overlay { return true; } + if (match_key(event, CONTROL_MASK | SHIFT_MASK, Gdk.Key.T)) { + open_terminal(); + return true; + } + if (match_key(event, CONTROL_MASK | SHIFT_MASK, Gdk.Key.O)) { open_directory(); return true; diff --git a/weltschmerz.1 b/weltschmerz.1 index 3c92ef6..a00894e 100644 --- a/weltschmerz.1 +++ b/weltschmerz.1 @@ -1,4 +1,4 @@ -.Dd June 17, 2021 +.Dd June 25, 2021 .Dt WELTSCHMERZ 1 .Os .Sh NAME @@ -52,6 +52,12 @@ Note that relies on proper support of OSC 7 to do this. If the child program (such as the shell or an editor) does not send OSC 7, this feature will not work. +.Pp +A new terminal window can likewise be opened in the program's current directory with +.Sy CTRL + Shift + T . +The limitations of +.Sy CTRL + Shift + O +also apply here. .Sh SEARCH OVERLAY The search overlay can be opened by pressing .Sy CTRL + Shift + F . -- cgit v1.2.3-2-gb3c3