読者です 読者をやめる 読者になる 読者になる

quickrun.vimからPrevimを呼んでMarkdownをプレビューする

PrevimMarkdownプレビュー用のVimプラグインです。
スタンドアロンで動作するのが魅力です。

そんなPrevimをQuickRunで呼び出せたらキーマップの節約になります。
autocmdでMarkdownのときだけキーマップを上書きしてもいいのですが、どうせならスマートに解決。

let g:quickrun_config = {
      \ 'markdown': {
      \   'runner': 'shell',
      \   'outputter': 'null',
      \   'command': ':PrevimOpen',
      \   'exec': '%c',
      \ },
      \ }

ざっと見た感じrunnershellを指定して、command:で始めればVimのコマンドが呼べるようです。

空行をレジスタに送らない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を強化した話

github.com

switch系プラグインについて

switch系プラグインとは定義されたルールに従ってテキストを置換する類のプラグインです。
よくあるルールはTrueFalseを切り替える、if -> else if -> else の順で切り替えるなどです。

vim-clurinの基本的な使い方は作者であるsynganさんの記事を参照してください。 qiita.com

switch.vimとの違い

変更内容の前に、筆者がvim-clurinを使ってる理由をざっと説明します。
筆者はvim-clurinの前はswitch.vimを使っていました。
筆者が使っていた範囲でのswitch.vimとの大きな違いは以下の2つです。

  1. ファイルタイプ毎の設定をグローバル変数1つで定義できる。
  2. パターンにマッチしたら関数を呼べる。
  3. ぱっと見設定が冗長に感じる
    • 拡張性のために冗長な書き方ができますが、ある程度簡略化して書けます。

関数を呼べるのがなかなか強力です。

改善内容

各変更のサンプルはリポジトリの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'までのリスト

最後に

これらの変更でRubydo ~ end{ ~ }の切り替えなど、様々な事が出来るようになりました。
やはり、関数を呼べるのは強力ですね。

vim-clurinはソースが読みやすかったので変更が用意でした。
見習いたいです。

btrfsで空き領域が開放されずにのディスク使用率が100%になる。

1週間ほど前、btrfsのデバイスが容量が空いているのにも関わらず使用率が100%のまま変わらない事があった。

いろいろやった気がするが、ほとんど思い出せないので覚えてる限りの解決法を載せておく。

注意点

btrfsは空き領域をプールするのでdfコマンドで見れる情報が正しいとは限らない。
ルートディレクトリの情報を見る場合は下記のコマンド。
filesystemは短縮してfでもいい

btrfs filesystem df -h /

解決策

btrfsのsubmoduleを削除したら領域が開放された。

「領域が開放されないときはsubmoduleを削除しろ」と言うサイトは幾つかあったが、submoduleなんて機能は使った覚えがなかったので無視していた。
しかし、自分で直接使った記憶はなくてもDockerが使っていた
Dockerが領域を開放しなかったわけではないだろうが、submoduleを全部消したら解決。
消えて困るコンテナはなかったので楽だった。

削除方法は覚えてないので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日目です。
かなり遅れました、ほんとすみません。

概要

github.com

みんな大好きkuportからデータを取得してJSONに変換して出力します。
ライブラリとしても使用可能です。
MechanizeとかNokogiri使いました。

詳細はREADME.md

データは全てJSONに変換されるため jqjid で閲覧してください。

jidは見ての通りインタラクティブにフィルタできるのでおすすめです。
ただ、マルチバイト文字の間にスペースが入るのが欠点です。

https://github.com/simeji/jid/wiki/images/demo-jid-main-640.gif

※内部の情報を公開するのは良くない気がするので、実行結果のスクショありません。

導入

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するとStringtoutf8メソッドが加わるので、それを使用します。

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作ろうと思ってたんですが挫折しました。
padが表示されない...
Curses::Padが動いたのでTUI作成中。

バグがあったりしたら、なんでもいいので気軽に連絡してください。
プルリク大歓迎です。

ターミナル上に画像を表示する方法いろいろ

ターミナル*1に画像表示したいですよね。

先日w3m*2ブラウジングしてたら、テキストブラウザなのに画像が表示されて驚きました。
f:id:u10e10:20161213205541g:plain:w500

