Ticket #3088 (closed enhancement: fixed)

Opened 11 years ago

Last modified 10 months ago

Tell the current directory to gnome-terminal

Reported by: egmont Owned by: andrew_b
Priority: minor Milestone: 4.8.32
Component: mc-core Version: 4.8.10
Keywords: Cc: egmont
Blocked By: Blocking:
Branch state: merged Votes for changeset: committed-master

Description

Gnome-terminal has had a cool feature for ages: when you open a new tab, it opens in the same directory as the one that was previously active. This gives a huge productivity boost. G-t used to achieve this by looking at the tab's immediately child (typically a shell), and checking its cwd under /proc. This way it was impossible for it to know MC's current directory.

G-t 3.7.0 (vte 0.34.0) changed the implementation: g-t no longer digs into /proc to figure it out automatically, it's the shells responsibility to tell it to g-t.

To test: if you have g-t >= 3.7.0 then execute this

echo -ne $'\e]7;file:///usr/bin\a'

and then open a new tab, it will open in /usr/bin.

The directory has to be URI-encoded, that is, prefixed by file:// and special characters encoded with %.

It would be really cool to have an option so that MC sets this whenever the directory is changed, pretty similar to the way it can update the window title. This way whenever you opened a new tab in g-t, it would open at the directory where you are in MC.

https://bugzilla.gnome.org/show_bug.cgi?id=675987
https://git.gnome.org/browse/gnome-terminal/commit/?id=7f185514f5fad3cea10bed6ee8057379e25a3573

Attachments

mc-4.8.10-terminal-cwd.patch (6.3 KB) - added by egmont 11 years ago.
first version
mc-4.8.13-terminal-cwd.patch (6.3 KB) - added by egmont 10 years ago.
updated to newest mc
mc-4.8.19-terminal-cwd.patch (5.8 KB) - added by egmont 7 years ago.
updated to current git, plus minor cleanups
mc-4.8.30-terminal-cwd.patch (6.4 KB) - added by egmont 11 months ago.
mc-4.8.30-terminal-cwd-v2.patch (6.1 KB) - added by egmont 11 months ago.

Change History

comment:1 Changed 11 years ago by egmont

The feature seems to originate from Mac terminal, here's a good description:
http://superuser.com/questions/79972/set-the-title-of-the-terminal-window-to-the-current-directory/321733#321733

Apparently the hostname should also be included in the URI so that the terminal knows if the shell is running on a remote host.

There's also a way to set the current filename. It might make sense to set to the name of the file being viewed/edited, or maybe even to the file where the cursor is. I'm not sure how this is being used, as I don't have access to Mac.

comment:2 Changed 11 years ago by egmont

Note: as opposed to the xterm window title, we should take care not to set it when on VFS.

Changed 11 years ago by egmont

first version

comment:3 Changed 11 years ago by egmont

I've added a version that works nice, but maybe still needs to be cleaned up a bit.

The feature has to be enabled in Options -> Configuration -> Auto cd new terminal.

It's disabled by default because the escape sequence that it prints messes up the display of old gnome-terminal (vte < 0.34). Other graphical emulators I've tried (xterm, konsole, urxvt, putty) ignore the sequence. The Linux console also becomes messed up, hence I added a check for xterm-like terminal.

TODOs:

Find a good name for this option, and find a shortcut key in the config dialog.

Figure out where the code should go in the source tree. Right now it's in filemanager/layout.c because the work was heavily based on the "xterm window title" feature which is there. But this new feature has nothing to do with the "layout". For the same reason I decided not to put the config option next to the xterm one.

Figure out when to call the method. This might depend on ticket #3090. Right now I'm calling this whenever the xterm window title is also updated. But it might be a better place to call it when the command prompt is updated, or when mc actually performs a chdir(). Although mc seems to call chdir() back and forth for both panels which would impose a short race condition here.

Please test the patch with Mac Terminal.app (>= Lion) or Gnome-terminal (>= 0.34). Expected behavior: when opening a new terminal tab, it should open in mc's current directory (unless it's a remote directory or an archive file or such). It should work even if the path contains all kinds of weird special characters.

A note for Konsole: when opening a new tab, it seems to look not only at the immediate child of the current tab, but somehow digs deeper and finds the actual "active" (?) process and takes its cwd. So in konsole you see this behavior even without this patch.

