web小説礼賛記

さらなる俺 TUEE をあなたに!

w3m (text-based web browser)

 Mac用のTiling WMに、yabaiというのがあります。これのキーマップ例に、option + tウィンドウを画面中央に表示する、という素敵な操作がありました。活用してみます。

すっかりターミナルに慣れてしまいました……。

GUI browsers

 GUI縦書きができるのが強みです。ターミナルでは決して実現できません……たぶん。

Firefox

 mobaがFirefoxを使うと、すぐにメモリ切れを起こしてしまいます。ですが、小説の閲覧のみなら、暴走することも無いはずです。

20190928214918

 これはいい。思わずガッツポーズをしてしまいました。普段から小説用タブがブラウザのタブを占領していましたが、アプリを分ければ整理がつきます。

Text-based web browsers

 ターミナルが好きな人は、ターミナルでブラウジングしましょう。メインのターミナルと別に、ブラウジング用のターミナルを起動します。Macなら、アプリのインスタンスを切り替えるショートカットも設定できます。

 ターミナルのブラウザは、癖が強く、画像も表示できません。ですが、軽量さにポテンシャルがあります。

w3m

 w3mというテキストベースのbrowserがあります。これで小説を読みましょう。

 例によってターミナルから起動します。

20190928214946

 素晴らしい。何よりもターミナルと近しいのが好ましいです。

追記

 欠点が二つ見つかったので、報告します。

 w3mでは、JavaScriptが動かないからですね。なおハーメルンでは、問題なくしおり機能を利用できます。ページ遷移が挟まれることが、w3mからはメリットになりました。

  • 2: URLのコピーができないnarou.rbにURLを送りたいときなどに不便です。

 external browserをシェルコマンドにすれば可能なはずなのですが、失敗しました。もしもtmuxからw3mを起動しているなら、w3mcopy mode を使えばコピーできると思います。僕の用途からは外れますけれど……。

tips

 w3mに半ページスクロールはありません。しかし、ページスクロール → z で擬似的な半ページスクロールが可能です。

screen shots

w3mのブックマーク機能 20190928214928

なろうのブックマークページ 20190928214955

ハーメルンのブックマークページ 20190928214935

configuration

 ~/.w3m/keymap でキー操作などを設定できます。このページなどを代わりにすると良いかもしれません。

 ~/.w3m/passwd でログインを自動化できます。たとえば、

machine syosety.com
realm 小説家になろう
login my_mail@address.domain
passwd my_password

machine syosetu.org
realm ハーメルン
login my_mail@address.domain
passwd my_password

emacs

 もしもあなたがEmacsユーザなら、このページなどを参考にブラウザを探せます。

 mobaはまだ動作法が分からず、実践中です。実際にEmacsのブラウザを使えたときには、この記事を更新します。

w3m

 Emacs上のw3mなら、本家の残念な部分を修正できるはずです。

 たとえば、小説ページに表示される余計な情報を除去できるでしょう。先ほどのリンクWeb Page Cleanupの項をパクったら終わりのはずです。

eww

 Emacsのブラウザの一つです。使ったときに追記します。

Mac用縦書きエディタ

 主にJedit Ωの紹介です。 プレインテキストの縦書き段組み すらできます。横書きでも段組みは可能です。

エディタの紹介

その前に……

黒背景に対しマウスカーソルを白くする方法

 アプリによっては、背景を黒に変更した場合、マウスカーソルが見えなくなってしまいます(色被り)。これには、マウス画像を差し替えるアプリを使って対処できます。

 Mousecapeをダウンロードします。こちらのファイルをMousecapeにドラッグ&ドロップすれば、高解像度の白カーソルを使用できます。

もしもリンク切れが起きていたら、 CotEditor のリポジトリからカーソル画像 (ハイビーム? だった気が) をコピーしてきて、 Mosecape でカーソルデータを作成します。

Plain text editors

Jedit Ω

 プレインテキストの縦書き段組みができるエディタです。機能的に希少であり、非常におすすめです。

f:id:moba_lake:20190804140149p:plain
Jedit Ω 文章はパラダイム・パラサイト第一話

 設定にはそれなりに時間がかかります。UIがあまり良くないのですね。細かい調整ができない部分もあります。

 段組みするには、『ページレイアウト』を使います。ヘルプを検索すると、多少分かりやすいかもしれません。

CotEditor

 こちらも縦書きができます。段組みが不要なら、消去法で最強の縦書きエディタです。

f:id:moba_lake:20190802222904p:plain
CotEditor

 段組みはできません。折り返し位置は、強制的にウィンドウの幅になります。

TATEditor

 タテエディタ、ってことですね。UIが合わなかったので、特に触れません。

stone

 3,000円払ったので言わせてもらいますが、全くもってお金の無駄でした。

egword Universal 2

 買っていないのでレビューできません。これはプレインテキストにも使えるのでしょうか。

 高評価が多いのですが、用途によると思うので、使ってみないことには分かりません。期待したい気持ちは強いです。

 一時期、半額の3,900円で販売されていました。

