Ubuntu – Remove the preceding “file://” when pasting in gnome terminal

clipboardcommand linegnome-terminalnautilustext processing

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).

Best Answer

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