秀丸エディタのアウトライン枠の幅や高さをマクロから変更する(できませんでした)

秀丸エディタのアウトライン枠の幅(高さ)をマクロから変更できるかもしれないと、ふとひらめいた。

秀丸エディタには「レジストリをいじる命令」と「秀丸エディタに再読込をかける命令」があるので、レジストリをいじった後で再読込をかけることで、マクロがサポートしてない設定変更も行えるようになる……と envchanged のヘルプに書いてあった。

試してみた。

結論

ダメだった。

レジストリについて

HKEY_CURRENT_USER\Software\Hidemaruo\Hidemaru\Outline

  • cx エントリ
    • REG_DWORD
    • 16進数
    • アウトライン枠左右表示時の横幅(pixel)
  • cy エントリ
    • REG_DWORD
    • 16進数
    • アウトライン枠上下表示時の縦幅(pixel)
  • Right エントリ
    • REG_DWORD
    • アウトライン枠の位置(0~3のいずれか)

Right の値と表示位置の対応

   2

 0   1

   3

書いたマクロ

// レジストリの cx を 5 だけ増やす
openreg "CURRENTUSER", "Software\\Hidemaruo\\Hidemaru\\Outline";
#cx = getregnum( "cx" );
#new_cx = #cx + 5;
writeregnum "cx", #new_cx;
closereg;

// 秀丸エディタにリロードをかける
envchanged;

// これで表示中の左端アウトライン枠が 5 pixel 伸びるはずだが……

実行結果

  • 再読込はされた
  • しかし 5 pixel 伸びることはなかった

なぜ動かなかったのか考えてみると、たぶん

秀丸エディタのマクロでは、[その他]-[動作環境]の内容を変更することができません。しかし、この文を使うとそれと同様のことができるようになります。

これが原因だと思われる。つまり 「アウトライン枠の幅(高さ)」という設定値はその他動作環境内には無いため、この envchanged のやり方は使えませんよ という可能性。

JavaScript 開発でよく使う Web ページやら Web サービスやら

フロント完結の小さな Web アプリというか Web ページというかツールを開発する時に、よくお世話になっているものたち。

オンラインコンパイラ Repl.it

左ペインで js 書いて Run したら、右ペインに結果が出るというもの。

配列操作、文字列操作、正規表現などが正しく動くかサクっと試行したい時などに重宝。

キーコード取得 JavaScript Event KeyCode Test Page

押したキーの KeyCode を表示するページ。

keydown、keyup などのイベント時に見る KeyCode の値を調べたい時に。

JSON 構文チェック JSONLint

jsonstring を貼り付けると、構文的に正しいかどうかを調べてくれる。

JSON フォーマット整形 JSON Formatter

jsonstring の pretty print 用。

リファレンス MDN

JavaScript の各種関数の使い方や仕様について知りたい時に。コード例からブラウザ毎のサポート状況が載っているので助かる。

利用時は Google で「javascript string replace」みたいに検索してアクセスすることが多い。検索しても出ない場合は「mdn」キーワードを引っ付ける。

Cheat Sheet(チートシート) とは何か

Cheat Sheet(チートシート)とはプログラマー用語で 見易く手頃サイズにまとまった「キーボードショートカットの一覧表」 のこと。

※Cheet Sheet ではない。ee ではなく ea が正しい。

Vim

おそらく最もチートシートが盛り上がっている分野。私も Vim を勉強していた頃は印刷して手元に置いておいた。

Visual Studio Code

最近使っている IDE、Visual Studio Code こと VSCode にもチートシートがあった。

Windows 10

Windows 10 の Windows キーコンビネーションに関するチートシート。Microsoft 公式。Word で書かれたファイルなのでブラウザからは読めない、いったんダウンロードしてから開くこと。

MacOS

CheatSheet - Know your short cuts

MacOS 用のチートシート を表示するアプリ。Command キーを 3 秒ほど長押しすると、チートシートが表示されるというタイプ。

チートシートの分類

以下三種類くらいあると思う。

  • Web ブラウザで読むもの
    • o 開くのが簡単
    • x 手元に置きづらい(印刷が考慮されたレイアウトになってない)
  • 印刷してから手元に置いておくもの
    • o 印刷して手元に置ける
    • x PDFなどフォーマットが少し煩わしい
  • アプリとして提供されているもの
    • o PCを離れることなく確認できる
    • x 印刷できない
    • x アプリのインストールが必要

チートシートの探し方

探したいツール名に「チートシート」やら「cheat sheet」といったワードをくっつけて検索する。

プログラマーやエンジニアが使うツールで、メジャーなツールであれば、たいてい見つかる。逆を言えばチートシートが見つからない = まだ成熟していない、と言えるかもしれない。

チートシートの語源は?

cheat sheet には元々カンニングペーパーといった意味がある。

秀丸エディタで「対応する括弧」の対応が正しく反映されない件

秀丸エディタで「対応する括弧」の対応が正しく反映されないことがあった。

わかってみれば単純なことだった。 コメント中に括弧が含まれていないか を確認すること。

前提

秀丸エディタ V8.58

クイズ

以下の Javascript コードは「対応する括弧」を狂わせる部分である。問題はどこか。

// prompt 出す系だとダイアログを閉じた直後に
//   if(('a_p' in stickflags) && keycode==K.P){
// この部分が通過しない( p の keyup が検出されない)せいで
// 「二度押さないともう一度ダイアログが出ない」現象が起きる.
// これを防ぐために, ここでクリアしてしまう.
delete stickflags['a_p'];

正解

// prompt 出す系だとダイアログを閉じた直後に
//   if(('a_p' in stickflags) && keycode==K.P){ ★ここ★
// この部分が通過しない( p の keyup が検出されない)せいで
// 「二度押さないともう一度ダイアログが出ない」現象が起きる.
// これを防ぐために, ここでクリアしてしまう.
delete stickflags['a_p'];

コメント中に括弧が表記されている。

対処方法

// prompt 出す系だとダイアログを閉じた直後に
//   if(('a_p' in stickflags) && keycode==K.P) ← ★ '{' を省いた
// この部分が通過しない( p の keyup が検出されない)せいで
// 「二度押さないともう一度ダイアログが出ない」現象が起きる.
// これを防ぐために, ここでクリアしてしまう.
delete stickflags['a_p'];

コメント中の括弧を省きましょう。

作者自身が贈る秀丸エディタ用アウトライナー houtliner の使い方のコツ

どうしても愛用の秀丸エディタでアウトライナーを実現したくて、つくったのが houtliner だったが、秀丸エディタの限界もあってあまり使い勝手がよろしくない。私自身も使うかどうか悩むレベルだったが、せっかくだからと使っていくうちに、使い方のコツがわかってきた。

というわけで記しておく。

前提

houtliner について既に知っているものとする。(この時点で日本に何人いるんだよって話だと思いますが 苦笑)

以下はこれまで公開した情報。

「タイトル」と「内容」を意識する

アウトライナーにおいては、各行の記述は二種類に分かれると思う。

「タイトル」と「内容」である。

  • タイトル → 俯瞰する時にも表示できる行
  • 内容 →俯瞰する時には表示させない行

タイトル行は折りたたみや目次ビューなどによって俯瞰表示できる。逆に内容行は表示されない。このような種類分けがあることで、「タイトルだけ表示する」という俯瞰が可能となる。アウトライナーでは箇条書きを並べるので、特定の単位でタイトルのみを表示させて俯瞰することは重要。これができないとキツイ。1000行の箇条書きは100行くらいで俯瞰したいのだ。

タイトルと内容は以下のように書く。

houtliner では、タイトルと内容は以下のように書く。

・・タイトル(セクション)
・タイトル(レベル1)
 ・タイトル(レベル2)
  ・本文(レベル3)
  ・本文(レベル3)
   ・本文(レベル4)
    ・本文(レベル5)

つまり セクション、レベル1、レベル2まではタイトルとして書く

逆に 本文はレベル3から書き並べる

なお、タイトルが思いつかない場合は「1」とか「2」とかダミーでいい。

以下に例を挙げる。

・・190311(Mon)
・ブログプロフィール検討
 ・結論
  ・2のプロフ案で下書きしてみるぞ
 ・2
  ・別のプロフ案試しに書いてみよか
  ・……
  ・……
 ・1
  ・なんか読みづらいんだよね
  ・何が読みづらい?あげてみ?
   ・……
   ・……

俯瞰する時はアウトライン枠で

アウトライナーの主な操作として

  • とりあえず書き殴っていく
  • 適当な単位で俯瞰する(セクションやレベル1など高い位置から全体を眺める)

があると思うが、houtliner は俯瞰が弱い。

1ペインだと一画面で両方できるが、houtliner は 1 ペインじゃない。折りたたみ機能(レベル2で全部折りたたむなど)もないので、1ペインみたいに編集画面上で俯瞰ができない。そこで houtliner では アウトライン枠 という別ペインを使っている。

アウトライン枠ではレベル2までを表示する 仕様なので、レベル2 までをタイトルとして書いておけ、というルールにすると、アウトライン枠が俯瞰ビューとして見やすくなる。逆にレベル2/レベル1/セクションに内容を書いてしまうと、俯瞰ビューも何百何千行となってしまい俯瞰の意味がなくなる。

シェイクは正直キツイです

アウトライナーの真価は Tak. さんが提唱する「シェイク」、つまりは特定の箇条書きの単位を自由にあちこちに移動させることにあると思うが、houtliner はこのシェイクが苦手だ。

並び替え自体はアウトライン枠で D&D でできるし、一応操作としても「一つ上に移動」みたいな操作を用意している。

しかし秀丸エディタは 並び替えを行うと、(折りたたんで表示していたとしても)折りたたみが強制的に解除される という致命的な欠点がある。

たとえばアウトライン枠で「レベル1のみ展開」にしていたとしよう。この時、アウトライン枠ではレベル1の単位で俯瞰できるようになる。となれば当然、並び替えもレベル1の単位で行うことになる。実際、並び替えは D&D で行える。問題はこの後だ。並び替えた後、当該部分の折りたたみが解除され、レベル2までズラリと展開されてしまう のである。レベル1のみ展開しろ、と設定しているにもかかわらず、強制的に解除されてしまうのだ。これが本当に鬱陶しい。

一文字目に x を書く場合は、前にスペースを

俯瞰とシェイクはこのくらいにして、別の話を。

houtliner ではタスクの完了を表現する文法がある。一文字目に x または x を書くと発動するが、これが「x から始まる文章」を書く時に鬱陶しい。

先頭にスペースを入れて回避してください。

・振り返り(良かったことは先頭に o を、悪かったことは先頭に x を書いてね)
 ・o 楽しかった
 ・o Aさんとしゃべれた
 ・x Bさんとしゃべれなかった
 ・x 頭痛でふらふらしてた

↓ 完了表記の強調表示を避けたいなら、以下のようにする

・振り返り(良かったことは先頭に o を、悪かったことは先頭に x を書いてね)
 ・o 楽しかった
 ・o Aさんとしゃべれた
 ・ x Bさんとしゃべれなかった
 ・ x 頭痛でふらふらしてた

↓ あるいは整合性を合わせるなら o 部分も同じように書くことになるか

・振り返り(良かったことは先頭に o を、悪かったことは先頭に x を書いてね)
 ・ o 楽しかった
 ・ o Aさんとしゃべれた
 ・ x Bさんとしゃべれなかった
 ・ x 頭痛でふらふらしてた

Windows 7 から Windows 10 にリモートデスクトップしてる時はファイルのコピーペーストはできない

Windows 7 マシンからリモートデスクトップで Windows 10 マシンにログインしており、ファイルをコピペしたかったのだが、できないっぽいと結論付けた。

以下、ありそうな対処とその見解(試したけどダメでした的な感想)を Q&A 形式で。

やりたいこと

1: 接続元から接続先に

  • 接続元 Win 7 でファイルを選択 > コピー
  • 接続先 Win 10 で貼り付け
  • ファイルがコピペされるはず

2: 接続先から接続元に

  • 接続先 Win 10 でファイルを選択 > コピー
  • 接続元 Win 7 で貼り付け
  • ファイルがコピペされるはず

Q: 接続時に「クリップボード」にチェック入れてる?

入れてます。

Q: 接続時に「ディスクドライブ」にチェック入れてる?

入れてます。効果ありませんでした。

また、エクスプローラーを見てもドライブは追加されませんでした。(情報によると接続元から接続先のドライブが見える or 逆も然りらしいが、どちらもダメだった)

Q: 接続先で rdpclip.exe は生きてる?

生きてます。

Q: 接続先の rdpclip.exe を再起動してみた?

してみました。効果ありませんでした。

Q: D&D でコピペするのはそもそもサポートされてないよ?

知ってます。

ファイルをコピペしたくば Ctrl + C や右クリックメニューのコピーから行う必要があるんですよね。知ってます。

Q: コピー元/コピー先はファイラーではなくエクスプローラーにしてる?

してみました。効果ありませんでした。

Q: 接続先の gpedit.msc(グループポリシー) で何か禁止されてるんじゃないですか?