Rich text editors

特殊なファイル形式を教養するエディタたちです。

Pages

 Pagesを使うのは、面倒くさい割にメリットが無くておすすめできません。

MS Word

 賞に応募するときは、MS Wordを使う人が多いと思います。ルビの表示など、リッチテキストの恩恵が得られます。段組みが特に魅力的だと思います。

 ただ、背景色の変更などのサポートは弱いです。白画面でOKな人が使うべきアプリだと思います。

 1.5万円くらいで購入するか、学生なら無料で使用できます。オンライン版のWordは無料ですが、縦書きの機能がありません。将来的には分かりませんが。

word to txt

 docxファイルは、特定のデータ構成をzip圧縮したファイルです。中身をunzip -lで確認すると、xml形式の原稿ファイルがword/document.xmlにあることが分かります。

 これからテキストデータを回収する、 bash のシェル関数を置いておきます。MS Word for Macで作ったファイル (.docx) に対して、動作を確認しています。実装によって生成されるデータが変わるため、別のWordを使ったときは動かないかもしれません。

# gsedはGNU sedです
word2txt() {
    unzip -p "$1" word/document.xml | # -p: print
    gsed 's/<w:p\ [^>]*>/\n/g'      | # 段落ごとに改行を挿入
    gsed 's/<[^>]\{1,\}>//g; s/[^[:print:]]\{1,\}//g'
}

 段落ごとに改行を入れてから、文字列を回収しています。ルビ文字の区別などは考慮していません。もう少し頑張れば、なんとかなると思いますが、取り急ぎ。

余談

 横書きかつ段組みが不要なら、Atomエディタが良いと思います。『ディレクトリを開く』機能があります。豊富なプラグインでカラフルにしたり、組み込みのコンソールも動きます。 素晴らしい

 追記: ……と思っていましたが、今はVim派です。Emacsは設定で手こずっています。  追記: Atom, VSCode, Sublime が並び立つような印象です。 Sublime が軽くていいと思います。

Pocket経由でWebをKindleで読む

 Kindleの大きさは、ラップトップよりも読書に適しています。自然とWebの文章も、Kindleで読みたいと僕は思います。

 一応Kindleにもブラウザ機能がありますが、操作が遅いため、ローカルファイルとしてwebを読めた方がベターです。

 pocketは、オンラインのブックマーク管理サイトです。ここに登録した記事を、最大20個単位でKindleへ送信することができます(P2K – Pocket to Kindle: Send Your Pocket Articles to Your Kindle)。ただし、横書き限定となります。

 P2Kで送信したファイルは、.azwファイルとなっており、Kindle上の表示名は、送信日で固定されます。

 リネームは有料の機能にあるのでしょうか。

Note 1: なろうリニューアル

 なろうのトップ画面が変わりましたね。前よりも機能的で良いと思います。

 ただ、表に出ているランキングは、必ずしもアテになりません。人によって趣味が異なり、多数派の好みが反映されるのがランキングですから、当然ですね。初見の読者が好きな作品を見つけるのは、やはり難しいでしょう。

 書店よりは、ネットの方が楽に探せるかもしれませんが。

 なろう読者は増えているようですね。累計ランキングが活発に動き続けています。無職すら一位から降り、転スラが頂点に輝きました。『すら』と言うあたり、僕も無職が不動だと思っていたようです。

 無職からは、初見で強烈なインパクトを受けました。完全にアングラな作品だと思っていました。出だしの気持ち悪さったらない。読み返したら続きもキモかった。リーリャ同様、僕の記憶もすっかり浄化されていたようです 笑。でも読み終えたときは、これが一位だと確信しました。

 私的になろうで象徴的なのは、弁当箱先生のアレです。天才的な発想と、書き抜く底力を見せつけられました。同作者の音使い(連載中)は、今でも最も期待している作品です。見つけてしまったときに思ったのですが、正直、弁当箱になりたい人生だった。出会えたのが、幸運であり不運でもあるという感じです。

 なろうから出版された有名物は、ダンまちログホラこのすばあたりでしょうか。ログホラだけは、なろう版も残っています。この辺の作品は、やっぱり面白いですね。

 ここまで礼賛的してきましたが、己の真なる目標に血汗を注ごうというときに、小説に現を抜かしていいる暇があるのか、という話もあると思います。小説を読むとしても、得るものなき読書などしてたまるか、という考えもあるでしょう。

 それはそれとして、作品を探し続けることには価値があると思います。もしも読み続けることを選ぶなら、できれば本気で探した方が良いのではないでしょうか。

シェル入門 #7: 基本操作の作成

