about summary refs log tree commit diff
path: root/saneterm/keys.py
blob: 925bdab3926be974f2503d7d7c07d05b0e4d82d0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import termios

from gi.repository import Gtk
from gi.repository import GObject

# Control keys are intercept directly (see DESIGN.md)
CTRL = {
    "<ctrl>c": termios.VINTR,
    "<ctrl>z": termios.VSUSP,
    "<ctrl>d": termios.VEOF,
}

class Bindings():
    stylesheet = b"""
        @binding-set saneterm-key-bindings {
            bind "<ctrl>u" { "kill-after-output" () };
            bind "<ctrl>a" { "move-input-start" () };
            bind "<ctrl>e" { "move-input-end" () };
            bind "<ctrl>j" { "insert-at-cursor" ("\\n") };

            bind "<ctrl>w" { "delete-from-cursor" (word-ends, -1) };
            bind "<ctrl>h" { "backspace" () };

            bind "Up" { "history-entry" (1) };
            bind "Down" { "history-entry" (-1) };

            /* Since <ctrl>c is used for VINTR, unbind <ctrl>v */
            unbind "<ctrl>v";
        }

        * {
             -gtk-key-bindings: saneterm-key-bindings;
        }
    """

    def __init__(self, widget):
        self.provider = Gtk.CssProvider()
        self.provider.load_from_data(self.stylesheet)

        style_ctx = widget.get_style_context()
        style_ctx.add_provider(self.provider,
                Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

    def add_bind(self, key, signal, arg):
        bindings = self.__binding_set()
        # Using Gtk.BindingEntry.add_signall() would be preferable
        # https://gitlab.gnome.org/GNOME/pygobject/-/issues/474
        Gtk.BindingEntry().add_signal_from_string(bindings,
                F'bind "{key}" {{ "{signal}" ({arg}) }};')

    def __binding_set(self):
        return Gtk.BindingSet.find("saneterm-key-bindings")