Skip to content

Instantly share code, notes, and snippets.

@kuuote
Last active March 18, 2025 18:37
Show Gist options
  • Save kuuote/f0403c85f758236e4849510c7604efa5 to your computer and use it in GitHub Desktop.
Save kuuote/f0403c85f758236e4849510c7604efa5 to your computer and use it in GitHub Desktop.
pty key remapper
#!/usr/bin/env python
import argparse
import os
import pty
import signal
import sys
import termios
parser = argparse.ArgumentParser()
parser.add_argument("filename", nargs="?")
options = parser.parse_args()
shell = os.environ.get("SHELL", "sh")
filename = options.filename
def parseconfig(path):
root = [None] * 257
if path is None:
# return root
path = os.path.dirname(__file__) + "/config.py"
env = {}
exec(open(path).read(), env)
for k, v in env["config"].items():
buf = k.encode()
node = root
for b in buf:
if node[b] is None:
node[b] = [None] * 257
node = node[b]
node[256] = v.encode()
return root
def find(trie, buf, start):
for i in range(start, len(buf)):
c = buf[i]
suc = trie[c]
if suc is None:
return (i + 1, None)
result = suc[256]
if result is not None:
return (i + 1, result)
trie = suc
return None
trie = parseconfig(filename)
size = None
mfd = None
def resize(*unused):
if mfd is not None:
newsize = termios.tcgetwinsize(sys.stdin.fileno())
termios.tcsetwinsize(mfd, newsize)
pass
signal.signal(signal.SIGWINCH, resize)
def read1(fd):
global mfd
if mfd is None:
mfd = fd
resize()
data = os.read(fd, 1048576)
return data
logfile = open("/tmp/ptylog", "wb")
def log(msg):
logfile.write("key:".encode())
logfile.write(msg)
logfile.write("\n".encode())
logfile.flush()
def read2(fd):
global trie
result = b""
buf = os.read(fd, 1048576)
log(buf)
if buf[0] == 0x1B:
return buf
while True:
found = find(trie, buf, 0)
if found is None:
# ここ(マッピングが解決できないタイミング)以外でreadすると詰まる
buf = buf + os.read(fd, 1048576)
log(buf)
continue
if found[1] is None:
result += buf[0 : found[0]]
else:
if found[1] == b"reload":
trie = parseconfig(filename)
pass
result += found[1]
buf = buf[found[0] :]
if len(buf) == 0:
break
return result
pty.spawn(shell, read1, read2)
config = {}
a = "abcdefghijklmnopqrstuvwxyz"
j = "かきくさしすたちつなにぬはひふまみむめやいゆらりるれ"
for i in range(len(a)):
config[j[i]] = a[i]
config["あ" + j[i]] = a[i].upper()
config["う" + j[i]] = chr(ord(a[i]) - 0x60)
config["え" + j[i]] = "\x1b" + a[i]
# わ + あ行は数値シフトの記号
j = "あかさたなはまやらわ"
a = "!@#$%^&*()"
for i in range(len(a)):
config["わ" + j[i]] = a[i]
# Vimだとドットの使用率の方が高いので入れ替える
config["、"] = "."
config["。"] = ","
config["を"] = ";"
config["ん"] = "'"
config["ー"] = "/"
config['ア'] = 'reload'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment