TL; DR
- vimtutorのnano版作ってみた
- nanoのショートカットを覚えよう!
はじめに
nanoは多くのLinuxに初めからインストールされています。機能がシンプルで愛用しているのですが、ネットの評判的には「VimかEmacsを覚えるまでのつなぎ」のような扱いが否めません...
しかし、nanoにも便利なショートカットはたくさんあります。
そこで、nanoの布教のためにチュートリアルを作ってみました。
作ったもの
実践型のチュートリアルです。
元ネタは、Vimのチュートリアル「vimtutor」です。テキストに従って移動、編集することで手を動かしながら操作を覚えられます。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
レッスン 1.1: カーソルの移動
** カーソルを移動するには、示される様に h,j,k,l を押します。 **
^
k ヒント: h キーは左方向に移動します。
< h l > l キーは右方向に移動します。
j j キーは下矢印キーのようなキーです。
v
1. 移動に慣れるまで、スクリーンでカーソル移動させましょう。
2. 下へのキー(j)を押しつづけると、連続して移動できます。
これで次のレッスンに移動する方法がわかりましたね。
3. 下へのキーを使って、レッスン1.2 に移動しましょう。
そんなvimtutorのパクrをリスペクトして、nanoのチュートリアルを作りました。
# Lesson 3: 編集
## 3.1: バッファの切り取り、貼り付け
ctrl + k : 現在の行をバッファへ切り取り
ctrl + u : バッファから内容を貼り付け
以下の各行を順番通りに並べ替えてください。
4. fox
1. The
7. the
8. lazy
3. brown
9. dog
5. jumps
6. over
2. quick
英語版を作ってから日本語に訳したのでちょっと文が硬いですね...
「あなたがvimtutorをもう一度復習してvimmerになれば良いのでは?」というご意見は受け付けておりませんのでご了承ください
仕組み
ショートカットの洗い出し
公式のチートシートを参考にしました。全部やると多いので、すぐに使いそうなものに絞って取り上げています。
コマンド化
続いて、nanotutor
のコマンドで実行できるようにします。今回はGoで実装しました。
シェルのエイリアスでも作れますが、Goの場合はインストールがシングルバイナリのダウンロードで完結し初心者にやさしいです。
tutor
のテキストを embed
で実行ファイルへ埋め込むことで、シングルバイナリ化しています。
import (
_ "embed"
)
// コンパイル時に、同じディレクトリ内のテキストファイル tutor の中身がセットされる
//go:embed tutor
var tutorTextBytes []byte
nanoの呼び出しには os/exec
を使用しています。
// `$ nano ${tempFilePath}` を実行
cmd := exec.Command("nano", tempFilePath)
// NOTE: 入出力を設定しないとnanoが異常終了してしまう
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
ファイルを壊してしまっても閉じれば元通り
vimtutorでは、繰り返し練習ができるようテキストを変更しても再起動すると元通りになります。一時ファイルへコピーしてから起動することでこれを実現しています。
というわけで、nanotutorでも一時ファイルを使うようにします。ランダムな名前の一時ファイルを作るには、os.CreateTemp
が便利です。
// nanotutorで使う一時ファイルを作成
func createTutorFile() (string, error) {
dir := os.TempDir()
// `nanotutor_` で始まるランダムな名前がつく
f, err := os.CreateTemp(dir, "nanotutor_*")
if err != nil {
return "", fmt.Errorf("failed to create tutor temp file: %w", err)
}
// tutorファイルの原本の内容(embedでバイナリに埋め込んでいる)をコピーし書き込み
_, err = f.Write(tutorTextBytes)
if err != nil {
return "", fmt.Errorf("failed to initialize tutor temp file: %w", err)
}
// ファイルの絶対パスを返す
return f.Name(), nil
}
ゴミが残らないように、終了時にファイルを消しておきましょう。
tempFilePath, err := createTutorFile()
if err != nil {
fmt.Fprintf(os.Stderr, "FATAL: %v\n", err)
os.Exit(1)
}
defer os.Remove(tempFilePath)
インストールしやすくする
インストールで詰まって心が折れてしまってはチュートリアルへ進めません。goreleaserでコンパイル済みのバイナリをリリースし、ダウンロードだけで使えるようにしておきます。
おわりに
以上、nanoのチュートリアルを作ってみた紹介でした。春からの新メンバーへの布教に活用してください