Submit Search
Upload
Common Lisp製のテキストエディタLemにフレーム多重化機能をつくった
•
1 like
•
640 views
t-sin
Follow
Common Lisp製のテキストエディタにコントリビューションをしたので、その実装とかこぼれ話を発表しました。
Read less
Read more
Software
Report
Share
Report
Share
1 of 31
Download now
Download to read offline
Recommended
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
Tomoya Kawanishi
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
MITSUNARI Shigeo
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
Yugo Shimizu
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
Lispマシン・シミュレータの紹介
Lispマシン・シミュレータの紹介
たけおか しょうぞう
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
shigeki_ohtsu
できる!並列・並行プログラミング
できる!並列・並行プログラミング
Preferred Networks
Recommended
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
Tomoya Kawanishi
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
MITSUNARI Shigeo
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
リアルタイムサーバー 〜Erlang/OTPで作るPubSubサーバー〜
Yugo Shimizu
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
Lispマシン・シミュレータの紹介
Lispマシン・シミュレータの紹介
たけおか しょうぞう
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
そうだったのか! よくわかる process.nextTick() node.jsのイベントループを理解する
shigeki_ohtsu
できる!並列・並行プログラミング
できる!並列・並行プログラミング
Preferred Networks
Quine・難解プログラミングについて
Quine・難解プログラミングについて
mametter
例外設計における大罪
例外設計における大罪
Takuto Wada
C#とILとネイティブと
C#とILとネイティブと
信之 岩永
非同期処理の基礎
非同期処理の基礎
信之 岩永
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
ラムダ計算入門
ラムダ計算入門
Eita Sugimoto
メタプログラミングって何だろう
メタプログラミングって何だろう
Kota Mizushima
Go入門
Go入門
Takuya Ueda
圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド
Yoshihiro Mizoguchi
暗認本読書会7
暗認本読書会7
MITSUNARI Shigeo
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
Hiromi Ishii
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
Etsuji Nakai
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf
Kazuaki Ishizaki
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
Ryoma Sin'ya
GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)
なおき きしだ
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
Masahiro Sakai
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
Takeshi Yamamuro
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
MITSUNARI Shigeo
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
Kinuko Yasuda
Vimから見たemacs
Vimから見たemacs
Shougo
Common Lispっぽいものをつくっています
Common Lispっぽいものをつくっています
t-sin
More Related Content
What's hot
Quine・難解プログラミングについて
Quine・難解プログラミングについて
mametter
例外設計における大罪
例外設計における大罪
Takuto Wada
C#とILとネイティブと
C#とILとネイティブと
信之 岩永
非同期処理の基礎
非同期処理の基礎
信之 岩永
明日使えないすごいビット演算
明日使えないすごいビット演算
京大 マイコンクラブ
ラムダ計算入門
ラムダ計算入門
Eita Sugimoto
メタプログラミングって何だろう
メタプログラミングって何だろう
Kota Mizushima
Go入門
Go入門
Takuya Ueda
圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド
Yoshihiro Mizoguchi
暗認本読書会7
暗認本読書会7
MITSUNARI Shigeo
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
Hiromi Ishii
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
Etsuji Nakai
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf
Kazuaki Ishizaki
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
Ryoma Sin'ya
GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)
なおき きしだ
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
Masahiro Sakai
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
Takeshi Yamamuro
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
MITSUNARI Shigeo
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
MITSUNARI Shigeo
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
Kinuko Yasuda
What's hot
(20)
Quine・難解プログラミングについて
Quine・難解プログラミングについて
例外設計における大罪
例外設計における大罪
C#とILとネイティブと
C#とILとネイティブと
非同期処理の基礎
非同期処理の基礎
明日使えないすごいビット演算
明日使えないすごいビット演算
ラムダ計算入門
ラムダ計算入門
メタプログラミングって何だろう
メタプログラミングって何だろう
Go入門
Go入門
圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド
暗認本読書会7
暗認本読書会7
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
20221226_TITECH_lecture_ishizaki_public.pdf
20221226_TITECH_lecture_ishizaki_public.pdf
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
GPUをJavaで使う話(Java Casual Talks #1)
GPUをJavaで使う話(Java Casual Talks #1)
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
Similar to Common Lisp製のテキストエディタLemにフレーム多重化機能をつくった
Vimから見たemacs
Vimから見たemacs
Shougo
Common Lispっぽいものをつくっています
Common Lispっぽいものをつくっています
t-sin
Eclipse modeling 勉強会 dslについて
Eclipse modeling 勉強会 dslについて
Akira Tanaka
Emacs上のターミナルを最強に
Emacs上のターミナルを最強に
Lintaro Ina
うわ…私のEmacs力、低すぎ...?
うわ…私のEmacs力、低すぎ...?
Masahiro Sano
KLab Social Game Platform ~Symfony1.4活用事例~
KLab Social Game Platform ~Symfony1.4活用事例~
KLab株式会社
Similar to Common Lisp製のテキストエディタLemにフレーム多重化機能をつくった
(6)
Vimから見たemacs
Vimから見たemacs
Common Lispっぽいものをつくっています
Common Lispっぽいものをつくっています
Eclipse modeling 勉強会 dslについて
Eclipse modeling 勉強会 dslについて
Emacs上のターミナルを最強に
Emacs上のターミナルを最強に
うわ…私のEmacs力、低すぎ...?
うわ…私のEmacs力、低すぎ...?
KLab Social Game Platform ~Symfony1.4活用事例~
KLab Social Game Platform ~Symfony1.4活用事例~
More from t-sin
続・SECDマシン
続・SECDマシン
t-sin
SECDマシン 実装と動きとその他もろもろについて
SECDマシン 実装と動きとその他もろもろについて
t-sin
Sounds Like Common Lisp - ゼロからはじめるサウンドプログラミング
Sounds Like Common Lisp - ゼロからはじめるサウンドプログラミング
t-sin
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した
t-sin
PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)
t-sin
バッテリー強奪! PythonをCommon Lispから使う
バッテリー強奪! PythonをCommon Lispから使う
t-sin
Common lispでグラフィックアート
Common lispでグラフィックアート
t-sin
One - Common Lispでもワンライナーしたい
One - Common Lispでもワンライナーしたい
t-sin
Inquisitor -Common Lispに文字コード判定を-
Inquisitor -Common Lispに文字コード判定を-
t-sin
More from t-sin
(9)
続・SECDマシン
続・SECDマシン
SECDマシン 実装と動きとその他もろもろについて
SECDマシン 実装と動きとその他もろもろについて
Sounds Like Common Lisp - ゼロからはじめるサウンドプログラミング
Sounds Like Common Lisp - ゼロからはじめるサウンドプログラミング
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した
PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)
バッテリー強奪! PythonをCommon Lispから使う
バッテリー強奪! PythonをCommon Lispから使う
Common lispでグラフィックアート
Common lispでグラフィックアート
One - Common Lispでもワンライナーしたい
One - Common Lispでもワンライナーしたい
Inquisitor -Common Lispに文字コード判定を-
Inquisitor -Common Lispに文字コード判定を-
Common Lisp製のテキストエディタLemにフレーム多重化機能をつくった
1.
Common Lisp製のテキストエディタ Lemにフレーム多重化機能をつくった t-sin (@sin_clav) 2020-08-27,
lispmeetup #89
2.
もくじ ● Lemについて ● フレーム多重化機能について ● Lemの描画関連用語について ● フレーム多重化機能対応でやったこと
3.
Lemってなんだ? ● Common Lisp製テキストエディタ
4.
Lemってなんだ? ● Common Lisp製テキストエディタ ● https://github.com/cxxxr/lem ● GNU Emacsのような操作感 ● vi-modeもある ● Common
Lispとの統合がよい
5.
フレーム多重化機能って? ● tmux ● あるいはGNU Emacsのelscreen ● 画面中のバッファ配置を複数記憶しそれらを 切り替えられる機能 ● つまりtmux
6.
フレーム多重化機能って? frame-multiplexerの ヘッダウィンドウ #付きが現在のフレーム
7.
Lemの描画関係用語 (ユーザが操作するもの) ウィンドウ モードライン バッファ ミニバッファ/エコーエリア floatingウィンドウ
8.
Lemの描画関係用語 (ユーザが操作するもの) ● ウィンドウ – 編集領域。C-x oで切り替えているアレ –
window-tree構造体により2分木で分割を表現 ● スクリーン – 各バッファの表示を抽象的に担当する構造体 ● 裏に具体的な描画を担当する「ビュー」がある(後述) – バッファとは1対他の関係(同じバッファを複数表示) ● バッファ – 編集内容を保持している構造体 – キー入力するとバッファの中身が書き換えられる
9.
Lemの描画関係用語 (実際に描画するためのもの) ● ディスプレイ – 描画している画面 – たとえば端末エミュレータなど ● ビュー –
スクリーンを実際の画面に表示するためのもの – スクリーンとは1対1の関係 ● フロントエンド – ディスプレイやビューの定義と描画を担当する – ncursesやelectronなど
10.
Lemの描画関係用語 (実際に描画するためのもの) Lem上のデータ構造 フロントエンド ビュー ビュー ビュー ビュー ディスプレイ ウィンドウ とスクリーン ウィンドウツリー
11.
フレーム多重化機能対応でやったこと ● 「フレーム」の概念をLemに追加 – ウィンドウ(つまり画面構成)を保持するもの ● Lemの描画処理をフレームに対して働くよう変更 – 起動時に1個のフレームを作成しておく ● フレームを複数持てるように拡張 –
仮想フレームって呼ぶことにした ● 切り替えコマンドを追加 – 大事
12.
フレーム多重化機能対応でやったこと ● 「フレーム」の概念をLemに追加 – ウィンドウ(つまり画面構成)を保持するもの ● Lemの描画処理をフレームに対して働くよう変更 – 起動時に1個のフレームを作成しておく ● フレームを複数持てるように拡張 –
仮想フレームって呼ぶことにした ● 切り替えコマンドを追加 – 大事
13.
フレームの概念を追加 ● 画面表示関係のグローバル変数を集約 ● frame構造体を作成 ● 以下のものを持つ – 現在操作しているウィンドウ – ウィンドウ構成(分割状態) –
ミニバッファのウィンドウ – ミニバッファのバッファ – 補完時に出てくるウィンドウ など…
14.
フレームの概念を追加 Lem上のデータ構造 フロントエンド ディスプレイ フレーム
15.
フレームの概念を追加 ● frame構造体 – 現在の「ウィンドウ」 – ウィンドウ構成(window-tree) –
ミニバッファ関連 – 補完時のfloatingウィンドウ – ヘッダウィンドウ – ウィンドウまわりのフラグ (defstruct frame ;; window current-window (window-tree nil) (floating-windows '()) (header-windows '()) (modified-floating-windows nil) (modified-header-windows nil) ;; minibuffer minibuffer-buffer echoarea-buffer (minibuffer-window nil) (minibuffer-calls-window nil) (minibuffer-start-charpos nil))
16.
フレーム多重化機能対応でやったこと ● 「フレーム」の概念をLemに追加 – ウィンドウ(つまり画面構成)を保持するもの ● Lemの描画処理をフレームに対して働くよう変更 – 起動時に1個のフレームを作成しておく ● フレームを複数持てるように拡張 –
仮想フレームって呼ぶことにした ● 切り替えコマンドを追加 – 大事
17.
フレームに対する描画処理 ● Lemの起動時に1個のフレームを作成 ● グローバル変数を使う処理が現在のフレームに 対して働くようにぜんぶ変更 ● 動作確認 – 大事
18.
フレームに対する描画処理(変更例) ● floating-windowに対する削除処理 – 前: グローバルな変数に対してsetf –
後: グローバルなフレームのスロットにsetf (defmethod %delete-window ((window floating-window)) (when (eq window (current-window)) (editor-error "Can not delete this window")) - (setf *modified-floating-windows* t) - (setf *floating-windows* - (delete window *floating-windows*))) + (setf (frame-modified-floating-windows (current-frame)) t) + (setf (frame-floating-windows (current-frame)) + (delete window (frame-floating-windows (current-frame)))))
19.
ここまでのPR ● https://github.com/cxxxr/lem/pull/500
20.
フレーム多重化機能対応でやったこと ● 「フレーム」の概念をLemに追加 – ウィンドウ(つまり画面構成)を保持するもの ● Lemの描画処理をフレームに対して働くよう変更 – 起動時に1個のフレームを作成しておく ● フレームを複数持てるように拡張 –
仮想フレームって呼ぶことにした ● 切り替えコマンドを追加 – 大事
21.
フレームを複数持てるよう拡張 ● やること – 「仮想フレーム」の用意 ● フレームを複数保持するスロット ● 現在表示中のフレームを置くスロット – 仮想フレームの描画処理の実装
22.
フレームを複数持てるよう拡張 ● 仮想フレームの用意 – フレームの配列 – 現在のフレーム –
ディスプレイ幅・高さ – 仮想フレームが変更されたかフラグ – 仮想フレームのヘッダ用バッファ ● (いまvfはvirtual-frameにリネームされてます) ● ディスプレイ-仮想フレームの対応表も追加 – ただのハッシュテーブル – キーはディスプレイ (現在は1つしかない) – Lemが複数の表示画面を持つときのため (defclass vf (header-window) ((frames) (current) (display-width) (display-height) (changed) (buffer)))
23.
フレームを複数持てるよう拡張 これが仮想フレーム 兼 ヘッダウィンドウ
24.
フレームを複数持てるよう拡張 ● vfはLemのヘッダウィンドウなので ● Lemのウィンドウ再描画メソッドを実装する必要あり ● 仮想フレームの描画処理 – ヘッダを描画 – 現在のフレームのウィンドウをぜんぶ描画 –
仮想フレームの描画フラグをnilに設定 (defmethod window-redraw ((window vf) force) ;; draw button for frames ... ;; redraw windows in current frame ... ;; clear all vf-changed to nil because of applying redraw ... (call-next-method))
25.
フレーム多重化機能対応でやったこと ● 「フレーム」の概念をLemに追加 – ウィンドウ(つまり画面構成)を保持するもの ● Lemの描画処理をフレームに対して働くよう変更 – 起動時に1個のフレームを作成しておく ● フレームを複数持てるように拡張 –
仮想フレームって呼ぶことにした ● 切り替えコマンドを追加 – 大事
26.
操作の実装とコマンドの定義 ● 基本的なフレーム操作 – フレーム多重化機能の起動・終了処理 – フレームの追加・削除 –
フレームの切り替え ● どの操作でも最後にvf-changedをtにする – 現在のフレームを変更した後に再描画させるため ● 操作用コマンド – toggle-frame-multiplexer – frame-multiplexer-create (C-z c) – frame-multiplexer-delete (C-z d) – frame-multiplexer-prev (C-z p) – frame-multiplexer-next (C-z n)
27.
操作の実装とコマンドの定義 (例) ● 仮想フレーム上のフレーム切り替え(前へ) – 仮想フレーム上の1つ前のフレームを探し、 –
そのフレームを現在のLemのフレームに設定し、 – 再描画フラグをtに設定する。 (define-command frame-multiplexer-prev () () (check-frame-multiplexer-enabled) (let* ((vf (gethash (implementation) *virtual-frame-map*)) (frame (search-previous-frame vf (virtual-frame-current vf)))) (when frame (setf (virtual-frame-current vf) frame) (lem:map-frame (implementation) frame)) (lem::change-display-size-hook) (setf (virtual-frame-changed vf) t)))
28.
ここまでのPR ● https://github.com/cxxxr/lem/pull/501 このPRのときはfm-mode という名前でした。 (いまはframe-multiplexer)
29.
こぼれ話 ● 実装にあたってLemのコードを調査した – よくできててかなり勉強になった – 描画の用語の整理結果はWikiに記載した https://github.com/cxxxr/lem/wiki/Lem's-displaying-concepts –
起動時の流れも調べた https://gist.github.com/t-sin/cc0d036e40669395fd41cfd48bb9c997 ● 最初はfm-modeという名前で作っていたが Lemのdefine-modeを使っておらず実はモードではなかった – frame-multiplexerに名称変更 – lem/modes/fm-mode/ から lem/lib/core/frame-multiplexer.lisp に – 地味にcoreに取り込まれた🎊
30.
こぼれ話 ● 現在はバッファリスト(C-x bの対象)が共有されている – elscreenの動き –
cxxxr氏より「作業を分けるためバッファリスト非共有がいい」 – ノリノリで雑ハックし、激しいバグを生む ● PR: https://github.com/cxxxr/lem/pull/504 ● Lemの非公開関数でグローバル変数をもりもり変更するマナーの悪いコードだっ たのでいったんクローズ ● 事前に設計をちゃんとしましょう ● ちなみにGNU Emacsで仮想フレームに対応するものは window-configurationというのだそう – https://www.gnu.org/software/emacs/manual/html_node/elisp/Window-Configurations.html – @conao_3 さんに教えてもらいました ● https://twitter.com/conao_3/status/1291710740294901760
31.
まとめ ● Lemにフレーム多重化機能を実装した ● Lemは読むとCommon Lispの勉強になる – clrhash関数など –
http://www.lispworks.com/documentation/HyperSpec/Body/f_clrhas.htm ● Lemは大きなソフトウェアなのでPRを投げると Common Lispチョットデキル…という気持ちになれる ● 事前の設計は大事
Download now