指定ディレクトリの下の写真をランダムにiTermの背景設定するコマンドができた。
https://gist.github.com/shokai/872e375c0b0636b0c2ae


Enterキーを押す毎に画像を切替えるようにzshを設定してみたらすごい疲れる感じになった。これでアニメgifが再生できたら最高だったんだけどただの静止画になってしまう。

写真.appの中身をランダムに表示している。写真.appの顔認識機能が作ったサムネイルも読み込まれるせいで、たまたま撮った写真に写っている知らない人の顔ドアップサムネイル画像もたまに表示されて誰コイツ感がある。
定期的にtumblrとかから画像を取ってきても楽しそう。


ふつうにプログラムを書いたりしているところ


JXA

AppleScriptの代わりにJavaScriptで書けるというJavaScript for Automationを使ってみた。Yosemiteから使える。公式名称ではないがなぜかJXAと呼ばれているらしい。

JavaScript for Automation Release Notes

ES6も微妙にサポートされていて、分割代入とspread operatorが動いた。
var [a,b] = ["foo","bar"]; // a="foo" b="bar"とそれぞれ代入される
[1,2,3,...[4,5,6]]; // [1,2,3,4,5,6]になる
Promiseオブジェクトはあるけど「Event loop not supported.」というエラーが出て使えない。
setTimeoutとsetIntervalは無い。ブロックするdelay(秒)がある


iTerm2

iTerm2 – Mac OS Terminal Replacement

デフォルトのTerminal.appと違ってMacのウニョーンエフェクトなしでフルスクリーンモードにできるので気に入ってる。あと背景を半透明にできるので裏のドキュメントを透かしながら見れるのが便利。

AppleScriptからの操作のドキュメントがある。
https://iterm2.com/applescript.html


AppleScriptでiTermの背景を変える

引数に渡した画像ファイルが背景画像になる。
iterm-bg-image.applescript
#!/usr/bin/osascript
on run argv
set img to item 1 of argv

tell application "iTerm"
tell the current terminal
tell the current session
set background image path to img
end tell
end tell
end tell
end run


JavaScript for Automation (JXA) でiTermの背景を変える

上のAppleScriptをJXAで書き直すとこうなる。
tell applicationのかわりにApplicationという関数があったりする。AppleScriptの文法は8割方理解してないんだけど、とりあえずキャメルケースで接続していけば良いっぽい。

iterm-bg-image.js
#!/usr/bin/osascript -l JavaScript

function run(argv){
var img = argv[0];
var app = Application("iTerm");
app.currentTerminal.currentSession.backgroundImagePath = img || null;
}
backgroundImagePathにnullを入れると背景をクリアできる。JSだとこういうのも書きやすい。

ディレクトリ内からランダムに背景指定する


指定パスがディレクトリかの判定はNSFileManagerを使った。ディレクトリの下のファイルの列挙はdoShellScriptでlsやfindを呼んだ。

-rオプションを付けるとサブディレクトリの下の画像も探すようにした。
iterm-bg-image.js
#!/usr/bin/osascript -l JavaScript

var fm = $.NSFileManager.defaultManager;

function run(argv){
var [path, opts] = parseArgv(argv);
var img = getImagePath(path, opts.r);
console.log(img);
setImage(img);
}

function parseArgv(argv){
var path = null;
var opts = {};
argv.forEach(function(arg){
var match = arg.match(/^\-+(.+)$/);
if(match){
opts[match[1]] = true;
}
else{
path = arg;
}
});
return [path, opts];
}

function getImagePath(path, recursive){
if(!path) return;
var ref = Ref();
var exists = fm.fileExistsAtPathIsDirectory(path, ref);
var isDirecotry = ref[0];
if(!exists) return;
if(!isDirecotry) return path;
var files = getImagesInDirectory(path, recursive);
return files[Math.floor(Math.random()*files.length)];
}

function getImagesInDirectory(path, recursive){
path = path.replace(/\/$/, "");
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var files = [];
if(recursive){
files = app.doShellScript("find '"+path+"'").split(/\r/);
}
else{
files = app.doShellScript("ls '"+path+"'").split(/\r/)
.map(function(f){
return path+"/"+f;
});
}
return files.filter(function(f){
return /\.(jpe?g|gif|png|bmp)$/i.test(f);
});
}

function setImage(img){
var app = Application("iTerm");
app.currentTerminal.currentSession.backgroundImagePath = img || null;
}


Enterキーを押す毎に背景を変える


参考:zshでコマンドが空の状態でenter押したときに任意のコマンドを実行する方法 – kei_q


写真.appに入っている写真を適当に表示する

.zshrc
function iterm-bg-image-random(){
zle accept-line
if [[ -z "$BUFFER" ]]; then
$(iterm-bg-image ~/Pictures/写真\ Library.photoslibrary -r > /dev/null 2>&1 &)
fi
}
zle -N iterm-bg-image-random
bindkey '^m' iterm-bg-image-random