gpedit.msc > ローカルコンピューターポリシー > コンピューターの管理 > 管理用テンプレート > Windows コンポーネント > リモートデスクトップサービス あたりを見てみましたが、全部未構成(未設定)でした。

Q: レジストリの fDisableCdm や fDisableClip は 0 になってる?

なってます。

というか fDisableCdm は「ディスクドライブにチェック入れてる?」のことですし、fDisableClip は「クリップボードにチェック入れてる?」のことなので、既に試してます。こ

参考: RDS(リモートデスクトップ)でファイルのコピー&ペーストが効かない場合の対処法 | MacRuby

まとめ

というわけでお手上げ。

残る可能性としては、

  • Win10 → Win10 接続なら行けるかもしれない

くらいしか思い浮かばない……。んー、ファイルをコピペできないのは不便すぎるのだが。ググった結果も一通り読んだし、うん、お手上げ。

github.com に表示される Markdown HTML が TOC が無くて見辛いので「すべて見出し単位でたたむ」「クリックで開閉」する Tampermonkey スクリプトをつくった

github.com はいいかげん TOC(目次)機能を実装するべきだと思う。Markdown で書かれた HTML の全体構造がわからなくて辛い。ふと「見出しだけ表示させてクリックした部分だけ開く」的な小細工を入れたら見やすいかも、とひらめいたので、早速試してみた。

デモ

f:id:stakiran:20190305214351g:plain

要件

Tampermonkey とは

Firefox アドオンの一つ(発祥は Google Chrome 拡張だが)で、Greasemonkey の後継となるスクリプト機構。

「このサイトを開いた時に」「この Javascript を実行してね」ってのを登録できる。

DOM とかいじって要らん要素を消したり、煩雑な情報を上手くまとめたり、と Javascript の書き方次第でウェブサイト(の今あなたが見ている表示)をカスタマイズできる。

インストール

1: Tampermonkey をインストールする

詳細は割愛。

2: 以下スクリプトを登録

// ==UserScript==
// @name         Folding per <h> in github.com
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  H要素単位で折りたたむ&クリックで開閉するスクリプト
// @author       You
// @match        https://github.com/*/*
// @require      http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @grant        none
// ==/UserScript==

/*
■設定
- ROOT_ELEMENT_SELECTOR
- @match

■仕様など
- click イベントを拾っているので, H要素中でクリック絡む操作する時がうざい
- 他サイトで動くかどうかは正直わからん...

*/

function hide_console_log(msg){
  return;
}
//var cc = console.log;
var cc = hide_console_log;

DisplayController = (function(){
    var DisplayController = function(h_elm_by_jq, index_in_body){
      this._elm_by_jq = h_elm_by_jq;
      this._index = index_in_body;
      this._controllees = [];
    }

    var p = DisplayController.prototype;

    p.add = function(elm_by_jq){
      this._controllees.push(elm_by_jq);
    }

    p.hide_all = function(){
      var controllees = this._controllees;
      for(var i=0;i<controllees.length;i++){
        var controllee = controllees[i];
        controllee.hide();
      }
    }

    p.show_all = function(){
      var controllees = this._controllees;
      for(var i=0;i<controllees.length;i++){
        var controllee = controllees[i];
        controllee.show();
      }
    }

    p.define_events = function(){
      var controllees = this._controllees;

      this._elm_by_jq.click(function(){
        for(var i=0;i<controllees.length;i++){
          var controllee = controllees[i];
          controllee.toggle();
        }
      });
    }

    return DisplayController;
})();

$(function(){
  var ROOT_ELEMENT_SELECTOR = '.markdown-body';
  //var ROOT_ELEMENT_SELECTOR = 'body';

  // ロジック上, 最後の要素が state2 → state1 にならないので,
  // ダミーの h 要素を入れとく.
  var dummy_element_html_for_logic = '<h6></h6>';
  $(ROOT_ELEMENT_SELECTOR).append(dummy_element_html_for_logic)

  var children = $(ROOT_ELEMENT_SELECTOR).children();

  var STATE_0_NOT_STARTED_YET = 'state0';
  var STATE_1_FOUND_HEADER = 'state1';
  var STATE_2_PARSING_THE_REST_ELEMENT_FOR_HIDDING = 'state2';
  var current_state = STATE_0_NOT_STARTED_YET;

  var controllers = [];
  var current_controller = null;
  var controller = null;

  children.each(function(i, elm_by_dom){
    var elm_by_jq = $(elm_by_dom);
    var tagname = elm_by_dom.tagName.toLowerCase();

    var is_header_element = false;
    if(tagname === 'h1' || tagname === 'h2' || tagname === 'h3' || tagname === 'h4' || tagname === 'h5' || tagname === 'h6'){
      is_header_element = true;
    }

    if(current_state === STATE_0_NOT_STARTED_YET){
      if(is_header_element){
        current_state = STATE_1_FOUND_HEADER;

        cc('state1::ここでヘッダを切り替える >'+tagname);
        controller = new DisplayController(elm_by_jq, i);
        controllers.push(controller);
        current_controller = controller;
      }
      return true;
    }

    if(current_state === STATE_1_FOUND_HEADER){
      current_state = STATE_2_PARSING_THE_REST_ELEMENT_FOR_HIDDING;
      // fall through
    }

    if(current_state === STATE_2_PARSING_THE_REST_ELEMENT_FOR_HIDDING){
      if(is_header_element){
        current_state = STATE_1_FOUND_HEADER;

        cc('state2(found)::新しいヘッダ切替前に, 全部 hide() と開閉用イベント登録');
        current_controller.hide_all();
        current_controller.define_events();

        cc('state1::ここでヘッダを切り替える >'+tagname);
        controller = new DisplayController(elm_by_jq, i);
        controllers.push(controller);
        current_controller = controller;

        return true;
      }
      cc('state2(notfound)::ここでヘッダに対応する「見せる見せないを切り替えるやつ」を積んでいく >'+tagname);
      current_controller.add(elm_by_jq);
      return true;
    }

    throw new Error('ここには来ないはず');
  });
});

雑談

主にコードについての話。

どうやって実装したか

まず HTML 文書構造が以下のようになっていることを想定する。

  • 便宜上 h1, h2, ... h6 要素を hx 要素と書く
  • hx 要素以外を not_hx 要素と書く
<RootElement>
 <hx></hx>
 <not_hx></not_hx>
 <not_hx></not_hx>
 ...
 <hx></hx>
 <not_hx></not_hx>
 <not_hx></not_hx>
 ...

つまり特定の要素を基準として、hx が 1 個 → not_hx が n 個、という順でシーケンシャルに並んでいるような構造を想定。

あとはこのシーケンシャル構造を「ある hx は、n 個の not_hx を持つ」という親子構造だと解釈した上で、hx 単位で「まとめて消す」「まとめて表示する」を行う処理とイベントを仕込んだ。

なお、仕込む際のパースは RootElement の children() を取得して、each() で行った。要素を一個ずつ見ていく&状態変数導入して漏れがないように。

使い心地

しばらく試してみる。

長い Markdown の時だけ使ってみて、見出しだけ読む → 読みたいところを開いてサクっと読む、みたいな拾い読み流し読みがスムーズにできるのではないかなぁと期待している。

改造の余地

この仕組みを使うかどうかの判定を Tampermonkey の @match で制御するのは面倒くさいので、以下のようにすればいいかなぁとか何とか思案中。

  • @match は * とかにしてどこでも動作するように
  • サイト読み込んだだけでは何も動かない
  • 何かアクションを行うと、動く
    • アクション is 何?
    • どっかダブルクリックするとか、ショートカットキー仕込むとか……?

ただ、root element がサイトによって違う(ローカルでテストした HTML だと body だし、GitHub だと .markdown-body だし、他のサイトやブログでは当然違ってくる)ので、これをどうやって吸収すればいいかがわからん。

Slack のリマインド機能 /remind がわかりづらいのでわかりやすくまとめた

Slack にはスラッシュコマンドという /xxxx と書いてコマンド xxxx を実行する仕組みがある。これに /remind があり、リマインダーを実現できるらしい。使い方を調べてみたが、既存の記事はわかりづらいので、自分にとってわかりやすいようにまとめてみた。

前半はリマインド概要、後半から具体例。

目的

やりたいことは以下の 2 つ。

  • 自分自身に対して
    • 「~~時に~~する」「~~分後に~~する」みたいな 今日中の予定をリマインドしたい
    • タスク管理したい。特にルーチンタスクを登録したい

これらの実現に絞って調べた。

リマインド概要

リマインドとは何か

リマインドとは指定時間後or指定時刻に指定メッセージを通知すること。事前に「~~時に~~というメッセージを表示しろ」と仕込んでおくことで実現する。

リマインドを実現するツールや機能はリマインダーと呼ばれる。

一番わかりやすいのは目覚まし時計。メッセージではなく音ではあるものの、事前に~~時に鳴るように設定しておけば、~~時に鳴った時に知らせてくれる。知らせてくれれば、思い出せる。

事前仕込みと通知。これがリマインド。

リマインドは何が嬉しいか

リマインドを導入すると「いったん忘れることができる」ようになる。その分、頭を本来の仕事に費やせる。集中できる。

たとえば 15 時から打ち合わせがあったとすると、忘れないよう「15時から会議、15時から会議」と頭で意識することになるが、これだと仕事に集中できない。リマインダーがあれば、14:50 くらいに「会議だぞ!」と表示するリマインドをセットしておくだけでいい。これだけで、14:50 に「会議だぞ!」と通知されるので思い出せる。それまでは、会議のことは一切意識することなく、仕事に集中できる。

予定失念を防止しつつ、集中も確保する。それがリマインドの意義。

Slack ではどうやってリマインドを行うか

本題。Slack ではどうやってリマインドを実現しているか。

以下のようなスラッシュコマンドを投稿すると、

/remind me メッセージ in 10 m

10分後に Slackbot から以下メッセージが届く。

Slackbot「あなたからのリクエストにより、リマインダーを送信します : “メッセージ”」

/remind コマンドはどこで投稿してもいい。

「/xxx」のようにスラッシュ始まりの文字列はコマンドであり、間違ってもメッセージとして投下されることはないから心配しなくてもいい。気兼ねなく投稿しよう。

Q: Slack を起動していなくてもリマインドされますか?

Ans: されません。

なので Slack のリマインドに頼りたければ、Slack は常に起動しておきましょう。

リマインドを設定する

ここから Slack の /remind の使い方例に入っていく。(基本n)と題して、計8個の例を紹介する。

(基本1) n秒後/n分後/n時間後にリマインドする

たとえば 10 秒、10分、10時間後だとすると。

/remind me メッセージ in 10 s
/remind me メッセージ in 10 m
/remind me メッセージ in 10 h

/remind me はお決まりなので絶対に書くこと。

in も必要なので書く。

秒分時の単位について smh が最も楽だろう。secondssecond も可能だが、あえて長い文字を打つ必要はあるまい。

(基本2) n秒後/n分後/n時間後にリマインドする(別パターン)

「メッセージ in 時間指定」の他に「in 時間指定 to メッセージ」という書き方もある。

/remind me in 10 s to メッセージ 
/remind me in 10 m to メッセージ 
/remind me in 10 h to メッセージ 

ルーチンタスクを設定する

ルーチンタスクとは「定期的に実施するタスク(やること)」であり、日々の雑務や定型作業をルーチンタスクとして扱うと日々忘れずに消化できる。(ゴミ捨てなど些細なものも含めれば)人は一日に数十のルーチンタスクを抱えており、頭だけでこなそうとするとたいていやり忘れが生じるが、タスク管理すればこれを完全に防止できる。

……と前置きはこのくらいにして。ルーチンタスクを管理する方法は様々だが、リマインダーを使って「繰り返しのリマインド」をセットすることで実現する方法もある。

ここでは /remind を使って繰り返しのリマインドを行う例をいくつか取り上げる。

(基本3) 毎週xx曜日にリマインドする

以下は毎週水曜日 9:00 にリマインドする例。

/remind me メッセージ every wed

時刻指定がない場合は 9:00 固定となる。

曜日は wed など三文字表記が楽。

(基本4) 毎週xx曜日のhh:mmにリマインドする

以下は毎週水曜日 12:35 にリマインドする例。

/remind me メッセージ every wed at 12:35

時間は at (hh:mm) のように指定する。しかしながら実は at は無しでもいける(次の基本5で取り上げる)。

(基本5) 毎週xx曜日とyy曜日のhh:mmにリマインドする

以下は毎週月曜日と木曜日の 8:30 にリマインドする例。

2 つ書いているがどちらを使っても良い。

/remind me メッセージ 8:30 every mon thu
/remind me メッセージ every mon thu 8:30

リマインドの状況を確認する

(基本6) リマインド状況を一覧表示する

/remind list を使うと、現在のリマインド状況を一覧で表示できる。また、ここから一部操作を行うこともできる。

表示内容と対応操作は以下のとおり。表示順もこのとおり。

  • 今後の予定
    • まだリマインドされていないもの
    • 対応操作: 完了, 削除
  • 繰り返しのイベント
    • every で設定されたリマインド
    • 対応操作: 削除
  • 未完了の過去の予定
    • リマインドされたが完了or削除or再通知していないもの
    • 対応操作: 完了, 削除, 再通知(15分後/1時間後/明日), 全削除
  • 完了
    • リマインドされ, 完了操作もされたもの
    • 対応操作: 削除

