Vimperatorとlivedoor Readerの連携で羅列型ニュースサイトを読みまくるぜ!

 VimperatorにfeedSomeKeys.jsプラグインを導入してからというもの、livedoor Readerでのフィード消化がとても快適になりました。特に威力を発揮するのは1つのページ内でリンクを羅列していくタイプのサイトにおいてです。従来のLDRでは記事単位/permalink単位しかキーボードで操作することができませんでした。しかしVimperatorとの連携によって記事中のリンクの操作が可能になったのです。これはすごい。

 などと書いたところで、それで何が嬉しいのかあんまり伝わらない気はします。なので、実際にどういう作業を行っているのか。その流れをスクショ付きで書いてみました。例がまなめはうすなのは言及するとリンク貼られると風の噂で聞いたので。


 rssで全文配信してないニュースサイトの場合、fでLDR Full Feedを起動。

 読み込み中…

 展開できた。Jを連打して読み進めていく。戻るのはK。

 読みたい記事がある時は;tでヒントを起動。

 リンクがハイライトされ番号が振られる。例えば女装メイド喫茶の記事が読みたければ;t18と入力すると新規タブで開く。同じ要領でリンクを開きまくる。

 開いたタブを確認するには:lsで。

 とりあえずタブは放置しておいてsとaを連打してLDRを掘っていく。ちょっと重くなってきたかなと感じるか、レートの区切れまで読んだかなどしたらタブを読みにいく。gtで隣のタブへ。面白ければdirect_bookmark.jsはてブにpost。読み終わったらxで閉じる。あとはこの繰り返し。

 
 feedSomeKeysについてはretlet.net - Vimperatorと、ウェブアプリやUserscriptのショートカットキーを共存させるfeedSomeKeys.jsプラグインを参照のこと。

 なんでこんな変なキーバインドになってるんだ?と思われた方は昨日の日記を参照のこと。ちょっと長い上に読み難くて申し訳ないんですが。

_vimperatorrc@0704

 _vimperatorrcを大分書き換えたので更新。主な変更点とかは以下。

  • いつも通りcodereposのdotfilesを参考に
  • feedSomeKeys.jsを入れたのでfmapを書いた
    • LDR Full Feedの為に多目的なgを殺すのはもったいないのでfmap f gとした。fは;oでも代用できる為
    • Minibuffer Bookmark Command のソースを書き換えてショートカットキーをb→Nにした後、LDR上にNを流した。LDR上でNを押すと一発ブクマ、それ以外でNを押すとVmiperatorデフォのキーバインドである「/や?で指定したパターンの後方検索」が優先される
      • ふつうにb押すとタブが開いてうっとうしかったのでこんな感じに
  • ホームページをLDRブックマークレットにした。gh→フィードを購読みたいな流れになってウマー
  • wildoptions=autoにした
    • exコマンドを実行する系のmapの補完を殺したりとかなんとか
  • wassrブームということでwassr.jsを入れたのでそれ関係とか
  • matanico.jsを入れた
    • 投稿時の要素の並び順をむぅもぉさんの本家「またニコニコ動画見てる」グリモンっぽくした
  • ,,スクロールを割り振った
    • splitBrowser使用時、メインのブラウザのフォーカスがLDRとかにあってキーがfmapに奪われていると、分割した側のブラウザでもキーが奪われてしまう。僕の設定だとjkJKあたりが使えなくなるのでその代わりとして
" noreply_vimperatorrc
" vimperator_1.2pre_2008-07-01.xpi	2008-Jul-01 07:30:04	234.2K	application/x-xpinstall
" http://vimperator.driftaway.org/

echo "loading..."

" / set /
set activate=
set complete=sl
set hintstyle+= font-size:15px;
set newtab=all
set preload
set scroll=5
set titlestring=Mozilla Firefox 3
set visualbell
set wildoptions=auto
set nextpattern+=next, 次(の)?ページ,\b次.*,→\b,下一頁,Следующая,・、・隹€
set previouspattern+=prev, 前(の)?ページ,\b前.*,\b←

" / set! /
set! browser.startup.homepage=javascript:location.href='http://reader.livedoor.com/subscribe/'+location.href
set! browser.tabs.closeButtons=3
set! browser.urlbar.filter.javascript=false
set! browser.urlbar.maxRichResults=50

