gnunn1 / tilix

A tiling terminal emulator for Linux using GTK+ 3
https://gnunn1.github.io/tilix-web
Mozilla Public License 2.0
5.43k stars 294 forks source link

Support DND of files #376

Open gnunn1 opened 8 years ago

gnunn1 commented 8 years ago

Now with #135 completed which depended on understanding local versus remote hosts, another cool feature to borrow from iterm2 is the dragging and dropping of files on to a terminal.

If the host is local, just copy it locally. If the host is remote, scp it to the remote host. I'm thinking a Ui similar to Nautilus (I.e. the button with the pie that fills in) would be cool here.

This would be a longer term enhancement.

gnunn1 commented 8 years ago

There is a new D library for wrapping libssh that would make the SCP portion much easier:

https://github.com/zebraxxl/libssh-d

bestouff commented 7 years ago

Bonus point (even if I have no idea how that would work): enable [xyz]modem transfers for hosts over a serial line.

stuaxo commented 7 years ago

With some extra ansi codes, it should be possible to support file operations it should be possible to support file operations from the terminal (drag to file manager, also right click operations: open file, open directory, copy file, copy location).

The 3 bits of information needed

[root] e.g. file:/// ssh://pi@raspberry/

[directory] e.g. /home/pi

[filename] e.g. hello.txt

