US配列 on JP109キーボードの感想

JP109キーボード上でUS配列にしてしばらく使ってみているが、特に問題はない。一部のショートカットキーがUS配列で押しやすいから割り当てられたんだろうなぁと気づくぐらいだった。

Mozcのローマ字テーブルを一部作り直し

JP109キーボードを前提としていた自作ローマ字テーブル(DvorakY改)を変更が必要になった。

  • 長音のキーが、":"から"'"にする。コレはキーの位置も変わらないので問題ない。
  • 小文字入力時のJIS配列で"@"の場所にあったキーが"["に変わってしまい、"「"が入力されるので使えなくなった。*1

@による小文字入力は殆ど使っていなかったので、少し遠くなるが"\"に割り当てることにした。

JP109キーボード上のUS配列にあわせたキーバインドにする

US配列でEscキーをどうするかを考えることになった。コレまでは、半角/全角をEscとしていたので、Escが遠くなってしまった。((日本語入力切り替えは、無変換/変換キーで行うMac流を使ってます。

で考えた結果、過去にCaps LockをEscとしたこともあるが今回は、"カタカナ/ひらがな"をEscとすることにした。以前と同様に、https://honmushi.com/2019/01/18/ubuntu-xkb/に書かれている方法でキーバインドを変更した。

setxkbmap -print > ~/.xkb/keymap/mykbd とした結果、下記となった。 +myswap(swapkeys) が以前と同様に追記した部分でswapは行為と変更内容が一致しないのだけど、昔の設定が残っているので流用した。

xkb_keymap {
        xkb_keycodes  { include "evdev+aliases(qwerty)"	};
        xkb_types     { include "complete"	};
        xkb_compat    { include "complete+japan"	};
        xkb_symbols   { include "pc+au+inet(evdev)+terminate(ctrl_alt_bksp)+myswap(swapkeys)"	};
        xkb_geometry  { include "pc(pc105)"	};
};

~/.xkb/symbols/myswapは、以下にした。Escは念の為に全角半角、メニューキーはxmonadのためにSuper_R(Winキー)としておいた。

partial modifier_keys
xkb_symbols "swapkeys" {
    replace key <MENU> { [ Super_R ] };
    replace key <HKTG> { [ Escape ] };
    replace key <ESC> {[ Zenkaku_Hankaku, Kanji ] };
};

プログラムを起動させる場所を集約させておきたかったので、xmonadから下記コマンドを実行させるようにした。 $DISPLAY~の環境変数がなぜか引き継がれていないようなので ~:0 と手書きしている。

xkbcomp -I$HOME/.xkb ~/.xkb/keymap/mykbd :0 2> /dev/null

この結果、日本語入力時のテーブルが以下のようになった。日本語入力中はシフト入力で同一キーに複数の機能をもたせることはさせない方針です。

DvorakY改:US配列用、Jp109キーボード対応

*1:例えば、"@a"で"ぁ" が入力されるようにローマ字テーブルを定義していた。普通のローマ字入力で"la"の"L"の代わり。

Rust By ExampleのFrom and Intoが分かりにくい

The From and Into traits are inherently linked, and this is actually part of its implementation. If you are able to convert type A from type B, then it should be easy to believe that we should be able to convert type B to type A.

Rust By Exampleに上記が書いてあるので、型Aから型Bへの変換と、型Bから型Aへの変換の両方ができると誤解してしまった。

写経してみると、into()もfrom()もi32をNumberへ変換しているので同じじゃないかとなる。誰かが解説書いているだろと思い、探すとhttps://dackdive.hateblo.jp/entry/2021/04/30/100000が見つかり、やっぱりそうかと納得できた。

use std::convert::From;

#[derive(Debug)]
struct Number {
    value: i32,
}

impl From<i32> for Number {
    fn from(item: i32) -> Self {
        Number { value: item }
    }
}

fn main() {
    let num = Number::from(30);
    println!("My number is {:?}", num);
    let int: i32 = 5;
    let num: Number = int.into();
    println!("My number is {:?}", num);
}

US配列とJIS配列の違い

キー配列に関して、自分の経験ではUS配列とJIS配列の間には特に違いを感じない。

かつて、US配列のマシンとJIS配列のマシンが混在する環境で過ごしていた時期があり、毎日違うマシンを使っていたので、その日にならないとどちらの配列を使っているかわからなかった。最初は混乱したが、すぐに両方に慣れてしまった。

むしろ、QWERTY配列からDvorak配列にすることにこだわった方が有意義だ。昔にDvorak配列を常用していた経験から言うと、ショートカットキーがDvorak配列を使う上での最大の障害だったが、それでも利用価値があると思う。

そこで、久しぶりにUS配列を使ってみることにした。キーボードを買い替えるまでの志はないので、ソフト的に配列を変更することにした。

Manjaro Setting Managerにあるキーボードの設定を眺めてみると、English(Austraria)配列がJISキーボードをUS配列として使ったときに近いことに気づきました。"\|"の位置がUS配列と異なる点がありますが、それほど大きな問題ではないと思います。

Manjaro LinuxでEnglish(Austraria)のキー配列に設定した

設定変更後の/etc/vconsole.confの内容は以下になっていた。

FONT=
FONT_MAP=
XKBLAYOUT=au
XKBMODEL=layouts
XKBOPTIONS=terminate:ctrl_alt_bksp

Xの設定は以下になっていた。

Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "au"
        Option "XkbModel" "layouts"
        Option "XkbOptions" "terminate:ctrl_alt_bksp"
EndSection

ちなみに、X11のAustraliaはUSの名前を変えただけだった。

// Keyboard layout for Australia.

// The default Australian layout is the same as the American.
default partial alphanumeric_keys
xkb_symbols "basic" {
    include "us(basic)"

    name[Group1]= "English (Australia)";
};

で、調べてみると同じことをしている人が何人もいて、Macを中心にする人がいるみたい。
https://note.com/kamemushi_works/n/n65ab71ca98ec

オーストラリアってこんな変なキーボードを標準で使っているの?と疑問に思い、検索したところ、https://geekscallout.com.au/what-keyboard-layout-does-australia-use/によると、US配列を使っているみたい。

なんでUK配列とUS配列の間の子がEnglish(Australia)と称されているのかは謎のままだ。

設定変更した後日、ログインするとキー配列の変更が反映されなかったので調べた。結論は、Fcitxがキー配列を奪っていた。*1
fcitx5-configtool を起動して、アドオン > XCB 設定と入り

  • システムXKB設定のオーバーライドを許可する
  • 常にレイアウトをグループレイアウトのみにする

の両方のチェックを外す。コレによりキー配列設定が設定したとおりに出来た。

*1:キーボード入力関連で変なことが起きたら大体、Fcitxを疑っておけば間違いない気がする。

forループでイテレータ into_iter() が所有権を奪う

for x in vec と書くと暗黙的に、into_iter()が呼ばれてvecは所有権を失ってしまう。forで暗黙的に呼ぶのなら、所有権を奪わないiter()の方が良かったんじゃないと思い、AI先生に理由を聞いた。どうも、into_iter()が効率がよく、所有権の管理が明確になるという2点がポイントだそうだ。
AI先生は嘘つきだから、どうせ誰かが検証しているだろうと検索してみた。https://dawn.hateblo.jp/entry/2017/07/24/165933によると、確かに、iter()のほうが誤差程度で遅いらしい。大きなデータ構造ではもう少し差がでるのだろう。

let vec = vec![1, 2, 3];
let vec_iter = vec.iter();
for x in vec_iter {
    println!("{}", x);
}
// まだvecは有効
println!("{:?}", vec);

let vec = vec![1, 2, 3];
for x in vec {
    // vec.into_iter()が呼ばれた
    println!("{}", x);
    //println!("{:?}", vec); 当然、使えない
}
// ここでvecは使えなくなる
//println!("{:?}", vec);

PRIMERGY TX1310 M1のメモリを16GBへ拡大

メモリが4GBの状態でデスクトップクライアントとして使用していると、油断した際にメモリ不足で固まることがあった。この問題に耐えてきましたが、ついに我慢できなくなり、Non-ECCメモリを追加して16GBに増設しました。価格を見ると、DDR3 PC3-12800 8GB 2枚組が3000円以下で手に入ることも理由の一つでした。

メモリを交換した後、Manjaro Linuxに付属しているMemtest86+で確認を行いました。放っておいて気づいたら4周をPASSしていたので、これで問題ないと判断した。

Firefoxのタブを多数開いても特に問題は発生しないので、普通に使えるようになった。

Manjaro Linuxで"Ctrl+;"で起動するクリップボード履歴は何のアプリ

"Ctrl+;"で起動するクリップボード履歴が表示されることに気づき、調べたがわからなかったので検索したところ、以下のページで記述があった。

https://qiita.com/daisuke0604/items/29e3143555677c61d4d0

Fcitxのアドオンでクリップボード履歴を扱うって、Input Methodとしてどうなんと思う。

Rustの勉強を始めた

Rustの勉強をはじめました。もう何年も話題になっているRustに興味を持ったのは、GCCでRustのサポートが進んでいると聞いたからです。

環境設定

mozcのAURではRustが使われているようで、すでに rustup default stable まで実行済みだった。
https://wiki.archlinux.org/title/rustに書かれているIDE関連のツール群もインストールした。

rustup component add rust-analyzer
rustup component add rust-src
rustup component add clippy
rustup component add rustfmt

また、Visual Studio Codeにはrust-analyzerの拡張もインストールした。

勉強開始

The Rust Programming Language 日本語版

とりあえず、一切、手を動かすことせずに一通りを読んでみた。例外のないC++11とRubyHaskellを3身合体させた言語と思ったのが、第一印象だ。LISPの雰囲気は感じられない。

C++11や(POSIX)UNIXプログラミングの知識がない状態から、Rustを学び始めるのは少し難しいかもしれませんが、それでも、C++11よりはRustの方が簡単だと思う。

まだ理解が曖昧なので、コードを書く段階にはまだ至っていません。

Rustの最初のステップ − Training

https://learn.microsoft.com/ja-jp/training/modules/rust-introduction/ MicrosoftによるRustの解説です。トピックが絞られているので、こちらを先に読むとよかったかもしれない。演習も実際にビルドしてみて、自分の理解度を確認しました。まだ理解が不十分だなと感じたので、再度The Rust Programming Languageを読み直して、確認コードを書いていくことにした。

疑問に思ったこと

自分でサンプルコードなどを書いて、確認しないと正確に理解できないハズ。

なぜ&が必要

下のコードでは、なぜ「&"coconut"」のように & が必要なのかわからず、ChatGPT先生に聞いたが、よく理解できませんでした。その後、Microsoft Copilot先生に聞いたところ、だいたい理解できましたが、まだ正確な理解には至っていない。テストコードを書いて確認していく予定です。

let fruits = vec!["banana", "apple", "coconut", "orange", "strawberry"];
for &index in [0, 2, 99].iter() {
    match fruits.get(index) {
        Some(&"coconut") => println!("Coconuts are awesome!!!"),
        Some(fruit_name) => println!("It's a delicious {}!", fruit_name),
        None => println!("There is no fruit! :("),
    }
}

理解できなかったポイントは、get メソッドの戻り値が以下のようになっていることでした。

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output> 

fruits.get(index) は Option<&&str> を返している。そのため、Some("coconut") のようにすると、Option<&str> と一致しない。そのため、Some(&"coconut") のように & を付ける必要がある。

まだ疑問点はあるが、長くなりそうなので、別途調査してみます。

構造体定義のライフタイム注釈の必要性

構造体にライフタイム注釈をつけないと、確かにビルドエラーになるが、コンパイラがライフタイムを省略すればいいのではないかと思ってしまった。構造体のフィールドの参照先が必ず長生きしなければならないのは明らかですし、複数のフィールドがあっても同じです。何か理由があるはずですが、各種AIに聞いてもよくわからなかった。

関数のライフタイム注釈については、まあそういうものかなと納得できる。