Skip to content

Instantly share code, notes, and snippets.

@takehaya
Last active June 3, 2018 07:20
Show Gist options
  • Save takehaya/2cb1fd98950b41b52b65b9a328e839b1 to your computer and use it in GitHub Desktop.
Save takehaya/2cb1fd98950b41b52b65b9a328e839b1 to your computer and use it in GitHub Desktop.
みんなquine(自己言及)を選ぶので自己改造も目指せるようにやってたけど出来なかったもの・・・(つらい)
import sys
import curses
import curses.ascii
def main():
# ライブラリを初期化し、スクリーンを表すWindowObjectを返す
win = curses.initscr()
# キー入力を自動的に画面に表示しない
curses.noecho()
# Enterキーを押さずに、キー入力に直ちに反応する
curses.cbreak()
keys = (
("h", "Left"),
("l", "Right"),
("k", "Up"),
("j", "Down"),
("c", "Clear"),
("q", "Quit"),
)
for y, key in enumerate(keys):
# カーソルを座標(x, y) に移動
win.move(y, 0)
# カーソル位置に文字を上書き
# 改行文字は使えないので、1行ずつ表示する
win.addstr("%s:%s" % key)
# メインウィンドウを更新
win.refresh()
# メインウィンドウの高さと幅を取得
y, x = win.getmaxyx()
# サブウィンドウを作成
swin = win.subwin(y, x-11, 0, 10)
# サブウィンドウの枠線を描画
# 左、右、上、下、左上、右上、左下、右下
swin.border("|", "|", "-", "-", "+", "+", "+", "+")
# カーソルが移動できる範囲は
# (0, 0)~(ウィンドウの高さ - 1, ウィンドウの幅 - 1)
# この範囲を超えた座標をmove()に渡すとエラー
min_x = 0
min_y = 0
max_y, max_x = swin.getmaxyx()
max_x -= 1
max_y -= 1
# 枠線を上書きしないように調整
min_x += 1
min_y += 1
max_x -= 1
max_y -= 1
# カーソルをサブウィンドウの座標(x, y)に移動
# サブウィンドウの左上の角が(0, 0)
x, y = min_x, min_y
swin.move(y, x)
# カーソル位置のチェックと座標変更用の無名関数
c_move = {
"h":(lambda x, y: x > min_x, lambda x, y: (x - 1, y)),
"l":(lambda x, y: x < max_x, lambda x, y: (x + 1, y)),
"k":(lambda x, y: y > min_y, lambda x, y: (x, y - 1)),
"j":(lambda x, y: y < max_y, lambda x, y: (x, y + 1)),
}
check_input_flag = False
while 1:
# 入力されたキーを文字コードで取得
c = swin.getch()
c_char = chr(c)
# escをおされた確認
if curses.ascii.ESC == c:
check_input_flag = False
elif "i" == c_char:
check_input_flag = True
elif check_input_flag == True:
if c == curses.KEY_BACKSPACE or c == curses.ascii.BS :
if c_move["h"][0](x, y):
swin.delch(y, x-1) # 今のカーソルの、一つ前の文字を削除
else:
swin.addstr(c_char)
elif check_input_flag == False and "x" == c_char:
if c_move["h"][0](x, y):
swin.delch(y, x-1)
# 入力されたキーがh,l,k,j
elif c_char in c_move:
# カーソル位置が端でなければ、座標を変更
if c_move[c_char][0](x, y):
x, y = c_move[c_char][1](x, y)
# 入力された文字を表示した後にカーソルを移動
# 文字を表示するとカーソルが右端に移動するので
# 文字表示、カーソル移動の順にしている
swin.move(y, x)
elif c_char == "c":
# サブウィンドウをクリア
swin.erase()
# 枠線も消えるので再描画
swin.border("|", "|", "-", "-", "+", "+", "+", "+")
swin.move(min_x, min_y)
elif c_char == "q":
break
swin.refresh()
# スクリーンを閉じる
curses.endwin()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment