Skip to content

Releases: MR-TABATA/MrEditor

v1.14.0 — 向こうにあるログ

Choose a tag to compare

@MR-TABATA MR-TABATA released this 30 Aug 05:01
b172349

見たいログはサーバーにある。落とさずに開く。

ssh host:/var/log/app.logファイル ▸ リモートを開く…(⌃⌘O) に入れると、そのまま開きます。

  • ダウンロードしません。 見たところだけを取ってくるので、10GB でも待ちません(落としてから開くなら scp で済みます)
  • 開くと、まず末尾。 障害は末尾にあります。行番号は本物です(wc -l は向こうで走るので、来るのは数字 1 つ)
  • 絞り込みは向こうで走りますgrep -n)。本文を 1 バイトも転送せずに、一致行と行番号が返ります ── 送らないぶん、手元で走査するより速い。± 欄で前後の行も(grep -C 相当)
  • 末尾追従(「追う」)。向こうの tail -f を流し込みます。止めれば向こうも止まるので、あなたのサーバーにプロセスは残りません
  • ⌘C は本文だけを返すので、そのまま ⇧⌘D のクリップボード比較へ渡せます。遠隔で絞って、手元と見比べる

認証は /usr/bin/ssh 任せです ── ssh_config・ProxyJump・多段・ssh-agent がそのまま効きます(ターミナルで繋がるなら、繋がります)。秘密鍵は保存しません。

正直なところ

手元のビューアとは別の面です。 構造化表示・diff・しおりは、まだ遠隔では効きません。向こうのコマンド(head / wc / tail / grep)に依存するので、BusyBox などで欠けていればその機能だけを畳んで、畳んだ理由を出します。編集も、いまは狙っていません(/etc は root 所有で、sudo 経路は作らない方針です)。


macOS 13+ / Apple Silicon・Intel(universal)。Developer ID で署名・公証済みなので、ダウンロードしてそのまま起動できます。

v1.13.0 — 入口を開ける

Choose a tag to compare

@MR-TABATA MR-TABATA released this 28 Aug 12:02
3447f96

巨大なログを見るための道具なのに、そのログは素のファイルとして転がっていないことが多い。パイプの向こうにあるか、圧縮されている。中でどれだけ機能があっても、そこへ届かなければ意味がありません。

入口を開けました

kubectl logs -f pod/api | mreditor     # パイプでそのまま
mreditor app.log.gz                    # gzip は展開して開く
mreditor logs.zip                      # zip も。複数入っていれば選ばせる

mreditor コマンドは 1 行で入ります(アプリ本体への symlink なので、アプリを更新しても張り直しは要りません)。

ln -sf /Applications/MrEditor.app/Contents/MacOS/MrEditor /usr/local/bin/mreditor

コマンドを使わなくても、ダブルクリックや「このアプリケーションで開く」で .gz.zip はそのまま開けます。

判定は拡張子ではなく中身で行います。 .log のまま gzip されたファイルも、.gz という名前なのに素のテキストのファイルも、実際に世の中にあります。先頭の数バイトを見て決めるので、どちらも正しく開きます。

末尾が欠けていても、出せたところまでは開きます。 落ちたログの尻尾が切れているのは日常で、「壊れているので何も見せません」は、この道具が一番してはいけない返事です。

zip に複数のファイルが入っていれば、名前を並べて訊きます。1 つしか入っていなければ黙って開きます —— 選択肢が 1 つのダイアログは、確認ではなく手間でしかないので。__MACOSX/.DS_Store は出しません(Finder で圧縮すると必ず入るもので、並べると選択肢が実際の倍になります)。

しおり

⌘B で今の行に印。⌘; で次のしおりへ、⇧⌘; で前のしおりへ。印は行番号の左に出ます。

調査は往復します。 絞り込んで見つけた行から本文へ飛び、周りを読み、また戻る。戻り先を頭に置いておけるのは 1 つか 2 つで、それを超えると行番号をメモに書き写すことになります。

検索で言い表せる戻り先なら、⌘G のほうが速い。しおりが埋めるのは検索語にできない戻り先です ——「4000 行を眺めていて引っかかった 5 行」のように、共通する文言も時刻も無いもの。

セッション内だけで、ファイルには何も書きません。

変わらないこと

⌘; を使わなければ、これまでと同じです。パイプも圧縮も、渡さなければ動きません。

v1.12.6 — 絞ったまま、次も開く

Choose a tag to compare

@MR-TABATA MR-TABATA released this 27 Aug 12:18
8d73680

⌘F を押すと、検索バーはいつも素の検索で開きました。構造化されたものを読んでいる間、やりたいのは「一致行へ飛ぶ」ことより 「絞る」 ことなのに、毎回そこへ 1 手かけて漏斗を入れ直すことになります。

もっと静かに効いていたのは往復のほうです。漏斗を使えないペイン(構造化・JSON)へ移ると、トグルは降ります。それ自体は正しいのですが、降りた理由が「本人が消した」のと同じ扱いで記録されていました。構造化と素のテキストを行き来するたびに、絞りたいという意図そのものが消えていたということです。

前に絞っていたなら、その状態で開きます

⌘F は、漏斗を最後に自分で押した状態で開きます。いつも絞って読む人は、最初の一度だけ押せば済みます。

覚えているのは意図であって、絞り込みそのものではありません。漏斗を使えないペインでは何も起きず、使えるペインへ戻ったときに当て直します。検索バーを閉じている間は当てません —— 開いていないのに本文が絞られるのは、事故にしか見えないからです。

何も変わらない人もいます

既定は off です。漏斗を使っていない人の ⌘F は、これまでとまったく同じように開きます。

変わるのは、一度でも自分で漏斗を押した後だけです。押していない状態に戻したければ、もう一度押して降ろせば、次からはその状態で開きます。

v1.12.5 — 一致行の、前後も出す

Choose a tag to compare

@MR-TABATA MR-TABATA released this 22 Aug 13:20
6c7a84e

絞り込むと、一致行しか残りません。でも調査は往復します。何が起きたかは、たいてい直前の行にあります。

これまでは、そこでフィルタを解除して、行番号を頼りに元の位置へ戻るしかありませんでした。絞り込んだ瞬間に文脈を失う道具だったということです。

一致行の、前後も出す

grep -C と同じことを、絞り込んだ画面の上で伸び縮みさせられます。

   1481  │ INFO   opening connection to db-03
   1482  │ WARN   pool exhausted, waiting
   1483  │ ERROR  connection reset by peer     ← 一致行
   1484  │ INFO   retrying in 500ms
   1485  │ ERROR  connection reset by peer     ← 一致行

入口は 2 つです。

  • 検索バーの ±に行数を打つ
  • ⌥⌘] で 1 行広げる、⌥⌘[ で 1 行縮める

ボタンでもアイコンでもなく、文字と数字にしました。絞り込んだ画面に「±2」と出ていれば、いま何を見せられているのかがそこで読めます。記号だけの切り替えは、気づかれません。

打った値はアプリの設定として覚えます(上限 100 行)。次に開いたファイルでも同じ見え方になります。

決めたこと

  • 窓が重なっても、行は重複しません。 一致が隣り合っていれば 1 本に繋がります。
  • 区切り線は入れません。 行番号のガターに元の行番号がそのまま出ているので、飛んでいることはそこで分かります(grep-- に当たるものは要りません)。
  • いまの一致行に帯を敷きます。 文脈行と一致行が同じ見た目で並ぶと、どれが引っかかった行か分からなくなるためです(構造化表示中は行内のハイライトが出せないので、帯だけが手がかりになります)。
  • 件数は一致行の数のままです。 「18 件中 1 件目」に文脈行は混ざりません。
  • 時間分布のドラッグで絞ったときは、足しません。 選んだ時間帯の外の行が混ざると、「選んだ範囲」が嘘になるからです。

画面に出して、初めて分かったこと

テストは緑のままでしたが、配布するものと同じ .app で触って 3 つ見つけて直しました。

出たこと 直し
構造化表示中、文脈行だけが con… と潰れた 列幅を一致行だけで測っていた。文脈行も同じ表に並ぶので、表示している行から測る
「18 件中 1 件目」の末尾が切れて何件目か読めない 詰まったときに縮むのは検索欄だけにした(打った語は自分で覚えている)
出したはずの直前の行が画面の上に隠れる 一致行を最上部に置いていた。前後を出しているぶんだけ上へ寄せる

確認したこと

配布するものと同じ .app で、4 経路とも通しています。

条件 結果
小さいファイル(編集ペイン) ± 欄・キーボードとも効く
10GB・8642 万行、1 件に ±3 7 行が 0.1 秒未満で出る
12.8MB・900,001 行の CSV、構造化+フィルタ+前後行 桁を保ったまま前後が出る
⌥⌘] / ⌥⌘[ 1 行ずつ伸び縮みする

641 のテストが緑。Apple Developer ID で署名し、公証を通しています——ダブルクリックで開きます(Apple Silicon / Intel 両対応・macOS 13+)。

v1.12.4 — 絞り込んだ行に、桁を合わせる

Choose a tag to compare

@MR-TABATA MR-TABATA released this 21 Aug 12:56
f22f755

桁を揃えたまま grep できる——それが 1.11 からの看板でした。ところが絞り込んだ結果の、肝心の値が読めていませんでした

絞り込んだら、絞り込んだ行に桁が合う

列幅は、ファイルの先頭 1000 行と末尾 1000 行から決めていました。だから、長い値が中間にしか無いファイルでは拾えません。

45MB・300 万行の CSV を CSV 表示にして ERROR で 59 行に絞ると、こうなっていました。

id      │ level │ note
50000   │ ERROR │ con…
100000  │ ERROR │ con…

note の中身は connection reset by peer - retrying で 34 桁。列幅は見出しの note と、先頭・末尾に並ぶ ok だけで決まって 4 桁でした。上限の 40 桁に当たっていたわけではありません。絞り込んだ後こそ読みたい列が、絞り込んだせいで読めない状態です。

いまは、フィルタが効いている間は一致行から列幅を決め直します。上の表示はこうなります。

id      │ level │ note
50000   │ ERROR │ connection reset by peer - retrying
100000  │ ERROR │ connection reset by peer - retrying
  • 一致が 400 行以下(ふつうの絞り込み)は全部見て決めます。近似ですらありません。
  • 一致が多いときは両端 200 行ずつで止めます。一致行はファイル全体に散らばるので 1 行ずつ引くことになり、10GB で 2000 行なら 0.419 秒、400 行なら 0.084 秒。絞り込みが確定した瞬間に払う代金なので、上限を掛けました。
  • 打っている途中で一瞬 0 件になっても、列名の帯は空にしません。
  • 絞り込んでから構造化表示に入ったとき、一致行の 1 本目が列名になっていたのも直しました(列名は必ず先頭行から取ります)。

フィルタを解けば、元どおりファイル全体の桁に戻ります。

小さいファイルで、画面が食い違っていた

8MB 未満のファイルで、フィルタ ON のまま構造化表示へ切り替えると、画面の 3 箇所が別のことを言っていました。

見るところ 出ていたもの
本文 絞り込みの生テキスト(整形もされない)
列名の帯 一致行の 1 本目
ステータス 絞り込みの行数

順番の問題でした。整形を組んだ直後に検索バーを閉じる処理が走り、退避してあった元の全文で本文を上書きしていました。整形結果だけが消えて、帯と行数が残る。整形の前にフィルタを畳むようにしました。

小さいファイルでは、絞り込みは維持されません。 本文そのものを整形後のテキストへ差し替える作りなので、両立できません(「桁を揃えたまま grep」は 8MB 以上のファイルの機能です)。

確認したこと

配布するものと同じ .app で、両方の順番を通しています。

条件 結果
45MB・300 万行 CSV、構造化 → 絞り込み 34 桁の値が全部出る
同、絞り込み → 構造化 同じ。列名も id / level / note
絞り込みを解除 元の桁に戻る
10GB・8642 万行、5134 万件ヒット 詰まらない(漏斗を押して 0.30 秒で戻る)
4.2MB CSV、絞り込み → 構造化 本文・帯・行数が一致

616 のテストが緑。Apple Developer ID で署名し、公証を通しています——ダブルクリックで開きます(Apple Silicon / Intel 両対応・macOS 13+)。

v1.12.3 — 値ではなく、形を比べる

Choose a tag to compare

@MR-TABATA MR-TABATA released this 19 Aug 12:05
4680d0e

テスト環境から取ったデータと、本番から取ったデータを並べる。値が違うのは当たり前で、見たいのは「日付の形が揃っているか」だけ。それなのに diff は全行を「違う」と言い、読める差分は 1 つも残りませんでした。

値ではなく、形を比べる

表示 ▸ 比較(diff)▸ フォーマットを比較(⇧⌘F)

数字は 1 桁ずつ、文字の並びは 1 個に潰してから比べます。だから:

  • 2026-08-19 12:00:00 ERROR uid=412001-12-31 03:59:07 WARN uid=88同じ
  • 2026-08-192026/08/19違う(型の名前に置き換えないので、区切りの違いが残ります)
  • 0077違う(ゼロ埋めの食い違いは、環境差の定番なので消しません)
  • 123123違う(全角と半角)

仮名・漢字も値として畳みます。 日本語の CSV でこれを畳まないと、氏名や住所が全部差分になって「値は無視する」が嘘になります。ただし全角の記号と全角スペースは形として残します——,、全角空白と半角空白の食い違いは、まさに見つけたい違いだからです。

入口 4 つ(2 つのファイル・開いているドキュメント・クリップボード・URL)のどれから開いても効きます。5 つ目の入口ではなく、開いた後に切り替えるモードです。値の違いで読めない、と分かるのは開いてからなので。

この間、マージは封じます。 形が同じ=中身は違うので、片方を採ると中身が消えます。

メニューのチェックマークが、初めて出ます

validateMenuItem が AppKit から一度も呼ばれていませんでしたNSMenuItemValidation に適合していなかったため)。構造化表示がいまどのモードか、桁ルーラーが出ているか、末尾追従が入っているか——メニューを見ても分からない状態で出荷され続けていました。押せば動いていたので気づけませんでした。直したので、いまの状態がメニューに出ます。できない操作は灰色になります。

