空行をレジスタに送らないVimオペレータ作ってみた
dd
で空行を削除したらヤンクしたテキストが上書きされてしまった… なんてことありますよね。
"_dd
でブラックホールに送れば済む話ですが、空行を消すために毎回レジスタ指定するのは面倒くさい。
そんな思いから、空行(空白のみも含む)を削除したときは自動でブラックホールに送ってくれるオペレータ作ってみました。
nmap d <Plug>(operator-blank2void) xmap d <Plug>(operator-blank2void) nmap <silent>dd :exec "normal Vd"<cr> call operator#user#define('blank2void', 'Operator_blank2void') function! Operator_blank2void(motion_wise) abort let v = operator#user#visual_command_from_wise_name(a:motion_wise) if join(getline("'[", "']"), '') =~ '\%^\_s*\%$' execute printf('normal! `[%s`]"_d', v) else execute printf('normal! `[%s`]d', v) endif endfunction
dd
のキーマップが冗長に思えますが、これは選択時のチラツキを無くすためです。
switch系プラグイン vim-clurinを強化した話
switch系プラグインについて
switch系プラグインとは定義されたルールに従ってテキストを置換する類のプラグインです。
よくあるルールはTrue
とFalse
を切り替える、if
-> else if
-> else
の順で切り替えるなどです。
vim-clurinの基本的な使い方は作者であるsynganさんの記事を参照してください。 qiita.com
switch.vimとの違い
変更内容の前に、筆者がvim-clurinを使ってる理由をざっと説明します。
筆者はvim-clurinの前はswitch.vimを使っていました。
筆者が使っていた範囲でのswitch.vimとの大きな違いは以下の2つです。
- ファイルタイプ毎の設定をグローバル変数1つで定義できる。
- switch.vimはファイルタイプ毎の設定をautocmdを使ってバッファローカル変数に定義する必要がありました。
- パターンにマッチしたら関数を呼べる。
- ぱっと見設定が冗長に感じる
- 拡張性のために冗長な書き方ができますが、ある程度簡略化して書けます。
関数を呼べるのがなかなか強力です。
改善内容
各変更のサンプルはリポジトリのREADMEを見てください。
※ GitHubを見る限りsynganさんは現在あまり活動されてないようなので、試す場合は筆者のリポジトリを使ってください。
1. ファイルタイプ別設定のキーに複数言語を指定できる
g:clurin
のキーには'c'
の用に単一のファイルタイプしか指定できませんでしたが、スペース区切りで複数の言語を指定できるようにしました。
C言語とC++共用の設定であればキーは'c cpp'
です。もちろん、C言語、C++独自の設定と共存できます。
2. デフォルトの設定をファイルタイプ毎に無効に出来る
g:clurin
で'use_default': 0
を指定すれば、デフォルトの設定を全て無効化出来ましたが、ファイルタイプ毎に無効化は出来ませんでした。
各ファイルタイプの設定で、'use_default': 0
を指定すれば無効化できるようになりました。
3. 関数内で置換処理を終了できる。
'replace'
で関数を指定した場合、'pattern'
にマッチしたテキストの置換には指定した関数の戻り値が使用されます。
ただ、複雑な置換をする場合は関数内で置換処理を行って、戻り値は使用しないほうが都合が良いときがあります。
そんな場合は'quit': 1
を指定すれば、関数呼び出し後に置換処理を即終了出来ます。
4. 'replace'
で'\2'
以降も使えるようにした。
'replace'
で使える部分正規表現が'\1'
だけだったので'\2'
以降も使えるようにしました。
ただし、これは破壊的な変更です。
'replace'
に指定した関数の第1引数が変わります。
- before:
'\1'
の文字列 - after:
'\1'
から'\9'
までのリスト
最後に
これらの変更でRubyのdo ~ end
と{ ~ }
の切り替えなど、様々な事が出来るようになりました。
やはり、関数を呼べるのは強力ですね。
vim-clurinはソースが読みやすかったので変更が用意でした。
見習いたいです。
btrfsで空き領域が開放されずにのディスク使用率が100%になる。
1週間ほど前、btrfsのデバイスが容量が空いているのにも関わらず使用率が100%のまま変わらない事があった。
いろいろやった気がするが、ほとんど思い出せないので覚えてる限りの解決法を載せておく。
注意点
btrfsは空き領域をプールするのでdf
コマンドで見れる情報が正しいとは限らない。
ルートディレクトリの情報を見る場合は下記のコマンド。
filesystem
は短縮してf
でもいい
btrfs filesystem df -h /
解決策
btrfsのsubvolumeを削除したら領域が開放された。
「領域が開放されないときはsubvolumeを削除しろ」と言うサイトは幾つかあったが、subvolumeなんて機能は使った覚えがなかったので無視していた。
しかし、自分で直接使った記憶はなくてもDockerが使っていた。
Dockerが領域を開放しなかったわけではないだろうが、subvolumeを全部消したら解決。
消えて困るコンテナはなかったので楽だった。
削除方法は覚えてないのでBtrfs - ArchWikiでも見てください。
letを使ってシェルで条件演算子(三項演算子)
ポイント
- シェル変数は$を省略する
- 未定義の変数は0として扱われる
- 文字列は扱えない
- シェルと反対にtrueは1、falseが0
$ let 'a = 1? 11 : 22' $ echo $a 11 $ let 'a = 0? 11 : 22' $ echo $a 22 $ let 'a = 3==3? 11: 22' $ echo $a 11
条件演算子以外にもインクリメントや復号代入も可能です。
$ let 'b++' $ echo $b 1 $ let 'c += 3' $ echo $c 3
ちなみに$((expr))
でも同様の事が可能。
$ echo $((d -= 10)) echo -10 $ echo $d -10
Have a nice shell life!
Kuportの情報取得するgem作った
この記事は
Kogakuin Univ Advent Calendar 2016 - Adventar
の15日目です。
かなり遅れました、ほんとすみません。
概要
みんな大好きkuportからデータを取得してJSONに変換して出力します。
ライブラリとしても使用可能です。
MechanizeとかNokogiri使いました。
詳細はREADME.md
データは全てJSONに変換されるため jq や jid で閲覧してください。
jidは見ての通りインタラクティブにフィルタできるのでおすすめです。
ただ、マルチバイト文字の間にスペースが入るのが欠点です。
※内部の情報を公開するのは良くない気がするので、実行結果のスクショありません。
導入
gem install kuport
最新の機能は避けたつもりですが、古いRubyだと動かないかもしれません。
使い方ざっくり
--id
で学籍番号を指定して実行するとパスワードが求められます。
キャシュが効くので一度ログインしたら暫く--id
は不要です。
ログイン
$ kuport --id jx99123 Pasword>
個人宛お知らせを取得
各メッセージのタイトル、内容、リンクを取得します。
-m
オプションにread
を渡すと既読メッセージを取得できます。
$ kuport -m > messages.json
jidで閲覧
$ kuport -m | jid
メッセージの添付ファイルをダウンロード
kuport -m | jid
でメッセージをフィルタリングしてリンクを出力すれば添付ファイルをダウンロードできます。
--download
には-m
で取得したリンク要素のJSONをそのまま渡せます。
JSONを渡せばブラウザでダウンロードするのと違ってまともなファイル名を付けてくれます。
$ kuport --download "$(kuport -m | jid)"
jqでフィルタリング
添字でメッセージを選択できます。
$ kuport --download "$(kuport -m | jq '.[0].links')"
時間割
時間割がJSONとして出力されます。
jid使ってもかなり見づらいです。
$ kuport -t | jid
ライブラリとして
おおまかな使い方
require 'kuport' kp = Kuport.new kp.login('jx91234') messages = kp.messages timetable = kp.timetable m = messages[0] puts m.title, m.body, m.links puts m.json puts messages.to_json timetable.compact puts timetable.to_json kp.download(url, name) kp.download([{name: 'File.pdf', path: 'https://example.com/file.pdf'}, ]) kp.cookies_clear # Logout
ハマったこと
文字コードが合わなくてパース中にエラー
CharsetはEUC-JPなのにCP932が混ざってるページがあって困りました。
幸いにもMechanizeはパーサを指定できるので、強制的にUTF-8に変換して処理するパーサを作りました。
MechanizeをrequireするとString
にtoutf8
メソッドが加わるので、それを使用します。
class Parser def self.parse(text, url = nil, encoding = nil, options = Nokogiri::XML::ParseOptions::DEFAULT_HTML, &block) Nokogiri::HTML::Document.parse(text.toutf8, url, 'UTF-8', options, &block) end end agent = Mechanize.new agent.html_parser = Parser
お知らせに共通するCSSクラスが無い
お知らせのクラスはざっと見た所3つありました。
- message_normal
- message_emergency
- message_check
Nokogiriでクラス指定で要素を抜き出すときはcss
メソッドが使えますが、これは正規表現やワイルドカードは使えないようです。
上記3つにマッチする要素を取り出すにはxpath
メソッドを使いました。
doc.xpath(".//*[contains(@class, 'message')]")
これでクラス名に'message'を含む要素を取得できます。
xpathなかなか強力ですね。
TODO
- 電子教材一覧
- インターフェース(TUI)
- テスト
終わり
なぜか公開後数分で10DL超えました。
間違って入れる人が沢山いるようですね。
当初はncurseswを使ってUI作ろうと思ってたんですが挫折しました。
Curses::Padが動いたのでTUI作成中。
padが表示されない...
バグがあったりしたら、なんでもいいので気軽に連絡してください。
プルリク大歓迎です。
ターミナル上に画像を表示する方法いろいろ
ターミナル*1に画像表示したいですよね。
先日w3m*2でブラウジングしてたら、テキストブラウザなのに画像が表示されて驚きました。
gnome-terminal, konsole, terminologyの3つの端末で表示されたので端末共通の画像表示方法がありそうです。
端末上での画像表示について調べたこと書きます。
(結論を言うと、端末に共通の表示方法はなかった)
この記事はKogakuin Univ Advent Calendar 2016 - Adventarの13日目です。
目次
- 目次
- 比較元画像
- アスキーアート
- エスケープシーケンス
- pxl
- DRCS(Soft Character Set)
- Sixel
- terminology
- iTerm2
- w3m(w3mimgdisplay)
- 結論
比較元画像
この画像が飽きるほど出てきますが、我慢してください。
※なにかを頑張ったわけではありません。
アスキーアート
「端末に画像」と聞いて最初に思いつくのはアスキーアートだと思います。
画像をAA化するサイト
を使用してフォントサイズ7で出力しました。
エスケープシーケンス
ターミナルでもエスケープシーケンスを使えば色付き文字を出力できます。
エスケープシーケンスについて詳しくは下記。
エスケープシーケンスを体感する - ザリガニが見ていた...。
画像表示
下記のスクリプトを使用
ターミナルに画像を表示する - Qiita
フォントサイズ12(普段)
フォントサイズ5(使用中端末の最小値)
改良版
「ターミナルに画像を表示する」の画質向上を試みる - Qiita
フォントサイズ12
フォントサイズ5
pxl
最近Go製のCLIツールをよく目にします。
pxlはターミナルに画像を表示するGo製ツールです。
go get github.com/ichinaski/pxl pxl img.png
GitHub - ichinaski/pxl: Display images in the terminal
フォントサイズ12
フォントサイズ5
縦に潰れてますが、かなり鮮明です。
※pxlは今までのものと違い仮想画面に描画しています。
DRCS(Soft Character Set)
平たく言うと画像をフォントとして扱う端末機能ですが対応端末は少ないです。
Soft Character Set (DRCS) - Togetter
Sixel
平たく言うとエスケープシーケンスで画像を表現する端末機能です。同じく対応端末は少ないです。*3
文字として表現できるので、対応端末ならssh先の画像をSixelで出力して手元で確認できます。
go-sixelで試してみました。 GitHub - mattn/go-sixel
go get github.com/mattn/go-sixel/cmd/gosr gosr img.png
非対応端末
文字が沢山出る
xterm -ti 340
色がおかしい(パッチを当てないと?)
mlterm
おぉ 見事に画像が表示されました!
対応端末が増えると良いですね。
参考資料
長編まとめ・Sixel Graphics復活への動き(1) (26ページ目) - Togetter
Sixel 情報 - ダメ出し Blog
OS X Mavericksにmltermとlibsixelをインストールして端末で画像を表示する - Keep It Simple, Stupid
ターミナル上でgnuplotの出力をターミナルに直接描画する - Qiita
Sixel Graphicsを活用したアプリケーションの御紹介 - Qiita
terminology
terminologyはモダンなカッコイイ系端末で、独自の便利コマンドを搭載しています。
youtu.be
tyls
はlsにサムネイルが付きます。
tycat
は引数のファイル(画像、音楽、動画)を内蔵プレイヤーで再生します。
typop
はtycat
のポップアップ版です。
tycat
で画像を表示した上にtypop
でポップアップを表示しています。
iTerm2
iTerm2でも公式サイトが配布しているスクリプトを使用することで画像が表示できるようです。
youtu.be
iTerm2の2.9以降でインライン画像表示できるようになってた - uzullaがブログ
w3m(w3mimgdisplay)
w3m
が画像を表示できるのはw3mimgdisplay
がXと通信して、端末上に画像を上書きしているからです。
つまりはw3mimgdisplay
さえあればX上では画像表示し放題です。
w3mimgdisplay
の使い方。
# x y w h と ./img.png を適切に指定する echo -e '0;1;x;y;w;h;;;;;./img.png\n4;\n3;' | /usr/lib/w3m/w3mimgdisplay
画像のサイズ取得もできます。
入力フォーマットの詳細はImages in terminalを見てください。
結論
- 端末共通の画像表示方法はなかった。
- w3mimgdisplayを使えばサクッと画像表示はできる。
- 各端末がSixelに対応すると幸せになれる。
- terminologyオススメです。