VSCode の Emacs keymaps 拡張についてのメモ
概要
Visual Studio Code で Emacs 風の操作を提供する拡張をいくつか試したが細かいところで違和感があったので、その覚え書きをメモしておく。
自分が本当に望む Emacs 風の操作を実現するためには、やはり自分で拡張を作成しなければならないようだ。NotKyon さんの Emacs Friendly Keybindings - Visual Studio Marketplace から fork するか、Pull Request を投げるのが一番目的に近いように思われる。
tuttieee さんが、かなり理想に近い Awesome Emacs Keymap - Visual Studio Marketplace を作成してくださったので、これを使っていこうと思います!!! (2019/1/11追記)
Keymap 調査
Emacs 風にする拡張はぱっと検索しただけで11個も見つかる。はたしてどれが良いのだろうか?
- なお、現在使用している Emacs Friendly Keymap 以外は短時間しか使用していない
- 最終更新日が2017年以前のものは、開発停止ということにしておく
hiro-sun 系
Emacs 風拡張のうち、最も古いと思われるものが hiro-sun のものであり、その派生物も多く存在する。派生物はだいたい共通の欠点を持ち、自分のニーズに合っていない部分もよく似ている。
- 全体的な特徴
- Emacs Keymap - Visual Studio Marketplace (2016/2/16 ~ 11/10) 開発停止
- hiro-sun
- Emacs Keymap Improved - Visual Studio Marketplace (2017/7/23 ~ 8/25) 開発停止
- rkwan94, Robert Kwan (forked from hiro-sun)
- cons:
- マウスで範囲選択後に M-w しても、範囲選択状態が継続してしまう
- Emacs HJKL - Visual Studio Marketplace (2017/6/7 ~ 22) 開発停止
- dotWaldemr, Waldemar D. (forked from hiro-sun)
- cons:
- 移動が HJKL
- 明示的に fork していないが、実際には hiro-sun のものからの fork だと思われる
- Emacs Mininum Keymap - Visual Studio Marketplace (2018/6/19)
- jamesyang999, futurist (forked from hiro-sun)
- cons:
- 移動系のコマンドのみを実装
- Emacs Keybindings with S-exp - Visual Studio Marketplace (2018/8/22 ~ 23)
- haruhi-s (forked from hiro-sun)
SebastianZaha 系 (forked from hiro-sun)
- Emacs Friendly Keymap - Visual Studio Marketplace (2017/3/9 ~ 10/10) 開発停止
- SebastianZaha, Leaping Frog Studios (forked from hiro-sun)
- 現在使用中
- Emacs - Visual Studio Marketplace (2018/4/8)
- VSCodeEmacs (forked from SebastianZaha (forked from hiro-sun))
- cons:
- ドキュメントが存在しない
- 明示的に fork していないが、実際には SebastianZaha のものからの fork だと思われる
- Emacs Friendly Keybindings - Visual Studio Marketplace (2018/12/2)
- NotKyon (forked from SebastianZaha (forked from hiro-sun))
- pros:
- C-x 2 (split-window-below), C-x 3 (split-window-right) の画面分割が Emacs とほぼ同じ
他の拡張と同時に使用するもの (2019/1/4追記)
- Emacs Candies - Visual Studio Marketplace (2017/7/31) 開発停止
- Giyya Pan
- Emacs Keymap (hiro-sun) と同時に使用する
- cons:
- cursorHome, killToEndOfLine を付け加えているのみ
- EmacsPigmee - Visual Studio Marketplace (2018/3/5 ~ 6)
- naturallucky
- Emacs Friendly Keymap (SebastianZaha) と同時に使用する
そのほか
- emacs-region - Visual Studio Marketplace (2016/4/2 ~ 2017/7/17) 開発停止 (2019/1/4追記)
- t-yng
- cons:
- M- 系のキーバインディングがほとんど定義されていない
- emacs-functions - Visual Studio Marketplace (2016/11/4 ~ 2017/2/18) 開発停止
- VSmacs - Visual Studio Marketplace (2017/2/26 ~ 11/25) 開発停止
- kpping, Krittanan Pingclasai
- cons:
- M- 系のキーバインディングが定義されていない
- VSCode Emacs Flavor - Visual Studio Marketplace (2018/5/25 ~ 6/2)
- tommas1988, Tommas Yuan
- cons:
- M-f, M-b が動作しない (エラーメッセージが表示される。bug?)
- emacs-region - Visual Studio Marketplace (2018/6/10) (2019/1/4追記)
- ayrtonmassey, Ayrton Massey (forked from t-yng)
- cons:
- M- 系のキーバインディングがほとんど定義されていない
- Emacs Extras - Visual Studio Marketplace (2018/10/5 ~ 12/7) (2019/1/4追記)
- youngderekm, Derek Young
- cons:
- ごく一部の機能しか実装されていない
- Awesome Emacs Keymap - Visual Studio Marketplace (2019/1/6 ~ 11) (2019/1/11追記)
- tuttieee, Yuichiro Tsuchiya
- pros
- Multi Cursor 機能と相性が良いように作られている
- C-x 2 (split-window-below), C-x 3 (split-window-right) の画面分割が Emacs とほぼ同じ
- この拡張単体で動作する (aki77は単体では定義されていない機能が多い)
- cons
- いくつかのバグ or 未実装 (issue を投げた)
macOS 専用 (2019/1/12追記)
- vscode-emacs-ergomac - Visual Studio Marketplace (2018/3/15) (2019/1/4追記)
- RumataEstor, Dmitry Belyaev (forked from SebastianZaha (forked from hiro-sun))
- SebastianZaha のものから C- を ⌘- に置き換えたもの。
- nemacs - Visual Studio Marketplace (2016/7/1 ~ 15) 開発停止 (2019/1/4追記)
- Tiny Emacs - Visual Studio Marketplace (2018/7/8 ~ 24)
- aki77
Emacs Keymap (hiro-sun) と同時に使用する (ドキュメントに書かれていないので推測)- いままで誤解していたのだが、この拡張はおそらく macOS 専用。VSCode を macOS で使用する場合は、デフォルトのカーソル移動キーが Emacs っぽいバインディングになっているらしいのでそのあたりはわざわざ定義していないと思われる (2019/1/12追記)
- pros:
- Multi Cursor 機能と相性が良いように作られている
- Multi Cursor で複数の選択範囲を有している際に、C-f で選択範囲を拡大したり C-b で選択範囲を縮小したりできる
- C-x 2 (split-window-below), C-x 3 (split-window-right) の画面分割が Emacs とほぼ同じ
- Multi Cursor 機能と相性が良いように作られている
- cons:
- デフォルト機能と被るキーは定義されていない (C-f など)
Keymap ではないものの調査 (2019/1/4追記)
以下のものは、Keymap を構成せず、コマンドだけを追加する。そのため、自分で Keyboard Shortcuts (keybindings.json) を設定しなければならない。 (試用していないので、実際に期待通りの動作をするのかどうか不明)
- VS Code Mark/Point - Visual Studio Marketplace (2016/1/5) 開発停止
- set-mark-command
- multi-cursor-emacs-mark - Visual Studio Marketplace (2017/8/23 ~ 9/2) 開発停止
- set-mark-command 関連のコマンド。Multi Cursor をサポートしている。
- vscode-emacs-tab - Visual Studio Marketplace (2017/11/15 ~ 12/2) 開発停止
- TAB を入力したときの挙動を Emacs っぽく (indent-for-tab-command) するコマンド
C# の double の %
C# 5.0 の double の % がなんか仕様とは異なる値を返す気がするという話。
Download C# Language Specification 5.0 from Official Microsoft Download Center C# 5.0 の言語仕様によれば、
7.8.3 Remainder operator
- Floating-point remainder:
double operator %(double x, double y);z is the result of x % y and is computed as x - n * y,
where n is the largest possible integer that is less than or equal to x / y.
とのことなので、n = Floor(x / y) のハズ...。でも実際は Truncate っぽい動作をする。
static void ReminderOperatorDoubleFloor() { var x = -5.2; var y = 2.0; var n = System.Math.Floor(x / y); var z = x - n * y; Console.Out.WriteLine("FLOOR: x = {0}, y = {1}, n = {2}, z = {3}, x % y = {4}", x, y, n, z, x % y); // => FLOOR: x = -5.2, y = 2, n = -3, z = 0.8, x % y = -1.2 } static void ReminderOperatorDoubleTruncate() { var x = -5.2; var y = 2.0; var n = System.Math.Truncate(x / y); var z = x - n * y; Console.Out.WriteLine("TRUNCATE: x = {0}, y = {1}, n = {2}, z = {3}, x % y = {4}", x, y, n, z, x % y); // => TRUNCATE: x = -5.2, y = 2, n = -2, z = -1.2, x % y = -1.2 } static void ReminderOperatorInt() { var x = -52; var y = 20; var n = x / y; var z = x - (x / y) * y; Console.Out.WriteLine("INT: x = {0}, y = {1}, n = {2}, z = {3}, x % y = {4}", x, y, n, z, x % y); // => INT: x = -52, y = 20, n = -2, z = -12, x % y = -12 }
で、実際どんな式が使われてるの、というと Math.IEEERemainder(Double, Double) Method (System) | Microsoft Docs の Remarks に書かれているが、Abs を使った上で Floor して符号は後から追加している。でも仕様には Abs 使うなんて書いてないじゃん!*1
C++11 の正規表現ライブラリの曖昧さ
libstdc++ の regex が実装されたそうです。
- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631#c17
- http://ww.reddit.com/r/cpp/comments/1nqxg5/regular_expression_support_c11_regex_in_libstdcv3/
- http://gcc.gnu.org/?20131008212833
そこで、仕様の曖昧な点(2点)を調査して纏めました。
GitHub Pages 機能を使ったことが無かったので、試しに使ってみようということで上記のところで公開してあります。
gh-pages ブランチの中で symlink を作っても、GitHub Pages で公開されたページでは symlink は辿ってくれないようでした。そのため、ちょっとだけ修正が必要でした。
正規表現で [a-[:alpha:]] の意味って?
C++11 の仕様に対する疑問
C++11 の正規表現 (std::regex_constants::ECMAScript 時) の仕様は ECMA-262 の文法を次のように微妙に変更したものとなっています。
ClassAtom ::
-
ClassAtomNoDash
ClassAtomExClass
ClassAtomCollatingElement
ClassAtomEquivalence
ClassAtomExClass ::
[: ClassName :]
ClassAtomCollatingElement ::
[. ClassName .]
ClassAtomEquivalence ::
[= ClassName =]
ClassName ::
ClassNameCharacter
ClassNameCharacter ClassName
ClassNameCharacter ::
SourceCharacter but not one of "." "=" ":"
(ドラフト n3337.pdf より)
そして ECMA-262 の正規表現の文字クラス周りの文法はだいたい以下のような感じになっています。
CharacterClass ::
[ [lookahead ∉ {^}] ClassRanges ]
[ ^ ClassRanges ]
ClassRanges ::
[empty]
NonemptyClassRanges
NonemptyClassRanges ::
ClassAtom
ClassAtom NonemptyClassRangesNoDash
ClassAtom - ClassAtom ClassRanges
NonemptyClassRangesNoDash ::
ClassAtom
ClassAtomNoDash NonemptyClassRangesNoDash
ClassAtomNoDash - ClassAtom ClassRanges
ClassAtom :: (ここは C++11 の仕様で変更される)
-
ClassAtomNoDash
ClassAtomNoDash ::
SourceCharacter but not one of \ or ] or -
\ ClassEscape
ClassEscape ::
DecimalEscape
b
CharacterEscape
CharacterClassEscape
(Standard ECMA-262 より)
ここで、強調した部分、つまり以下の部分
ClassAtom ::
ClassAtomExClass
NonemptyClassRanges ::
ClassAtom - ClassAtom ClassRanges
NonemptyClassRangesNoDash ::
ClassAtomNoDash - ClassAtom ClassRanges
を素直に解釈すると、例えば次のような正規表現は文法上正しいということになります。
[a-[:alpha:]] [[:alpha:]-a] [[:alpha:]-[:alpha:]]
文法上は正しいといっても、何を表現しているのか意味がよくわかりません。
現実の実装では?
例えば、Boost C++ Libraries ではテストケース (test_sets.cpp) 内で、以下のようなテストをしており、
TEST_INVALID_REGEX("[a-[:alpha:]]", boost::regex::extended);
問題となる正規表現を記述できないことを確かめています。
また、OS X Mountain Lion の clang-425.0.28 では、
#include <regex> #include <iostream> int main() { std::locale::global(std::locale("C")); std::regex re("[a-[:alpha:]]"); std::cout << std::boolalpha << regex_match("a", re) << std::endl; std::cout << std::boolalpha << regex_match("b", re) << std::endl; return 0; }
上記のソースを -std=c++11 -stdlib=libc++ でコンパイルして実行すると
が出力されます。なにが起こったのかよくわかりません。
true
false
また、Visual Studio 2012 Express では上記のソースを実行すると std::regex のコンストラクタ内で std::regex_error 例外が .code() == std::regex_constants::error_range で throw されます。
まとめ
というわけで、この問題は C++11 の仕様の間違いとして解釈するのが良いと思います。
zshのデフォルトの補完の定義を使わないことにした
zshで以下のように設定しておくと
autoload -Uz compinit
compinit
様々な補完がデフォルトで定義されますが、ほとんどの定義は自分には不要であることが最近分かってきました。
むしろ
make ファイル名
と実行したいのにファイル名を補完できないなど、不便な点のほうが目立ちます。
compinit を行わなければデフォルトの補完も定義されないので上記のような不便はないのですが、その代わり補完候補に色が付かなくなってしまうのでそれはそれで不便です。
そこで、compinit を実行した上で不要な定義をばっさり削除することにしました。
autoload -Uz compinit compinit # ほとんどの補完の定義を削除する。 # special contexts の定義のみ残す (see: man zshcompsys) fix_comp_assoc() { local var=$1 shift for key in "$argv[@]"; do case $key in -redirect-,\<,*) unset "${var}[$key]";; -redirect-,\>,*) unset "${var}[$key]";; -value-,-*) ;; -value-,*) unset "${var}[$key]";; -*) ;; *) unset "${var}[$key]";; esac done } fix_comp_assoc _comps "${(k)_comps[@]}" fix_comp_assoc _services "${(k)_services[@]}" fix_comp_assoc _patcomps "${(k)_patcomps[@]}" fix_comp_assoc _postpatcomps "${(k)_postpatcomps[@]}"
compinit では、補完する時にどのようなコンテキストでどのコマンドを利用するという一覧は _comps, _services, _patcomps, _postpatcomps という連想配列に格納されるようです*1。そこで、それらの定義の中から special contexts の定義以外をばっさり削るようにしました。
これで
make ファイル名
も実行可能になり、快適zshライフを送ることができそうです。
# しかし、もっと良いやりかたがありそうなものですが…
*1:これらの変数のデフォルトの内容は ~/.zcompdump へダンプされているのでそこで確認するのが楽です
Storyboardsを使っている時のUITableViewのdequeueReusableCellWithIdentifier:の挙動
UITableViewのdequeueReusableCellWithIdentifier:がnibからCellを自動的に作成してくれるように見える挙動はどこで説明されているんだ?
2012-02-28 19:12:22 via web
@ganaware 発見。Storyboardsを使っているとき限定の機能なのね。 URL
2012-02-28 19:39:16 via web to @ganaware
この情報に行き当たるのに苦労したのでメモ
はてなブックマーク/COOKPAD画像表示(Chrome拡張)
はてなブックマーク/COOKPAD画像表示 - Chrome Web Store
はてなブックマークでCOOKPADのレシピをブックマークしている場合に、レシピの写真を一緒に表示してくれる拡張です。先日ふと思い立って作ってみました。
Greasemonkeyでも書ける内容の拡張ですが、Chrome拡張として作りました。なんとなく。