git-credential-manager-coreのインストール場所が Git for Windows 2.36.1で変更されていた
WSL2の git認証の手間を省くために git-credential-manager-coreを使っているが, Git for Windows 2.36.1でインストールパスが変わっており, pushや pullをしたりしようとすると file not found
と出るようになってしまった. パスは次のように変わっていました.
C:/Program Files/Git/mingw64/libexec/git-core/git-credential-manager-core.exe
から
C:/Program Files/Git/mingw64/bin/git-credential-manager-core.exe
に変わっていた. 古い記事を参照しようとするとハマるので注意.
変更が行われた PRはこれ.
WSL2内の .gitconfigを下記のように変更しておいた.
[credential] helper = "/mnt/c/Program\\ Files/Git/mingw64/bin/git-credential-manager-core.exe"
emacs 28.1で導入された repeat-modeに関する調査
はじめに
最近まともに追っていなかったから存在さえ知らなかったのだけど、markdown-modeの issueでそういう機能があってどういうものかと使い方を調べてみた.
機能
特定のコマンドのグループを連続でお手軽に実行するための仕組み. 例えば移動系コマンドで次に移動が C-c n
, 前に移動が C-c p
みたいな場合毎回 C-c n
, C-c p
と叩くの面倒くさい。一方的に進む、戻るのであれば数値プレフィックスがあるが Vimのように数だけ押せばいいとわけじゃないし、進んだり戻ったりと繰り返したい場合などは使えない。そこで使えるのが repeat-mode
。repeat-mode
を使って初回実行だけは C-c n
だが以降は n
, p
でそれぞれ移動するということが実現できる.
myuheさんが作られた smartrep.elに近い.
使い方
repeat-mode
を有効にする- キーマップを定義する
- 起点となるコマンドの
repeat-map
属性に定義した keymapを設定する
repeat-mode
を有効にする
;; global minor modeです (repeat-mode +1)
グループで使いたいコマンド郡のキーマップを定義する
(defvar git-gutter-repeat-map (let ((map (make-sparse-keymap))) (define-key map (kbd "n") 'git-gutter:next-hunk) (define-key map (kbd "p") 'git-gutter:previous-hunk) map))
コマンドの repeat-map
属性を設定する
(put 'git-gutter:next-hunk 'repeat-map 'git-gutter-repeat-map) (put 'git-gutter:previous-hunk 'repeat-map 'git-gutter-repeat-map)
実行例
repeat-mode起点となるコマンドを実行すると minibufferに
Repeat with` と表示され, 該当するキーマップが有効になる.
おわりに
導入されたばかりということもあってか標準パッケージではほとんど使われておらずごく一部のモードで使われていませんでした。標準ライブラリで汎用的な機能を提供してくれるのはありがたいけど、どのコマンドをグルーピングするかとかは好みによるところもありそうなのでライブラリ側で設定すべきなのか個人で設定すべきなのかまだよくわかっていない。個人で設定する場合は smartrepなどに比べるとコード量が多くそれほど良いものではないのかなという気もしている。今後の使われ方を見て markdown-modeでどうするかなというのを考えていきたいかな。
LinkedIn Learningの Rust Code Challenges をやった
課題がいくつかあって解いて解説を見てという感じのコース。コードの雛形は githubに用意されているので, 足りていないところ埋めてテストが通れば OKという感じ.
かっちりしたコースではなく解説はわりとグダっていたり雛形のコードに微妙に問題があったりというケースがあったのでクオリティが高いものとは決して言えなかった. でもまあ 3rd partyライブラリを使ったり, そこそこ実用的なものもあり Rustで何を書いたらいいかわからんという自分には少しプラスになったかなとは思った. Rustの基本を習得してその後何か少し発展的なものを書いてみたいという人にちょうどいいぐらいかなと思った。
Ubuntuで VSCodeの Quick Fixが使えなかった問題の調査と修正
VScodeには Quick Fixという機能があって, Rustとか Goの traitとか interfaceを実装する際の雛形の生成に使えるのですが, そのショートカットである Ctrl + .
が Ubuntuで効かなかったのでその原因の調査と修正を行った.
バインドされているキーを探す
gsettings list-recursively
を使ってショートカット一覧を出力し, Ctrlがバインドされているキーを探す.
% gsettings list-recursively | grep "<Control>" org.freedesktop.ibus.panel.emoji hotkey ['<Control>period', '<Control>semicolon'] org.freedesktop.ibus.panel.emoji unicode-hotkey ['<Control><Shift>u'] org.gnome.Terminal.Legacy.Keybindings close-tab '<Control><Shift>w' org.gnome.Terminal.Legacy.Keybindings close-window '<Control><Shift>q' org.gnome.Terminal.Legacy.Keybindings copy '<Control><Shift>c' org.gnome.Terminal.Legacy.Keybindings find '<Control><Shift>F' org.gnome.Terminal.Legacy.Keybindings find-clear '<Control><Shift>J' org.gnome.Terminal.Legacy.Keybindings find-next '<Control><Shift>G' org.gnome.Terminal.Legacy.Keybindings find-previous '<Control><Shift>H' org.gnome.Terminal.Legacy.Keybindings move-tab-left '<Control><Shift>Page_Up' org.gnome.Terminal.Legacy.Keybindings move-tab-right '<Control><Shift>Page_Down' org.gnome.Terminal.Legacy.Keybindings new-tab '<Control><Shift>t' org.gnome.Terminal.Legacy.Keybindings new-window '<Control><Shift>n' org.gnome.Terminal.Legacy.Keybindings next-tab '<Control>Page_Down' org.gnome.Terminal.Legacy.Keybindings paste '<Control><Shift>v' org.gnome.Terminal.Legacy.Keybindings prev-tab '<Control>Page_Up' org.gnome.Terminal.Legacy.Keybindings zoom-in '<Control>plus' org.gnome.Terminal.Legacy.Keybindings zoom-normal '<Control>0' org.gnome.Terminal.Legacy.Keybindings zoom-out '<Control>minus' org.gnome.desktop.wm.keybindings cycle-panels ['<Control><Alt>Escape'] org.gnome.desktop.wm.keybindings cycle-panels-backward ['<Shift><Control><Alt>Escape'] org.gnome.desktop.wm.keybindings switch-panels ['<Control><Alt>Tab'] org.gnome.desktop.wm.keybindings switch-panels-backward ['<Shift><Control><Alt>Tab'] org.gnome.shell.extensions.screenshot-window-sizer cycle-screenshot-sizes ['<Alt><Control>s'] org.gnome.shell.extensions.screenshot-window-sizer cycle-screenshot-sizes-backward ['<Shift><Alt><Control>s']
org.freedesktop.ibus.panel.emoji
に '<Control>period'
がアサインされており, こちらにキーが取られ VScodeの方が効いていないと予想される
ibusのショートカットを変更する
ibus-setup
で ibusの設定画面を起動, emoji
タブが下記のようになっていることを確認する
絵文字を直接使うことはまずないし, 使ったこともないのですべて削除した.
最後に
これで VScodeで Ctrl+.
でショートカットが効くようになりました.
merge sort in F#
merge sortを何も見ずに書けるかが気になって書いてみたが特に問題なく書けた. この手の問題は筋トレと同じでいかに普段手を動かして解いている感があるので, leetcodeなどは継続していた方がいいのかなと思った.
open System let generateNumbers (n: int) : int list = let rec generateNumbers' n (r: Random) acc = if n = 0 then acc else generateNumbers' (n - 1) r (r.Next(0, 100) :: acc) generateNumbers' n (new Random()) [] let merge a b = let rec merge' a b acc = match a, b with | [], [] -> acc |> List.rev | h :: t, [] -> merge' t b (h :: acc) | [], h :: t -> merge' a t (h :: acc) | h1 :: t1, h2 :: t2 -> if h1 < h2 then merge' t1 b (h1 :: acc) else merge' a t2 (h2 :: acc) merge' a b [] let rec mergeSort (nums: int list) = let len = nums.Length if len <= 1 then nums else let half = len / 2 let a = nums |> List.take half |> mergeSort let b = nums |> List.skip half |> mergeSort merge a b let nums = generateNumbers 100 let got = mergeSort nums let expected = List.sort nums // true got |> List.zip expected |> List.forall (fun (a, b) -> a = b)
zero length array, flexible array
たまたま目に入ったこのコードを見ていて, zero length arrayって末尾のメンバ以外でも使えたんだって思って気になるところを調べてみた.
Flexible array
C99から入った機能. 配列の長さを宣言しないことで利用できる. sizeofはできない. 構造体などの末尾フィールドに置くことができる. 典型的な使い方は以下のような感じ.
struct Data { // some fields SomeData s[]; }; struct Data *d = malloc(sizeof(Data) + some_arbitrary_size);
ポインタを使ってしまうと構造体とこの末尾のデータがある場所は別の領域になってしまうわけだが, このようにすることで連続するメモリにすべて割り当てることができる.
構造体の末尾以外に置くことはできない
struct Data { int a[]; int b; };
このようなコードはエラーとなる
a.c:2:7: error: flexible array member not at end of struct 2 | int a[]; |
Zero length array
GCC拡張. C90時代から使えたもので, 宣言時に配列サイズを 0とする. Flexible arrayと違い構造体に何個でも宣言でき, GCCでは sizeofを行った場合 0が返るものと規定している.
struct Data { int a; unsigned char b[0]; int c[0]; };
このように宣言した場合, b
と c
は同じ先頭アドレスを持ち実質的に union
のようになる.
#include <stdio.h> #include <stdlib.h> struct Data { int a; unsigned char b[0]; int c[0]; }; int main() { struct Data *d = malloc(sizeof(int) * 2); printf("&d.a=%p\n", &d->a); printf("&d.b=%p\n", &d->b); printf("&d.c=%p\n", &d->c); d->b[0] = 0; d->c[0] = 0xdeadbeef; printf("d.b[0]=%x\n", d->b[0]); printf("d.c[0]=%x\n", d->c[0]); return 0; }
結果は以下の通りで
&d.a=0x559613d242a0 &d.b=0x559613d242a4 &d.c=0x559613d242a4 // cは bと同じアドレス d.b[0]=ef // cを書き換えると bも変わってしまう d.c[0]=deadbeef
Flexible array, zero length arrayを使わない場合
今時そんな環境はないと思うが, C99以前かつ GCC拡張が使えない場合は長さ 1の char配列などを置いて代用していたように記憶している.
その他
上記の変更が含まれる PRにあった non temporalって何ぞやと思ってググると下記の解説があった.
Non-temporal in this context means the data will not be reused soon, so there is no reason to cache it.
とのこと. streamな dataで, 非常に計算速度が重要なものになるとそこまで意識する必要があるんですね. 計算する際キャッシュにうまく載せることは考えたことあったけど不要なものはそもそも載せないという発想がなかった.
いろいろ学びがあった.
markdown-fontify-whole-heading-line
markdown-mode
に markdown-fontify-whole-heading-line
flagを実装した. 機能としては org-fontify-whole-heading-line
と同じで, non-nilの場合 header lineを丸々一行色付けできるようになる. 特に emacs 27で追加された faceの extend
属性を non-nilにして, 背景色を設定すればその行をすべて色付けできる. (補足 extend
属性が nil
だと文字がある部分までしか色付けされない)
設定は以下のようになる
(setq markdown-fontify-whole-heading-line t) (set-face-attribute 'markdown-header-face-1 nil :extend t :background "green" :foreground "black") (set-face-attribute 'markdown-header-face-2 nil :extend t :background "pink" :foreground "black")