"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")
(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)
(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)
(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
(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
(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)
(delete-region start end)
(insert port))))
+
+;;; experiments
+
;;; iprolog.el ends here