comment:4 Changed 11 years ago by egmont

Sorry, I meant: test with Gnome-terminal >= 3.7 (which depends on vte >= 0.34).

comment:5 Changed 11 years ago by egmont

I've been happily using this patch for 2 months, it makes opening a new terminal tab much more convenient. I just press Ctrl+Shift+T in gnome-terminal, and the new tab opens in the directory where I navigated to in MC. A convenience feature I could hardly live without, once I got used to it.

Dear developers, could you please comment on this, would you accept this feature to MC? If so, could you please help finalize the implementation (as detailed in comment 3)?

comment:6 Changed 11 years ago by egmont

Friendly ping - dear developers, any comments on this?

Note to myself: Should use g_filename_to_uri() rather than manually crafted code.

comment:7 Changed 11 years ago by mgedmin

/etc/profile.d/vte.sh, shipped with the libvte package on Ubuntu, does an explicit check

# Not running under vte?
[ "${VTE_VERSION:-0}" -ge 3405 ] || return 0

Midnight Commander could look at this environment variable and determine whether it needs to emit the OSC 7 escape code whenever the current working directory changes.

This would help Mac terminals, but would autodetect gnome-terminal versions that support and need this escape.

Last edited 11 years ago by mgedmin (previous) (diff)

Changed 10 years ago by egmont

updated to newest mc

comment:8 Changed 10 years ago by zaytsev

Aha, so that's why this feature doesn't work in latest Ubuntu :-/

Maybe mooffie is right though and this kind of stuff should be all offloaded to the scripting engine? Of course, the engine should first get merged, and then a consistent effort has to happen to strip the auxiliary niceties, where auxilariness of features might become a subject of sharp debates, but maybe mc-4.6 could be a good baseline...

comment:9 Changed 7 years ago by egmont

OSC 7 is now supported by:

  • Mac:
    • the default Terminal.app
    • the extremely popular iTerm2
  • VTE-based:
    • the standard GNOME Terminal
    • the well-known tiling emulator Terminator
    • the shiny brand new tiling emulator Tilix
  • KDE's Konsole

The list may be incomplete.

I've also just filed feature requests for VTE-based emulators mate-terminal, xfce4-terminal, sakura and tilda.

Do you guys mind if I move forward and finalize the patch, aiming for 4.8.21?

I would even enable it by default, and wouldn't bother with any kind of autodetection. The only terminal emulator I'm aware of that does not at least silently ignore OSC 7 is the ancient Gtk2-based VTE, practically only used by Guake nowadays.

comment:10 Changed 7 years ago by zaytsev

I don't mind, but could you please tell me what will happen in ancient Gtk2-based VTE? Sadly I still use it... Will it be broken in some way?

comment:11 Changed 7 years ago by egmont

Yup, display corruptions will happen if this option is enabled.

I guess I can be convinced to keep this option disabled for now... but I'd also like to understand why you (or people in general) still use that ancient VTE version :-)

Changed 7 years ago by egmont

updated to current git, plus minor cleanups

comment:12 Changed 7 years ago by egmont

Attached an updated version.

Issues from comment:3 are still to be addressed.

In particular, I don't like the name "Auto cd new terminal" in the config dialog and I cannot find a good (and short) one.

Also, we're pretty much out of hotkeys in the config dialog. In English, only 'j', 'q', 'x' and 'z' to go, and none of these letters appear in any of the existing option names, so we cannot shuffle the hotkeys around.

I wouldn't even want to refer to the escape sequence "OSC 7" on the UI (even though it would allow '7' as the hotkey) because that's so user-unfriendly.

Suggestions welcome :)

comment:13 Changed 7 years ago by zaytsev

I can be likewise convinced to disable it for if it's a configurable option (it seems this is exactly your plan) or patch it out.

