Gibt es in Gnome-Terminal einen Befehl oder eine tabellarische Shell, um einen neuen Tab zu öffnen?

11

Ich suche keine Tastenkombination, sondern möchte Befehle für:

  • Neues Fenster
  • Neue Registerkarte
  • Schließen Sie die aktuelle Registerkarte oder das aktuelle Fenster
  • Shell-Fenster maximieren
  • Shell-Fenster minimieren
  • Verschieben Sie Shell in einen anderen Arbeitsbereich
  • Registerkarte wechseln

Und im Grunde so etwas. Merken; Ich möchte keine Verknüpfungen, sondern tatsächliche Befehle. Der Grund dafür ist, dass ich die Alias-Funktionalität nutzen kann.

Akiva
quelle
1
Ist Python für dich in Ordnung?
Sergiy Kolodyazhnyy
4
"Aktuelle Registerkarte schließen" - dieser Befehl heißt "exit": D
egmont
"Ich möchte keine Verknüpfungen [...], damit ich die Alias-Funktionalität nutzen kann" - könnten Sie dies bitte näher erläutern? Was ist der genaue Vorteil, auf den Sie hoffen, anstelle der bekannten Verknüpfungen? Was ist das Problem oder die fehlende Funktionalität in Verknüpfungen? Ich denke, sie sind der richtige Ansatz für das, was Sie suchen.
Egmont
@egmont Ich bin ein Vim-Süchtiger, wenn das Sinn macht.
Akiva
Nehmen wir also an, z. B. für Maximieren, anstatt einen Fenstermanager-Hotkey zu haben, der für alle Arten von Fenstern (Browser, Bildeditor, Textverarbeitung usw.) in allen Zuständen (dh was auch immer Sie in ihnen tun) funktioniert. Ich bevorzuge einen Befehl, der nur für das Terminal und keine andere App funktioniert, und nur dann, wenn darin kein Befehl ausgeführt wird (außer natürlich der Standard-Shell). Nein, sorry, diese Idee macht für mich immer noch nicht allzu viel Sinn :(
egmont

Antworten:

14

Sie können dies in Gnome-Terminal nicht standardmäßig tun, zumindest nicht mit Raw-Befehlen.

Sie können jedoch Skripte schreiben, die Tastaturkürzel aufrufen, die dies tun können. Beachten Sie, dass Sie dazu Folgendes benötigen xdotool:sudo apt install xdotool

  • Neues Fenster : Starten Sie ein neues Terminalfenster mit nw
    Wir können dies mit nur tun gnome-terminal.
    Hinzufügen zu.bashrc :

    echo "alias nw=gnome-terminal" >> ~/.bashrc
  • Neuer Tab : Starten Sie einen neuen Tab mit nt
    Wir können dies mit xdotool getactivewindow $(xdotool key ctrl+shift+t)
    Hinzufügen zu.bashrc :

    echo "alias nt='xdotool getactivewindow $(xdotool key ctrl+shift+t)'" >> .bashrc
  • Registerkarte schließen : Schließen Sie die aktuelle Registerkarte oder das aktuelle Fenster erneut mit ct
    xdotoolStreiks: xdotool getactivewindow $(xdotool key ctrl+shift+w)
    Hinzufügen zu.bashrc :

    echo "alias ct='xdotool getactivewindow $(xdotool key ctrl+shift+w)'" >> .bashrc
  • Fenster maximieren : Maximieren Sie das gesamte Fenster mit maw
    Wir können wmctrlhier verwenden: wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz
    Hinzufügen zu.bashrc :

    echo "alias maw='wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz'" >> .bashrc
  • Fenster minimieren : Minimieren Sie das gesamte Fenster mit miw
    Wir können es xdotoolwieder verwenden: xdotool windowminimize $(xdotool getactivewindow)
    Hinzufügen zu.bashrc :

    echo "alias miw='xdotool windowminimize $(xdotool getactivewindow)'" >> .bashrc
  • In Arbeitsbereich verschieben : Verschieben Sie ein Fenster in einen anderen Arbeitsbereich mit mtw <id>
    Dies wäre bei Shell-Skripten kaum möglich und geht weit über meine persönlichen Erfahrungen hinaus. Ich würde empfehlen, Sergs Skript für diesen Zweck zu verwenden, da es ab sofort tatsächlich funktioniert. Ah, die Vorteile von Compiz.

Kaz Wolfe
quelle
7

Einführung

Das in dieser Antwort dargestellte Skript ermöglicht es dem Benutzer, sein Terminalfenster über einen einzigen Befehl und eine Liste von Optionen zu steuern. Es ist einfach zu verwenden und mit jedem Terminalemulator kompatibel, dessen Tastenkombination ähnlich ist gnome-terminal. Verschiebungsoptionen können auch mit anderen Terminals verwendet werden, das Öffnen von Registerkarten ist für diese Terminals jedoch nicht garantiert.

Das Skript behandelt das Öffnen von Registerkarten, das Öffnen von Fenstern, das Verschieben in den Arbeitsbereich nach unten, den Arbeitsbereich nach rechts und den spezifischen Arbeitsbereich, auf den durch eine Ganzzahl verwiesen wird, das Minimieren, Maximieren und Aufheben der Maximierung eines Fensters. Das einzige, was das Skript nicht behandelt, ist das Schließen von Tab / Fenster, einfach weil jeder Shell- / Terminal-Emulator bereits einen Befehl dafür hat - exitoder alternativ über eine CtrlDVerknüpfung.

!!! HINWEIS: Sie müssen den xdotoolArbeitsbereich wechseln und Registerkarten öffnen. Installieren Sie es über sudo apt-get install xdotool. Wenn Sie keine zusätzlichen Pakete installieren möchten, beachten Sie, dass das Wechseln des Arbeitsbereichs und der Registerkarten nicht funktioniert , andere Optionen jedoch.

Verwendung:

Alle Argumente windowctrl.pysind optional, sodass sie separat oder möglicherweise zusammen verwendet werden können. Wie durch -hOption gezeigt .

$ ./windowctrl.py -h                                                                               
usage: windowctrl.py [-h] [-w] [-t] [-m] [-M] [-u] [-v VIEWPORT] [-r] [-d]

Copyright 2016. Sergiy Kolodyazhnyy.

    Window control for terminal emulators. Originally written
    for gnome-terminal under Ubuntu with Unity desktop but can 
    be used with any other terminal emulator that conforms to 
    gnome-terminal keybindings. It can potentially be used for 
    controlling other windows as well via binding this script
    to a keyboard shortcut.

    Note that --viewport and --tab options require xdotool to be
    installed on the system. If you don't have it installed, you 
    can still use the other options. xdotool can be installed via
    sudo apt-get install xdotool.


optional arguments:
  -h, --help            show this help message and exit
  -w, --window          spawns new window
  -t, --tab             spawns new tab
  -m, --minimize        minimizes current window
  -M, --maximize        maximizes window
  -u, --unmaximize      unmaximizes window
  -v VIEWPORT, --viewport VIEWPORT
                        send window to workspace number
  -r, --right           send window to workspace right
  -d, --down            send window to workspace down

Skript-Quellcode:

Der Skript-Quellcode ist sowohl auf GitHub als auch hier verfügbar. Die neuesten Änderungen werden wahrscheinlich eher in den GitHub als hier übertragen. Ich empfehle daher dringend, dort nach der neuesten Version zu suchen. Es wird auch empfohlen, dort auch Fehlerberichte zu veröffentlichen.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Program name: windowctrl.py
Author: Sergiy Kolodyazhnyy
Date:  Sept 18, 2016
Written for: http://askubuntu.com/q/826310/295286
Tested on Ubuntu 16.04 LTS
"""
from __future__ import print_function
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gio,Gdk
import sys
import dbus
import subprocess
import argparse

def gsettings_get(schema,path,key):
    """Get value of gsettings schema"""
    if path is None:
        gsettings = Gio.Settings.new(schema)
    else:
        gsettings = Gio.Settings.new_with_path(schema,path)
    return gsettings.get_value(key)

def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError:
        print(">>> subprocess:",cmdlist)
        sys.exit(1)
    else:
        if stdout:
            return stdout

def get_dbus(bus_type,obj,path,interface,method,arg):
    # Reusable function for accessing dbus
    # This basically works the same as 
    # dbus-send or qdbus. Just give it
    # all the info, and it will spit out output
    if bus_type == "session":
        bus = dbus.SessionBus() 
    if bus_type == "system":
        bus = dbus.SystemBus()
    proxy = bus.get_object(obj,path)
    method = proxy.get_dbus_method(method,interface)
    if arg:
        return method(arg)
    else:
        return method() 

def new_window():
    screen = Gdk.Screen.get_default()
    active_xid = int(screen.get_active_window().get_xid())
    app_path = get_dbus( 'session',
                         'org.ayatana.bamf',
                         '/org/ayatana/bamf/matcher',
                         'org.ayatana.bamf.matcher',
                         'ApplicationForXid',
                         active_xid
                         )

    desk_file  = get_dbus('session',
                          'org.ayatana.bamf',
                          str(app_path),
                          'org.ayatana.bamf.application',
                          'DesktopFile',
                          None
                          )

    # Big credit to Six: http://askubuntu.com/a/664272/295286
    Gio.DesktopAppInfo.new_from_filename(desk_file).launch_uris(None)



def enumerate_viewports():
    """ generates enumerated dictionary of viewports and their
        indexes, counting left to right """
    schema="org.compiz.core"
    path="/org/compiz/profiles/unity/plugins/core/"
    keys=['hsize','vsize']
    screen = Gdk.Screen.get_default()
    screen_size=[ screen.get_width(),screen.get_height()]
    grid=[ int(str(gsettings_get(schema,path,key))) for key in keys]
    x_vals=[ screen_size[0]*x for x in range(0,grid[0]) ]
    y_vals=[screen_size[1]*x for x in range(0,grid[1]) ]

    viewports=[(x,y)  for y in y_vals for x in x_vals ]

    return {vp:ix for ix,vp in enumerate(viewports,1)}


def get_current_viewport():
    """returns tuple representing current viewport, 
       in format (width,height)"""
    vp_string = run_cmd(['xprop', '-root', 
                         '-notype', '_NET_DESKTOP_VIEWPORT'])
    vp_list=vp_string.decode().strip().split('=')[1].split(',')
    return tuple( int(i)  for i in vp_list )

def maximize():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.maximize()
    screen.get_active_window()
    window.process_all_updates()

def unmaximize():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.unmaximize()
    screen.get_active_window()
    window.process_all_updates()

def minimize():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.iconify()
    window.process_all_updates()

def window_move(viewport):

    # 1. grab window object
    # 2. jump viewport 0 0 so we can move only
    #    in positive plane
    # 3. move the window.
    # 4. set viewport back to what it was

    # Step 1
    screen = Gdk.Screen.get_default()
    screen_size=[ screen.get_width(),screen.get_height()]
    window = screen.get_active_window()

    viewports = enumerate_viewports()
    current = get_current_viewport()
    current_num = viewports[current]
    destination = [ 
                   key for  key,val in viewports.items() 
                   if val == int(viewport)
                   ][0]
    # Step 2.
    run_cmd([
            'xdotool',
            'set_desktop_viewport',
            '0','0'
            ]) 
    # Step 3.
    window.move(destination[0],destination[1])
    window.process_all_updates()

    run_cmd([
            'xdotool',
            'set_desktop_viewport',
            str(current[0]),
            str(current[1])
            ]) 

def move_right():
    sc = Gdk.Screen.get_default()
    width = sc.get_width()
    win = sc.get_active_window()
    pos = win.get_origin()
    win.move(width,pos.y)
    win.process_all_updates()

def move_down():
    sc = Gdk.Screen.get_default()
    height = sc.get_height()
    win = sc.get_active_window()
    pos = win.get_origin()
    win.move(pos.x,height)
    win.process_all_updates()

def new_tab():
    run_cmd(['xdotool','key','ctrl+shift+t'])

def parse_args():
    """ Parse command line arguments"""

    info="""Copyright 2016. Sergiy Kolodyazhnyy.

    Window control for terminal emulators. Originally written
    for gnome-terminal under Ubuntu with Unity desktop but can 
    be used with any other terminal emulator that conforms to 
    gnome-terminal keybindings. It can potentially be used for 
    controlling other windows as well via binding this script
    to a keyboard shortcut.

    Note that --viewport and --tab options require xdotool to be
    installed on the system. If you don't have it installed, you 
    can still use the other options. xdotool can be installed via
    sudo apt-get install xdotool.
    """
    arg_parser = argparse.ArgumentParser(
                 description=info,
                 formatter_class=argparse.RawTextHelpFormatter)
    arg_parser.add_argument(
                '-w','--window', action='store_true',
                help='spawns new window',
                required=False)
    arg_parser.add_argument(
                '-t','--tab',action='store_true',
                help='spawns new tab',
                required=False)
    arg_parser.add_argument(
                '-m','--minimize',action='store_true',
                help='minimizes current window',
                required=False)
    arg_parser.add_argument(
                '-M','--maximize',action='store_true',
                help='maximizes window',
                required=False)
    arg_parser.add_argument(
                '-u','--unmaximize',action='store_true',
                help='unmaximizes window',
                required=False)
    arg_parser.add_argument(
               '-v','--viewport',action='store',
               type=int, help='send window to workspace number',
               required=False)
    arg_parser.add_argument(
               '-r','--right',action='store_true',
               help='send window to workspace right',
               required=False)
    arg_parser.add_argument(
               '-d','--down',action='store_true',
               help='send window to workspace down',
               required=False)
    return arg_parser.parse_args()

def main():

    args = parse_args()

    if args.window:
       new_window()
    if args.tab:
       new_tab()
    if args.down:
       move_down()
    if args.right:
       move_right()       
    if args.viewport:
       window_move(args.viewport)
    if args.minimize:
       minimize()
    if args.maximize:
       maximize()
    if args.unmaximize:
       unmaximize()

if __name__ == '__main__':
    main()

Randnotizen

  • Sie fragten: "Gibt es in Gnome-Terminal einen Befehl oder eine tabellarische Shell, um einen neuen Tab zu öffnen?" Das Gnome Terminal-Handbuch listet diese Option nicht auf. Die Shells sind Befehlszeilenprogramme. Registerkarten sind Funktionen von GUI-Anwendungen. Es gibt Terminal-Multiplexer wie screenoder, tmuxdie "Tabs" oder geteilte Fenster haben können, die der "tabbable shell" nahe kommen, aber dies ist nicht die gleiche Art von Verhalten, die Sie fragen. Grundsätzlich lautet die Antwort auf Ihre Frage "Nein". Es gibt immer Alternativen, und meine Antwort liefert eine davon. Es behandelt das Terminalfenster entsprechend seiner Art - X11-GUI-Fenster.

  • In welcher Beziehung steht diese Antwort zu Aliasnamen? Zunächst einmal können Aliase etwas chaotisch sein, insbesondere wenn es darum geht, mehrere Ausgaben mehrerer Befehle zu zitieren und zu analysieren. Dieses Skript gibt Ihnen einen zentralen Befehl mit Flags / Switches, mit denen Sie eine diskrete Aufgabe in einem Fenster ausführen können. Es macht auch Aliase einfacher. Du könntest es tun alias nw='windowctrl.py --window'. Viel kürzer, viel ordentlicher.

Sergiy Kolodyazhnyy
quelle
Ich bin zufrieden mit Split-Terminals
Akiva
1
@Akiva Soll ich eine Frage zum Teilen des Terminals verlinken? Hast du dieses Skript übrigens ausprobiert? was denkst du ?
Sergiy Kolodyazhnyy
Ich werde Ihr Skript ausprobieren, da die obige Antwort mir Probleme bereitet. Allerdings habe ich möglicherweise nicht so viel Glück, da das Problem hauptsächlich bei xdotool liegt.
Akiva
@ Akiva und was ist das Problem mit xdotool? Vielleicht könnte ich es reparieren?
Sergiy Kolodyazhnyy
Ich muss darauf zurückkommen. Ich habe möglicherweise mit meinem benutzerdefinierten Tastaturlayout zu tun oder mit der Tatsache, dass ich auf 16.10 bin oder dass ich es bei Guake versuche.
Akiva