Yearly Archives: 2016

2016-04-26 ,

日本語grep(lvgrep)

日本語のgrepってみんなどうやってるんだろう。メジャーなディストリビューションとか、日本語でgrepが出来ないとは思えないけど。あ、今はもうUTF-8統一なのか。

Emacs25でdiredのAとQがdired-do-find-系(dired-do-find-regexpとdired-do-find-regexp-and-replace)に変わってしまったのでさあ大変。 これまでのdired-do-searchとdired-do-query-replace-regexpは外部コマンド(find,grep)に依存していないのでWindows上でも安定して使えたのだけど、dired-do-find-系はそれらに依存しているのでトラブルに。 dired-do-searchとdired-do-query-replace-regexpはまだ使えるのでキーを割り当て直せば良いんだろうけど、dired-do-find-系はディレクトリを指定できるメリットがあるのでこれを機に使えるようにした。

まずはfind。そのままだと環境変数PATHの優先順位の関係でWindowsのfindコマンドが使われてしまう。 私の場合、シェル(shell-file-name)はcmdproxy.exeではなくてCygwinのshにしてあるので、find-programに /bin/find と絶対パスを指定して解決。

次はgrep。日本語のgrepは前世紀からいろんな人が苦労していた気がするけど、いまさらまたこの設定をいじるなんて。 日本語(正確には日本語でよく使われる文字符号化方式でエンコードされたテキスト)のgrepの方法としては次のようなものが思い当たる。

  • lgrepを使う
  • nkfを噛ます
  • iconvを噛ます
  • 日本語に対応する改造を施したgrepを使う

私はlgrepを使ってきた。lgrepはlvの検索機能部分で、Cygwinのパッケージになっていて簡単にインストールできる。lv&lgrepの文字変換機能は素晴らしいけれど、最大の欠点はGNUのgrepとオプションに互換性がないことだ。特に-Hでファイル名が表示できないのが痛い。代わりになるオプションもない。

nkfはパッケージになってないからビルドするのが面倒くさいし(lvも昔はパッケージになっていなかったので自分でビルドしてた)、日本語対応grepをビルドするのも同じ。iconvは自動判別がそのままでは難しい。

結局やりたいことは、文字コードを自動的判別して変換して、それに対してgrepをすることだから、次のようなスクリプトを作成した。