シェルマッチョになったため全面改稿予定

 目次の閲覧など、基本的な操作をn-xxxというコマンドにし、シェルから利用できることにします。これらのコマンドを、n-シリーズと名付けます。n-シリーズは~/binに置くことにします。

 早く動かしたいため、n-commands sub-commandという形式は止めました。サブコマンドを使う場合、サブコマンド間で実装の共有などができるのがメリットです。

 mobaはシェルスクリプトの本を読んでいないため、いい加減なコードを書きます。御免なさい。とにかく動けばOKだと割り切っています。

n-seriesの作成

前提

 これらのコマンドは、小説ディレクトリの上で実行されるものとします。エラーチェックは、ほどほどにしかやりません。

 ディレクトリ構成は、

$ tree -d -L 1
.
├── build
├── gnome
└── src
  • src/に原稿が入り、build/に原稿の変換結果が入ります。gnome/に設定ファイルを入れます。

  • 原稿の名前はすべてn.txtで、一行目にタイトルが書いてあるとします。

作成用 Creaters

n-new

 touch -aとするだけで、既存ファイルのmodification timeの更新を避けることができます。

 これもコマンドにします(~/bin/n-new)。また、小説データのルートディレクトリから使用し、番号のみを与えて使うことにします。

#!/bin/bash
echo "$@" | xargs -I{} touch -a 'src/{}.txt'

 n-new {0..24}のように使えます。スクリプトの作成後は、chmod +x ~/bin/*で実行許可を与える必要があります(x: execute)。n-newを実行し、ファイルが作られることを確認しましょう。

stdinを受け取れるようにする

 先ほどのコマンドは、引数しか使用しませんでした。標準引数も入力として扱えるようにします。

 この辺り、全く『正しい』方法なのか分かりません。特にシェルは、確信を持つのが難しい言語ですね。検索では、肝心な部分はヒットしませんし 笑

# cat は stdin が空の場合フリーズするため、分岐が必要
if [ -p /dev/stdin ] ; then
    echo "$(cat) $@"
else
    echo "$@"
fi | tr ' ' '¥n' | grep -v '^$' |
while read n; do
    # 注意: このとき、nは一つの引数であるが
    #     任意の文字が許されており、番号ではない可能性がある
    touch -a "src/$n.txt";
done
  • echo "$@" は全ての引数をスペース区切りにします。
  • tr (translate) は文字の置換を行います。
  • grep -v '^$' は空行を削除します。

 何度も書く部分なので、以後どのファイルからも、while read 以前は省略します。

番号 -> 原稿ファイルのパス を抽象化

 後でn-pathコマンドを作り、n-newでもn-pathコマンドを使うようにします。

    touch -a "$(n-path $n)"
エラーチェックを追加

 飛ばして行きますね。

# 省略: stdin と引数を改行区切りで連結する処理
..
while read n; do
    # n が整数でなければ、エラー出力をして次のnへ
    [[ ! n =~ ^0$|^[1-9][0-9]*$ ]] || {
        echo "not given valid number: $n" 1>&2
        continue
    }
    touch -a "$(n-path $n)"
done
echo .. 1>&2

 stderr2に出力しています。#3でも書きました。

[[]]=~

 正規表現でnを0以上の整数とマッチさせています。(マッチしなければリスト{}を実行)。

 [[]]は強力なテストです。man bashの329行目に書いてあります。=~正規表現とマッチングできます。

  • 正規表現をクオーツで囲うとエラーなので注意してください(bash)。
  • 0を使うとあ0あみたいなものにも部分的にマッチする(結果、[[]]の終了ステータスが、マッチ成功の0になる)ので、^0$とすることで完全一致を検出します。`
  • [0-9]\d(d: digit)とは書けません。文字クラス:digit:`はありますが、使いたくないですね。

 [[ .. =~ // ]] の代わりに、grepの終了ステータス$?(マッチが無ければ1)を使うこともできます。

 grepで検証する場合、出力を (/dev/nullに) 捨てる手間があります。

 bashとは厄介な言語ですね。このコマンドが書ければ、他のコマンドも十分書けます。

閲覧用 Viewers

目次生成 n-table

 #5でもやりました。sortはfindの直後にやってもいいです。

#!/bin/bash
# -d: ディレクトリが存在しなければ終了(エラー)
[ -d src/ ] || exit 1
find src/* -type f | while read f; do
    printf '%2d %s\n'  "$(basename "$f" .txt)" "$(sed -n 1p "$f")"
done | sort -n

 ひとまず、話数が2桁の前提で整形して書きました。もしくは、多めの桁数でフォーマットしておけば安全です。

 テストコマンド[]中の表現-については、man [を参照してください。制御文字&&については、man bashを参照してさい。

文字数カウントするオプション

 -cもしくは--countオプションが指定されていた場合、文字数も表示する処理に切り替えます。エイリアスでデフォルトにしてもいいでしょう。

 目次や中間データに対して列を足していくスタイルもアリです。今は3つしかありませんが、列の組み合わせは二項分布で増えていくので。

 オプションの分解(パース)は、今回は単に$1を調べれば良いです。

if ! ( [ "$1" == '-c' ] || [ "$1" == '--count' ] ) ; then
    # 文字数カウント無し
    find src/* -type f | while read f; do
        printf '%2d %s\n' "$(basename "$f" .txt)" "$(sed -n 1p "$f")"
    done
else
    # 文字数カウント有り
    find src/* -type f | while read f; do
        printf '%2d %4d %s\n'       \
            "$(basename "$f" .txt)" \
            "$(cat "$f" | wc -m)"   \
            "$(sed -n 1p "$f")"
    done
fi | sort -n
wcの出力を使う

 wcの出力が、閲覧用に整えられているのが厄介です。頭に四つの空白がありますが、printfが数値として評価し、空白を消してくれました。

 wcの出力を空白区切りと見て、フィールドを抜き出す方法もあります。awkが無難です: wc -m <file> | awk -F ' ' '{print $1}'

 cutでフィールドを抜き出す場合、空のフィールドを無視しないため、5番目のフィールドにアクセスして、.. | cut -d ' ' -f 5となります(実装によるかもしれませんが)。先に、sedで行頭の空白を消し、連続する空白を圧縮しておくと確実です。

総文字数

 総文字数は、wcの出力を使うなら、wc -m src/* | tail -1。もしくは、文字数カウント付きの目次に対し、awk '{sum+=$2; print $0} END {print " " sum " chars in total."}'などとして得られます。

後から整形する

 タブ文字\t区切りのデータを作り、最後に空白の整形をします。awkを使うのが基本だと思います。

#!/bin/bash
..
# -F: field separator
fi | sort -n | awk -F '\t' '{printf "format", paramA, paramB, .. }'

 左寄せでよければcolumn -t -s '\t'も使えます。(t: table, s: separator)

確実な配列 ensureing alignment

 tab文字区切りの目次にスペースを入れて、列ごとに右寄せや左寄せにします。自動的にやってくれるコマンドは無いようです(table化するツールは? 要改稿)。

 配列用のコマンド(もしくは一般的なテーブリングコマンド)を作っても良いかもしれません。案としては、データの最大値(もしくは最大桁数)を記憶しておいて、awk内のprintfで配列(整形)できます。

専用の文字数カウントを使う

 空白文字をカウントしない、タイトルを文字数に含めない、などの配慮をしてくれるコマンドを使用します。(#8で作るn-count)

 front matter付きのファイルにする場合を考えても、専用コマンドでカウントすべきです。

| columnの自動化
エイリアスを設定する
# .bashrc
n-table() { command n-table "$@" | column ; }
パイプ先なら出力に対し| columnを行う

 多分こんな感じ。要改稿。

if [ -p /dev/stdout ] ; then
    cat | column
else
    cat
fi

n話目の内容をコピー n-pc

 pbcopyは、stdinをpaste board(クリップボード)にコピーするコマンドです。

 mobaはpcエイリアスを作っています。

 n-pcにより、n話目をpbcopyします。n-build自体は、#8で作ります。

#!/bin/bash
# TODO: 出力先ディレクトリの設定

# 0以上の整数が与えられなければ終了
[[ "$1" =~ ^0$|^[1-9][0-9]*$ ]] || {
    echo 'error: not given number.' 1>&2
    exit 1
}
# ファイルが存在しなければ終了
[ -f "build/$1.txt" ] || {
    echo "error: number $1 doesn't exist in your build." 1>2&
    exit 1
}
cat "build/$1.txt" | pbcopy

 n-build関連の部分はコメントアウトしておきました。実際、コピーする度にbuildするのは、安全ですが重いです。ユーザがbuildを忘れないようにする方針で行きます。

編集用 Editors

 ちょっとしたコマンドの有無で大違いです。

通し番号 -> 原稿のパス n-path

 基本的な道具から作ります。スペース区切りの番号を、改行区切りのsrc/n.txtに変えます。

#!/bin/bash
# 通し番号 -> 原稿のパス の変換を行う

# stdin と引数を改行区切りで連結する処理 |
while read n; do
    if [[ ! "$n" =~ ^0$|^[1-9][0-9]*$ ]] ; then
        echo "invalid arugument: $n" 1>&2
        continue
    fi
    echo "src/$n.txt"
done

 動作を確認します。

$ echo '-2' | n-path {-1..0*
invalid arugument: -2
invalid arugument: -1
src/0.txt
$ echo '-2' n-path {-1..0} 1>/dev/null
invalid arugument: -2
invalid arugument: -1

タイトルの変更 n-title

 つまり原稿の一行目を差し替えます。n-title number titleという形で使います。

一行目を消してから入力内容を挿入する

 行の削除は、seddコマンドで行います。ファイルの上書きは、tee経由なら、リダ入れクションよりも確実でしょう。

#!/bin/bash

# 原稿が存在しなければ終了
[ -f "$(n-path "$1")" ] || {
    echo "error: not given number: '$1'" 1>&2
    exit 1
}

# "$1"話目の原稿の一行目を"$2"に差し替える
cat "$(n-path "$1")"         |
    sed '1d'                 |
    printf "$2\n%s" "$(cat)" |
    tee "$(n-path "$1")" > /dev/null

 gsed -i "1s/.*/$2/g"とか、BSD系のsedsed -i '' "1s/.*/$2/g"としてもいいです。

