2

I am using Ubuntu 14.04 but I guess this thing can be seen in almost all versions of Ubuntu.

When I copy a file from nautilus using Ctrlc and paste into gedit it pastes the text like /home/urvish/.bash_history which is perfect for me. But when I paste it in terminal using CtrlShiftv it goes like file:///home/urvish/.bash_history.

Is there any way I can remove that preceding file:// while pasting? (I know I can do it manually but I do it very frequently and always doing manually is time taking).

muru
  • 197,895
  • 55
  • 485
  • 740
urvish
  • 21
  • 1
    Technically, yes, it's possible. I've written an indicator that does automatic replacement of clipboard contents based on the patterns. See here: http://askubuntu.com/a/875038/295286 – Sergiy Kolodyazhnyy Feb 09 '17 at 05:28
  • A side note: i have Ubuntu 16.04, and with terminator ( it's a different terminal emulator ) that doesn't seem to happen. In other words, gnome-terminal does that for whatever reason – Sergiy Kolodyazhnyy Feb 09 '17 at 05:34
  • 2
    Alternative way is dragging and dropping the file into terminal. That gets single quotes around the path , but that's actually good, because if you have filenames with spaces, you won't need to quote manually - that's already done for you. Let me know if you want any of these suggestions posted as an actual answer, instead of comments. – Sergiy Kolodyazhnyy Feb 09 '17 at 05:35
  • Hi @Serg, thanks for the quick reply and thanks muru for editing the questions to make it look better. Actually the drap and drop is good a way that I haven't used. But I use multi desktop and while moving around or while doing some other work after copying it makes this little difficult at times. I know that gnome is adding this extra text. I just want to see from where so that it can be modified. – urvish Feb 09 '17 at 05:55
  • OK. How about the indicator ? Think it's a good solution ? – Sergiy Kolodyazhnyy Feb 09 '17 at 06:01
  • It would take time to test that. I am little hesitant to add a new repo in my work pc which I use for lot many builds daily. I'll surely update once I try it on my personal pc. – urvish Feb 09 '17 at 06:34
  • If you don't want to add the repository, you can also get the indicator from github directly - the link is in the answer as well. Launched also allows downloading deb files alone. Ok, test it out, let me know how you like it. Also, I could just make a script version of the same thing, but that'll require a bit of time to write. I might do that tomorrow. – Sergiy Kolodyazhnyy Feb 09 '17 at 06:41
  • Thanks for going an extra mile and thinking to make the script. I saw your launchpad page and good to see many indicators. For now, can you please point me to the link to download the .deb file? I guess I can give it a try now. Thanks again. – urvish Feb 09 '17 at 09:19
  • here is the link to latest deb file as requested : https://code.launchpad.net/~1047481448-2/+archive/ubuntu/sergkolo/+files/clipboard-autoedit-indicator_0.1-0~201701231953~ubuntu17.04.1_all.deb – Sergiy Kolodyazhnyy Feb 09 '17 at 09:40
  • nothing happens when I click on "set regex pattern" :( – urvish Feb 10 '17 at 03:43
  • What do you mean , nothing happens ? Does popup appear ? – Sergiy Kolodyazhnyy Feb 10 '17 at 04:05
  • I see indicator, replacement enable/disable changes the colr of indicator, I can see clipboard content, quit button works. But nothing comes up when I click on "set regex pattern". – urvish Feb 10 '17 at 04:36
  • ok, I'll write a script then and see how to troubleshoot the indicator. Can you please run indicator from terminal and let me know if it throws any errors when you click set regex pattern ? Thanks – Sergiy Kolodyazhnyy Feb 10 '17 at 04:59
  • I ran "clipboard-autoedit-indicator" from cmdline. No messaged while accessing any other button but I get "This option is not available. Please see --help for all possible usages." when I hit "set regex pattern". – urvish Feb 10 '17 at 06:26
  • I've figured out what gnome-terminal is doing. It's not quite as obvious as one would think, and will write a script for that tomorrow. The indicator itself operates on plain text, so for what `gnome-terminal is doing, it won't work. Thank you very much for posting this question ! I probably wouldn't have figured this out otherwise. – Sergiy Kolodyazhnyy Feb 10 '17 at 07:06
  • Hi ! Posted an answer. It has two manual scripting approaches and small explanation what's happening with gnome-terminal. I'll keep searching for a automatic method as well, but for now that's the best I can provide – Sergiy Kolodyazhnyy Feb 10 '17 at 19:22
  • Comments are not for extended discussion; this conversation has been moved to chat. – Seth Feb 24 '17 at 22:04

2 Answers2

0

What gnome-terminal does

From reading through Gtk documentation, it appears that there are 2 ways a program can treat contents of clipboard - plain text and list of URIs to file. For whatever reason, gnome-terminal decided that it will be good idea to differentiate between two, and therefore it when you copy a file from Nautilus to gnome-terminal, the terminal retrieves the URI list, while other programs - only plain text.

Automatic editing of clipboard would be slightly troublesome ( although I'm still pursuing the idea) - we'd need to define a way of detecting where you're trying to paste the clipboard contents, and running persistent script that edits script into plain text ( effectively deleting the URIs ) will prevent you from copying files from one Nautilus window to another.

Dragging-and-dropping is probably the simplest solution. But since a scripting approach has been requested,I came up with idea for two manual approaches. One relies on the Nautilus' built in feature of adding scripts to your right-click menu. The other on entering a specific shortcut before pasting into gnome-terminal.

Manual script approach, version 1

This script is to be placed into ~/.local/share/nautilus/scripts folder and made executable via chmod +x ~/.local/share/nautilus/scripts/scriptname.sh or via right clicking on file and editing Permissions tab in properties. Effectively, it allows you to copy path to selected files as quoted strings and with file:// portion removed.

To use it, select file or files in Nautilus, and right click them. Select Scripts menu -> your_script_name.py.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
import sys
import os
import time
import subprocess
import signal
import urllib.parse
import threading

def autoquit(*args):
    subprocess.call(['zenity','--info'])
    time.sleep(1)
    Gtk.main_quit()

def main():

    uris = os.getenv("NAUTILUS_SCRIPT_SELECTED_URIS")
    new_text = " ".join([ "'" + urllib.parse.unquote(i).replace('file://','') + "'"
                          for i in uris.split()])

    clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    if clip.set_text(new_text,-1):
        thread = threading.Thread(target=autoquit)
        thread.start()
    Gtk.main()

if __name__ == '__main__': 
    try:
        main()
    except Exception as e:
        subprocess.call(['zenity','--info','--text',str(e)])

Manual script approach, version 2

This approach relies on the idea of running the python script below right before you paste into gnome-terminal. You can call it from gnome-terminal manually as command , or bind this to a keyboard shortcut. Thus, with shortcut method, I would bind it to CtrlShiftB (because it's B and V are close on keyboard), and each time I need to paste from Nautilus, I'd hit CtrlShiftB to edit , then CtrlShiftV to paste

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
import subprocess
import urllib.parse
import signal
import sys

def unquote_uri(*args):
    uris = args[-2]
    new_text = " ".join([ "'" + str(urllib.parse.unquote(i).replace('file://','')) + "'"
                          for i in uris])
    print(new_text)
    args[-3].clear()
    args[-3].set_text(new_text,-1)
    Gtk.main_quit()

def main():
    cached = str()
    clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
    clip.request_uris(unquote_uri, None)
    signal.signal(signal.SIGINT,signal.SIG_DFL)
    Gtk.main()

if __name__ == '__main__': main()

Disclaimer: answer still under development; additional content/ideas may be added later

Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • Hi Serg, Thanks for the effort. I would prefer the 2nd approach because 1st one would take the flexibility to past the file if it is already copied. More over, the copying by Ctrl + C is almost reactive. I'll try this and let you know how this went. – urvish Feb 13 '17 at 10:29
  • I saved the 2nd script as paste_in_terminal. Copied a file from nautilus and run the script. This is what I got : ** ERROR:../../gi/pygi-argument.c:1583:_pygi_argument_to_object: code should not be reached Aborted (core dumped). – urvish Feb 13 '17 at 10:35
  • @urvish How did you run the file on command-line and what is full error ? Please copy whole command-line and paste it to paste.ubuntu.com, then copy link to paste here. Also, what's your Ubuntu version ? – Sergiy Kolodyazhnyy Feb 13 '17 at 18:32
  • Hi @serg, sorry for the delay. Plz see this http://paste.ubuntu.com/24011930/ – urvish Feb 17 '17 at 06:08
0

I'm a little late to the party, but I'm seeing this issue on Linux Mint MATE (mate-terminal).

It seems that simply grabbing the contents of the clipboard and then passing it back to the clipboard again will suffice. If this is the case, then we need only concerns ourselves with testing if the clipboard contents comprises one or more valid file paths, and leaving the rest unmolested.

The following will drop the file:// prefix on Mint:

#!/usr/bin/env python

import os
import pyperclip
import time

class ClipboardWatcher():

    def __init__(self,latency):
        self.clipboard_last = pyperclip.paste()
        self.clipboard_now = None
        self.latency = latency

    def check_clipboard(self):

        # assume clipboard is space delimited list of valid paths
        as_list = self.clipboard_now.split()  
        valid_path = [ i for i in as_list if os.path.exists(i) ] 

        if len(as_list) == len(valid_path): # assumption true
            self.clipboard_now = " ".join(valid_path) 
            return True

        return False

    def run(self):
        while True:
            time.sleep(self.latency)  
            self.clipboard_now = pyperclip.paste()
            if self.clipboard_now != self.clipboard_last:                 
                if self.check_clipboard(): 
                    pyperclip.copy(self.clipboard_now)
                    print "Matched:", self.clipboard_now
            self.clipboard_last = self.clipboard_now

clippy = ClipboardWatcher(1)  # watch every n seconds
clippy.run()

If you were going to implement this sort of approach then you would probably also want to daemonize it. The pyperclip module can be had with:

sudo pip install pyperclip
faustus
  • 101