13

I don't like to have dozens of terminals opened. Is there a way to add Open in current Terminal instead of Open in Terminal when using Nautilus?

  • Only dirty solutions as far as I can imagine. I can give one if you are fine with that... – Jacob Vlijm Nov 3 '16 at 17:54
13

Dirty or not, the solution below worked perfectly in the 30 minutes I tested it frequently. The solution works as long as you can right-click a file (any) inside the directory:

1.

enter image description here

2.

enter image description here

3.

enter image description here

Nautilus script

#!/usr/bin/env python3
import subprocess
import os
import time

def replace(path):
    for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
              ("file://", ""), ("%20", " ")]:
        path = path.replace(c[0], c[1])
    return path

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

t = get(["pgrep", "gnome-terminal"])
if t:
    w = [l.split()[0] for l in get(["wmctrl", "-lp"]).splitlines() if t in l][0]
    # get the current path
    current = replace(os.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))
    dr = os.path.realpath(current)
    # raise the found terminal window
    subprocess.call(["wmctrl", "-ia", w])
    time.sleep(0.3)
    # copy the cd command to clipboard
    c1 = "printf 'cd ' | xclip -in -selection c"
    c2 = 'echo "'+"'"+dr+"'"+'"  | xclip -in -selection c'
    # paste & run it
    for c in [c1, c2]:
        subprocess.call(["/bin/bash", "-c", c])
        subprocess.call(["xdotool", "key", "Control_L+Shift+v"])
        time.sleep(0.05)

How to use

  1. The script needs wmctrl, xdotool and xclip:

    sudo apt-get install wmctrl xdotool xclip
    
  2. Copy the script into an empty file, save it as open_in_terminal (no extension) in ~/.local/share/nautilus/scripts. Create the directory if needed. Make the script executable

That's it. Log out and back in and you'll have the script available as in the image (2).

Explanation

  • Right- clicking a file, we can get the path using nautilus' "NAUTILUS_SCRIPT_CURRENT_URI".
  • In a script, we can then load this path into the clipboard (using xclip)
  • Subsequently, the script raises the (first found) gnome-terminal window and pastes the path, preceded by the cd command. Since we used echo to load the whole line into the clipboard, Return is included.

Notes

  1. It should be clear that there should be nothing running in the terminal, and it works best if there is only one terminal window open. In case there are multiple, the script picks the oldest gnome-terminal window.
  2. The script needs to be tested thoroughly in practice. While I ran it, the timing was no issue even a single time, not even when the Desktop had to "travel" across four or five viewports to get to the terminal window. IF errors would occur however, with a few lines more we could make it actually wait in a smart(er) way for the terminal window to be raised. Let's see what happens. It doesn't seem necessary.
  3. Since the script uses the realpath, also linked directories will work correctly.

More information on nautilus scripts here.


Alternatively, pick your own terminal window if you have multiple

If you want to be able to choose in which terminal window you would open the current (nautilus) directory, use the script below.

How it works in practice

  1. Right- click (any) file inside the directory (in this case my desktop) like below:

    enter image description here

  2. Click on (or raise otherwise) the terminal window you'd like to use, and it will cd to the directory:

    enter image description here

The script

#!/usr/bin/env python3
import subprocess
import os
import time

def replace(path):
    for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
              ("file://", ""), ("%20", " ")]:
        path = path.replace(c[0], c[1])
    return path

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

# check if gnome-terminal runs
pid = get(["pgrep", "gnome-terminal"])

if pid:
    t = 0
    while t < 30:
        # see if the frontmost window is a terminam window
        active = get(["xdotool", "getactivewindow"])
        if pid in get(["xprop", "-id", active]):       
            # get the current path
            current = replace(os.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))
            dr = os.path.realpath(current)
            # copy the cd command to clipboard
            c1 = "printf 'cd ' | xclip -in -selection c"
            c2 = 'echo "'+"'"+dr+"'"+'"  | xclip -in -selection c'
            # paste & run it
            for c in [c1, c2]:
                subprocess.call(["/bin/bash", "-c", c])
                subprocess.call(["xdotool", "key", "Control_L+Shift+v"])
                time.sleep(0.05)
            break
        else:
            t += 1
            time.sleep(0.5)

Setup

Is exactly like the first script.

Explanation

The script has one difference from the first one: instead of automatically raising the first found terminal window, it waits for the first terminal window to have focus. Then it cd's to the directory inside that window.

  • since you're using file to launch the script anyway, just remove filename from sys.argv[1] path. it'll make the script far shorter – Sergiy Kolodyazhnyy Nov 3 '16 at 21:25
  • 1
    @TonyLancer the menu appears after creating the directory ~/.local/share/nautilus/scripts logout and back in :) – Jacob Vlijm Nov 3 '16 at 21:29
  • 1
    @Benny it only works from nautilus right-click. – Jacob Vlijm Nov 3 '16 at 23:09
  • 1
    @Benny the environment for the script gets passed down from the parent process. In this case, Nautilus is the parent process of the script, and it sets up the environment for the script. If you're trying to do that same thing from python interpreter or a script, it will have different parent process, therefore it will return None because there's no such variable( outside of Nautilus that is). – Sergiy Kolodyazhnyy Nov 3 '16 at 23:15
  • 1
    @JacobVlijm you're awesome. Fully working! Now I understood how the second script works, you're right about trigger. It is really a nice gadget for ubuntu community. Of course we can think about many improvements as for any script, but this one does the job. Just mention in your answer that the second script works with Alt Tab. – Vitor Abella Nov 4 '16 at 20:42
8

I'm pretty sure there's no way to do this, however I have a workaround for you that might help.

You can always drag and drop a directory from Nautilus into a terminal window and Nautilus will pass that directory and paste it into the command line, so you could do cd and then drag the folder onto the terminal and hit enter.

8

Simplest way is this:

  1. From nautilus, press Ctrl + L , this will open the address bar for editing. Press the Ctrl+C
  2. Switch to terminal and type in cd, space, then Shift + Insert (or INS) to paste the path. Hit Enter.

No need for scripts or extra work.

  • I use Ctrl+Shift+V to paste the path. – Katu Nov 4 '16 at 9:48
  • 1
    yup, that's another way to do it. Linux has two clipboards, actually, so Ctrl+Shift+V is for primary and Shift+Insert is for secondary, but because second one requires only two keys, i use that mostly. They're shared, unless you highlight something - that's when stuff goes into secondary clipboard – Sergiy Kolodyazhnyy Nov 4 '16 at 17:50
1

In my opinion the only elegant way to solve this without fuding around is to use a terminal multiplexer like tmux and have your file manager

  • open new terminal windows inside an existing session or
  • start a new terminal emulator with a new tmux session.

The following shell script achieves just that:

#!/bin/sh
set -e
TMUX=tmux
#TERMINAL_EMULATOR='gnome-terminal -x'

cd "$1"
if $TMUX has-session; then
  exec $TMUX new-window
else
  exec ${TERMINAL_EMULATOR:-x-terminal-emulator -x} $TMUX
fi

TERMINAL_EMULATOR holds the desired terminal emulator for new terminal windows (if you don't like the default of whatever x-terminal-emulator points to) plus a command-line option for the command to execute inside the emulator.

You can register the file handler script like any other file type association in your file manager.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.