話の入れ替え n-swap

 シェルコマンドには、ファイルのswap(入れ替え)が無いのですね。

#!/bin/bash

[ ! -f n-path "$1" ] && [ ! -f n-path "$2" ] || {
    echo 'not given two valid numbers.' 1>&2
    exit 1
}

# swapping
mv "$(n-path $1)"{,.cptemp}
mv "$(n-path $2)" "$(n-path $1)"
mv "$(n-path $1).cptemp" "$(n-path $2)"

 要改稿: mktempコマンドを利用し、安全に入れ替える

 簡単にテストしておきます。

~/Dropbox/n/narou/ms $ n-table
 0 プロローグ Prologue      13
 1 悪の製法 Making of Evils  14
 2 タイトル            15
 3 あああ           16
 4 いいい           17
 5                 18
<省略>
$ n-swap 3 4
$ n-table
 0 プロローグ Prologue      13
 1 悪の製法 Making of Evils  14
 2 タイトル            15
 3 いいい           16
 4 あああ           17
 5                 18
<省略>

※ターミナルではきちんと揃って表示されています。

n-edit

 エディタを開くコマンドを用意します。今回はパスが空白を含まないため、シェルの単語分解に任せてvim $(n-path "$@")とすることもできます。(Vimを使う場合)。

 いくつか方法を試しましたが、『Vim: Warning: Input is not from a terminal』というエラーが出ることが多いです。厄介な仕様があるようです。

 これだから、シェルは程々でいい気がします……。

 BSD系のxargsだと話が早いです。

#!/bin/bash
n-path "$@" | tr '\n' '\0' | xargs -0o vim

 この素晴らしい回答を参考に、gxargsでも書いてみました。

n-path "$@" | gxargs -d '\n' sh -c '</dev/tty vim "$@"' zero
# ヌル文字区切り版(BSD系のxargsでも使えてベター)
n-path "$@" | tr  '\n' '\0' | gxargs -0 sh -c '</dev/tty vim "$@"' zero

終わり

 お疲れ様でした! n-new, n-table, n-pc, n-path, n-count (現在はwc -m), n-title, n-swap, n-vim が用意できました。無敵に近づいた気がしませんか?(執筆力は上がりませんが)

 同じような操作を何度も書き過ぎました。まだ改善が見込めますが、それは後のお愉しみ。

シェル入門 #6: CLIツールの見直し

 標準のシェルとコマンド群は、ぶっちゃけ古いです。モダンなツールを入れて、もっと便利になってしまいましょう。

Shell

 bashは古いです。普段使いのシェルは、変えたほうが便利になります。

 シェルスクリプトを書くときは、意外にbashが楽です。ネットの情報量が多いためです。

fish

 fishは非常に親切なシェルです。リアルタイムで候補を表示してくれますし、サブコマンドや省略パスにも補完が効きます。(e.g. ~/b/n-b->~/bin/n-build)。これが以外と便利です。

 ただし、本は少ないですし、検索して情報を得るのもしんどいかもしれません。

設定ファイルの書き方

 変数はsetコマンドで設定します。=は使わず、常に空白で引数を区切ります。関数やエイリアスの書き方も異なるため、自由に書くためには数十分必要でしょう。

 dotfiles fish で検索すると、人の設定ファイルが読めます。

文法の違い

  • コマンド置換は(command)です。実行順を変える機能だと思えば合理的です。
  • コマンド置換や変数展開に対しては単語分解が行われません。おかげで、余計なクォーテーション"を省くことがでいます。
  • brace{}展開に連番生成{m..n}がありません。代わりにseqのコマンド置換(seq m n)を使えますが、{0..3}.txtのような文字列を作るには、一手間かかります。(例: seq 0 3 | sed 's/$/.txt/') )

 とりあえず、これだけで十分だと思います。ドキュメントは、有名な方が翻訳してくれています。

zsh

 fishと並んで有名です。bashcshのいいとこ取りをしたシェルらしいです。調査中です。

bashでもオプションなどに補完を利かせる

 調査中です。

Emacs

 ELispを駆使する人々は、Emacsエディタ上でシェルを使うようです。(ちょっと変態的な指向ですね)。ファイルをエディタのバッファ(タブのようなもの)に貯められるのは便利そうです。興味があれば頑張ってください。