確認したこと

国税庁の法人番号 CSV から作った 20 万行で測りました(release ビルド)。

比べ方 結果
同じ行の値だけ差し替え 完全一致(ハッシュ 0.14 秒)
別のレコード同士 5,040 箇所が差分

下の行は正直に書いておきます。レコード自体が別物だと、空欄の有無や住所の桁ちがいで 1 行ごとに「形」が違うので、日付の差はその中に埋もれます。行が対応している比較(同じ抽出をやり直した、同じ行の値が置き換わった)では狙いどおりに効きますが、行が対応しない比較には「列ごとに形をまとめて突き合わせる」別の道具が要ります。それは次に作ります。

611 テスト green。配布と同じ .app で、4 つの入口・トグル・マージ封じまで通しました。


ダウンロード: MrEditor-1.12.3.dmg(署名・公証済み / macOS 13+)

v1.12.2 — 線を引いたら、その場で列になる

Choose a tag to compare

@MR-TABATA MR-TABATA released this 17 Aug 12:27
7975d11

1.12 で桁ガイドを引けるようにしましたが、引いても本文は何も変わりませんでした。列として読むにはメニューを 3 階層たどる必要があり、「線を引いたけど、で?」で終わる道具でした。そこを作り直しました。

線を引いたら、そのまま表になる

固定長のデータは、もともと桁が揃っています。 だから列に見せるのに整形は要りません——項目が 1 つおきに薄く塗られるだけで表になります。整形しないので、読み取り専用になりません。見ながら、そのまま直せます。

字が動く

  • Tab — 次の項目の桁まで空白が詰まり、後ろの字がその桁へずれます。⇧Tab で戻します(詰めた空白だけが消え、字は消えません)。タブ文字は入りません——固定長にタブが混ざると、他の道具で読んだ瞬間に桁が崩れるからです。
  • ⌥Tab — 2 行目以降も同じ桁割りへ揃います。切れ目がまだ無ければ、中身から桁割りを作ります(各項目の一番長いものが収まる幅。column -t と同じ考え方)。つまり、バラバラのテキストを開いて ⌥Tab を押すだけで表になります
  • 線を掴んで動かす — 桁割りが変わり、字もそこへ揃います(要らなければ ⌘Z)。

順番を覚えなくていい

入口はどれも単独で成立します。打つ → Tabいきなり ⌥Tab目盛りをクリック⇧⌥⌘K で 1-8,9-14,15-40 と打つ。桁に触る操作はルーラーを連れてくるので、先に ⌥⌘K を押しておく必要はありません。

ルーラーにはキャレットのいる項目が帯で出ます。右端の「⌥Tab で 2 行目以降も揃います」は、押すと実際に変わる行があるときだけ出て、揃え終われば消えます。

確認したこと

593 tests green。配布物と同じ .app で確認しています。

Apple Developer ID で署名し、Apple の公証を通しています。Apple Silicon / Intel の universal。

v1.12.1 — 浮きパネルの移動と、列名の帯

Choose a tag to compare

@MR-TABATA MR-TABATA released this 16 Aug 06:33
ffb1b66

1.10.3 と 1.11.1 で残していた宿題を 2 つ片付けました。

浮いている小窓を、好きな場所へ

検索バーと構造化表示のバナーは同じ右上に浮いていて、1.11.1 では「バナーが出たら検索バーを下げる」で凌いでいました。浮かせる物が増えるたびに逃がし方を足していくやり方は、組み合わせのぶんだけ破綻します。

  • 掴んで動かせるようになり、置いた場所を覚えます(次に開いてもそこに出ます)。
  • 戻したくなったら 表示 ▸ 浮きパネルの位置を戻す
  • 窓を縮めても画面の外に残りません。広げれば元の場所へ戻ります。

構造化表示に、列名の帯

桁は揃うのに、300 万行目まで下がると「この列が何か」は分からなくなっていました。

  • 列名が本文の上に固定されます(CSV/TSV はヘッダ行、NDJSON はキー、固定長は 1-8 などの桁)。
  • 帯の境界を掴むと列幅が変わります。 引きずっている間は線だけが動き、離したときに組み直すので、40 万行でも詰まりません。