" / normal mode /
noremap j 5j
noremap k 5k
noremap J <C-d>
noremap K <C-u>
noremap <C-j> <C-d>
noremap <C-k> <C-u>
map ,y mziggvGy<esc><esc>'z:delmarks z<CR>
"map gm :tabmove! +1<CR>
"map gM :tabmove! -1<CR>
"map \a :echo Application.extensions.all.map(function(e) e.name+" ("+e.id+")")<CR>
"map \l :ls!<CR>
"map \m :marks<CR>
"map \q :qmarks<CR>
"map ! :set invum<CR>

" / ex mode & insert mode /
cmap <C-n> <Tab>
cmap <C-p> <S-Tab>
cmap <C-f> <Right>
cmap <C-b> <Left>
cnoremap <C-v> <S-Insert>
inoremap <C-v> <S-Insert>

" / wildoptions=auto / http://unsigned.g.hatena.ne.jp/Trapezoid/20080620/1213961754
js <<EOM
[
	['!',':set invum'],
	['\\a',':echo Application.extensions.all.map(function(e) e.name+" ("+e.id+")")'],
	['\\b',':bicon'],
	['\\c',':colorschema'],
	['\\w',':wassr -footmark'],
	['\\l',':ls!'],
	['\\m',':marks'],
	['\\q',':qmarks'],
	['\\t',':twitter!?skashu'],
	[',b',':sbm'],
	[',m',':matanico'],
	[',s',':hatenastar 1'],
	['b',':hbinfo'],
	['W',':twitter watching %TITLE% - %URL%<'],
	['gb',':bentry'],
	['gB',':bentry!'],
	['gm',':tabmove! +1'],
	['gM',':tabmove! -1'],
].forEach(function([key,command]){
    liberator.mappings.addUserMap([liberator.modes.NORMAL], [key],
        "User defined mapping",
        function () { liberator.execute(command); },
        {
            rhs: key,
            noremap: true
        });
});
EOM

" / plugin /
" // browser_object.js //
map x dd

" // copy.js //
map c :copy<Space>
map C :copy hatenabookmark<CR> 
js <<EOM
liberator.globalVariables.copy_templates = [
  { label: 'titleAndURL',    value: '%TITLE% %URL%' },
  { label: 'title',          value: '%TITLE%' },
  { label: 'markdown',       value: '[%TITLE%](%URL% "%TITLE%")' },
  { label: 'markdownsel',    value: '[%SEL%](%URL% "%TITLE%")' },
  { label: 'htmlblockquote', value: '<blockquote cite="%URL%" title="%TITLE%">%HTMLSEL%</blockquote>' },
  { label: 'hatena',         value: '[%URL%:title=%TITLE%]' },
  { label: 'hatenabookmark', value: '<a href="%URL%">%TITLE%</a><a href="http://b.hatena.ne.jp/entry/%URL%"><img src="http://b.hatena.ne.jp/entry/image/%URL%" border=0></a>' },
  { label: 'hatenacite',     value: '>%URL%:title=%TITLE%>\n%SEL%\n<<' }
];
EOM

" // direct_bookmark.js //
let g:direct_sbm_use_services_by_tag = "h"
let g:direct_sbm_use_services_by_post = "h"
"map \b :bicon<CR>
"map ,b :sbm<CR>:echo "bookmarked!"
"map gb :bentry<CR>
"map gB :bentry!<CR>

" // hatenabookmark_show.js //
"map b :hbinfo<CR>

" // hatenastar.js //
"map ,s :hatenastar 1<CR>

" // ime_controller.js //
let g:ex_ime_mode = "inactive"
let g:textarea_ime_mode = "inactive"

" // ldrize_cooperation //
let g:ldrc_captureMappings = "['j', 'k', 'p']"

" // matanico.js //
let g:matanico_status_format='$SERVICENAME : $SUBJECT $URL ($PLAYTIME) $COMMENT'
"map ,m matanico.js

" // stylechanger.js //
let g:styles = "BrightFocus,Tooltip,LDR,LDR_Article,Tab,TumblrDashboardBigPhotos"
"map \c :colorschema<CR>

