defstruct(構造体定義) について
common lisp の構造体の使い方がやっとわかったのでメモ
- こんな感じで構造体を作ることができる
? (defstruct human (height 0) (weight 0)) HUMAN ? (make-human) ;; デフォルトのコンストラクタ名は make-<構造体名> #S(HUMAN :HEIGHT 0 :WEIGHT 0) ? (make-human :height 999) #S(HUMAN :HEIGHT 999 :WEIGHT 0) ? (make-human :weight 999) #S(HUMAN :HEIGHT 0 :WEIGHT 999) ? (make-human :height 1 :weight 2) #S(HUMAN :HEIGHT 1 :WEIGHT 2)
- 引数 :constructor で 構造体を生成する関数名を指定することができる
? (defstruct (keymap (:constructor aaa)) (a 1)) KEYMAP ? (aaa) #S(KEYMAP :A 1) ? (aaa :a 100) #S(KEYMAP :A 100) ? (make-keymap) ;; デフォルトの構造体コンストラクタは使えない > Error: Undefined function MAKE-KEYMAP called with arguments () . > While executing: CCL::TOPLEVEL-EVAL, in process listener(1). > Type :GO to continue, :POP to abort, :R for a list of available restarts. > If continued: Retry applying MAKE-KEYMAP to NIL. > Type :? for other options. 1 >
- 引数 :print-function で渡した関数で表示方法を規定することができる
(defun print-hoge (hoge stream depth) (format stream "#hoge<~Ahoge>" (hoge-hoge hoge))) ;Compiler warnings : ; In PRINT-HOGE: Undefined function HOGE-HOGE ; In PRINT-HOGE: Unused lexical variable DEPTH PRINT-HOGE ? (defstruct (hoge (:print-function print-hoge)) (hoge 0)) HOGE ? (make-hoge) #hoge<0hoge> ? (make-hoge :hoge 1000) #hoge<1000hoge>
参考
素因数分解をしてみた
素因数分解をしてみたのでメモ
(defun primep-1 (n i) (cond ((> i (sqrt n)) T) ((zerop (mod n i)) nil) (t (primep-1 n (1+ i))))) (defun primep (number) (primep-1 number 2)) (defun next-prime (n) (cond ((primep n) n) (t (next-prime (1+ n))))) (defun factoring-1 (n divisor) (cond ((zerop n) n) ((primep n) (format t " ~A ~%" n) n) ((zerop (mod n divisor)) (format t "~A| ~A ~%----------~%" divisor n) (list divisor (factoring-1 (floor (/ n divisor)) divisor))) (t (factoring-1 n (next-prime (1+ divisor)))))) (defun factoring (n) (factoring-1 n 2))
こんな感じで使います
$ ros run ? (factoring 360) 2| 360 ---------- 2| 180 ---------- 2| 90 ---------- 3| 45 ---------- 3| 15 ---------- 5 (2 (2 (2 (3 (3 5))))) ?
※ 標準出力をちょっとだけ整えました
Ubuntu18.04 で apt upgrade が失敗
概要
定期的に apt upgrade
を実行しているのですが、今日に限って急に失敗。
とりあえず upgradeができるまでは成功したので手順を書いておきます
ながれ
こんな感じで対応しました
ことのはじまり
apt upgrade に失敗
$ sudo apt upgrade パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 これらを直すためには 'apt --fix-broken install' を実行する必要があるかもしれません。 以下のパッケージには満たせない依存関係があります: libglvnd-dev : 依存: libglvnd0 (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています 依存: libglvnd-core-dev (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています 依存: libegl1 (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています 依存: libgles2 (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています 依存: libgl1 (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています 依存: libglx0 (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています 依存: libopengl0 (= 1.0.0-2ubuntu2.1) しかし、1.0.0-2ubuntu2.2 はインストールされています E: 未解決の依存関係です。'apt --fix-broken install' を実行してみてください (または解法を明示してください)。
言われたとおり apt --fix-broken
$ sudo apt --fix-broken install パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 依存関係を解決しています ... 完了 以下のパッケージが自動でインストールされましたが、もう必要とされていません: linux-headers-4.15.0-30 linux-headers-4.15.0-30-generic linux-image-4.15.0-30-generic linux-modules-4.15.0-30-generic linux-modules-extra-4.15.0-30-generic これを削除するには 'sudo apt autoremove' を利用してください。 以下の追加パッケージがインストールされます: libgles1 libglvnd-dev 以下のパッケージが新たにインストールされます: libgles1 以下のパッケージはアップグレードされます: libglvnd-dev アップグレード: 1 個、新規インストール: 1 個、削除: 0 個、保留: 53 個。 14.6 kB 中 0 B のアーカイブを取得する必要があります。 この操作後に追加で 66.6 kB のディスク容量が消費されます。 続行しますか? [Y/n] y (データベースを読み込んでいます ... 現在 276241 個のファイルとディレクトリがインストールされています。) .../libgles1_1.0.0-2ubuntu2.2_amd64.deb を展開する準備をしています ... libgles1:amd64 (1.0.0-2ubuntu2.2) を展開しています... dpkg: アーカイブ /var/cache/apt/archives/libgles1_1.0.0-2ubuntu2.2_amd64.deb の処理中にエラーが発生しました (--unpack): '/usr/lib/x86_64-linux-gnu/libGLESv1_CM.so.1' を上書きしようとしています。これはパッケージ nvidia-340 340.106-0ubuntu3 にも存在します .../libglvnd-dev_1.0.0-2ubuntu2.2_amd64.deb を展開する準備をしています ... libglvnd-dev:amd64 (1.0.0-2ubuntu2.2) で (1.0.0-2ubuntu2.1 に) 上書き展開しています ... dpkg: アーカイブ /var/cache/apt/archives/libglvnd-dev_1.0.0-2ubuntu2.2_amd64.deb の処理中にエラーが発生しました (--unpack): '/usr/lib/x86_64-linux-gnu/libGLESv1_CM.so' を上書きしようとしています。これはパッケージ nvidia-340 340.106-0ubuntu3 にも存在します 処理中にエラーが発生しました: /var/cache/apt/archives/libgles1_1.0.0-2ubuntu2.2_amd64.deb /var/cache/apt/archives/libglvnd-dev_1.0.0-2ubuntu2.2_amd64.deb E: Sub-process /usr/bin/dpkg returned an error code (1)
パッケージ nvidia-340 340.106-0ubuntu3 にも存在します
これが問題なんだな。
$ sudo apt list nvidia-340 一覧表示... 完了 nvidia-340/bionic,now 340.106-0ubuntu3 amd64 [インストール済み]
よし、このパッケージを消しちゃお。
ほんとに消していいかは不明だけど、だめだったら入れ直せばええやろ!ガハハ!
apt で消せなかったので dpkg で直接処すよ
apt
、aptitude
で最初は消そうと思ったんですがなんかエラーが出てだめでした。
なので dpkg
で直接やってしまいます
$ sudo dpkg -l | grep nvidia-340 ii nvidia-340 340.106-0ubuntu3 amd64 NVIDIA binary driver - version 340.106 ~$ sudo dpkg -r nvidia-340 (データベースを読み込んでいます ... 現在 276240 個のファイルとディレクトリがインストールされています。) nvidia-340 (340.106-0ubuntu3) を削除しています ... Stopping nvidia-persistenced nvidia-persistenced: no process found Done. Removing all DKMS Modules Done.
なんかたくさん出てきたけどうまくいったみたい。
fix-broken 再チャレンジ
$ sudo apt --fix-broken install パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 依存関係を解決しています ... 完了 以下のパッケージが自動でインストールされましたが、もう必要とされていません: libcuda1-340 libxnvctrl0 linux-headers-4.15.0-30 linux-headers-4.15.0-30-generic linux-image-4.15.0-30-generic linux-modules-4.15.0-30-generic linux-modules-extra-4.15.0-30-generic nvidia-settings screen-resolution-extra これを削除するには 'sudo apt autoremove' を利用してください。 以下の追加パッケージがインストールされます: libgles1 libglvnd-dev 以下のパッケージが新たにインストールされます: libgles1 以下のパッケージはアップグレードされます: libglvnd-dev アップグレード: 1 個、新規インストール: 1 個、削除: 0 個、保留: 53 個。 14.6 kB 中 0 B のアーカイブを取得する必要があります。 この操作後に追加で 66.6 kB のディスク容量が消費されます。 続行しますか? [Y/n] y (データベースを読み込んでいます ... 現在 275959 個のファイルとディレクトリがインストールされています。) .../libgles1_1.0.0-2ubuntu2.2_amd64.deb を展開する準備をしています ... libgles1:amd64 (1.0.0-2ubuntu2.2) を展開しています... .../libglvnd-dev_1.0.0-2ubuntu2.2_amd64.deb を展開する準備をしています ... libglvnd-dev:amd64 (1.0.0-2ubuntu2.2) で (1.0.0-2ubuntu2.1 に) 上書き展開しています ... libgles1:amd64 (1.0.0-2ubuntu2.2) を設定しています ... libglvnd-dev:amd64 (1.0.0-2ubuntu2.2) を設定しています ... libc-bin (2.27-3ubuntu1) のトリガを処理しています ...
成功!
apt upgrade
にも成功!
いちおう 消したパッケージを復旧しておく
$ sudo apt install nvidia-340/bionic パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 'nvidia-340' のバージョン '340.106-0ubuntu3' (Ubuntu:18.04/bionic [amd64]) を選択しました 以下のパッケージが自動でインストールされましたが、もう必要とされていません: linux-headers-4.15.0-30 linux-headers-4.15.0-30-generic linux-image-4.15.0-30-generic linux-modules-4.15.0-30-generic linux-modules-extra-4.15.0-30-generic これを削除するには 'sudo apt autoremove' を利用してください。 以下のパッケージが新たにインストールされます: nvidia-340 アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。 51.9 MB のアーカイブを取得する必要があります。 この操作後に追加で 274 MB のディスク容量が消費されます。 取得:1 http://jp.archive.ubuntu.com/ubuntu bionic/restricted amd64 nvidia-340 amd64 340.106-0ubuntu3 [51.9 MB] 51.9 MB を 31秒 で取得しました (1,651 kB/s) 以前に未選択のパッケージ nvidia-340 を選択しています。 (データベースを読み込んでいます ... 現在 275967 個のファイルとディレクトリがインストールされています。) .../nvidia-340_340.106-0ubuntu3_amd64.deb を展開する準備をしています ... 'nvidia-340 による /usr/lib/x86_64-linux-gnu/libGL.so.1 から /usr/lib/x86_64-linux-gnu/libGL.so.1.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/i386-linux-gnu/libGL.so.1 から /usr/lib/i386-linux-gnu/libGL.so.1.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/x86_64-linux-gnu/libGL.so から /usr/lib/x86_64-linux-gnu/libGL.so.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/i386-linux-gnu/libGL.so から /usr/lib/i386-linux-gnu/libGL.so.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/x86_64-linux-gnu/libEGL.so.1 から /usr/lib/x86_64-linux-gnu/libEGL.so.1.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/i386-linux-gnu/libEGL.so.1 から /usr/lib/i386-linux-gnu/libEGL.so.1.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/x86_64-linux-gnu/libEGL.so から /usr/lib/x86_64-linux-gnu/libEGL.so.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/i386-linux-gnu/libEGL.so から /usr/lib/i386-linux-gnu/libEGL.so.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/x86_64-linux-gnu/libGLESv2.so から /usr/lib/x86_64-linux-gnu/libGLESv2.so.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/i386-linux-gnu/libGLESv2.so から /usr/lib/i386-linux-gnu/libGLESv2.so.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/x86_64-linux-gnu/libGLESv2.so.2 から /usr/lib/x86_64-linux-gnu/libGLESv2.so.2.distrib への退避 (divert)' を追加しています 'nvidia-340 による /usr/lib/i386-linux-gnu/libGLESv2.so.2 から /usr/lib/i386-linux-gnu/libGLESv2.so.2.distrib への退避 (divert)' を追加しています nvidia-340 (340.106-0ubuntu3) を展開しています... dpkg: アーカイブ /var/cache/apt/archives/nvidia-340_340.106-0ubuntu3_amd64.deb の処理中にエラーが発生しました (--unpack): '/usr/lib/x86_64-linux-gnu/libGLESv1_CM.so' を上書きしようとしています。これはパッケージ libglvnd-dev:amd64 1.0.0-2ubuntu2.2 にも存在します 処理中にエラーが発生しました: /var/cache/apt/archives/nvidia-340_340.106-0ubuntu3_amd64.deb E: Sub-process /usr/bin/dpkg returned an error code (1)
だめみたい。
まえっか。ガハハ!
その後
nvidia パッケージで問題が起きてるっていう警告は出ていますが
再起動、問題なく動きました。
しばらく様子見・・・
Caveman2 + keycloak で 認証サンプルを作ってみた
以下の記事を参考にしながらCaveman2 + Keycloak でOpenID connectをするサンプルを作ってみたいと思います
注意! OpenID 初心者によるサンプル実装ですので ご自身で使用するときは しっかりした調査とテストをよろしくおねがいします
Caveman2 をインストール
$ ros install caveman2
プロジェクト作成
~/common-lisp
ディレクトリ内であれば (ql:quickload :****) でロード可能なので
そこを作業ディレクトリにします
$ mkdir ~/common-lisp && cd ~/common-lisp
プロジェクトのひな型を作り、Webサーバを起動します
$ ros -s caveman2 -e "(caveman2:make-project #P\"openid-connect\" :auther \"moremagic\")" writing openid-connect/openid-connect.asd writing openid-connect/openid-connect-test.asd writing openid-connect/app.lisp writing openid-connect/README.markdown writing openid-connect/.gitignore writing openid-connect/db/schema.sql writing openid-connect/src/web.lisp writing openid-connect/src/view.lisp writing openid-connect/src/main.lisp writing openid-connect/src/db.lisp writing openid-connect/src/config.lisp writing openid-connect/static/css/main.css writing openid-connect/templates/index.html writing openid-connect/templates/_errors/404.html writing openid-connect/templates/layouts/default.html writing openid-connect/tests/openid-connect.lisp $ ros -s openid-connect -e "(openid-connect:start)" run To load "openid-connect": Load 1 ASDF system: openid-connect ; Loading "openid-connect" Hunchentoot server is started. Listening on localhost:5000. Clozure Common Lisp Version 1.11.5/v1.11.5 (LinuxX8664) For more information about CCL, please see http://ccl.clozure.com. CCL is free software. It is distributed under the terms of the Apache Licence, Version 2.0. ?
http://localhost:5000 でWebアプリケーションが起動します。
停止したい場合は (openid-connect:stop)
もしくは (quit)
と打つことでWebアプリケーションが停止します
keycloak の起動
Docker で keycloak Imageを起動します
docker run -d -p 18080:8080 \ -e KEYCLOAK_USER=admin \ -e KEYCLOAK_PASSWORD=admin \ --name keycloak \ jboss/keycloak
http://localhost:18080/auth/admin/ にアクセス。admin / admin でログインできます
Keycloakの設定
client 設定を追加します
Instralletion からクライアントシークレット等を取得します
Client側に認証コードを実装します
git diff
~/common-lisp/openid-connect$ git diff diff --git a/openid-connect.asd b/openid-connect.asd index 35dff1e..ac20e92 100644 --- a/openid-connect.asd +++ b/openid-connect.asd @@ -17,7 +17,13 @@ ;; for DB "datafly" - "sxql") + "sxql" + + ;; for OAuth + "dexador" + "cl-base64" + "secure-random" + "jsown") :components ((:module "src" :components ((:file "main" :depends-on ("config" "view" "db")) diff --git a/src/web.lisp b/src/web.lisp index 45fe73d..a725828 100644 --- a/src/web.lisp +++ b/src/web.lisp @@ -6,7 +6,8 @@ :openid-connect.view :openid-connect.db :datafly - :sxql) + :sxql + :quri) (:export :*web*)) (in-package :openid-connect.web) @@ -33,3 +34,135 @@ (declare (ignore app)) (merge-pathnames #P"_errors/404.html" *template-directory*)) + +;; auth parameter +(defparameter +keycloak-client-id+ + "openid-connect") +(defparameter +keycloak-client-secret+ + "9bc0468f-ce9b-4c90-ac93-4837b57494ab") +(defparameter +keycloak-auth-url+ + "http://localhost:18080/auth/realms/master/protocol/openid-connect/auth") +(defparameter +keycloak-token-url+ + "http://localhost:18080/auth/realms/master/protocol/openid-connect/token") +(defparameter +keycloak-token-info-url+ + "http://localhost:18080/auth/realms/master/protocol/openid-connect/userinfo") +(defparameter +keycloak-logout-url+ + "http://localhost:18080/auth/realms/master/protocol/openid-connect/logout") +(defparameter +keycloak-redirect-uri+ + "http://localhost:5000/oauth2callback") + +;; +;; Utility functions + +(defun get-keycloak-auth-url (state-token) + "keycloakアカウントでの認証URLを生成" + (render-uri + (make-uri :defaults +keycloak-auth-url+ + :query `(("client_id" . ,+keycloak-client-id+) + ("redirect_uri" . ,+keycloak-redirect-uri+) + ("scope" . "openid profile email") + ("response_type" . "code") + ("approval_prompt" . "force") + ("access_type" . "offline") + ("state" . ,state-token))))) + +(defun request-keycloak-token (code) + "トークンを要請" + (format t "[DEBUG] call request-token ~A~%" code) + (dex:post +keycloak-token-url+ + :content `(("code" . ,code) + ("client_id" . ,+keycloak-client-id+) + ("client_secret" . ,+keycloak-client-secret+) + ("redirect_uri" . ,+keycloak-redirect-uri+) + ("grant_type" . "authorization_code")))) + +(defun request-keycloak-token-info (access_token) + "トークン情報を要請" + (format t "[DEBUG]===========================================~%") + (format t "[DEBUG][request-keycloak-token-info] '~A'~%" access_token) + (dex:post +keycloak-token-info-url+ + :headers `(("content-type" . "application/json") + ("Accept" . "application/json") + ("Authorization" . ,(concatenate `string "Bearer " access_token))) + :content `())) + +(defun loginp () + "ログインしているかどうかを確認" + (format t "[DEBUG] session in accsess_token '~A'~%" (gethash :access_token *session* nil)) + (not (null (gethash :access_token *session* nil)))) + +(defun logout (refresh_token) + "ログアウト処理" + (format t "[DEBUG]logout api call...") + (dex:post +keycloak-logout-url+ + :headers `(("Content-Type" . "application/x-www-form-urlencoded")) + :content `(("client_id" . ,+keycloak-client-id+) + ("client_secret" . ,+keycloak-client-secret+) + ("refresh_token" . ,refresh_token ) + ))) + +(defroute "/" () + (if (loginp) + (redirect "/home") + (render #P"index.html"))) + +(defroute "/home" () + (if (loginp) + (render #P"home.html") + (redirect "/"))) + +(defroute ("/auth-keycloak" :method :POST) () + (let ((state-token + (cl-base64:usb8-array-to-base64-string + (secure-random:bytes 32 secure-random:*generator*)))) + (setf (gethash :oauth-keycloak *session*) (acons :state state-token (list))) + (redirect (get-keycloak-auth-url state-token)))) + +(defroute ("/oauth2callback" :method :GET) (&key |error| |state| |code|) + ;; エラーが発生した場合はエラーを表示してそのままルートにリダイレクト + (unless (null |error|) + (format t "Error: ~A~%" |error|) + (redirect "/")) + (let ((session-oauth-keycloak (gethash :oauth-keycloak *session* nil))) + ;; セッションにステートトークンが存在するか確認 + (if (not (null (assoc :state session-oauth-keycloak))) + ;; セッションのステートトークンがレスポンスのステートトークンと一致するか確認 + (if (string= (cdr (assoc :state session-oauth-keycloak)) |state|) + ;; レスポンスに認証コードが存在するか確認 + (if (not (null |code|)) + ;; keycloakの認証サーバーにトークンを要請 + (let ((response (jsown:parse (request-keycloak-token |code|)))) + ;; ログイン成功。access_tokenを取り出してセッションの:access_tokenに格納 + (format t "[DEBUG] response '~A'~%" response) + (setf (gethash :access_token *session*) (jsown:val response "access_token")) + (setf (gethash :refresh_token *session*) (jsown:val response "refresh_token")) + (format t "[DEBUG] refresh_token '~A'~%" (gethash :refresh_token *session*)) + + ;; トークンが有効か確認(ライフタイムが残っているか?) + ;; さらにIDトークンの存在を確認 + (if (and (> (jsown:val response "expires_in") 0) + (not (null (jsown:val response "id_token")))) + ;; IDトークンをkeycloakに投げてユーザー情報を取得 + ;; この処理は不要かも + (let ((api-result + (jsown:parse (request-keycloak-token-info (gethash :access_token *session*))))) + + ;; ユーザ名を取り出してセッションの:preferred_usernameに格納 + ;; 本来ならここでJWTをばらして、ロール等の情報をセッションに登録をする + (let ((preferred_username (jsown:val api-result "preferred_username"))) + (format t "Signin: success keycloak OAuth '~A'~%" preferred_username) + (setf (gethash :preferred_username *session*) preferred_username) + (redirect "/home"))))))))) + ;; 認証に失敗した場合はHTTP 401認証エラーコードを投げる + (throw-code 401)) + +(defroute "/logout" () + (if (loginp) + (progn + (format t "[DEBUG] refresh_token '~A'~%" (gethash :refresh_token *session*)) + (logout (gethash :refresh_token *session*)) + (setf (gethash :access_token *session*) nil) + (setf (gethash :refresh_token *session*) nil) + (redirect "/")) + (render #P"index.html"))) + diff --git a/templates/index.html b/templates/index.html index 6a3c687..c45861e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,5 +3,9 @@ {% block content %} <div id="main"> Welcome to <a href="http://8arrow.org/caveman/">Caveman2</a>! + <form action="/auth-keycloak" method="post"> + <button>Login with Keycloak</button> + </form> </div> + {% endblock %}
実行
http://localhost:5000 にアクセス。loginしてみます
admin/admin
login 成功! logout押してみると・・・
ログアウトできました
ここまでの成果物はここにおいてあります。
大変だった・・・
チェックアウトしたソースコードから lemを動かす
(前の記事からの続きです)
チェックアウトしたソースコードをちょっとだけいじって
REPL から起動することに成功したのでメモ。
ソースをちょっとだけ改変
Visual mode のコードをちょっとだけ変えてみます
~/.roswell/local-project/cxxxr/lem/lem-vi-mode/visual.lisp
$ git diff --- a/lem-vi-mode/visual.lisp +++ b/lem-vi-mode/visual.lisp (define-command vi-visual-line () () (if (visual-line-p) (vi-visual-end) (progn (change-state 'visual 'visual-line) - (message "-- VISUAL LINE --")))) + (message "-- VISUAL LINEa --"))))
起動
$ ros run * (ql:quickload :lem-ncurses) To load "lem-ncurses": Load 1 ASDF system: lem-ncurses ; Loading "lem-ncurses" .................................................. [package trivial-clipboard]....................... [package lem.term]................................ [package lem-ncurses]... (:LEM-NCURSES) * (lem:lem)
Visual モードにしてみると・・・
できたぁぁぁ!!
あれ、、もしかして、、、
ros -s lem-ncurses -e '(lem:lem)'
うごいた! なるほど・・・
参考にした資料
local-project フォルダの使い方がやっと理解できました。感謝。
REPL から lem を動かすことには成功したけど、、、
こないだの記事の続き
roswell/lem を覗いて、roswell/lem-ncurses.ros が呼ばれているっぽいことまでわかったので
roswell/lem-ncurses.ros の中身をまねっこして動かしてみた
ros -Q -m lem-ncurses -L sbcl-bin -e '(lem:lem)'
うぉー!lem が起動したぞ!
でも .roswell/local-project
内のソースコードをイジってみても挙動が変わるようには見えないなぁ
ソースコードから実行できているわけではなさそう。
-m オプション が味噌なのかな?
roswell のヘルプを読んでみても -m オプションの意味がよくわからない
-m IMAGE --image IMAGE continue from Lisp image IMAGE
うーん。もうちょっと調べてみよっと
lem を REPL から実行したいのだけど・・・
common lisp で作られたエディタがあるらしい。 早速試してみる
インストール
$ ros install cxxxr/lem
実行
$ ~/.roswell/bin/lem
ソースから実行してみたいなと思って やり方をいろいろググってみました。 peccu.hatenablog.com
$ ros -s lem -e '(lem:lem)' debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD "main thread" RUNNING {10005505B3}>: The variable LEM:*IMPLEMENTATION* is unbound.
うーん・・・なんでじゃろ?