⌨️

使用しやすい、Dvorak配列を考える

2024/12/18に公開

はじめに

 Qiita Advent Calendar 2024 の「⌨ ぼくのかんがえたさいきょうのきーぼーど ⌨」の18日目の投稿です。

Dvorak配列とは?

 疲労軽減を期待できる、キーボード配列。

My Custom Dvorak

 以下を参考に、カスタムキーマップを作成。

レイヤー


Layer0


Layer1


Layer3


Layer4


Layer5


Layer6


Layer7


Layer8

コンボ

 Dvorak配列の場合、kの入力での運指、lsコマンドなど使用する際、小指がきつい。どちらも、Combosで対応。lキーをCombosでしか使っていないので、削除しても問題ないかもしれない。

同時押し キー
h + t k
c + r l

Shortcut key

 Dvorak配列を使用すると、ショートカットキーはメチャクチャになる。karabiner-elementsで、ショートカットキーをQwertyと同じ位置にして対応。

変換例(押された時に、上書きされるように設定している)

 以下は一部の変換例で、すべてのショートカットキーを上書きしています。

変換前 変換後
cmd + ' cmd + z
cmd + q cmd + x
cmd + j cmd + c
cmd + k cmd + v
cmd + x cmd + b

Karabiner-Elementsの設定を作る

 雑にスクリプトを書き、キーマップを作成する。

karabiner.ts
export class Karabiner {
  static karabinerDescription(title: string, description: string, result: string[]) {
    return {
      title: title,
      rules: [
        {
          description: description,
          manipulators: result,
        },
      ],
    }
  }

  static mandatoryKeymap(fromKey: string, toKey: string, mandatory: string[]) {
    return {
      type: 'basic',
      from: {
        key_code: fromKey,
        modifiers: {
          mandatory: mandatory,
        },
      },
      to: [
        {
          key_code: toKey,
          modifiers: mandatory,
        },
      ],
    }
  }

  static jpMode(fromKey: string, toKey: string) {
    return {
      type: 'basic',
      from: {
        key_code: fromKey,
      },
      to: [
        {
          key_code: toKey,
        },
      ],
      conditions: [
        {
          type: 'input_source_if',
          input_sources: [
            {
              language: 'ja',
            },
          ],
        },
      ],
    }
  }

  static toggle(lan: string, fromKey: string, toKey: string, opt: string[]) {
    return {
      type: 'basic',
      conditions: [
        {
          input_sources: [
            {
              language: lan,
            },
          ],
          type: 'input_source_if',
        },
      ],
      from: {
        key_code: fromKey,
        modifiers: {
          optional: opt,
        },
      },
      to: [
        {
          key_code: toKey,
        },
      ],
    }
  }

  static generateMandatoryKeymap(from_layout: string[][], to_layout: string[][], mandatory_keys: string[][]): object[] {
    const res: object[] = []
    for (let i = 0; i < from_layout.length; i++) {
      const row_from = from_layout[i]
      const row_to = to_layout[i]
      for (let j = 0; j < row_from.length; j++) {
        const col_from = row_from[j]
        const col_to = row_to[j]
        for (const mandatory of mandatory_keys) {
          res.push(this.mandatoryKeymap(col_from, col_to, mandatory))
        }
      }
    }
    return res
  }
}

 キーの配列を変数に格納。

const mandatory = [
  ['command'],
  ['command', 'shift'],
  ['control'],
  ['control', 'shift'],
  ['option'],
  ['option', 'shift'],
]

const programmer_dvorak = [
  ['semicolon', 'comma', 'period', 'p', 'y', 'f', 'g', 'c', 'r', 'l'],
  ['a', 'o', 'e', 'u', 'i', 'd', 'h', 't', 'n', 's'],
  ['quote', 'q', 'j', 'k', 'x', 'b', 'm', 'w', 'v', 'z'],
]

const qwerty = [
  ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
  ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'quote'],
  ['z', 'x', 'c', 'v', 'b', 'n', 'm', 'comma', 'period', 'slash'],
]

const expected_mandatory_keymap = {
  title: 'Programmer Dvorak Qwerty',
  rules: [
    {
      description: 'Programmer Dvorak Qwerty',
      manipulators: [
        {
          type: 'basic',
          from: {
            key_code: 'semicolon',
            modifiers: {
              mandatory: ['command'],
            },
          },
          to: [
            {
              key_code: 'q',
              modifiers: ['command'],
            },
          ],
        },
        {
          type: 'basic',
          from: {
            key_code: 'semicolon',
            modifiers: {
              mandatory: ['command', 'shift'],
            },
          },
          to: [
            {
              key_code: 'q',
              modifiers: ['command', 'shift'],
            },
          ],
        },
        {
          type: 'basic',
          from: {
            key_code: 'semicolon',
            modifiers: {
              mandatory: ['control'],
            },
          },
          to: [
            {
              key_code: 'q',
              modifiers: ['control'],
            },
          ],
        },
        ...
        以下省略
      ],
    },
  ],
}

test('mandatoryKeymap', () => {
  const keymap = Karabiner.generateMandatoryKeymap(programmer_dvorak, qwerty, mandatory)
  const result = {
    title: 'Programmer Dvorak Qwerty',
    rules: [
      {
        description: 'Programmer Dvorak Qwerty',
        manipulators: keymap,
      },
    ],
  }

  const expected = expected_mandatory_keymap

  expect(result).toEqual(expected)
})

使用してきた、キーボード

Moonlander


カメラスタンドで角度をつけてみた

GrabShell

HHKB Studio


キーキャップを変えてみた

Keyball39


持ち運びしやすい

Voyager


デスクにアームで取り付け


right


left

おわりに

 分割キーボードを使うことで肩こりが解消され、さらにDvorak配列に移行したことで指の疲労が軽減されました。

Discussion