" // twitter.js //
map ,t :twitter<space>
map gf :twitter!+@
map gs :t twitter?<space>
"map \t :twitter!?skashu<CR>
"map W :twitter watching %TITLE% - %URL%<CR>

" // wassr.js //
map ,w :wassr<space>
"map \w :wassr -footmark<CR>

" // feedSomeKeys.js //
autocmd LocationChange .* :fmapc

" Gmail
js <<EOF
autocommands.add('LocationChange',/mail\.google\.com\/(mail|a)\//,[
  'js plugins.feedKey.setup(',
  '"c / y j k n p o u e x s r a # [ ] z ? gi gs gt gd ga gc".split(/ +/).map(function(i) [i, "4" + i])',
  ');'
].join(''));
EOF

" livedoor Reader/Fastladder
js <<EOF
autocommands.add('LocationChange',/reader\.livedoor\.com\/reader\//,
  'js plugins.feedKey.setup("j k s a p v c <Space> <S-Space> z Z < > q w i f u n B N".split(/ +/));');
EOF
js <<EOF
autocommands.add('LocationChange',/(fastladder\.com|0\.0\.0\.0\:3000)\/reader\//,
  'js plugins.feedKey.setup("j k s a p v c <Space> <S-Space> z Z < > q w".split(/ +/));');
EOF
autocmd LocationChange http://(reader\.livedoor\.com|fastladder\.com|0\.0\.0\.0\:3000)/reader/ :fmap o vj
autocmd LocationChange http://(reader\.livedoor\.com|fastladder\.com|0\.0\.0\.0\:3000)/reader/ :fmap J <Space>
autocmd LocationChange http://(reader\.livedoor\.com|fastladder\.com|0\.0\.0\.0\:3000)/reader/ :fmap K <S-Space>
autocmd LocationChange http://(reader\.livedoor\.com|fastladder\.com|0\.0\.0\.0\:3000)/reader/ :fmap f g

" Tumblr
js <<EOF
autocommands.add('LocationChange',/.*\.tumblr\.com\//,
  'js plugins.feedKey.setup("j k p o".split(/ +/));');
EOF
autocmd LocationChange http://.*\.tumblr\.com/ :fmap i tj

" / misc /
" ステータスバーにfeedボタンを表示
js <<EOM
(function () {
var feedPanel = document.createElement('statusbarpanel');
var feedButton = document.getElementById('feed-button');
    feedPanel.setAttribute('id','feed-panel-clone');
    feedPanel.appendChild(feedButton.cloneNode(true));
    feedButton.parentNode.removeChild(feedButton);
    document.getElementById('status-bar')
        .insertBefore(feedPanel,document.getElementById('security-button'));
})();
EOM

" ページのアクセスキーを無効化
js <<EOM
 liberator.options.setPref('ui.key.generalAccessKey', 0);
EOM

" タブの属性除去
js <<EOF
(function(){
var tabs = getBrowser().mTabs;
for (var i=0; i<tabs.length; i++){
  ['width','maxwidth','minwidth','flex'].forEach(function(attr)tabs[i].removeAttribute(attr));
}
document.getElementById('content').addEventListener('TabOpen',function(e){
  var t = e.originalTarget;
  ['width','maxwidth','minwidth','flex'].forEach(function(attr)t.removeAttribute(attr));
},false);
})();
EOF

"source! ~/_vimperatorrc.local

echo "done"

_vimperatorrc晒す

 昨日Firefox3がリリースされた。これを機にVimperaotorを使ってみようという人もいると思うので参考までに_vimperatorrcを晒してみる。プラグインへの依存度が高いのでまずは使わせて頂いているプラグインを列挙。ほぼ/lang/javascript/vimperator-plugins/trunk - CodeRepos::Share - Tracから入手可。

 browser_object / copy / direct_bookmark / gmail_biff / gmperator / hatenabookmark_show / hatenaStar / ime_controller / ldrize_cooperation / ldrize_cooperation_fetch_flv / lookupDictionary / splitBrowser / stylechanger / twitter / twitterView / walk-input

 ちなみにVimperatorの最新版はここから。以下、コメントをほとんどつけていなくて不親切ですが、日本語ヘルプなどを参照しながら読んでみてください。

