From fcf8a6598a4a53813a1e8c48330133dd14b43cb2 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Sat, 13 Aug 2022 16:04:15 +0300 Subject: [PATCH] Checkpoint --- .emacs.d/esy.org | 18 +++++++++ .emacs.d/lisp/iprolog.el | 83 ++++++++++++++++++++++++++++++---------- 2 files changed, 81 insertions(+), 20 deletions(-) diff --git a/.emacs.d/esy.org b/.emacs.d/esy.org index c15936d..2d81967 100644 --- a/.emacs.d/esy.org +++ b/.emacs.d/esy.org @@ -1507,6 +1507,24 @@ include =emacs-lisp-mode= and =lisp-interaction-mode=. #+begin_src emacs-lisp (add-to-list 'auto-mode-alist '("\\.pl\\'" . iprolog-mode)) (add-to-list 'auto-mode-alist '("\\.plt\\'" . iprolog-mode)) + + (require 'lsp-mode) + + (setq lsp-semantic-tokens-enable t + lsp-log-io t) + + (lsp-register-client + (make-lsp-client + :new-connection + (lsp-stdio-connection (list "swipl" + "-g" "use_module(library(lsp_server))." + "-g" "lsp_server:main" + "-t" "halt" + "--" "stdio")) + :major-modes '(iprolog-mode) + :priority 1 + :multi-root t + :server-id 'prolog-ls)) #+end_src *** Make =rg= regard =.pl= files as Prolog rather than Perl diff --git a/.emacs.d/lisp/iprolog.el b/.emacs.d/lisp/iprolog.el index 98dde4b..2fec8ac 100644 --- a/.emacs.d/lisp/iprolog.el +++ b/.emacs.d/lisp/iprolog.el @@ -23,7 +23,7 @@ "Editing and running Prolog code." :group 'prolog) -(defcustom iprolog-program "swipl" +(defcustom iprolog-program "/Users/eshelyaron/checkouts/iprolog/iprolog" "The Prolog executable." :package-version '((iprolog . "0.1.0")) ;; :link '(custom-manual "(iprolog)Top") @@ -321,11 +321,12 @@ value of `iprolog-project-definition-file-name'." (defvar iprolog--top-level-buffers-alist nil "Global mapping between directories and Prolog top-level buffers.") -(defvar-local iprolog-top-level--captured-output nil - "Accumulated captured process output.") - (defvar-local iprolog--helper-connection nil) +(defvar iprolog--buffer-server-process nil) + +(defvar-local iprolog--server-process nil) + (defvar-local iprolog--pending-requests (make-ring 128)) (defvar-local iprolog--last-request-id 0) @@ -334,6 +335,35 @@ value of `iprolog-project-definition-file-name'." (defvar iprolog--last-helper-port 11111) +(defvar iprolog--last-server-port 22222) + +(defvar iprolog--last-buffer-server-port 33333) + +(defun iprolog--ensure-buffer-server () + (unless (process-live-p iprolog--buffer-server-process) + (setq iprolog--buffer-server-process + (make-network-process + :name "iprolog_buffer_server" + :local `[127 0 0 1 ,(setq iprolog--last-buffer-server-port (1+ iprolog--last-buffer-server-port))] + :coding 'utf-8 + :server 5 + :buffer "foobar" + :log + (lambda (server client message) + (with-current-buffer (process-buffer server) + (goto-char (point-max)) + (insert (format "%s %s %s" server client message)))) + :sentinel + (lambda (proc state) + (message "update %s: %s" proc state)) + :filter + (lambda (proc output) + (message "serving %s to %s" output proc) + (save-excursion + (with-current-buffer (find-file-noselect (car (string-lines output))) + (process-send-region proc (point-min) (point-max)) + (process-send-eof proc)))))))) + (defun iprolog--ensure-top-level () (if-let ((buffer (iprolog--top-level-buffer))) (iprolog--ensure-top-level-in-buffer buffer) @@ -382,23 +412,34 @@ value of `iprolog-project-definition-file-name'." (defun iprolog--make-top-level (buffer) (iprolog-top-level--start-in-buffer buffer (setq iprolog--last-helper-port - (1+ iprolog--last-helper-port)))) + (1+ iprolog--last-helper-port)) + (setq iprolog--last-server-port + (1+ iprolog--last-server-port)))) -(defun iprolog-top-level--start-in-buffer (buffer port) +(defun iprolog-top-level--start-in-buffer (buffer port server-port) "Create a Prolog top-level process in BUFFER. Also start a Prolog server listening on UDP port PORT." (make-comint-in-buffer - "top-level" buffer iprolog-program nil - "-g" "[library(pldoc)]" - "-g" "[library(pldoc/doc_process)]" - "-g" "[library(pldoc/doc_wiki)]" - "-g" "[library(pldoc/doc_modes)]" - "-g" "[library(pldoc/doc_man)]" - "-g" "[library(lynx/html_text)]" - "-g" "[library(diagnostics)]" - "-g" (concat "thread_create((udp_socket(Socket), tcp_bind(Socket," (number-to-string port) "), tcp_setopt(Socket, sndbuf(65535)), repeat, (catch(udp_receive(Socket, Data, Peer, [as(term),encoding(utf8)]), Ball, (debug(iprolog, \"Caught ~q.\", [Ball]), fail)), debug(iprolog, \"Got ~p from ~q.\", [Data, Peer]), Data = (Id :- Goal) -> debug(iprolog, \"Executing goal ~w.\", [Goal]), catch(with_output_to(string(Output), ignore(Goal)), GBall, (debug(iprolog, \"Ball ~q thrown during goal execution.\", [GBall]), fail)), string_concat(Id, \" :- \", Prefix), string_length(Output, Length), phrase(helper(Output, Length, 49152), Replies), forall(member(Reply0, Replies), (string_concat(Prefix, Reply0, Reply), udp_send(Socket, Reply, Peer, [encoding(utf8)]))) ; debug(iprolog, \"udp_receive failed.\", [])), fail), _, [])") - "-t" "prolog") - (setq iprolog--helper-connection + "top-level" buffer iprolog-program nil "-u" (number-to-string port) "-e" (number-to-string server-port) "-b" (number-to-string iprolog--last-buffer-server-port)) + (setq iprolog--server-process + (make-network-process + :name "iprolog_server" + :local `[127 0 0 1 ,server-port] + :coding 'utf-8 + :server 5 + :buffer (generate-new-buffer "*iprolog-server-log*") + :log + (lambda (server client message) + (with-current-buffer (process-buffer server) + (goto-char (point-max)) + (insert (format "%s %s %s" server client message)))) + :sentinel + (lambda (proc state) + (message "update %s: %s" proc state)) + :filter + (lambda (proc output) + (message "got %s from %s" output proc)))) + (setq iprolog--helper-connection (make-network-process :name "iprolog_helper" :host 'local @@ -935,14 +976,13 @@ explanation about the argument CALLBACK." (buffer (current-buffer)) (default-directory (or (iprolog-project--root) default-directory))) - (message "(re)fontifying from %s to %s %s %s" beg end (point-min) (point-max)) (iprolog--ensure-top-level) (if (and (= beg (point-min)) (= end (point-max)) (not (buffer-modified-p))) (iprolog--request-goal-output (concat "'" (buffer-file-name buffer) "' = Orig," - "ensure_loaded(Orig), xref_source(Orig), setup_call_cleanup(prolog_open_source(Orig, Stream), prolog_colourise_stream(Stream, Orig, [T, S, L]>>format(\"~w:~w:~w~n\", [S,L,T])), prolog_close_source(Stream))") + "ensure_loaded(Orig), xref_source(Orig), setup_call_cleanup(prolog_open_source(Orig, Stream), prolog_colourise_stream(Stream, Orig, [T, S, L]>>(debug(iprolog,\"~w:~w:~w~n\", [S,L,T]),format(\"~w:~w:~w~n\", [S,L,T]))), prolog_close_source(Stream))") (lambda (o) (with-current-buffer buffer (with-silent-modifications @@ -968,7 +1008,7 @@ explanation about the argument CALLBACK." (iprolog--request-goal-output (concat "'" (buffer-file-name buffer) "' = Orig," "\"" tempfile "\"= Path," - "ensure_loaded(Orig), xref_source(Orig), setup_call_cleanup(prolog_open_source(Path, Stream), (repeat, once(prolog_colourise_term(Stream, O, [T, S, L]>>format(\"~w:~w:~w~n\", [S,L,T]), [])), at_end_of_stream(Stream), !), prolog_close_source(Stream))") + "ensure_loaded(Orig), xref_source(Orig), setup_call_cleanup(prolog_open_source(Path, Stream), (repeat, (once(prolog_colourise_term(Stream, O, [T, S, L]>>(debug(iprolog,\"~w:~w:~w~n\", [S,L,T]),format(\"~w:~w:~w~n\", [S,L,T])), [])) -> at_end_of_stream(Stream), ! ; true)), prolog_close_source(Stream))") (lambda (o) (with-current-buffer buffer (font-lock-unfontify-region beg end) @@ -1013,4 +1053,7 @@ explanation about the argument CALLBACK." (delete-region start end) (insert port)))) + +;;; experiments + ;;; iprolog.el ends here -- 2.39.5