在 gnome 终端中粘贴时删除前面的“file://”

在 gnome 终端中粘贴时删除前面的“file://”

我正在使用 Ubuntu 14.04,但我猜这个东西在几乎所有版本的 Ubuntu 中都可以看到。

当我使用 nautilus 复制文件Ctrlc并粘贴到 gedit 中时,它会粘贴如下文本,/home/urvish/.bash_history这对我来说很完美。但是当我使用 将其粘贴到终端中时,CtrlShiftv它显示如下file:///home/urvish/.bash_history

有什么方法可以file://在粘贴时删除前面的内容?(我知道我可以手动完成,但我经常这样做,而且总是手动执行很耗时)。

答案1

gnome-terminal 的作用

通过阅读 Gtk 文档,似乎程序可以通过两种方式处理剪贴板内容 - 纯文本和文件 URI 列表。无论出于何种原因,gnome-terminal决定区分两者是个好主意,因此当您将文件从 Nautilus 复制到时gnome-terminal,终端会检索 URI 列表,而其他程序 - 仅检索纯文本。

自动编辑剪贴板会稍微麻烦一些(尽管我仍在追求这个想法) - 我们需要定义一种方法来检测您尝试粘贴剪贴板内容的位置,并且运行将脚本编辑为纯文本的持久脚本(有效地删除 URI)将阻止您将文件从一个 Nautilus 窗口复制到另一个窗口。

拖放可能是最简单的解决方案。但由于要求使用脚本方法,我想到了两种手动方法。一种依赖于 Nautilus 的内置功能,即向右键菜单添加脚本。另一种依赖于输入特定的快捷方式粘贴到 gnome-terminal。

手动脚本方法,版本 1

该脚本将被放入文件夹中,并通过右键单击文件并编辑属性中的权限选项卡~/.local/share/nautilus/scripts使其可执行。实际上,它允许您将路径复制到选定的文件作为带引号的字符串并删除部分。chmod +x ~/.local/share/nautilus/scripts/scriptname.shfile://

要使用它,请在 Nautilus 中选择一个或多个文件,然后右键单击它们。选择Scripts菜单 -> 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)])

手动脚本方法,版本 2

这种方法依赖于在粘贴到 之前运行下面的 Python 脚本的想法gnome-terminal。您可以手动将其gnome-terminal作为命令 调用,或将其绑定到键盘快捷键。因此,使用快捷方式方法,我会将其绑定到CtrlShiftB(因为它的 B 和 V 在键盘上很接近),并且每次我需要从 Nautilus 粘贴时,我都会点击CtrlShiftB编辑,然后CtrlShiftV粘贴

#!/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()

免责声明:答案仍在开发中;稍后可能会添加其他内容/想法

答案2

我有点迟到了,但是我在 Linux Mint MATE(mate-terminal)上看到了这个问题。

看起来,只需抓取剪贴板的内容,然后将其再次传递回剪贴板就足够了。如果是这样的话,那么我们只需要关心测试剪贴板内容是否包含一个或多个有效的文件路径,其余部分则不受影响。

以下命令将删除 Mint 上的 file:// 前缀:

#!/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()

如果你要实现这种方法,那么你可能还需要将其守护进程化。 pyperclip 模块可以通过以下方式获取:

sudo pip install pyperclip

相关内容