ただし 一度に10件までしか表示されない。ページネーションについては「次の10件を表示する」→「次の10件を表示する」→ …… 「残りを表示する」という具合に、10件ずつ辿っていく感じ。「前の10件を表示する」みたいな仕組みはない。大量のリマインダーを管理するにはいささか不便か。

リマインドの動作や挙動を試したい

(基本7) どのように通知されるかを試したい

以下は 1 秒後にリマインドを行う例。1秒はすぐに過ぎるので、事実上リマインドの動作確認になる。

/remind me in 1 s to 表示テストです

ただし 1 秒後ジャストにリマインドされるわけではなく、若干(数秒~十数秒くらいか)のタイムラグがある。

(基本8) 設定した繰り返しのリマインドが正しいか確かめたい

/remind を実行した後に設定内容が表示されるので、それを見て確かめる。

例1:

/remind me メッセージ 8:30 every mon thu

これを投稿すると「毎週月曜日と木曜日 8:30 に、あなたにこれをリマインドします : “メッセージ”」と表示される。これは期待通り。ただしい。

例2:

/remind me メッセージ 8:30 12:33 every mon thu

これを投稿すると「毎週月曜日と木曜日 8:30 に、あなたにこれをリマインドします : “メッセージ”」と表示される。これは正しくない。12:33 はどこに行った?

おそらく /remind は時刻の複数指定には対応していないのだろう。

……とこのような感じで、試しに投稿してみる → 設定結果を読んでみる、を繰り返して正しい書き方を覚えていくことになる。

参考資料

いずれも網羅的はあるものの、「~~したいだけなんだけど、結局どうすればいいの?」が少しわかりづらかったので、今回このような記事を書くことにした。

AutoHotkey で指定ウィンドウでのみリマップを無効にしたい

私は「Alt + W」に「Ctrl + F4」、つまりは「タブを閉じる」を割り当てているのだが、これだとアプリ中で Alt + W にショートカットキーを割り当てても動作しない(タブが閉じられてしまう)。このアプリ中でのみ Ctrl + F4 リマップを無効にしたかったのでメモ。

元々の設定

!w::Send ^{F4}

上記のとおり、単純なリマップ構文で Alt + W → Ctrl + F4 にリマップしている。

結論

以下のように「#IfWinNotActive」を使った。

#IfWinNotActive my task-management tool
!w::Send ^{F4}
#If

これはウィンドウタイトルが "my task-management tool" の時 以外に Alt + W → Ctrl + F4 リマップをする、という命令になる。

失敗例

思考過程的なものを残しておく。

失敗1. Return

最初に考えたのは「適用したくないケースは個別に除外すればいい」「除外として Return すればいい」と考えて、以下のように書いた。

!w::Send ^{F4}
#If WinActive("my task-management tool")
!w::Return
#If

これはダメだった。

リマップで Return すると その割り当てが押された時は何もしません(その割り当て本来の機能も無効にします) という意味になる。つまり my task-management tool ウィンドウの時は、Alt + W でタブクローズは起こらなくなったが、そもそも Alt + W 自体が転送されなくなる。

失敗2. Hotkey

次に考えたのが、Return じゃなくて「その割り当て本来の働きをそのまま使う」的な構文を使えばいいんじゃないか、だったが、そんな構文はなさそう。しかし Wiki を漁っていると、いけそうな構文があった。

この Hotkey は、ホットキー設定を部分的に on/off にしたりできるようだ。

早速読んでみたのだが……よくわからん。ピンと来ない。ハマりそう。いったんスキップ。

成功

もっと楽にできないか、と粘っていると、あ、#IfWinNotActive で省けばよくない?とひらめいた。

解決。

MkDocs で何故か docs_dir の直下にある readme.md が変換されない件

MkDocs 1.0.4 の話。docs_dir で示したディレクトリに index.md と readme.md を置いていると、なぜか readme.md だけビルドの対象にならない。

原因は MkDocs のソースを見てようやくわかった。

index.md が存在する場合、readme.md のパースは無視される 仕様になっている。

該当ソース部分

from: https://github.com/mkdocs/mkdocs/blob/592e0852fe9e9c6c1316da818a8db402f73ff0c0/mkdocs/structure/files.py#L237

        for filename in _sort_files(filenames):
            path = os.path.normpath(os.path.join(relative_dir, filename))
            # Skip any excluded files
            if _filter_paths(basename=filename, path=path, is_dir=False, exclude=exclude):
                continue
            # Skip README.md is an index file also exists in dir
            if filename.lower() == 'readme.md' and 'index.md' in filenames:
                continue
            files.append(File(path, config['docs_dir'], config['site_dir'], config['use_directory_urls']))

1.0.4 後のバージョンでは log.warning が出そう

しかし現在進行のバージョンでは、log.warning による Warning メッセージが出るよう修正されている。

from: https://github.com/mkdocs/mkdocs/blob/cc03fd05876ad7ff14dfeff55832dc0dd7f0bf06/mkdocs/structure/files.py#L238

            if filename.lower() == 'readme.md' and 'index.md' in filenames:
                log.warning("Both index.md and readme.md found. Skipping readme.md from {}".format(source_dir))
continue

MkDocs で .git や node_modules など指定ディレクトリを exclude(除外) したい

MkDocs でリポジトリ中の Markdown ファイルたちを HTML に変換したいのだが、.git やら node_modules やら巨大なテンポラリフォルダが邪魔なせいで MkDocs のビルドが終わらない。

exclude できないかと思って、調べて、対処法にたどり着いたのでメモ。

対処方法

mkdocs-exclude プラグインを使う。

(設定1/2) インストール

1: MkDocs が古いならバージョンアップしておく

MkDocs が古いと mkdocs-exclude が動作しないので、先にバージョンアップしておく。

私の場合、元々こんな感じだった。

$ pip freeze | grep mkdocs
mkdocs==0.17.4
mkdocs-alabaster==0.7.4
mkdocs-material==2.9.1

これに対して mkdocs を upgrade する。

$ pip install mkdocs --upgrade
...
mkdocs-material 2.9.1 has requirement tornado<5, but you'll have tornado 5.1.1 which is incompatible.
...

エラーが一つ出ている。mkdocs-material 2.9.1が古いぞオイ(tornado ver 5 以下が必要なのに、あんた今は ver 5.1.1 になってんで) とのこと。

つまり mkdocs-material も古いので upgrade する。

$ pip install mkdocs-material  --upgrade

この時点でこうなった。