変えた列幅はそのセッション限りです(構造化表示を抜けると既定に戻ります)。

確認したこと

553 tests green。配布物と同じ .app で、小ファイルと 40 万行の両方を通しています(掴んで動かす/終了して開き直しても同じ場所/構造化バナーを出しても動かした位置が消えない/CSV で列を広げる/固定長で列を詰めて 000… に切り詰まる/横スクロールで帯が本文と一緒に流れる)。

Apple Developer ID で署名し、Apple の公証を通しています。Apple Silicon / Intel の universal。

v1.12 — 桁ルーラーと、固定長の項目定義

Choose a tag to compare

@MR-TABATA MR-TABATA released this 15 Aug 13:17
8e46159

固定長のデータを、数えられるようにしました。

区切り文字があるものは構造化表示で列に開けるのに、固定長のレコードには何も効きませんでした。桁を数えるのは、指で画面をなぞる仕事のままでした。

入るもの

  • 桁ルーラー(表示 ▸ 桁ルーラー・⌥⌘K) — 本文の上に目盛りを出す。目盛りをクリックすると項目の切れ目に縦線(桁ガイド)が入り、掴んで動かせる。1 桁ずらすのに消して置き直す必要はない。
  • 数値で打てる(表示 ▸ 桁の項目定義…・⇧⌥⌘K) — 仕様書があるなら 1-8,9-14,15-40。全角の数字・カンマ・波ダッシュも受ける(仕様書はそう書かれている)。読めない書き方は一部だけ通さず、直るまで同じシートに戻る。
  • ファイルごとに覚える — 開き直すと、同じ定義とルーラーのまま開く。
  • 構造化表示に 5 つ目のモード=固定長 — 置いた切れ目がそのまま列になる。列名は 1-8 など桁そのもの。桁揃え・構造化中の検索/フィルタもそのまま効く。定義が無いまま選んだら、その場で訊く(中身から列を割り出せない唯一のモードなので)。

桁は文字数でなく表示幅(全角=2)で数えます。ガイド線は画面上の位置に引かれるので、文字数で数えると全角を含む行だけ線と中身がズレます。

確認したこと

537 tests green。配布物と同じ .app で、小ファイルと 40 万行の両方で通しています(定義 → 線が出る → ドラッグで桁を動かす → アプリを終了して開き直しても定義が戻る → 固定長で列として読める)。

Apple Developer ID で署名し、Apple の公証を通しています(ダブルクリックで開きます)。Apple Silicon / Intel の universal。

v1.11.2 — 他のアプリでの変更を自動で読み込む

Choose a tag to compare

@MR-TABATA MR-TABATA released this 14 Aug 10:57

他のアプリで直したのに、こちらは古い中身を見せ続けていた。エディタで書き換える・sed を回す・ブランチを切り替える —— ファイルは変わっているのに、開いたままの MrEditor は何も言わなかった。

  • 開いているファイルを見張り、未保存の変更が無ければその場で読み込み直す(キャレットとスクロール位置は保つ)。
  • 未保存なら潰さない。 「このファイルは他のアプリで変更されました」と帯で知らせ、読み込むかどうかを選ばせる。
  • 巨大ファイルは追記された分だけ索引を伸ばすtail -f と同じ経路)。10 GB のログが 1 行増えるたびに 8 秒かけて張り直すことはしない。
  • 監視は stat だけで内容を読まないので、10 GB を開いていてもコストは無視できる。書き込み途中を掴まないよう、同じ版を 2 回見てから取り込む。
  • 環境設定 ▸ 一般でオフにできる。オフでも帯は出す(古い内容を黙って見せ続けない)。

あわせて、追記を取り込んだ後に編集すると追記分が消える穴を塞いだ(末尾追従にも前からあった)。


Fix it in another app and this one kept showing you the old bytes.

  • Open files are watched: with no unsaved changes, the new contents load in place, keeping your caret and scroll position.
  • With unsaved changes nothing is overwritten — a banner says the file changed and lets you decide.
  • A large file that only grew extends its index instead of being reopened, so a 10 GB log does not pay 8 seconds per append.
  • Watching costs one stat per file — the contents are never read — and a change is taken only after the same version is seen twice, so a half-written file is never loaded.
  • Preferences ▸ General turns the automatic part off; the banner still appears.

Also fixes a hole where text appended by another process vanished the moment you started editing (Follow mode had it too).

macOS 13+ · Apple Silicon / Intel universal · Developer ID 署名 + 公証済み