gnome-terminal, konsole, terminologyの3つの端末で表示されたので端末共通の画像表示方法がありそうです。 端末上での画像表示について調べたこと書きます。
(結論を言うと、端末に共通の表示方法はなかった)

この記事はKogakuin Univ Advent Calendar 2016 - Adventarの13日目です。

目次

比較元画像

この画像が飽きるほど出てきますが、我慢してください。 f:id:u10e10:20161213214732p:plain:w400
※なにかを頑張ったわけではありません。

アスキーアート

「端末に画像」と聞いて最初に思いつくのはアスキーアートだと思います。 画像をAA化するサイト を使用してフォントサイズ7で出力しました。
f:id:u10e10:20161213215842p:plain:w400

エスケープシーケンス

ターミナルでもエスケープシーケンスを使えば色付き文字を出力できます。 f:id:u10e10:20161213222016p:plain

上記コードの関数版
カラーコード表示スクリプト

エスケープシーケンスについて詳しくは下記。
エスケープシーケンスを体感する - ザリガニが見ていた...。

画像表示

下記のスクリプトを使用
ターミナルに画像を表示する - Qiita

フォントサイズ12(普段)
f:id:u10e10:20161213224208p:plain:w400

フォントサイズ5(使用中端末の最小値)
f:id:u10e10:20161213224220p:plain:w400

改良版

「ターミナルに画像を表示する」の画質向上を試みる - Qiita

フォントサイズ12
f:id:u10e10:20161213232040p:plain:w400

フォントサイズ5
f:id:u10e10:20161213231538p:plain:w400

pxl

最近Go製のCLIツールをよく目にします。
pxlはターミナルに画像を表示するGo製ツールです。

go get github.com/ichinaski/pxl
pxl img.png

GitHub - ichinaski/pxl: Display images in the terminal

フォントサイズ12
f:id:u10e10:20161213233531p:plain:w400

フォントサイズ5
f:id:u10e10:20161213232655p:plain:w400

縦に潰れてますが、かなり鮮明です。
※pxlは今までのものと違い仮想画面に描画しています。

DRCS(Soft Character Set)

平たく言うと画像をフォントとして扱う端末機能ですが対応端末は少ない。
vimと端末エミュレーション - Qiita  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
非対応端末

文字が沢山出る
f:id:u10e10:20161214010637p:plain:w400

xterm -ti 340

色がおかしい(パッチを当てないと?)
f:id:u10e10:20161214010159p:plain:w400

mlterm

f:id:u10e10:20161214010447p:plain:w400

画像をそのまま表示できたので、対応端末が増えると良いですね。

参考資料
長編まとめ・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にサムネイルが付きます。
f:id:u10e10:20161214032929p:plain

tycatは引数のファイル(画像、音楽、動画)を内蔵プレイヤーで再生します。
typoptycatのポップアップ版です。

tycatで画像を表示した上にtypopでポップアップを表示しています。 f:id:u10e10:20161214032920p:plain

iTerm2

iTerm2でも公式サイトが配布しているスクリプトを使用することで画像が表示できるようです。
youtu.be iTerm2の2.9以降でインライン画像表示できるようになってた - uzullaがブログ

w3mimgdisplay

w3mが画像を表示できるのはw3mimgdisplayがXと通信して端末上に画像を上書きしているからです。
つまりはw3mimgdisplayさえあればX上では画像表示し放題です。

w3mimgdisplayの使い方。

echo -e '0;1;x;y;w;h;;;;;./img.png\n4;\n3;' | /usr/lib/w3m/w3mimgdisplay

f:id:u10e10:20161214032843p:plain

画像のサイズ取得もできます。
f:id:u10e10:20161214032832p:plain

入力フォーマットはImages in terminalを見てください。

結論

  • 端末共通の画像表示方法はなかった。
  • w3mimgdisplayを使えばサクッと画像表示はできる。
  • 各端末がSixelに対応すると幸せになれる。
  • terminologyオススメです。

*1:GUIのターミナルを想定

*2:有名なテキストブラウザ

*3:gnome-terminal, konsole, terminologyでは動かなかった