$ pip freeze | grep mkdocs
mkdocs==1.0.4             ★from 0.17.4
mkdocs-alabaster==0.7.4
mkdocs-material==4.0.1    ★from 2.9.1

もう一度 pip install mkdocs --upgrade を行って、エラーが出ないことを確認。これで upgrade はおわり

2: mkdocs-exclude をインストールする

apenwarr/mkdocs-exclude をインストールする。

$ pip install mkdocs-exclude

(設定2/2) mkdocs.yml に設定を書く

glob が使えるので楽。

以下は .git、coverage、node_modules の三つのディレクトリを弾く例。

plugins:
  - exclude:
      glob:
        - '**/.git/*'
        - '**/coverage/*'
        - '**/node_modules/*'

設定完了

これで指定ディレクトリが除外されてビルドが走るはず。

1分経っても終わらないビルドが10秒以内で終わるようになった。助かる。

(余談) あってもいい機能なのになんで MkDocs 公式はサポートしない?

MkDocs の Issues で議論されてる。

色々あるけど、一言で言うなら https://github.com/mkdocs/mkdocs/issues/1152#issuecomment-285083310 ここの

Finally, if we were to change the current behavior, it would break a lot of users existing sites. So while I can see an argument for an adjustment here, it is not likely to overcome the backward compatibility argument to leave things as-is.

これだろうか。よくわからんが今の仕組み的に、exclude 機能を入れようと思ったら後方互換性壊れちゃうみたい。

で、今年の 1 月になって、apenwarr さんという人が プラグインをつくった

I created a mkdocs-exclude plugin that uses the new plugin API to do what's requested in this bug: https://github.com/apenwarr/mkdocs-exclude

plugin API として exclude 機能が追加されたから実現できたみたい。あざっす。助かりました。

【オレオレ晒し】TIL(Today I Learned) 環境を整える

Githubのリポジトリ「TIL」を使って小さなアウトプットを習慣化する - Qiita に触発されたので、オレオレの TIL を晒してみる。

TIL とは

最初に簡単に取り上げておく。

TIL とは Today I Learned の略。

GitHub 文化の一つで、til という三文字名称のリポジトリを作って、日々学んだことを Markdown などで蓄積していくというもの。

メリット

  • 後々読み返せるので個人的に役に立つ
  • アウトプットの習慣や練習に適している
    • 自分のスペースに好き勝手に書きなぐるだけだし
    • Qiita みたいに晒されるものでもないし
  • 書きやすい
    • ローカルの使い慣れたエディタで書いて、最後に push
    • github.com の UI は使いやすいので、ブラウザでそっちで書いても良いが
  • 承認欲求を満たせる
    • GitHub の草が映える
    • 「オレ、こんなこと勉強してんだぜ?」
    • 「こんなに蓄積してるオレ、すごくない?」 etc
  • コミュニティや他ユーザーに貢献できる
  • 自分の興味や志向などを端的に表現できる

オレオレ TIL を晒す

ここからは私の TIL を晒す。コンセプトからしてかなりオレオレ。

コンセプト

  • 1: プライベート …… 自分だけが読めればそれでいい
  • 2: ローカル駆動 …… 編集、閲覧、検索などは全部ローカルでやる
  • 3: 物置 …… GitHub は物置として使うだけ

1 のプライベートは、公開だと 第三者が読んでも問題ないよう表現を考えるコスト が発生して面倒くさいから。

2 のローカル駆動は、 最も効率的に編集や閲覧ができるのは「使い慣れたテキストエディタ」 だから。

そうなると「GitHub に置く必要ある?」となるが、私は Dropbox が嫌い(常時同期が走るのが気持ち悪いうざい、gitignore がないなど)なので、普段使っている GitHub に置くことにした。ただ、そうなると git コマンドの利用が面倒くさいので、スクリで適当に端折る。

全体像

前提:

  • Windows

構造:

  • knowledge リポジトリ
    • プライベートリポジトリにする
    • リポジトリ名は何でもいい。TIL したいんだから til が無難か
    • しかし私は将来公開用の til を作るかもしれないので、あえて til は使わなかった
  • ローカルで xxxx.md や xxxx.txt に、xxxx に関するネタを書き殴り、適宜アップロード(add-commit-push)

編集時:

  • xxxx について書きたい時は、xxxx.txt や xxxx.md をつくる or 既存ならそこに書き足す
  • つくる際はスクリプトで一発で(xxxxを入力するだけで作成するとか)できるようにすると楽

検索時:

  • fenrir を使って xxxx.txt や xxxx.md にアクセス
    • いわゆるファイル名のインクリメンタルサーチ
    • Mac で言えば Spotlight や Alfred みたいな感じだろうか
  • Grep を叩くスクリプトを実行する
    • スクリ叩く → キーワード打つ → knowledge配下がgrepかけられる
    • このスクリも fenrir から呼び出す(例: _grep.bat )

同期時:

  • 適当なタイミングで _upload.bat を叩いてアップロード
    • これは add, commit -m "テキトーなメッセージ", push を行うスクリ
  • 他 PC からは git pull でダウンロード

環境のつくりかた

  • 1: til リポジトリをつくり、適当なところに clone
  • 2: fenrir をインストールして、clone した 1 をスキャンさせる
  • 3: AutoHotkeyをインストールして、2 の fenrir をキー一発で呼べるようにする
  • 4: 便利スクリプトを clone した 1 に追加する
    • xxxx.txt や xxx.md を新しくつくるやつ
    • Grep するやつ
    • アップロード(add-commit-push)するやつ
    • ダウンロード(pull)するやつ

fenrir や AutoHotkey などの詳細は割愛。

オレオレ TIL 付録

使うツールやスクリやらの中身を晒す。

fenrir の scan.ini

*.txt;*.bat;*.py;*.md;*.rst;\
D:\work\github\stakiran\knowledge
-D:\work\github\stakiran\knowledge\.git

まずファイルタイプは txt や md など主要なものは網羅する。スクリプトも呼び出すのでバッチファイル bat や Python py なども追加している。

次に走査先だが、.git フォルダは省くこと。

fenrir.exe の設定ファイルなど

長くなるので割愛。

AutoHotkey から fenrir を呼び出す

; fenrir を Alt + 1 で呼ぶ
!1::
  run, D:\bin\fenrirs\fenrir\fenrir.exe /t /pathfile=D:\bin\fenrirs\knowledge\path /scanfile=D:\bin\fenrirs\knowledge\scan.ini /initfile=D:\bin\fenrirs\fenrir\data\fenrir.ini /instantfile=D:\bin\fenrirs\fenrir\data\instant.ini /cmddir=D:\bin\fenrirs\fenrir\cmd, D:\bin\fenrirs\fenrir