自作コマンド(シェルスクリプト)の設置法

 自作コマンドもCLIツールと言えるので、ここで扱います。(コマンド自体は、#7で作ります)。

 スクリプトファイルは、一つのコマンドに相当します。書いたコマンド(スクリプト)は、(PATHを通せば)どのシェルからでも利用できます。

 つまりbashを書ければ、他のシェルでスクリプトを書けなくても十分です。

~/bin$PATHを通す

 シェルは、コマンドを環境変数$PATHから探します。$PATH~/binを追加すれば、~/binに設置したスクリプトをコマンドとして実行できます。(これを『~binPATHを通す』と表現します)。

 bashにおいて、$PATH:文字区切りのパスの集まりです。このような環境変数は、~/.bash_profileから設定するのが常です。

 export PATH="~/bin:$PATH"~/.bash_profileに追記します。

シェルから追記する

 やや技巧的な書き方をしてみました。普通にエディタで書いて構いません。

$ # パスが通っているかを確認
$ echo "$PATH" | tr ':' '\n' | grep ~/bin || echo not found
not found
$ # ~/binにPATHが通っていなかった場合
$ # 追記されるように .bash_profile を変更する
$ echo 'export PATH="$HOME/bin:$PATH"' | cat - ~/.bash_profile > ~/.bash_profile.new
$ mv ~/.bash_profile{.new,}
$ source $_ # $_ は前回のコマンドの最後の引数
解説
  • tr (translate) は文字の置換を行います
  • grep は行の抽出を行います(マッチがあれば『成功』)
  • cat では - 文字でstdinを表します(そして連結: concatenate してくれました)

 cat file | .. > fileをすると、fileが空になるので気をつけましょう。

ファイルの上書きについて

 teeで出力したり、sed -iで上書きする方法もあります。

 sedは常にGNU系のsedを使うと良いと思います。MacではBSD系のsedが入っていますが、書き方がかなり紛らわしいです。

c.f. GNU sed の用法
  • 1行目に挿入(insert)して上書き: gsed -i '1i text_to_insert' <file>
  • 1行目を消去(delete)して上書き: gsed -i 1d <file>

設定の変更

 書き換えたrcファイルの内容を、現在のシェルに反映します。

予備知識: サブシェルと現在のシェル

 シェルスクリプトは、通常subshell(という名前のサブプロセス)で実行されます。サブシェルで環境変数を変えたり、シェル関数の定義を上書きしても、元のシェルには影響しません。変数なども同様です。

現在のシェルで実行する

 source <file>で、呼び出し元のシェルでファイル内容が実行されます。これまでのrcファイルは、現在のシェルで実行することで、シェルの状態を上書きしてきたのですね。

スクリプトの書き方

 具体的には次回やるので、流してください。

解釈プログラムの宣言

 一行目のshebang (#!/bin/name_of_shell)で表します。

ファイルの末尾で改行

 入れておいたほうが無難です

実行許可 Execure permissions

 作成したファイルは、まだ実行できません。chmod +x <file>で、スクリプトの実行権限を与えます。許可はls -l (もしかしたらllでもok) から確認できます。詳しくは、manを読むか何かの本で。

GNU系のコマンド

 Mac向けです。Macには、初期ではBSD系のコマンドが入っています。GNU系のコマンドも加えましょう。

インストール

 Homebrew経由で入れていきます。gxxxという名前になります。BSD系のコマンドを上書きしたい場合は、こちらの記事などを参照してみたください(Qiita)。

$ echo gawk grep gnu-sed findutils | xargs brew install

GNU系commands

gawk, ggrep

 あまり差が分からないので、入れなくてもいいです。gawkは、組み込み関数の種類が豊富だとか。

gsed

 gsedでは、置換内容に改行\nを使えます。-i --in-place(上書き)の書き方が直感的なため、重宝します。(MacBSDsedは複雑)

gxargs

 -dでdelimiter(区切り文字)を指定できます。改行を区切り文字に使えるのは重宝します。

既存コマンドの代わりになるもの

 着色が綺麗だったり、取り回しの良い道具があります。Rust製のものが多いため、先にRustをインストールしておくと良いでしょう。cargoというパッケージマネジャ経由でインストールできます。

マニュアル

tldr

 すでに何度か紹介していますが、具体例が主な非公式マニュアルです。

ファイル関連

 見出しはGitHubへのリンクになっています。

bat

 catの代わりになるコマンドです。ソースコードを鮮やかに着色して表示します。出力が長ければ、ページャを起動して見せてくれます。

fd

 遥かに便利なfindです。再帰的検索、拡張正規表現(ERE)、着色がデフォルトになっています。

ripgrep (rg)

 再帰、着色、ERE、行番号表示がデフォルトで、出力がファイル毎になっているgrepです。

 出力をページャに流すなら、着色を強制するコマンドを用意してもいいかもしれません:

# .bashrc
rg-c() { command rg --color=always "$@" ; }
再訪: グレッグ様の数を数えよ

 fd, rg, それにgxargsがあれば、グレッグ様の数を数えるのも楽だったのでした。

$ # まず .txt ファイルを抽出(相対パス)
$ fd . "$(fd -t d 嘆きの亡霊)/raw" | rg '\.txt$'

$ # グレッグをファイル毎にカウントする場合
$ fd . "$(fd -t d 嘆きの亡霊)/raw" | rg '\.txt$' | gxargs -d '\n' rg -co グレッグ
小説データ/小説家になろう/n6093en 嘆きの亡霊は引退したい _最弱ハンターは英雄の夢を見る_/raw/10 10 腕試し.txt:3
..

$ # ファイル名とマッチ数を抜き出し
$ ls "$(fd -t d 嘆きの亡霊)/raw" | rg '\.txt$' | gxargs -d '\n' rg -co グレッグ | awk -F '/' '{print $(NF-1) $(NF)}'
10 10 腕試し.txt:3
..

$ # 最後にマッチ数の合計を得る
$ fd . "$(fd -t d 嘆きの亡霊)/raw" | rg '\.txt$' | gxargs -d '\n' rg -co グレッグ | awk -F '/' '{print $(NF)}' | awk -F ':' '{sum+=$(NF)} END {print sum}'
148

 今回は、全話を結合した一時ファイルを作りませんでした。計上するのにawkで頑張っています。

exa

 ls / tree の代わりとなるツールです。両者に似たオプションの形を取っているため、乗り換えが楽です。着色が美しいのも特徴的です。

# .bashrc
e() { command exa -F "$@" ; }
el() { command exa -alF "$@" ; }
# ディレクトリのみ表示(着色付き)
e-d() { command exa -F --color=always "$@" | grep / | column ; }
# ディレクトリのみツリー表示(着色付き)
e-dT() { command exa -FT --color=always "$@" | grep / ; }

 exa -lで、容量や実行権限も見られます。

その他 娯楽用ツールなど

 一応紹介してみます。

コンテンツ周り

cmus

 Vim風キー操作の音楽プレイヤです。キュー機能もあって便利です。

 音楽は、主にアーティストのタグで分けて表示されます。アルバム分けなどもしてくれます。

narou.rb

 小説のダウンロードに使用できます。mobaによる解説はこちら

 より便利に使うための記事を執筆中……。(例えば: 現ディレクトリ位置に関係なく使用する)

youtube-dl

 グレーゾーンな気はしますが、ニコニコやYoutubeダウンローダです。音声のみ(サムネイルつき)のダウンロードもできます。詳しくは検索から。

Editors

Neovim / Spacemacs

 Vim入門#1を参照してください。

Vim入門 #2: リソース/拡張の基本

 大幅な改稿を予定

 先にキーリピートを最速にしておくのがオススメです(OSの設定)。追記予定。

 Spacemacsのことは考慮しません。

入門法

$ vimtutor$ vimtutor jp

「20~30分で終わる」チュートリアルです。

mobaは途中で止めてしまいました

:helpVimの中で)

 キー操作や用語解説などが見られます。

チートシート

 を印刷したり、自作するのが効率的だと思います。

Vim入門 #3

 執筆中です。操作法のリファレンスになる予定です。

本(紙媒体)

 買っておくと、時間的に得をします。

実践Vim 思考のスピードで編集しよう!

 一通り操作に慣れたら、この本によって更なる改善を見込めます。入門者が読むにはハードルが高いと思います。

 序章でリピートキー.;n@を導入し、次章からvimゴルフが始まります。

読み物(web)

 一応リンクを貼りましたが、Vimをプログラミングに使わないなら、必要な知識はぐっと減ります。キー操作を覚えるだけでも十分かもしれません。特にGVimを使うなら、タブ関連の操作すら、ブラウザと同じにできます。

Vim のすゝめ - SOUM/misc

 サクッと読めます。良文でした。

Vim-Galore : Vimについて知っておくべき全てのこと (1~5)

 翻訳記事です。視野を広げるのにいいかもしれません。URLの番号を1~5に変えることで、シリーズの他の記事に移動できます。

Vimの生産性を高める12の方法

 翻訳記事です。良いキーマップの例が少しだけ載っています。

.vimrcの設定

 執筆中です。ページを分ける?

.vimrcの役割

 Vimの起動時に実行されるコマンド(run commands)の集まりです。Vim Scriptで記述されます。

Exコマンド:command

 Vimの中で: commandとして実行されるものです。Vim Scriptは、先頭の:を省略したコマンドの集まりと言えます。

 歴史的には、Vimよりも前に、Exというエディタがありました。

.vimrcの位置

~/.vimrc

~/.vim/.vimrc

ファイル分け
GitHubとの連携

Vim Script の基本

 %は現ファイル。

基本的な設定

 やはり記事を分ける?

日本語入力のための設定

文字数カウントを常駐表示(ステータスライン)

 試していないのでアレですが、set statusline='%{wordcount().chars}'で表示できると思います。

 g<C-g>:! wc -m %からも確認できます。キーマッピングを作っても良いでしょう。

 プラグインの項では、airlineというリッチなステータスラインに常駐表示させています。

normalモードに戻った時の全角/半角の扱い

強制的に半角
他のモードでは全角/半角状態を維持

テキストブロックを設定

スクロールなど

タイプライタースクロール(自動半画面スクロール)
フォーカスモード(現段落以外を暗くする)
余白行
検索結果を画面中央に表示(上端ではなく)

 wikiを参照。

不可視記号の可視化

半角記号
全角スペース

マッピング(キーバインディング

設定の確認

  :mapで一覧が出ます。:help ^aでCTRL-aの操作が出ます。

 既存のマッピングと被ると、意図しない動作が発生するので気をつけます。

設定法

 詳しい話は:help map-overviewから。

キーの表記

 同時押しは山括弧<>で表現します。例: Ctrl+Shift+aは<C-S-a>

Leader

 キーマッピングに使用できる変数です。デフォルトでは\になっていますが、mobaはSpaceキーにしています。

let mapleader=' '
" 以後のマッピングで、<Leader>はスペースキーを表す

 キーマッピングを変えたくなったとき、Leaderの値を変えれば、操作がまとまって変わるというわけです。普通にSpaceキー(<Space>)を使ったマッピング書いても構いません。

nnoremap (LHS) (RHS)

 一連のキーストローク (LHS) を別のキーストローク (RHS) に翻訳してくれます。

LHS: left hand side; 左辺 RHS: right hand side; 右辺

 xmapのxは、どのモードで働くかを表します(x = n: normal, v: visual, ..)。mapは一度マッピングしたら修理しますが、noremapはマッピングの入れ個を許します。

設定例

 .vimrcに以下のように書いています。何かのプラグインと衝突すると思うので、自分で設定した方がいいです。

 ハイライトの切り替えは、この回答をコピーしました。

" ############### MAPPING ###############
let mapleader=' '

" .vimrcの編集用
nnoremap <leader>v :tabnew ~/.vimrc<CR>
nnoremap <leader>s :source ~/.vimrc<CR>

" ハイライトの切り替え
:nnoremap <silent><expr> <Leader>h (&hls && v:hlsearch ? ':nohls' : ':set hls')."\n"

" プラグインの設定
let g:NERDTreeWinPos = 'right' " エクスプローラを右側に表示(お好みで)

" プラグインの呼び出し
" vnoremapだとNeovimでは動かない(なぜ? 要改稿)
vmap v <Plug>(expand_region_expand)
vmap <C-v> <Plug>(expand_region_shrink)
nnoremap <leader>t :NERDTreeToggle<CR>
nnoremap <leader>g :Goyo<CR>

nnoremap <leader>w f。
nnoremap <leader>b F。
nnoremap <leader><C-w> f、
nnoremap <leader><C-b> F、

 句読点へのジャンプには、マシなマッピング法があるはずです。要改稿。

normalモードに戻ったら半角入力にする

 調査中です。もしくは全角入力でも操作できるようにする?

プラグイン

 ユーザが書いた拡張を導入します。

マネジャ

 プラグイン管理を便利にしてくれる拡張を使います。種類は色々ありますが、多過ぎるので一つに絞って紹介します。

vim-plug

 最も簡単なプラグインマネジャです。リンク先の指示に従ってダウンロード後、.vimrcにcallコマンドを書きます。

" ############### Plugin #################
call plug#begin('~/.vim/plugged') " vim-plug
" ここでプラグインをインストールする。書式は、
" Plug 'GitHub-user-account/repository-name'
call plug#end

 Vimの中で :PlugInstall とすれば、Plug宣言したプラグインのインストールが始まります。(必要ならば、その前に:source ~/.vimrcを忘れずに)

おすすめプラグイン

call plug#begin('~/.vim/plugged') " vim-plug
Plug 'scrooloose/nerdtree'
Plug 'junegunn/goyo.vim'
Plug 'terryma/vim-expand-region'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
call plug#end

NERDTree

 擬似エクスプローラです。画面分割したウィンドウで開かれます。ウィンドウの切り替えは、主に<C-w>w

" NERDTree(詳しくは:help NERDTree)
let g:NERDTreeWinPos = 'right'
let g:NERDTreeNaturalSort=1
"let g:NERDTreeWinSize=30
" let g:NERDTreeShowLineNumbers=1

Goyo

 執筆モードを生み出すプラグインです。主に、ウィンドウに余白を作ります。

 現在のウィンドウをフル画面表示するコマンドだと思えば、NERDTreeの閲覧にも有用です。

行あたり文字数を設定する

 調査中です。

ウィンドウのリサイズに対応する

 調査中です。ショートカット?

行数やステータスラインを表示する

 調査中です。

expand-region

 visualモードの選択範囲を、段階的に増やすか減らす操作を追加してくれます。

全角括弧()や句点。を範囲に入れる方法

 調査中です。

airline

 ステータスバーとタブバーを、機能的かつ美しくするプラグインです。マニュアルはこちら、もしくはダウンロード後に:help airline。helpを読むのに、早速goyaプラグインが役立つかもしれません。

改稿