When you ssh to a new host, e.g. pi@raspberry, the ansi codes could tell the terminal the new remote root (and when you disconnect, revert it to file:///)

Every time an app changes directory, it would send back the current directory, and every time a filename is displayed it is wrapped in codes to say it is a filename.

The aim would be to be able to do this

$ ssh pi@raspberry
$ ls
hello.txt

And then be able to right click or drag the hello.txt to my local computer.

Obviously patching everything to output the extra ansi codes is out of the question. It may be possible to write something using LD_PRELOAD that knows if a file stat happened (e.g. for hello.txt) and wrap the output.

gnunn1 commented 7 years ago

@stuaxo It shouldn't need any special codes, triggers can already detect the user/host when you SSH to a host by parsing out the login prompt.

stuaxo commented 7 years ago

How about knowing knowing that 'hello.txt' is a filename, in the directory /home/pi so that right clicking it can open gedit at ssh://pi@raspberry/home/pi/hello.txt

Or be able open nautilus to ssh://pi@raspberry/home/pi/ ?

gnunn1 commented 7 years ago

You can configure the custom links to look for filename patterns, however at the moment it doesn't do variable substitution but it would be easy to extend.

If you are interested in working on this feature let me know.

stuaxo commented 7 years ago

I could be interested in starting a proof-of-concept... is terminix all written in D ?

If I could make even, just a replacement $ ls command output info that could make something like this, it would be an interesting start.

gnunn1 commented 7 years ago

Yes terminix is all written in D. I'm not following on the replacement for ls, are you thinking of it as a way to identify remote files? Up to now I haven't thought a custom command is required here as you can't send OSC codes to terminix without patching the VTE which is written in C. I have a request for this open in the VTE bugzilla but it's fairly complicated to implement (https://bugzilla.gnome.org/show_bug.cgi?id=734823).

Here's what my current plan looks like:

I think the easiest to implement is SCP'ing to the remote host via drag and drop onto the terminal. The drop event is already wired in terminal.d, right now all it does is paste the file name into the terminal. To take this further, you would need to prompt the user on drop rather to paste the file name or copy the files (copy if local, scp if remote). Ideally it could piggy back on top of the existing SSH connection to avoid authentication.

SCP'ing out of the host is more tricky, but could be done by enhancing the custom links so that when a file name is clicked it again triggers the SCP process. This isn't ideal since it's a regex for detecting filenames, particularly standalone ones, is never going to be perfect. Once the user clicks the file, you'd prompt them where to save the file and then trigger the SCP process.

There is a D library in comment 2 that links to a library that wraps libssh that might be useful for this.

stuaxo commented 7 years ago

Ah, yes - I'm definitely talking about file operations from the terminal + be able to identify arbitrary files in places where regex might be hard (output of ls, file managers like mc or ```ranger).

The custom OSC codes would make it unambiguous. Piggy backing the current SSH connection, it definitely opens some possibilities.

I had a play with strace just now, and it shows that intercepting lstat can get back which files are accessed:

$ strace -e trace=lstat ls -l 
lstat("hello.txt", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat("world.txt", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
total 0
-rw-r--r-- 1 stu stu 0 Feb 26 12:11 hello.txt
-rw-r--r-- 1 stu stu 0 Feb 26 12:11 world.txt
+++ exited with 0 +++
$ strace -e trace=lstat mc
lstat("/bin", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
lstat("/bin/bash", {st_mode=S_IFREG|0755, st_size=1045704, ...}) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=31546, si_uid=1000, si_status=3, si_utime=0, si_stime=0} ---
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_STOPPED, si_pid=31547, si_uid=1000, si_status=SIGSTOP, si_utime=7, si_stime=0} ---
                                                                                                                             --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_CONTINUED, si_pid=31547, si_uid=1000, si_status=SIGCONT, si_utime=7, si_stime=0} ---
                                                              lstat("/home/stu/projects/work/cord/projectlumen-ansible/raspberry-pi/test_dir/hello.txt", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
      lstat("/home/stu/projects/work/cord/projectlumen-ansible/raspberry-pi/test_dir/world.txt", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0

+++ exited with 0 +++

If this info was timestamped + got back terminx somehow then it might be good enough (at least to know what is a file from ls, mc and ranger).

Also, realised that my feature dragging / file ops from the terminal is different than to the terminal, so apologies for hijacking the thread :)

despens commented 7 years ago

I dunno, if I want a remote file manager, I use a remote file manager... :upside_down_face:

stuaxo commented 7 years ago

I use a terminal and a file manager - sometimes at the same time, more integration can save fiddling around with highlighting, copying and pasting of filenames etc.

despens commented 7 years ago

To get consistent behavior in the shell will be so tricky though: sshing to a remote host, from there ssh into another, then enter a container via lxc-attach, docker exec -i bash, or another method. Now I'm dragging a file into the terminal window… where will it go, and how?

stuaxo commented 7 years ago

I'm not sure there is a practical way of doing it for lxc or docker, it would be enough to popup a dialog,

Cannot copy to docker container.

Copy to outer ssh:  ssh://mydockerhost/somepath  ?

[Cancel]  [Copy]

Multiple layers of ssh should be possible via forwarding.

We don't have to cover all kinds of endpoint to be useful initially (though architecting things in such a way that they can be added is probably an idea though).

egmontkob commented 7 years ago

Please take a look at the hyperlink support #904. It takes a somewhat different approach (e.g. needs a patched ls), but is probably quite relevant and usable here (e.g. the right-click menu could contain a convenience option to scp the given file).

hg42 commented 3 years ago

Note, I am a very interested potential user of Tilix, but some things stop me from using it. One of them is dnd support.

While I generally like the idea to add more creative drag and drop support, this would break everything I do (and need to do) with drag and drop and a terminal.

I usually open some file managers for locations I work on and then compose command lines by entering some command and dragging files and folders from different parts of the gui to the terminal.

In an ideal world, I would also have another window from where I could drag preconfigured text items (like commands) and a clipboard with draggable items. I would also like dragging selected text snippets from terminals into the current command line.

I usually use the terminal for things I cannot do easier with other tools. Which is roughly 50% of my work. As @despens already mentioned there are file managers or remote managers that can handle usual file handling.

A drop could open a menu to choose which way of dragging should be executed. I would prefer modifier keys for the copy operation. From my experience with other people, both should be configurable, e.g. like rox filer implements it. Some people cannot remember the key combinations, while others that do dragging all the time, will prefer to omit another click on the menu.