" _vimperatorrc
" vimperator_1.2pre_2008-06-19.xpi	2008-Jun-19 07:30:05	233.3K	application/x-xpinstall 
" http://vimperator.driftaway.org/

" / set /
set activate=
set complete=sfbhS
set hintstyle+= font-size:15px;
set newtab=all
set preload
set scroll=5
set titlestring=Mozilla Firefox 3
set visualbell
set nextpattern+=next, 次(の)?ページ,\b次.*,→\b,下一頁,Следующая,・、・隹&#128;
set previouspattern+=prev, 前(の)?ページ,\b前.*,\b←

" / let /
let g:direct_sbm_use_services_by_tag = "h"
let g:direct_sbm_use_services_by_post = "h"
let g:ex_ime_mode = "inactive"
let g:ldrc_captureMappings = "['j', 'k', 'p']"
let g:styles = "BrightFocus,Tooltip,LDR,LDR_Article,TumblrDashboardBigPhotos"
let g:textarea_ime_mode = "inactive"

" / map /
" スクロール
noremap j 5j
noremap k 5k
noremap J <C-d>
noremap K <C-u>

" バッファ移動
noremap gm :tabmove! +1<CR>
noremap gM :tabmove! -1<CR>

" sbm
map B :sbm<space>[
map bb :hbinfo<CR>
map bi :sbm [niconico][idolm@ster][mad][
map bv :sbm [niconico][vocaloid][
map by :sbm [niconico][music][mashup][吉幾三][

" Copy
map ca :copy anchor<CR>
map cb :copy hatenabookmark<CR>
map cc :copy hatenacite<CR>

" Twitter
map wf :twitter *<space>
map wl :twitter<CR>
map wr :twitter d rtm<space>
map ws :tabopen twitter?<space>
map wt :twitter<space>

map ww :twitter! watching %TITLE% - %URL%<CR>


" その他
map ga :echo Application.extensions.all.map(function(e) e.name+" ("+e.id+")")<CR>
map gl :ls!<CR>
map gr :m pinned-or-current-link | reblog | clear-pin<CR>
map gs :hatenastar 1<CR>
map gy mziggvGy<esc><esc>'z:delmarks z<CR>
map I <C-q>
map x dd
map ! :set invum<CR>

" / ex mode /
cmap <C-n> <Tab>
cmap <C-p> <S-Tab>
cmap <C-f> <Right>
cmap <C-b> <Left>

" / Javascript /
" ステータスバーにfeedボタンを表示
javascript <<EOM
(function () {
var feedPanel = document.createElement('statusbarpanel');
var feedButton = document.getElementById('feed-button');
    feedPanel.setAttribute('id','feed-panel-clone');
    feedPanel.appendChild(feedButton.cloneNode(true));
    feedButton.parentNode.removeChild(feedButton);
    document.getElementById('status-bar')
        .insertBefore(feedPanel,document.getElementById('security-button'));
})();
EOM

" disable accesskey
javascript <<EOM
liberator.options.setPref('ui.key.generalAccessKey', 0);
EOM

echo ".vimperatorrc sourced"

柏木博『モダンデザイン批判』

モダンデザイン批判

モダンデザイン批判

 著者はムサビの教授。書き下ろし。以下メモとか。

  1. 思考する《もの》 近代におけるものは視覚的イメージを用いたコミュニケーションツールであり、言語と同じくらい重要。デザインはものを扱う。
  • 近代は何をめざしたか 近代の理想は人間主義。「誰でも等しく」がキーワード。スラム(貧困)をなくす為に都市計画がされ、健康のために料理学校が作られた。「誰でも等しく」を体言するのがバウハウスの普遍的デザイン。
  1. 消費される欲望 広告=デザインが欲望を組織化する。個人主義
  2. 廃棄か回収か 家事に関する教育は衛星と健康の為に始まった。廃棄のグローバル化(経済的に豊かな国が商品を受け取り、貧しい国がごみを受け取る)。リサイクルはシステム。
  3. モダンデザイン批判を批判する カウンターカルチャーポストモダン。近代の理想の挫折と問題の回避。
  4. デザインするアメリカ フォーディズムは重要。アメリカ式生産=消費様式は冷戦を背景に発達し伝播した。インターネットはアメリカ化、グローバル化だ。
  5. モダンデザインの彼方へ モダンデザインは近代の理想を体現し、挫折した。システムの一元化はあぶれる人を生み出すからだ。だからといってモダンデザインを否定するのではなく(ポストモダン)、意味を再解釈してリサイクルする必要がある。

 もの・デザインの観点から哲学書などを引用しつつ近代史をまとめてみたといった趣の本。テーマは硬めだけど、文章が読みやすいので新書を読む程度の集中力で一応読み通せた。図版が少ないので、その辺はネットか図書館でカバーする感じで。

 消費という言葉の語源について書いてある箇所があって、面白かったので引用しておく。注を読むとスチュアート&エリザベス・イーウェン『欲望と消費』(小沢瑞穂訳)を引いているらしいので孫引用ですが。

 レイモンド・ウィリアムズの研究を引きながら、スチュアート・ユーインは、「消費する」という言葉はフランス語が起源で、元は略奪を意味していたのだと説明している。また消費という言葉は、「完全に取り上げる」「むさぼり食う」という意味で使われたのだという。破壊し、浪費し、枯渇させるといった悪しき意味を持っていた。現在でも、結核を意味するコンサプション(consumption)は消費という意味でもあり、その悪しき意味を遺している。それが、十七世紀に世界市場経済が広がっていく中で、「使い切る」ことが商業的繁栄を意味するようになり、好ましい意味を持ちはじめた。現在、アメリカ的消費社会の中にあって、消費という言葉は、まったく悪しき意味は失われ、むしろ肯定的に使われている。

欲望と消費―トレンドはいかに形づくられるか

欲望と消費―トレンドはいかに形づくられるか

 サブテキストとしてこれもぱらぱらと眺めてみた。イメージを大まかに掴むのに役に立った。

バウハウス (タッシェン・建築デザインシリーズ)

バウハウス (タッシェン・建築デザインシリーズ)

ジョージ・R・R・マーティン『王狼たちの戦旗』

王狼たちの戦旗 (上) (氷と炎の歌 2)

王狼たちの戦旗 (上) (氷と炎の歌 2)

王狼たちの戦旗 (下) (氷と炎の歌 2)

王狼たちの戦旗 (下) (氷と炎の歌 2)

  • 大長編ファンタジー小説氷と炎の歌」の2巻目。
  • 国盗りですよ、国盗り!
  • シブサワ・コウ プレゼンツとか巻頭に出てきても違和感ない。
  • 乱世である!
  • 視点人物の切り替え=ターン制のシミュレーションみたいなイメージ。
  • 1巻はそうでもなかったけど2巻からは魔法とかもちょこちょこ出てくる。しかしそれでゲームバランスがぶっ壊れる、ということもなくて、むしろ大概不利な勢力が一発逆転する為に使うなどバランス調整に使われてる感。
  • 最後まで出てこなかった老騎士バリスタン・セルミー。好きなキャラだったので次巻以降に期待。
  • 小鬼(インプ)ティリオン・ラニスターはヤン・ウェンリーや新城直衛の如く王都の防衛と治安維持に奔走するんだけど、誰からも褒められず、かつ手柄を親父に取られてすごい残念なことに。こういう報われなさが共感を生むのだけど。

コマンドラインモードのコマンドとcmap関連

2008.05.17 16:21追記:
 id:teppeisからコメントを頂いたので追加。

行頭移動は でできますよ。



 標準で使えるコマンドラインモードのコマンドはだいたいこんな感じ。

コマンド 内容
1文字左へカーソル移動
1文字右へカーソル移動
1単語左へカーソルを移動
1単語右へカーソル移動
or 行頭へカーソル移動
or 行末へカーソル移動
or 1文字削除
1単語削除
行削除
補完(順方向)
補完(逆方向)
ヴィジュアル選択左へ
ヴィジュアル選択右へ

 ヴィジュアル選択後、y打ってもヤンクできないのでフツーにでコピーなどする。
 この状態だとちょっと使いので_vimperatorrcにcmapを追加。

" / ex mode /
cmap
cmap
cmap
cmap

 これでホームポジションから手を動かす量がやや減る。行頭へカーソル移動がでしかできない(多分)けど、あんまり使わんだろうということで放置。