Unfortunately, there is no good reason for me to use an ancient VTE. It's just that I tend to throw away operating systems together with the hardware they're running on. In practice, this means that my 7yo private laptop is still running the same system I installed when I bought it, and I've been compiling from source to get newer versions of software I absolutely need. Given that I mostly only need a terminal, mc, alpine, irssi, a web browser + IDEA this has been a viable strategy for the last 15 years, and the stuff has grown so complex it's a project on its own to reinstall. Last time I reinstalled was some 5 years ago, when I gave now 12 years old laptop to my parents. I guess I will have to buy a new laptop in the coming years, because both 7 & 12 year old ones are starting to show their age... ;-) but I'm so busy I can't afford making time for it unless I'm really pressed against the wall and there is no way out :-/

I hope this answers your question, but I'm not sure if this would make you any happier; most likely you'll end up concluding that I'm nuts, which is not far from truth.

comment:14 follow-up: ↓ 16 Changed 7 years ago by egmont

Thanks for your detailed answer :)

The pattern you describe is not really practical, at least in the sense that after so much time vendors typically stop supporting the system and stop shipping even critical security fixes. As such, I believe most people update at least a bit more frequently than you do.

More importantly: I believe that most people who update rarely (like you do) not only have a potentially quite old base system, but also have a correspondingly old mc. So this shouldn't stop us from introducing new stuff. Using a cutting edge mc on a 7 year old system is probably unique to you and maybe like a dozen folks around the globe.