return

; fenrir の作業フォルダを Ctrl + Alt + F で呼ぶ
^!f::
  run, D:\bin\fenrirs
return

まず fenrir のディレクトリ構造を整理しておく。

  • D:\bin\fenrirs
    • fenrir …… fenrir本体フォルダ
    • knowledge …… knowdlgeリポジトリ用の設定を入れるフォルダ
    • ...

コマンドラインは煩雑だが、fenrir 本体に必要なパラメータを指定しているだけである。

あとは、おまけとして fenrir 絡みの作業フォルダを一発で開くホットキーも用意している。fenrir 自体をいじりたい時に地味に便利。

アップロードするやつ

_upload.bat

git add -A
git commit -m "update."
git push -u origin master
pause

最後の pause は、このバッチファイルを実行した時の画面を閉じずに止めるための決まり文句。

ダウンロードするやつ

_download.bat

git pull
pause

たまにアップロード忘れで衝突が発生するが、その時は手作業でテキトーに解決する。

xxxx.txt や xxx.md を新しくつくるやつ

_new_knowledge.bat

@echo off

prompt $$
pushd %0\..

set /p filename="Input the textfilename and the extension if needed. >"
copy /-Y nul %filename%
start "" "%filename%"

ファイル名 xxxx.ext を入力すると、knowledge/xxxx.ext を空ファイルで生成した後、関連付けられたエディタで開くという感じ。

※英語はたぶんおかしいけど見逃してください(普段 utf-8 で書いてるので日本語で指示させるとコマンドプロンプトが文字化けしてしまう&文字コード cp932 に直すのだるかったのであえて英語にした、のがそのまま放置されている 苦笑)

Grep するやつ

実はスクリプトとしては用意してない。

私が使っている秀丸エディタでは、knowledge/xxxx.xxx を開いている状態で F4 を押すだけで Grep 機能を呼び出せる(検索先は knowledge ディレクトリ配下がデフォ)ようになっている。ので、Grep したい時は

  • Alt + 1 で fenrir 呼び出して何か開く
  • F4 で Grep 機能呼び出す

という流れ。

Javascript ES5 などで this がおかしい時に確認すること

Javascript(ES5 など古いやつ) の this は呼び出し元次第で中身が変化するという、大変扱いづらい仕様をしている。そのせいで、なぜか TypeError が発生し、調べてみると this がなぜか別のオブジェクト(window)を指していたりする。勘弁してほしい。何度ハマったことか。

というわけで、「おかしい時に確認すること」と題して、まとめておく。次ハマったら、ここを見に来ること。

1: new してるか確かめろ

var table_xxx = VIEW_XXXX_SPACE.XXXXTableBuilder(param1, param2);
         //    A
         //    |
         //  new が足りてないぞ!

2: jQuery 等でメソッドチェーンでコールバック関数書いてると this は見えないから外から見ろ

    ...

    var p = ClassXXX.prototype;

    p._onclick = function(){
        var self = this;

        $(some_selector).click(function() {
            var result = this.calc();
                     //  ^^^^
                     // 違うぞ! this は $(some_selector) の中を指してるぞ!
                     // このクラス(もどき)の this が見たいなら
                     // 外で定義してる self を見ろ!
        });
    }

    ...

3: xxxx.func を this._func = xxxx.func みたいに持たせるのはやめて

問題となる書き方:

    ...

    var p = ClassXXX.prototype;

    p.set_update_func = function(f){
        // こんな感じで yyy の update() を保持することを想定.
        //    xxx.set_update_func = yyy.update
        this._func_update = f
    }

    p.process = function(f){
        ...

        // ここでハマる!
        // さっきセットした yyy.update を呼ぶことを想定しているのだろうが、
        // yyy.update() 側で this の中身がおかしくなる!
        // (yyy の中身じゃなくてこの ClassXXX インスタンスの中身になってる。
        this._func_update();

        ...
    }

    ...

じゃあどう書けばいいの?:

→ 関数を保持するのではなくオブジェクトを保持して Duck typing してください。

    ...

    var p = ClassXXX.prototype;

    p.set_yyy_instance = function(yyy){
        this._yyy = yyy
    }

    p.process = function(f){
        ...

        // これなら update() 中の this は yyy インスタンスの中身を指す!
        // 正しく動く!
        //
        // これはいわゆる Duck Typing。
        // 「this._yyy は yyy インスタンスであるはずだ」
        // 「yyy インスタンスであるなら update() を持っているはずだ」
        // 「私は yyy さんの update() をここで呼ぶのが仕事だから、とりあえず呼ぶ」
        // 「実際に _yyy が何を指してるかは知らん。私は呼ぶだけだ」
        // みたいな。
        this._yyy.update();

        ...
    }

    ...

Dropbox サポート終了のため MacBook Air を 10.9(Mavericks) から 10.14(Mojave) にアップデートした

執筆マシン&ネットサーフィンマシンとして使っている MacBook Air だが、Dropbox が「10.9 以前は 2019 年 4 月で使えなくなります」と仰る。MacOS をアップデートせなばならない。調べてみると、10.14 の Mojave にアップデートできる模様。一連の作業内容についてメモ。

1. MacOS を Mojave にアップグレード

まずは OS のアップグレードが必要。

  • 作業時間: 10分
  • 所要時間: 一晩丸々かかる

手順としては、以下公式サイトを辿る。

すると最終的には App Store で Mojave をインストールする形になるはず。

時間がかかるのはここから。何しろ 6.1GB もあるブツだから。ダウンロードはすぐ終わる(オンライン型のインストーラなのだろう)が、続くインストールがとにかく長い。私は WiFi をつないだまま一晩放置した(朝起きたら完了していた)。

2. Git コマンドが動かないので対処する

GitHub を物置として使っているので、git が使えないと死ぬ。今は git を実行しただけで「pxcrun: error: invalid active developer path...」などと怒られる。対処したい。

  • 作業時間: 1分
  • 所要時間: 20分

以下コマンドを実行するだけで良い。ただし XCode をインストールする形になるらしく、この XCode が中々に大きいブツなので結構時間かかる。気長に待つ。

$ xcode-select --install

3. 日本語入力システムが使いづらいので対処する

日本語入力システムがなんかおかしい。日本語が打ちづらい。対処する。

(余談) ちなみに Google 日本語入力など他の IME を使うつもりはない。バッテリー消費が激しいから。

3-1. ライブ変換を無効にする

なんか勝手に変換が走る?感じの、よくわからない使いづらい挙動をしている。これは「ライブ変換」という機能らしいので無効にする。

  • 作業時間: 1分
  • 所要時間: 1分

