Script to copy the path of a file, opened in gedit
With the gedit window in front, the small script below derives the path from the (gedit
) window's name, and copies it to the clipboard.
The script has two options:
Only copy the path to the file's directory, running the script with the option
-path
or
Copy the path including the file name, running the script with the option
-file
The script
#!/usr/bin/env python3
import subprocess
import sys
name = subprocess.check_output(["xdotool", "getactivewindow", "getwindowname"]).decode("utf-8").strip()
if all(["(" in name, ")" in name]):
path = name[name.find("(")+1:name.find(")")]
if sys.argv[1] == "-file":
fname = name[:name.find("(")]
elif sys.argv[1] == "-path":
fname = ""
command = "echo "+'"'+path+"/"+fname+'"'+" | xclip -selection clipboard"
subprocess.Popen(["/bin/bash", "-c", command])
How to use
Install both xdotool
and xclip
:
sudo apt-get install xdotool xclip
Copy the script into an empty file, save it as get_path.py
Test run the script:
- open an existing
gedit
file
open a terminal window, run the command:
sleep 5 && python3 /path/to/get_path.py -file
immediately switch to the gedit
window, to make the last part of tyhe command run with the gedit
window in front.
- Press Ctrl+V somewhere to paste the just copied path.
If all works fine, you can make the options available in two ways:
- Create two shortcut keys for both options: choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add both commands to two different shortcuts.
Make both options available in the gedit
launcher:
Copy the content below into an empty file, save it as gedit.desktop
in ~/.local/share/applications
[Desktop Entry]
Name=gedit
GenericName=Text Editor
Comment=Edit text files
Exec=gedit %U
Terminal=false
Type=Application
StartupNotify=true
MimeType=text/plain;
Icon=accessories-text-editor
Categories=GNOME;GTK;Utility;TextEditor;
X-GNOME-DocPath=gedit/gedit.xml
X-GNOME-FullName=Text Editor
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gedit
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.4
X-GNOME-Bugzilla-ExtraInfoScript=/usr/share/gedit/gedit-bugreport
Actions=Window;Document;divider1;Copy current file's directory;Copy path+file name;
Keywords=Text;Editor;Plaintext;Write;
X-Ubuntu-Gettext-Domain=gedit
[Desktop Action Window]
Name=Open a New Window
Exec=gedit --new-window
OnlyShowIn=Unity;
[Desktop Action Document]
Name=Open a New Document
Exec=gedit --new-document
OnlyShowIn=Unity;
[Desktop Action Copy current file's directory]
Name=Copy current directory
Exec=python3 /path/to/get_path.py -path
OnlyShowIn=Unity;
[Desktop Action divider1]
Name=.....................................
OnlyShowIn=Unity;
[Desktop Action Copy path+file name]
Name=Copy current directory, include file name
Exec=python3 /path/to/get_path.py -file
OnlyShowIn=Unity;
In both lines:
Exec=python3 /path/to/get_path.py -path
and
Exec=python3 /path/to/get_path.py -file
replace /path/to/get_path.py
by the real path to the script.
Log out and back in to make Unity "switch" to the new, local .desktop
file.
Explanation
In the gedit window name, the path is displayed between (
and )
. The script simply sees the frontmost window with the help of xdotool
, then reads the path between those two characters.
Notes
Since the path is read in a textual way, the script will fail if the file's name includes other ()
characters.
Examples
With the following window in front:
the first option will copy to the clipboard the path to the file:
~/Bureaublad
while the second option includes the file itself:
~/Bureaublad/some test file.txt
As you can see, spaces are taken care of :).
NOTE: in this answer there are two solutions, each with its own benefits. Users are encouraged to find out which one works best for their specific case.
Introduction
Nautilus by itself doesn't offer a way to define custom keyboard shortcuts and their actions. This is the main reason why the scripts you tried have failed. $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
can only be used via right click submenu. But we can exploit something else to achieve the desired result - shortcuts defined in the settings and system clipboard.
Nautilus is built in something known as Gtk toolkit. It is an extensive library for creating graphic applications, and among other things it has utilities for interfacing with system clipboard. Nautilus, being a file manager, is special in the fact that it outputs a list of URIs ( in the form file:///home/user/Pictures/encoded%image%name.png
) to clipboard (which isn't a well known fact to most users, and I've learned quite recently as well). Apparently this is the way GUI file-managers copy files.
We can exploit that fact by copying the URI of the file (or to be exact, the list of URI's; even if there's just one, it defaults to a list). Then we can pass that list to gimp
. The two solutions presented below operate exactly on that idea.
Reasoning for 2 solutions:
I personally consider solution #1 as preferred one. It relies on manually pressing copy shortcut first, and then script shortcut - that's two keyboard shortcuts - but it has advantage in having less dependencies. It's a more manual approach , but fairly decent. It uses os.execlp
call, which will replace script's process with Gimp, thus acting as merely a springboard for Gimp
. It's a frequent practice in scripting and system programming to use exec
family of functions
The second solution was written because Jacob Vlijm mentioned in the comments that for him the execlp
function didn't work, for whatever reason. I find this very strange because the execlp
belong to standard os
module for python , which is one of the modules installed default. In addition, subprocess.Popen()
defaults to exec()
family of functions; from subprocess
documentation:
On POSIX, with shell=False (default): In this case, the Popen class
uses os.execvp() to execute the child program. args should normally
be a sequence. A string will be treated as a sequence with the string
as the only item (the program to execute).
( Note "On POSIX" means "POSIX compliant OS"; Ubuntu is POSIX-compliant)
Thus, it doesn't seem like an issue with a function itself, but with user's system. Nevertheless, I wrote second script. That one uses subprocess
module and relies on xdotool
, which will basically automate pressing Ctrl+C shortcut for you, and then launch Gimp. I personally don't like this one as much, since it requires additional item to be installed, but it has advantage of needing just one keyboard shortcut.
The idea, however, is the same. We still use Gtk tools to query clipboard contents and in each case, scripts must be bound to a shortcut.
Solution #1, two shortcuts, minimum dependencies
Usage: select file and press Ctrl+C to copy file first, then press the shortcut you've assigned to this script. execlp
function will replace the script's process with gimp
.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from os import execlp
from time import sleep
from urllib.parse import unquote
import signal
import threading
import subprocess
uris = None
def autoquit():
global uris
#sleep(0.5)
while not uris:
# allow sufficient time to obtain uris
sleep(2)
pass
Gtk.main_quit()
def get_clipboard_contents():
global uris
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
tr = threading.Thread(target=autoquit)
tr.daemon = True
tr.start()
uris = clip.wait_for_uris()
Gtk.main()
return [unquote(i).replace('file://','')
for i in uris]
def main():
signal.signal(signal.SIGINT,signal.SIG_DFL)
files = get_clipboard_contents()
print(files)
args = ['gimp'] + files
execlp('gimp',*args)
if __name__ == '__main__': main()
Solution #2: single shortcut, xdotool dependency
Usage for this script is simpler: select file(s) in Nautilus and press keyboard shortcut. NOTE: you must have xdotool
installed for this to work, use sudo apt-get install xdotool
.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from subprocess import Popen,STDOUT
from time import sleep
from urllib.parse import unquote
import sys
def unquote_uri(*args):
uris = args[-2]
unquoted_args = [ str(unquote(i).replace('file://',''))
for i in uris]
with open('/dev/null','w') as dev_null:
proc = Popen(['gimp',*unquoted_args],stdout=dev_null,stderr=STDOUT)
Gtk.main_quit()
def main():
# NOTE: xdotool is REQUIRED for this to work
Popen(['xdotool','key','Ctrl+c'])
sleep(0.5)
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clip.request_uris(unquote_uri, None)
Gtk.main()
if __name__ == '__main__': main()
Setting up the shortcut
In both cases, you need to have script linked to a shortcut. Open System Settings -> Keyboard -> Shortcuts -> Custom. Click the + button. Give full (!) path to file as command. For example, /home/User_Name/bin/clipboard_launch.py
Assign the shortcut to be something sensible. For example, since we're calling Gimp, I've assigned my script to Ctrl+Super+G.
Best Answer
With a little reaserch, I found out what you may be looking for. This can be done using
.desktop
files. Let me demonstrate.Create a file in your home diretory(as an example) with the extension
.desktop
with the following content:Replace
<path-to-your-script>
with path of the script you want to execute. Here%u
is the path of the file which you will be dragging on the .desktop file to trigger the script. This will obviously be passed as an argument to your script.Don't forget to make your
.desktop
executable as well by:To check if it is working you can point it to this script:
You will see the full path of the file which you dragged onto your .desktop file stored in out.txt in you home directory.
Finally, you can set up a dock to have just this in it, so you have it at the side of the screen.
References:
Desktop Entry Specification
Gnome Developer - Desktop Files