However, mc seems to be quite conservative here, e.g. it tends to keep a window of 5-7 years before requiring newer glib. (I'd be totally okay with decreasing this window size to maybe like 1-2 years.)

What I see being more risky is people ssh'ing across systems, from and old one (old terminal emulator) to a new one (new mc). I'd guess the other way around is more typical, I'd guess desktops are typically kept more up to date than servers, but sure this direction happens as well.

The display corruption is not terribly unbearable, the current path overwrites the panel's header (".n Name Size Modify time") or clutters the command line entry. It doesn't interfere with opening the Config dialog and change the settings there. The problem is: how would people know that they can "fix" this corrupiton in Config?

The main dilemma is: A minor breakage for some users vs. a minor new convenience feature for more users?

I tend to be a new guy who prefers pushing new features to users, rather than just making it available for them. Here too I'd like this feature to become the default for them, not just an option. If we ship this option disabled by default, and enable by default in a couple of years, users who have saved their config just once in between will still have it disabled, I think mc has no way to do a one-shot change to users' configs.

A nasty workaround that occurred to me: Emit OSC 7 with the fake URI that spells "If you can see this message then disable this and that feature" followed by another OSC 7 with the actual URI. Do we want such a hack?

Or we could disable it by default, and add a "hint" entry.

Version 0, edited 7 years ago by egmont (next)

comment:15 Changed 7 years ago by ossi

it's kinda a pity that there isn't a standardized escape sequence that would make any terminal dump the terminfo (equivalent) for itself, huh?

i'd just enable it. the resulting potential problem will be trivially googleable, first this ticket here, and then stackoverflow.

comment:16 in reply to: ↑ 14 Changed 7 years ago by andrew_b

Replying to egmont:

it tends to keep a window of 5-7 years before requiring newer glib. (I'd be totally okay with decreasing this window size to maybe like 1-2 years.)

Not quite. We try to require as low version of GLib as possible.

comment:17 Changed 7 years ago by zaytsev

The pattern you describe is not really practical, at least in the sense that after so much time vendors typically stop supporting the system and stop shipping even critical security fixes.

As a matter of fact, it is a very practical pattern, only maybe not for an average desktop user:

https://en.wikipedia.org/wiki/Red_Hat_Enterprise_Linux#Product_life_cycle

I would push it even further and claim that I actually have 3 more years to think about the meaning of life on RHEL6 without buying into ELS, and about the same for RHEL5 with an ELS contract. Now, I'm not even mentioning Solaris, AIX, HP-UX, VMS and the like...

Anyways, at this point, I'm basically arguing for the sake of the argument, and now that your curiosity has been satisfied, I would suggest to forget about poor me and go ahead with enabling it by default.

My bigger concern about the patch is that the name for the option sucks, but I couldn't come up with a better suggestion yet.

comment:18 Changed 11 months ago by egmont

I'd like to revive this long-forgotten idea and recommend again for upstream inclusion.

I'm attaching a new patch so that it cleanly applies to master. I made two noteworthy changes.

As per ossi's comment, I flipped the default to enabled.

I changed the escape sequence's terminator from \a to \e\\. For consistency, I did this change in the unrelated update_xterm_title_path() method, too. The reason for this is that various standards (at least ECMA-48 and DEC STD 070) agree that an OSC is to be terminated by an ST, i.e. \e\\. Using BEL \a is a nonstandard solution introduced and popularized by xterm. We should prefer the standard sequence over the nonstandard one. (I'm not aware of any terminal that would not recognize either of the two possible endings.)

---

The name and UI label of the option is still up for improvement.

vim introduced an analogous option and it calls it autoshelldir. This name might serve as an inspiration. Although, the use of "shell" might be misleading for us. In vim it refers to a shell one might start up inside vim. In mc we do have a subshell, but I think the point is the user-friendly navigation of the panels, so users don't necessarily think of a shell being involved here (and mc even has a no-subshell mode, just panels only).

And outside mc there's no shell of interest, we don't update the invoker shell's (which might not even exist) directory but the terminal's.

So going with the exact same name would probably not be great, yet it might give us ideas.

For example, instead of "cd" (i.e. change directory) go with "dir" (i.e. directory), therefore not focus on the change per se but on the actual value; also we might omit the word "new" (we don't think of the overall picture of new terminals opening there but on the more technical aspect of the current terminal being updated on its concept about the directory), therefore instead of "Auto cd new terminal" we could maybe say "Auto terminal dir"? Might be a nice choice.

Changed 11 months ago by egmont

comment:19 follow-up: ↓ 20 Changed 11 months ago by zaytsev

Andrew, after so many years, maybe we can just take it in without an option? What do you think?

comment:20 in reply to: ↑ 19 Changed 11 months ago by andrew_b

Replying to zaytsev:

Andrew, after so many years, maybe we can just take it in without an option? What do you think?

I agree.

Some notes about patch.

  • Use g_ascii_isalnum() instead of

(c >= '0' && c <= '9') || ((c & ~0x20) >= 'A' && (c & ~0x20) <= 'Z').

  • Get rid of pathlen = strlen (path). Apply

for (p = path; *p != '\0'; p++)

instead of

for (i = 0; i < pathlen; i++).

Changed 11 months ago by egmont

comment:21 Changed 11 months ago by egmont

  • Cc egmont added

Attached an updated patch.

Re source code feedback:

I actually found a glib method to do all the URI escaping, so it's all much simpler. (The method is available since glib 2.16 and mc requires 2.30 so we're good.)

Re name of the feature and config option:

GNOME Terminal doesn't have a config option whether to respect OSC 7 and open the new tab/window there, or to ignore it. It always respects the given sequence. I suspect other terminals that support OSC 7 don't have such a switch either.

I have, maybe about 2-3 times throughout the years, come across forum posts where a user didn't like this behavior and wanted to switch it off, i.e. wanted new tabs in the home directory.

Since their preferred terminal couldn't be configured for this, they had two choices: Either make sure not to emit OSC 7, or to change back to the home dir in .bashrc.

Therefore I believe that a very few people might be looking for a config option to disable this behavior in mc.

If you guys are brave enough to go ahead without such an option then I won't try to stop you, it's your call; but I probably wouldn't be brave enough, I vote to have a "kill switch".

Now, it might be a "hidden" config option. One that is written to the config file and can be edited there, but doesn't have a corresponding UI option in mc. My vague memories tell me that mc already has several such "hidden" features, do I recall it correctly?

What do you guys think?

Last edited 11 months ago by egmont (previous) (diff)

comment:22 Changed 11 months ago by egmont

One more thing to figure out:

What to do when on a virtual file system?

Probably what makes the most sense is to set to the closest ancestor real directory (e.g. if you dig into /foo/bar/mc.tar.gz to see its contents then set it to /foo/bar).

I'm yet to implement this.

comment:23 follow-up: ↓ 24 Changed 11 months ago by zaytsev

I very much dislike the idea of a hidden option. Making it a bit easier to achieve their goals for a few people who would possibly use it doesn't justify code complexity and documentation in my opinion, and especially being hidden, the chance that whomever won't like the change will find it is very low. I'd either have a real one, or else no option at all. However, since as you say, it's easy enough to change this in shell initialisation script, I'd rather have no option at all. But I'll let Andrew to be the judge of it.

Re. virtual FS. What is the state right now? We are actually thinking of releasing an RC, so I'm wondering if the patch can be committed in it's current state in your opinion.

comment:24 in reply to: ↑ 23 Changed 11 months ago by andrew_b

Replying to zaytsev:

We are actually thinking of releasing an RC, so I'm wondering if the patch can be committed in it's current state in your opinion.

I think this is not a critical feature.

I'd like to froze the master till the release.

Last edited 11 months ago by andrew_b (previous) (diff)

comment:25 Changed 10 months ago by egmont

Hi guys,

First: I don't get e-mail notifications about updates here. I've even added myself to cc and still no. Yes I've checked my spam folder. Is this a known isuse, affecting others as well?

Also the mc-bugs archives linked from the homepage stopped updating a few months ago. I don't know if it's related.

For the time being, the communication between us involves me having to check back here whenever it occurs to me. This definitely may slow things down.

Back ontopic:

The feature has been sitting here unfinished for 10 years. I see no point in quickly rushing and submitting a half-baked solution to the upcoming release, and then possibly having to deal with bugreports. (When I revived this thread, I didn't realize the patch was a proof of concept rather than a polished up work.) Let's target the subsequent release 4.8.32.

Re the setting or not. Currently, at least in gnome-terminal and other OSC 7 supporting terminals, and assuming that the shell is set up to emit this escape, the behavior is that the new tab opens in the directory where you started mc from. Without a config option this behavior won't be available anymore, the directory will either follow what you do in mc, or if you cd back to your home from .bashrc then all new tabs will open in your home. I'm not firmly against going without any sort of a config option, but it has to be understood that then the exact old behavior can not be achieved via .bashrc or other quirks. With that in mind, it's still probably a fair game to say that we believe the new behavior is superior to the old one and we knowingly no longer offer the old behavior. Or _if_ someone complains then we'll consider adding a config option.

ossi (years ago), andrew_b and zaytsev (recently) all said you're fine without a config option. If, given the behavioral change as per the previous paragraph, you are still on this opinion, please give one final confirmation. I'm happy to adjust the patch to whatever the final decision is.

comment:26 Changed 10 months ago by egmont

Re vfs:

What happens now: If you change dir to a vfs path, or switch to a panel that's on a vfs, the OSC 7 is simply not emitted.

Example: The left panel is at directory /a, the right panel is at directory /b. You're working on the left panel. There you enter a compressed file.

Open a new terminal tab: it opens in /a.

Press the TAB key to switch to the right panel. Open a new terminal tab: it opens in /b.

Press the TAB key again to switch back to the left panel. Open a new terminal tab: it opens in /b.

I'd expect it to open in /a instead, that is, from its current vfs path walk upwards until a real directory is found and use that.

However...

This inconsistency is not new to the OSC 7 feature. The directory as shown in the prompt, as well as the actual directory used if you hide the panels with Ctrl+O, suffer from this very same inconsistency.

If we care about OSC 7 being consistent, where the history of changing dirs / switching panels is irrelevant, then I believe this work should begin by making it consistent for the displayed prompt, and for the working directory after hiding the panels.

I'm yet to find, or implement if it's not yet implemented, the method that takes a vfs path and returns its closest ancestor that's a local file.

Do we care about this at all?

comment:27 Changed 10 months ago by andrew_b

  • Owner set to andrew_b
  • Status changed from new to accepted
  • Branch state changed from no branch to on review
  • Milestone changed from Future Releases to 4.8.32

Branch: 3088_terminal_cwd
Initial changeset:e7e267d8c79197bac2e55987d0c73a2f00af5509

comment:28 Changed 10 months ago by andrew_b

  • Votes for changeset set to andrew_b
  • Branch state changed from on review to approved

comment:29 Changed 10 months ago by andrew_b

  • Status changed from accepted to testing
  • Votes for changeset changed from andrew_b to committed-master
  • Resolution set to fixed
  • Branch state changed from approved to merged

Merged to master: [6b44fce839b5c2e85fdfb8e1d4e5052c7f1c1c3a].

git log --oneline dc1aa3e4e..6b44fce83

comment:30 Changed 10 months ago by andrew_b

  • Status changed from testing to closed
Note: See TracTickets for help on using tickets.