手順は、右上の IME アイコンをクリックしてメニューを開いて、「ライブ変換」を無効にすればいい。

3-2. 常に半角スペースで入力する

Mojave の日本語入力システムは「ことえり」ではなく JapaneseIM というそうだが、コイツが常に半角スペースで入力するオプションを用意してないポンコツである。

設定変更は結構めんどうくさかった。

  • 作業時間: 10分
  • 所要時間: 10分

i. まず全体像をおさらい

  • 「常に半角スペース」の実現は、KeySetting_Default.plist というファイルをいじる
  • でもこれ、システムファイルで、簡単にはいじれない
  • いじるには...
    • csrutil とかいうセキュリティツールでセキュリティを落とす
    • KeySetting_Default.plist をいじる
    • csrutil とかいうセキュリティツールでセキュリティを戻す

ii. 作業手順

※本手順では、macOS の再起動と(Windows でいうセーフモードみたいな)モードを使う(つまり 作業中の mac でブラウザ等で手順見ながら、なんてことができない )ので、別途本手順を読める手段を用意しておくと良い。

  • (1) macOS 復元システムを起動する
  • (2) ユーティリティ > ターミナルからターミナルを開いて、セキュリティを落とす
$ csrutil disable

ちなみに csrutil disable 実行時点で、既に disable になっている。csrutil status を見ると enabled のままだが、これは再起動してなくて反映されてないだけ。

  • (3) reboot コマンド等で再起動し、普通にログインして、ターミナルを開いて、以下のように plist ファイルをいじる
$ cd /System/Library/Input\ Methods/JapaneseIM.app/Contents/PlugIns/JapaneseIM.appex/Contents/Resources/
$ sudo vi KeySetting_Default.plist

いじり方だが、 macOS High Sierra / Mojave で 日本語モード時に スペース <-> 半角 入れ替え - Qiita がわかりやすいので抜粋

--- /System/Library/Input Methods/JapaneseIM.app/Contents/PlugIns/JapaneseIM.appex/Contents/Resources/KeySetting_Default.plist.orig 2017-09-26 10:34:40.000000000 +0900
+++ /System/Library/Input Methods/JapaneseIM.app/Contents/PlugIns/JapaneseIM.appex/Contents/Resources/KeySetting_Default.plist  2017-09-26 10:38:30.000000000 +0900
@@ -11,12 +11,16 @@
            <key>&apos; &apos;</key>
            <dict>
                <key>command</key>
-               <string>contextual_space</string>
+               <string>direct_input</string>
+               <key>character</key>
+               <string> </string>
            </dict>
            <key>shift+&apos; &apos;</key>
            <dict>
                <key>command</key>
-               <string>contextual_space_reverse</string>
+               <string>direct_input</string>
+               <key>character</key>
+               <string> </string>
            </dict>
            <key>delete:</key>
            <dict>

コピペ用文字列も置いとく。

                <string>direct_input</string>
                <key>character</key>
                <string> </string>

                <string>direct_input</string>
                <key>character</key>
                <string> </string>
  • (4) 日本語入力システムを再起動して反映させる
$ killall JapaneseIM

ここまでで「常に半角スペース」は実現できているはず。

あとは、落としたセキュリティをもとに戻しておく。

  • (5) (1) と同じ要領で macOS 復元システムを起動し、ユーティリティ > ターミナルから以下を実行
$ csrutil enable

もう一度再起動。これで一段落。

4. 使っているアプリに許可を与える

私の場合、BetterTouchTool や ClipMenu を使っているのだが、これらが動かなかった。権限付与されていないせい。付与していく。

  • 作業時間: 3分
  • 所要時間: 3分

設定は 2 箇所必要。

設定手順(全体的な設定):

  • システム環境設定 > セキュリティとプライバシー > 一般
  • ダウンロードしたアプリケーションの実行許可を「App Store と確認済みの開発元からのアプリケーションを許可」にする

設定手順(個別の許可):

  • システム環境設定 > セキュリティとプライバシー > プライバシー
  • 左ペインからアクセシビリティを選ぶ
  • 右ペインに、実行を許可するアプリを追加

5. システム環境設定は全部眺めてみる

他にもシステム環境設定は一通り眺めてみて、要らないものや気に入らないものは適宜変えると良い。なんかちょろちょろ変わってたりするので。

  • 作業時間: 10分
  • 所要時間: 10分

6. キーボードのバックライトを消す

バッテリーを食うし目障りなので、キーボードのバックライトは無効にしていたのだが、勝手に有効になっていた。

  • 作業時間: 1分
  • 所要時間: 1分

Fn + F5 キーで明かりを 1 段落とせるので、一番左まで落とす。

※Mission Control の設定次第では F5 キーだけで作用するかも

7. ファイルの関連付けがリセットされているので適宜直す

私の場合、.txt と .dry は mi に関連付けしていたが、これら関連付け設定がリセットされてやがるので再設定が必要。

  • 作業時間: 1分
  • 所要時間: 5分

作業手順は以下のとおり。

  • 1: Finder で関連付けを変えたいファイルのあるフォルダを開く
  • 2: 当該ファイルを選択して、ファイル > 情報を見る
  • 3: このアプリケーションを開く、から関連付けしたいアプリを設定し、すべて変更ボタンを押す

8. bin/ 配下のエイリアスが死んでいるので .bash_profile などに書き直す

  • 作業時間: 1分
  • 所要時間: 5分

私は Sublime Text のエイリアス subl を以下のようにしてつくっていた。

sudo ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/bin/subl

しかし Mojave ではセキュリティが強化されて bin/ 配下に書き込めないからか、パーミッションエラーが出る。

仕方ないので、.bash_profile などに以下を書くことで対処。

alias subl="/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl $1"

ひとまずここまで

とりあえずここまで。

他に設定を直したことがあったら、気が向いたら追記する (2019/02/14 追記) 7と8を追記した。

Mavericks と比べて Mojave はどう?

一言で言うと なんか動作が重たいのでイライラする

私にとって MacBook Air は「軽快な執筆マシーン&ネットサーフィンマシーン」でしかなく、アプリの充実やら画面がキレイになりましたとか、そういうのはどうでもいい。iTunes も消してるくらいだし。

Mojave になってから露骨に動作が重たくなった。

どれくらいかというと、Alfred2 でキーワード検索した時の動きがもっさり(反映が遅い)していて「ん?バックで何か慌ただしいプロセスでも動いてるんか?」と疑うレベル。まるで Windows Update が走っている Windows みたいなもっさりさだ。

常にここまで重たいわけではないが、少なくとも Mavericks の時よりは明らかに重い。やらなくていいならアップグレードしたくなかったなぁ。

……他の使い心地については、これからわかることだろう。