xterm.jsでキーボード入力を受け付ける方法
本記事で行うこと
- xterm.jsを利用して、キーボード入力を受け付けるhtmlを作成する。
- ※環境はnode.jsを使いますが、最後にCDNサイトを使ってhtmlファイルのみで行う方法も記載しておきます。
モチベーション
- vscodeのterminalなどで採用されているxterm.jsをつかってプロダクトを作ろうと思ったため。
- xterm.jsの使い方を開発メンバーと共有したかったため。
環境
- macbook pro/node.jsを利用
$ sw_vers ProductName: Mac OS X ProductVersion: 10.15.7 BuildVersion: 19H15 $ node -v v12.18.3
xterm.jsのインストール
versionは本記事を書いたときの最新版を利用します。
$ npm install --save xterm@4.9.0
Hello xterm.js
まず公式ページにあるとおり、html上にterminal windowを表示してみます。
github.com
<!doctype html> <html> <head> <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" /> <script src="node_modules/xterm/lib/xterm.js"></script> </head> <body> <div id="terminal"></div> <script> let term = new Terminal(); term.open(document.getElementById('terminal')); term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ') </script> </body> </html>
headのpathはインストールした場所を指定してください。
作成したhtmlファイルにブラウザでアクセスすると以下のようにterminalを表示できます。
- term.openでterminalを開いて、term.writeでterminalに文字を書き込めるようです。
この状態だとterminalに向かってキーボードを打っても何も反応しないのですが、
せっかくなのでこの状態で、Chromeの開発者モードで少し遊んで見たいと思います。
Chromeの開発者モードのConsoleを開き以下のように打ち込んで見ると画面が更新されました。
term.write("書き込んでみた")
Consoleにtermを打ち込むと何やら使えそうな関数が色々出てくるので、公式サイトで使い方を見てみます。
term
xtermjs.org Doc -> Class: Terminalを参照しいくつか試した結果を書いておきます。
- 書き込んで改行する。
term.writeln("改行する")
- 書き込んでpromptを表示する。 今後Enterを押した時に必ずこれを実行すれば良さそうです。
term.write('\r\n$ ')
- terminalに書き込まれたものをresetする。 clearが入力された時にこれを実行すれば良さそうな気がします。
term.reset()
キーボード入力を受け付けるhtmlを作成する。
公式が的供しているdemoサイトを参考に以下を作りました。 xterm.js/client.ts at master · xtermjs/xterm.js · GitHub
<!doctype html> <html> <head> <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" /> <script src="node_modules/xterm/lib/xterm.js"></script> </head> <body> <div id="terminal"></div> <script> let term = new Terminal(); term.open(document.getElementById('terminal')); function runFakeTerminal() { if (term._initialized) { return; } term._initialized = true; term.prompt = () => { term.write('\r\n$ '); }; term.writeln('Welcome to xterm.js'); term.writeln('This is a local terminal emulation, without a real terminal in the back-end.'); term.writeln('Type some keys and commands to play around.'); term.writeln(''); term.prompt(); term.onKey(e => { console.log(e) const ev = e.domEvent const printable = !ev.altKey && !ev.ctrlKey && !ev.metaKey if (ev.keyCode === 13) { term.prompt(); } else if (ev.keyCode === 8) { if (term._core.buffer.x > 2) { term.write('\b \b'); } } else if (printable) { term.write(e.key); } }); } runFakeTerminal() </script> </body> </html>
これでキーボード入力を受け付けるようになりました。
少しだけ解説すると・・・
- term.prompt関数は呼ばれるとterm.write('\r\n$ ')を実行しバッファ2の『$ 』を書き込みます。
- keyCode === 13はEnter
- keyCode === 8はBackspace
- term._core.buffer.x > 2はtermのバッファが3以上の時1文字消します。
- printable = !ev.altKey && !ev.ctrlKey && !ev.metaKeyはこの条件がtrueの時の判定に利用
- else if (printable) {term.write(e.key);でprintableがtrueの時にterm.write(e.key)して入力をterminal上に書き込みます。
キーボード入力とコードの対応表 KeyboardEvent.keyCode - Web API | MDN
CDNサイト版
手っ取り早く試してみたい人は以下をhtmlファイルで保存すればnode.jsなしでも実行できます。
※CDNサイトがある限り。
<!doctype html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/xterm@4.9.0/css/xterm.css"> <script src="https://unpkg.com/xterm@4.9.0/lib/xterm.js"></script> </head> <body> <div id="terminal"></div> <script> let term = new Terminal(); term.open(document.getElementById('terminal')); function runFakeTerminal() { if (term._initialized) { return; } term._initialized = true; term.prompt = () => { term.write('\r\n$ '); }; term.writeln('Welcome to xterm.js'); term.writeln('This is a local terminal emulation, without a real terminal in the back-end.'); term.writeln('Type some keys and commands to play around.'); term.writeln(''); term.prompt(); term.onKey(e => { console.log(e) const ev = e.domEvent const printable = !ev.altKey && !ev.ctrlKey && !ev.metaKey if (ev.keyCode === 13) { term.prompt(); } else if (ev.keyCode === 8) { if (term._core.buffer.x > 2) { term.write('\b \b'); } } else if (printable) { term.write(e.key); } }); } runFakeTerminal() </script> </body> </html>