#!/bin/sh
export LANG=ja_JP.CP932
lv -Os ${@:$#} | grep --label=${@:$#} ${@:1:$#-1}

LANGが無いとCygwinのgrepはUTF-8前提になってしまうのでLANGを指定した。私はCP932前提のコマンドライン用プログラムを多数抱えているのでWindowsでUTF-8に移行する気にはまだなれない。

lvには-Osだけを指定して、入力は自動判別にし出力はShift_JIS(≒CP932)とする。

入力ファイルの指定はスクリプトの最後の引数とする。それをlvとgrepの–label=オプションへ渡す。その他の引数はgrepにそのまま渡すことにした。

これをlvgrepとして保存して、Emacsではgrep-program、grep-command、find-grep-optionsあたりでこれを指定するようにした。

とりあえずうまく行っているみたい?

dired-do-searchと比べて外部のgrepを使っているせいで空白の検索が素直に指定できない等不便なことはあるけど仕方なし。Emacsの正規表現と一貫性を持たせることを考えると、あまり外部コマンドに依存するのは考え物だと思うんだけどなぁ。

(2019-01-15追記)

grepのオプションにできるだけ対応した。複数ファイル処理可能。ただしディレクトリを指定する機能は対応していない。

#!/bin/bash
export LANG=ja_JP.CP932

# option alias map
declare -A OPT_ALIASES;
OPT_ALIASES["--regexp"]="-e";
OPT_ALIASES["--file"]="-f";
OPT_ALIASES["--ignore-case"]="-i";
OPT_ALIASES["--invert-match"]="-v";
OPT_ALIASES["--word-regexp"]="-w";
OPT_ALIASES["--line-regexp"]="-x";
OPT_ALIASES["--count"]="-c";
OPT_ALIASES["--colour"]="--color";
OPT_ALIASES["--files-without-match"]="-L";
OPT_ALIASES["--files-with-matches"]="-l";
OPT_ALIASES["--max-count"]="-m";
OPT_ALIASES["--only-matching"]="-o";
OPT_ALIASES["--quit"]="-q";
OPT_ALIASES["--silent"]="-q";
OPT_ALIASES["--no-messages"]="-s";
OPT_ALIASES["--byte-offset"]="-b";
OPT_ALIASES["--with-filename"]="-H";
OPT_ALIASES["--no-filename"]="-h";
OPT_ALIASES["--line-number"]="-n";
OPT_ALIASES["--initial-tab"]="-T";
OPT_ALIASES["--unix-byte-offsets"]="-u";
OPT_ALIASES["--null"]="-Z";
OPT_ALIASES["--after-context"]="-A";
OPT_ALIASES["--before-context"]="-B";
OPT_ALIASES["--context"]="-C";
OPT_ALIASES["--text"]="-a";
OPT_ALIASES["--devices"]="-D";
OPT_ALIASES["--directories"]="-d";
OPT_ALIASES["--recursive"]="-r";
OPT_ALIASES["--dereference-recursive"]="-R";
OPT_ALIASES["--binary"]="-U";
OPT_ALIASES["--null-data"]="-z";

# parse command line
declare -a files=()
declare -a opt_arr=()
declare -A opt_hash
declare unresolved_arg=""

function push_opt () {
    if [[ -v OPT_ALIASES[$1] ]]; then
        opt_hash[${OPT_ALIASES[$1]}]=$2;
    else
        opt_hash[$1]=$2;
    fi
}

for arg in "$@"; do
    # \ -> \\
    qarg="${arg//\\/\\\\}"
    # " -> \"
    qarg="${qarg//\"/\\\"}"

    if [[ -n $unresolved_arg ]]; then # -prev curr
        options+=($unresolved_arg);
        options+=("$qarg");
        push_opt $unresolved_arg "$qarg";
        unresolved_arg="";
    elif [[ ${arg} =~ ^(--[^=]+)=(.*)$ ]]; then # --???=???
        options+=("$qarg");
        push_opt ${BASH_REMATCH[1]} "${BASH_REMATCH[2]}";
    elif [[ $arg =~ ^-- ]]; then # --???
        options+=("$qarg");
        push_opt $arg "";
    elif [[ $arg =~ ^-[efmABCDd]$ ]]; then # -curr next
        unresolved_arg=$arg;
    elif [[ $arg =~ ^-[^-] ]]; then # -???
        options+=("$qarg");
        i=1;
        while [[ $i -lt ${#arg} ]]; do
            push_opt -${arg:(i++):1} "";
        done;
    elif [[ ! -v opt_hash["-e"] ]]; then # PATTERN
        options+=("$qarg");
        push_opt "-e" "$qarg";
    else # FILE
        files+=("$qarg");
    fi
done

# echo files="${files[@]}" >> ~/tmp/lvgrep.log
# echo options="${options[@]}" >> ~/tmp/lvgrep.log
# for x in "${!opt_hash[@]}"; do printf "%s = %s\n" "$x" "${opt_hash[$x]}" >> ~/tmp/lvgrep.log; done

# -h or -H
if [[ -v opt_hash["-h"] || -v opt_hash["-H"] ]]; then
    :
elif [ ${#files[@]} -lt 2 ]; then
    options+=("--no-filename");
else
    options+=("--with-filename");
fi

# execute each file
found=false
for file in "${files[@]}"; do
    cmd="lv -a -Os \"${file}\" | grep --label=\"${file}\" ${options[@]@Q}"
    # echo "$cmd" >> ~/tmp/lvgrep.log
    if bash -c "$cmd"; then
        found=true
    fi
done

# return exit status code
if [ "$found" = true ]; then
    exit 0;
else
    exit 1;
fi;

(2016-12-21追記)

複数のファイルを指定したときに正しく動作するようにした。

#!/bin/bash
export LANG=ja_JP.CP932

# parse command line
files=()
pattern=""
options=()
for arg in "$@"; do
    # \ -> \\
    qarg="${arg//\\/\\\\}"
    # " -> \"
    qarg="${qarg//\"/\\\"}"
    if [[ ${arg} = -* ]]; then
        options+=(${qarg});
    elif [[ -z "${pattern// }" ]]; then
        pattern=${qarg};
    else
        files+=(${qarg});
    fi
done
#echo pattern=${pattern}
#echo files="${files[@]}"
#echo options="${options[@]}"

# -h or -H
if echo " ${options[@]} " | grep -e " \\(--no-filename\\|--with-filename\\|-[^ -]*[hH][^ -]*\\) "; then
    :
elif [ ${#files[@]} -lt 2 ]; then
    options+=("--no-filename");
else
    options+=("--with-filename");
fi

# execute each file
found=false
for file in "${files[@]}"; do
    c="lv -Os \"${file}\" | grep --label=\"${file}\" ${options[@]} \"${pattern}\""
    #echo "$c"
    if bash -c "$c"; then
        found=true
    fi
done

# return exit status code
if [ "$found" = true ]; then
    exit 0;
else
    exit 1;
fi;
2016-04-23

Emacs25(MinGW64)+cygwin-mount.elでtramp経由でリモートファイルを開けない

diredでリモートのディレクトリリストは表示されてもファイルを開こうとすると次のようなエラーが。

Tramp: Encoding remote file ‘/scpx:user@example.jp:/home/user/tmp/test1.txt’ with ‘openssl enc -base64 <%s’...done
Tramp: Decoding local file ‘c:/app/cygwin/tmp/tramp.6920y_V.txt’ with ‘base64-decode-region’...done
Tramp: Inserting ‘/scpx:user@example.jp:/home/user/tmp/test1.txt’...failed
Removing old name: No such file or directory, /app/cygwin/app/cygwin/tmp/tramp.6920y_V.txt

調べていくとカレントディレクトリ(default-directory)によって結果が変わった。 scratchバッファからリモートファイルをfind-fileすると問題なく開いた。 tramp上のパスをdiredで開いて、そこから開こうとするとエラーになった。

  1. find-file
  2. insert-file-contents
  3. tramp-handle-insert-file-contents
  4. tramp-sh-handle-file-local-copy
  5. with-temp-file
  6. write-region

と追っていくと、次のようなコードでエラーが再現。

(let ((default-directory "/scpx:user@example.jp:/home/user/tmp"))
  (write-region nil nil "c:/app/cygwin/tmp/a.txt"))

default-directoryがローカルなら何事もなく成功する。

write-regionはCで書かれているので見てみると、中でexpand-file-nameを使ってファイル名を展開し、そのファイルに対して出力している。

絶対パスにしているならカレントディレクトリによって動作が変わるはずはない。

エラーメッセージとして/app/cygwin/app/cygwin/tmp/tramp.6920y_V.txtのような全くおかしなパスが表示されているので、念のためexpand-file-nameを調べたところ、おかしな挙動に気がついた。

  • (expand-file-name "c:/a.txt" "c:/")c:/a.txt
  • (expand-file-name "c:/a.txt" "/ssh:/")/a.txt

あれれ?

expand-file-nameもCで書かれていたので中身を見てみると、default-directoryを元にfind-file-name-handlerして実際にexpand-file-nameを処理する関数を求めていた。

あー、ローカルとリモートでファイルシステムが違うんだ。default-directoryがtrampパスの時tramp-sh-handle-expand-file-nameが使われるんだ。 で、tramp-sh-handle-expand-file-nameはWindowsのことをこれっぽっちも考慮していないからc:/aが/aになってしまうのね。

C:/app/cygwin/tmp/a.txt が tramp-sh-handle-expand-file-name によって /app/cygwin/tmp/a.txt になり、これがcygwin-mount.elによってcygwinルートディレクトリを基準にしたパスとして展開され、/app/cygwin/app/cygwin/tmp/a.txtになるわけだ。ヤレヤレ。

というか、そもそもexpand-file-nameにローカルの絶対パスを渡したときにtrampのexpand-file-nameが使われるってどうなのよ。 ここは展開対象パスがローカルの絶対パスなのだから、default-directoryに関わらずローカルのハンドラによってexpandするべきなんじゃないのか? というわけで、expand-file-nameにadvice-addしたのだけど、何故かうまく行かなかった。Cから呼んでいるからだろうか。

仕方ないのでtramp-sh-handle-expand-file-name側にadvice-addしてc:/がc:/のまま/にならないようにしたところ、リモートのファイルがtramp経由で開けるようになった。

(advice-add
 'tramp-sh-handle-expand-file-name :around
 (lambda (orig-func name &optional dir)
   (if (save-match-data (string-match "^[a-z]+:[/\\]" name))
       (expand-file-name name (file-name-directory name))
     (apply orig-func (list name dir)))))

ちなみに、リモート・ローカル間でコピーできない現象は次のページの tramp-do-copy-or-rename-file-out-of-band へのadviceで治った。

NTEmacs @ ウィキ - tramp を tramp-method “scp” で使うための設定 - @ウィキモバイル

最後に、trampのコードを追うためにはファイル名ハンドラのことを知っていないといけないのでしっかり押さえておくこと。

2016-04-22 ,

Windows10でウィンドウのアクティブタイトルバーに色をつける

Vistaからだったろうか、Win7からだったろうか。アクティブタイトルバーに色が付かなくなったのは。主にキーボードで操作している人間にとって、今どこにキーフォーカスが当たっているのかは非常に重要な情報だ。特に最近のディスプレイは大きい。23インチ、マルチディスプレイ環境で沢山のウィンドウがあると、一目で全てのウィンドウに目を通すのは難しい。ましてやわずかな明暗の差しか無いアクティブウィンドウを識別するのは容易ではない。

そんな状況が続きつつも最近は諦めていたのだが、ひょんな事から何か状況が変わっていないかと「windows10 active titlebar」で検索したら「タイトルバーに色づけ」なんて記事が大量に出てくるではないか!

どうもWindows10のThreshold2から(Insider Previewではその前から)出来るようになっていたらしい。

最近の私の情報感度の低さというか、情弱っぷりには我ながらびっくりするくらいだ。

などと記事を辿っていくと、Aero Liteなるテーマがあったようだ。

何はともあれ、あるべき設定があるべき場所にあるのは良いことだ。

2016-04-21

Windows(MSYS2 MinGW64)でEmacs25+IMEパッチをビルド

(2019-12-08追記: 新しいものを書きました Windows用のEmacs26.3をMSYS2でビルドする方法(IMEパッチ、ImageMagick-6))

新しいPCにしてからEmacsの適当なWindows用バイナリを試してみたのですが、gnutlsが使えなかったりIMEまわりが不安定だったりどれが最新だか分からなかったり色々したので諦めて自分でビルドすることにしました。SSDになったことですし!

ビルドの方法については nt/INSTALLnt/INSTALL.W64 が一次情報となり、詳しいと思います。私はW64の方を参考にしました。

日本語では次のページが参考になりました。

特にIMEパッチを提供されている rzl24ozi’s gists のREADME.txtが最も参考になりました。

以下、私がビルドした時の手順です。

ソースコードは emacs.git - Emacs source repository (GitHubならemacs/nt at master - emacs-mirror/emacs)、リリース版なら http://ftp.gnu.org/gnu/emacs/ からダウンロード可能です。 (Gitで落とすときは改行コードを変換しないように注意(autocrlf=false))

Gitでは全て落とすとリポジトリがかなりの容量になるそうなので、 --depth 1 を指定してみました。それでも時間はちょっとかかりますね。

git clone --depth 1 git://git.savannah.gnu.org/emacs.git --config core.autocrlf=false

emacs-25ブランチなら次のようにします(masterは少し不具合があるのでこちらの方が良いかも)。

git clone --depth=1 -b emacs-25 git://git.savannah.gnu.org/emacs.git --config core.autocrlf=false

ビルドの前にMSYS2のインストールとパッケージの設定が必要です。 MSYS2 に書かれていることに加えて nt/INSTALL.W64 に書かれているパッケージをインストールしました。

  1. MSYS2ダウンロード: http://sourceforge.net/projects/msys2/files/latest/download?source=files
  2. MSYS2インストール: msys2-x86_64-20160205.exeを実行
  3. MSYS2のbashから pacman -Sy
  4. パッケージのインストール

       pacman -S base-devel \
       mingw-w64-x86_64-toolchain \
       mingw-w64-x86_64-xpm-nox \
       mingw-w64-x86_64-libtiff \
       mingw-w64-x86_64-giflib \
       mingw-w64-x86_64-libpng \
       mingw-w64-x86_64-libjpeg-turbo \
       mingw-w64-x86_64-librsvg \
       mingw-w64-x86_64-libxml2 \
       mingw-w64-x86_64-gnutls   
    

    (1回でうまく入らないことあり)

私の場合、ここでautocrlf=trueにしていたことに気がついたので、その解消をしました。 cloneしたディレクトリで git config core.autocrlf false して、.git以外全て消して、 git reset --hard しました。

そしてビルド。

  1. (重要) mingw64_shell.bat (スタートメニューからMinGW-w64 Win64 Shell)を実行してMinGW64環境へ切り替える(これをしないとmake段階でエラーになります)
  2. 後はだいたい以下のような感じ

    ./autogen.sh
    ./autogen.sh git #こうしろと言われたので
    ./autogen.sh  #こうしろと言われたので
    
    PKG_CONFIG_PATH=/mingw64/lib/pkgconfig ./configure --prefix=/c/<checkout-dir> --without-imagemagick
    
    make -j4 #4コアで
    
    make install prefix=/c/<install-dir>
    
    <install-dir>/bin/runemacs #起動
    

    最適化するなら chuntaro/NTEmacs64: Windows 版 Emacs (通称 NTEmacs) の 64bit 版 にあるようにCFLAGSを指定して以下のようにすれば良い。

       PKG_CONFIG_PATH=/mingw64/lib/pkgconfig CFLAGS='-Ofast -march=x86-64 -mtune=corei7' ./configure --prefix=/c/<checkout-dir>/ --without-imagemagick
    
  3. (おっと、パッチを当ててなかった)rzl24ozi’s gists から emacs-25.0.92-x64.diff をダウンロード
  4. ソースコードのあるディレクトリトップで patch -b -p0 < emacs-25.0.92-x64.diff (patchはCygwinでテキストマウントを使っていると色々ハマるので注意)
  5. いくつかのHunkが失敗したり曖昧だったりするので一つ一つ確認して修正

    現時点でリジェクトされたのは次の2箇所のみでした。前後の内容が変わってしまって失敗しただけなので、手作業で修正すれば難しくありません。 (ちなみにemacs-25ブランチなら特にリジェクト無くパッチが当たる模様。masterは不具合もあるのでそっちの方が良いかも)

    --- ./src/Makefile.in.orig      2016-03-02 19:21:43.000000000 +0900
    +++ ./src/Makefile.in   2016-03-26 11:17:17.908757300 +0900
    @@ -396,7 +396,7 @@
            region-cache.o sound.o atimer.o \
            doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \
            $(XWIDGETS_OBJ) \
    -       profiler.o decompress.o \
    +       profiler.o decompress.o cmigemo.o \
            $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
            $(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ)
     obj = $(base_obj) $(NS_OBJC_OBJ)
    
    --- ./src/w32fns.c.orig 2016-03-02 19:21:43.000000000 +0900
    +++ ./src/w32fns.c      2016-03-26 11:17:17.988761000 +0900
    @@ -52,6 +52,11 @@
     #include "w32.h"
     #endif
     
    +#ifdef USE_W32_IME
    +#include "fontset.h"
    +#include "w32font.h"
    +#endif
    +
     #include <commctrl.h>
     #include <commdlg.h>
     #include <shellapi.h>
    
  6. 再度makeしてmake installでok

    作成するexeのサイズを小さくするなら make install-strip とする。

       make install-strip prefix=/c/<install-dir>/
    

うん、ちゃんとIME使える!

2016-04-18

冬もすっかり終わって日中部屋にいると暑さを感じるくらいになりましたね。ついこの間年が明けたと思ったのに。

今年はもっと色々出来るかと思ったのですが、ちょっと色々あって思うように捗りません。

着実に一つ一つやっていくしか無いと思われ。

2016-04-18

2016春の新番組

さて、今期はどうでしょう。作品数も多いですし、良さそうなのも多いです。

04/01(金) 22:30~ □ TOKYO MX うしおととら 第3クール  
04/01(金) 23:00~ □ TOKYO MX 影鰐(KAGEWANI)-承- ※ウルトラスーパーアニメタイム
04/01(金) 23:00~ □ TOKYO MX 宇宙パトロールルル子 ※ウルトラスーパーアニメタイム
04/01(金) 24:30~ □ TOKYO MX ジョジョの奇妙な冒険 第4部 -ダイヤモンドは砕けない-  
04/01(金) 25:05~ □ TOKYO MX テラフォーマーズリベンジ  
04/01(金) ~ ニコニコCh 猫も、オンダケ  
04/02(土) 04:52~ □ フジテレビ ぼのぼの 新作  
04/02(土) 08:00~ □ テレビ東京 フューチャーカード バディファイトDDD (第3期)  
04/02(土) 09:30~ □ テレビ東京 レゴ ニンジャゴー 新シリーズ  
04/02(土) 12:00~ □ TBS アグレッシブ烈子 ※「王様のブランチ」内
04/02(土) 17:30~ □ 日本テレビ 逆転裁判  
04/02(土) 24:30~ □ TOKYO MX 学戦都市アスタリスク 2nd Season  
04/02(土) 24:56~ □ TOKYO MX ラグナストライクエンジェルズ ※CM枠の30秒アニメ
04/02(土) 25:00~ □ TOKYO MX ニンジャスレイヤー フロムアニメイシヨン TV版 スペシャルエディション  
× 04/02(土) 26:30~ □ 日本テレビ エンドライド~X fragments  
04/02(土) 深夜~ □ MBS 「かっちけねぇ!」「風の又三郎」(あにめたまご2016)  
04/03(日) 07:00~ □ テレビ朝日 機動戦士ガンダムUC RE:0096  
04/03(日) 08:30~ □ テレビ東京 デュエル・マスターズ VSRF  
× 04/03(日) 17:00~ □ TBS 僕のヒーローアカデミア  
△- 04/03(日) 22:30~ □ TOKYO MX マクロスΔ(デルタ)  
04/03(日) 23:00~ □ TOKYO MX コンクリート・レボルティオ~超人幻想~ THE LAST SONG (第2期)  
04/03(日) 24:30~ □ TOKYO MX くまみこ  
04/03(日) 25:35~ □ テレビ東京 Re:ゼロから始める異世界生活  
04/04(月) 06:45頃~ □ 日本テレビ 朝だよ!貝社員 ※「ZIP!」内
04/04(月) 17:55~ □ テレビ東京 ベイブレードバースト  
04/04(月) 18:00~ □ NHK Eテレ わしも-wasimo- 第4期?  
04/04(月) 18:10~ □ NHK Eテレ 忍たま乱太郎 第24シリーズ  
04/04(月) 19:00~ □ TOKYO MX 怪盗ジョーカー シーズン3  
04/04(月) 19:30~ □ TOKYO MX 12歳。~ちっちゃなムネのトキメキ~  
04/04(月) 23:00~ □ TOKYO MX 美少女戦士セーラームーンCrystal デス・バスターズ編 (第3期)  
04/04(月) 24:00~ □ TOKYO MX ばくおん!!  
04/04(月) 25:00~ □ TOKYO MX パンでPeace!  
△- 04/04(月) 25:35~ □ テレビ東京 聖戦ケルベロス 竜刻のファタリテ  
△- 04/04(月) 26:05~ □ テレビ東京 ハンドレッド  
04/05(火) 17:55~ □ テレビ東京 プリパラ 3rdシーズン  
× 04/05(火) 18:25~ □ テレビ東京 アルティメット・スパイダーマン VS シニスター・シックス  
04/05(火) 18:30~ □ BSプレミアム ぼくらベアベアーズ  
04/05(火) 18:45~ □ NHK Eテレ 少年アシベ GO!GO!ゴマちゃん  
△+ 04/05(火) 21:55~ □ TOKYO MX 薄桜鬼 ~御伽草子~  
04/05(火) 24:30~ □ TOKYO MX ジョーカーゲーム  
04/06(水) 17:55~ □ テレビ東京 バトルスピリッツ ダブルドライブ Official  
04/06(水) 18:00~ □ NHK Eテレ おじゃる丸 第19シリーズ  
04/06(水) 18:25~ □ テレビ東京 双星の陰陽師  
04/06(水) 18:45~ □ NHK Eテレ ねこねこ日本史  
04/06(水) 22:00~ □ TOKYO MX 美少女遊戯ユニットクレーンゲール  
× 04/06(水) 25:00~ □ TOKYO MX 鬼斬  
△- 04/06(水) 25:05~ □ TOKYO MX 文豪ストレイドッグス  
△+ 04/06(水) 25:35~ □ TOKYO MX SUPER LOVERS -スーパーラヴァーズ-  
04/07(木) 18:25~ □ テレビ東京 アイカツ スターズ!  
04/07(木) 21:00~ LINE LIVE 秘密結社 鷹の爪 GT  
04/07(木) 22:00~ □ TOKYO MX クロムクロ  
04/07(木) 22:30~ □ TOKYO MX あんハピ♪  
04/07(木) 23:30~ □ TOKYO MX ネトゲの嫁は女の子じゃないと思った?  
04/07(木) 24:25~ □ フジテレビ 甲鉄城のカバネリ  
△+ 04/07(木) 25:58~ □ TBS 少年メイド  
04/07(木) 26:28~ □ TBS 坂本ですが?  
04/08(金) 18:20~ □ NHK Eテレ あはれ!名作くん ※ビットワールド内
04/08(金) 26:10~ □ TBS 迷家-マヨイガ-  
04/09(土) 10:00~ □ CartoonNetwork パワーパフ ガールズ 新作  
04/09(土) 17:30~ □ NHK Eテレ 境界のRINNE 第2シリーズ  
04/09(土) 22:00~ □ TOKYO MX 田中くんはいつもけだるげ  
04/09(土) 23:30~ □ TOKYO MX キズナイーバー  
04/09(土) 24:00~ □ TOKYO MX はいふり  
04/09(土) 26:25~ □ 日本テレビ ふらいんぐうぃっち -flying witch-  
04/09(土) ~ □ TOKYO MX CoCO & NiCO  
04/10(日) 17:00~ □ NHK Eテレ なめこ~せかいのともだち~ ※「ニャンちゅうワールド放送局」内
04/10(日) 22:15~ □ TOKYO MX とんかつDJアゲ太郎  
04/10(日) 24:00~ □ TOKYO MX 三者三葉  
04/11(月) 25:05~ □ TOKYO MX うさかめ  
× 04/11(月) 25:10~ □ TOKYO MX ワガママハイスペック  
04/15(金) 25:40~ □ TOKYO MX ビッグオーダー  
04/15(金) 26:25~ □ TBS マギ シンドバッドの冒険  
04/16(土) 07:00~ □ TBS カミワザ・ワンダ  
04/17(日) 10:00~ □ テレビ東京 カードファイト!! ヴァンガードG -ストライドゲート編-(第7期)  
12歳。
このご時世にこんなコテコテの少女漫画をゴールデンでやるとは思いませんでしたよ。
Re:ゼロから始める異世界生活
これまでの所意外と面白い。
くまみこ
良い滑り出しですが今後次第でしょうか。
マクロスΔ
私はマクロスがあまり好きではないのかなぁと良く思います(←マクロスは2が良いと思っている人間)。
ネトゲの嫁は女の子じゃないと思った?
はがないみたいな雰囲気。
坂本ですか?
坂本カッコいい可笑しい。
夏目友人帳シリーズセレクション
第5期を前に復習ですね。夏目は良い話もそれほどでもない話も沢山あるので、つまみ食いでまた見られると良い感じ。
ニンジャスレイヤー
お話しの芯は意外としっかりしているかもしれない。
2016-04-07

自宅デスクトップPC部品注文

前回がこのあたりだから、ちょうど5年過ぎたところですね。なんかSATAまわりが調子悪いんですよ……。まぁ、そろそろWindows10にもしたかったので。

それにしてもPC高いですね。円相場の影響もあるのか、いや、CPU良いのを選んでいるからなのか(Core i7-6700)、さりげなくメモリ多め(DDR4 16GB)とかケースもそれなりとか(Fractal Design Define R5)、誘惑に負けてSSD買ってしまったり(1TB!)とか……。まぁ、でもBlu-rayドライブは使い回すし、GPUもとりあえず外付けしない方向で。M/BはASUS H170M-PLUS。

15インチのセカンドディスプレイ(RDT156M)も調子悪くて電源がなかなか入らないし、セカンドディスプレイがないと別なことをしながら録画を消化できないので番組改編期は辛いし、これも新調すべきなんだろうけど、今更15インチ買っても仕方ないしかといって23インチ並べるのも場所取るしどうしたら良いんだろう。

10万円手に入れるのにどれだけ苦労するのか考えると散在する気も失せるけど、仕事で使うものでもあるし仕方ないよね。

ソフトウェアのインストール・セットアップがまた面倒くさいし、データのコピーもしなければならず。MSDNはProにダウンしているのでOfficeどうしようとかも。なんだかいろいろ気が重い。

新しいPC買ったのにネガティブ全開なんて、なんだか歳なんですかね。

まぁ、でも、SSDになるので快適になると良いなぁ。ノートはSSDですけど、やっぱり自宅だとノートよりもデスクトップを使ってしまうので。

2016-03-01

Diredで一部の詳細(属性、ユーザ名、グループ名)を隠す(ファイルサイズと日時は残す)

Emacs24.4 から dired-hide-details-mode が使えるようになりましたが、ファイル名以外全部隠すんですね。極端だってば。いや、それが良いときもありますけど。

普段欲しい情報はファイルサイズと日付くらいでしょうか。属性(パーミッション等)、ユーザ名、グループ名は日頃の作業(一人用PCの非root作業)では意識する必要がないでしょう。しかし、これだけを隠すのは一筋縄ではいかないようです。

diredはいろんな動作がバッファ上のテキストに依存しています。例えばディレクトリかどうかはバッファにdという文字があるかどうかで判断していますし、マーク自体もバッファに*が付いているかで記録しているくらいです。なので、不用意に文字を消すと動作に支障を来してしまいます。

lsコマンドの引数を指定する dired-listing-switches という変数がありますが -l オプションを省くことは出来ません。gを指定すればグループ名くらいは消せます(全てのアクションが正しく動作するかは不明)。

それでは dired-hide-details-mode はどうやって情報を消しているかというと、文字列を存在させたまま非表示にすることで実現しています。実装を見ると dired-insert-set-properties関数 でバッファ上のテキストに invisibleプロパティ を設定しています。そしてそのdired-insert-set-properties関数は、diredバッファ上のテキストに次の三種類のシンボルをinvisibleプロパティとして設定します。

  • dired-hide-details-information (バッファ先頭の残り容量などの行)
  • dired-hide-details-detail (ファイルの詳細情報の部分)
  • dired-hide-details-link (シンボリック情報の部分)

それらのシンボルに対して dired-hide-details-update-invisibility-spec関数add-to-invisibility-specやremove-from-invisibility-spec を使うことでinvisible状態を変化させています。(GNU Emacs Lisp Reference Manual: Invisible Text)

さて、どうしましょうか。

理想的には dired-hide-details-detail を細分化すべきでしょう。

  • dired-hide-details-detail-perms
  • dired-hide-details-detail-links
  • dired-hide-details-detail-user
  • dired-hide-details-detail-group
  • dired-hide-details-detail-size
  • dired-hide-details-detail-time

といった具合に。

(setq dired-hide-details-parts '(perms links user group size time))

というリストを作っておけば、次のコードでこれらのシンボルが得られます。

(mapcar
 #'(lambda (part) (intern (concat "dired-hide-details-detail-" (symbol-name part))))
 dired-hide-details-parts)

表示する部分を指定するリストを次のように定義します。

(setq dired-hide-details-visible-parts '(size time)) ;;sizeとtimeのみ表示

実際にこれらを使ってinvisibleプロパティを操作するには次のようにします。

(mapc
 #'(lambda (part)
     (funcall
      (if (memq part dired-hide-details-visible-parts) 'remove-from-invisibility-spec 'add-to-invisibility-spec)
      (intern (concat "dired-details-s-" (symbol-name part)))))
  dired-hide-details-parts)

と、このような理屈で詳細をさらに詳細に非表示に出来るようにする dired-details-s.el を作成しました。

2016-03-01-dired-details-s-1.png

うまくパーミッション等だけを消せたのですが、うーん、どうにも見た目がダサいような。バッファの左端にいきなり右寄せの数字が現れるせいでしょうか。日時、サイズの順に並べればもう少し良くなると思います。順番を入れ替えるにはinvisibleプロパティだけでは実現できないので大変なのですが、それが出来たとしても根本的な解決にはならない無い気もします。ファイル名は左端、詳細情報はその右に表示するのが普通ではないでしょうか。エクスプローラにせよ、昔ながらのファイラーにせよ、少なくともデフォルトはそうなっているような気がします。

というわけで、頑張って詳細情報をファイル名の右に表示させてみたのが dired-details-r.el です。

2016-03-01-dired-details-r-1.png

うん、こんなもんでしょう。

もはやinvisibleプロパティだけでは対処できないので、ファイル名にオーバーレイを適用してafter-stringプロパティで文字列を表示しています。

その弊害がいくつか。

  • Font Lockで色づけできない(代わりの手段を提供)
  • カーソルの移動に不自然な所あり(左右移動でオーバーレイの右に出ると左に戻れないことがある。Dired側でもカーソルの動きを多少制限しているので、その兼ね合いか?)
  • オーバーレイの削除のタイミングが難しい(沢山のファイルがあると効率的に心配)
  • たまにレイアウトが崩れるかも?(元々?)

文字列は自分で組み立てているので自由な順番にカスタマイズできます。 わざわざ最大文字幅を計算してレイアウトし直しているので。 あらかじめ設定した組み合わせを'('キーでローテート出来ます。

あまりに長いファイル名が数個あるために全体が空白だらけになってしまうのを防ぐため、レイアウト上の最大幅を設定できるようにしました。レイアウトは崩れますが、見やすさを確保することが出来ます。

参考:

2016-01-27

今年の抱負

早いもので今年ももう1ヶ月経とうとしています。

去年は遊びすぎたので、今年はもう少し生産的なことに時間を使いたいなと思っております。いや、色々遊びたいネタも沢山あって、それはそれでやりたいのですが、もう少しメリハリをつけたいものです。選択と集中ってやつです。というわけで、お仕事お待ちしております(笑)

2016-01-26

トーストの進化

トーストを焼くようになってから、少しずつバリエーションが広がっています。

ピザ用チーズを常備しておけばトーストなら何にでも合います。これまでは自宅でほとんどパンを食べなかったのでチーズを買う気がしなかったのですが、食べるようになったら一袋買っても3~4週間くらいで使い切れました。

キューピーのあえるだけミートソースは一人分を手軽に使えるので常備しているのですが、それを使ってピザトーストにしてみたり。一人分100円弱くらいするので少し勿体ない気もしますが。

冷凍庫に冷凍ほうれん草が眠っていたので、それをチーズと一緒にしてみたり、卵と混ぜてみたり。

今日は卵とほうれん草に加えてこれまで使った具材を混ぜ合わせて焼いてみたら、ほとんどキッシュのようなトーストができあがりました。

  1. 皿の上でソーセージ1本を包丁で薄く輪切りにする
  2. 小さな耐熱容器に冷凍ほうれん草を入れて電子レンジで1分ほど加熱する
  3. 2に塩、胡椒、卵1個、マヨネーズ、ピザ用チーズ、1のソーセージを加えて混ぜ合わせる
  4. 皿の上にパンを乗せて、中心を広めに強く押して凹ませ、凹んでいないところにマーガリンを塗る
  5. パンの上に3を乗せて具材が偏らないように広げる
  6. しっかり焼く
  7. (゚д゚)ウマー

食べた瞬間、これキッシュじゃん! って思いました。ほうれん草のキッシュは大好きでパン屋で見かけるとつい買ってしまうのですが、何かもうこれでいいや~と思うほどの出来です。

検索すると同じようなものが結構ヒットしますね。なるほど牛乳を入れるのですか。でも牛乳を入れなくてもかなりキッシュっぽいですがチーズのおかげ?

それにしても、料理が苦手な私でも続いているのはひとえに手軽さ故ですね。

洗い物を極力出さないようにしています。なので使う食器は、小さな耐熱容器とパンが乗る皿、それと包丁、後は箸のみ。

調理方法も電子レンジとトースターのみ。

卵はトースターだけだとなかなか中まで固まらないので、先に電子レンジにかけて目玉焼きにしてから乗せるなどしています(穴開けとラップ推奨)。卵1個をパン2枚で使うなら、薄く伸ばせるのでトースターだけでも何とかなるかもしれません。

結局オーブンレンジのトースト機能を使用しています。温まりにくいためか少し時間はかかりますが、一応使えてます。

食材も今のところ日持ちがして一人ですぐに使い切れるもの、食べちゃわなきゃーとプレッシャーにならないものを使っています。いつ飽きるか分からないので。

食材は消費期限・賞味期限に十分注意して購入していますが、パンだけは仕方が無いですね。スーパーの中でできるだけ消費期限が先のものを買うようにしています。冷凍するのは面倒なので。冷凍するならレンジで半解凍して後はトースターで何とかする感じなのでしょうか。レンジしすぎてふにゃふにゃベトベトになったパンが大嫌いなんですよね。トースターと併用できるようになった今なら、正確な時間を掴めば何とかなるのかな。