;;; 99-my-ediprolog.el --- ediprolog extras -*- no-byte-compile: t; lexical-binding: t; -*- ;;; Commentary: ;; ediprolog is a very minimalist package, and I find myself needing to code ;; some functionality myself. Ergo, this file. ;;; Code: (defun my-ediprolog-run-in-own-buffer () "Copy this query to another buffer and run it there." (interactive) ;; This is the same logic ediprolog uses to check if the point is on query. (when (and (not (and transient-mark-mode mark-active)) (save-excursion (beginning-of-line) (looking-at "\\([\t ]*%*[\t ]*[:?]- *\\)"))) (let* ((from (goto-char (match-end 0))) (to (if (re-search-forward "\\.[\t ]*\\(?:%.*\\)?$" nil t) ;; omit trailing whitespace (+ (point) (skip-chars-backward "\t ")) (error "Missing `.' at the end of this query"))) (query (buffer-substring-no-properties from to)) (buffer (get-buffer-create "*Prolog Query*"))) (pop-to-buffer buffer) (unless (eq major-mode "prolog-mode") (prolog-mode)) (goto-char (point-max)) (unless (eq (line-number-at-pos) 1) (insert "\n\n")) (insert "/*\n ?- ") (save-excursion (insert query "\n*/")) (ediprolog-dwim)))) (defun my-ediprolog-delete-next-comments () "Delete all commented lines after point (excluding the line under point). Will continue until a line without a comment is encountered. See also 'ediprolog-dwim'." (interactive) (save-excursion (beginning-of-line) (next-line) (while (looking-at "[ ]*%") (delete-line)))) (defun my-ediprolog-return-to-closest-query () "Tries to set point to closest query (starts with ?-) preceding it." (interactive) (re-search-backward "\\([\t ]*%*[\t ]*[:?]- *\\)" nil t)) (defcustom my-ediprolog-system-types '(("scryer-prolog" . (scryer . ("systemd-run" "--user" "--scope" "-p" "MemoryMax=2G" "-p" "MemoryHigh=1.9G" "scryer-prolog"))) ("swi-prolog" . (swi . ("swipl")))) "An alist of prolog systems and their respective run commands. This has the form of form (NAME . TYPE . COMMAND). NAME is the display name that user will be presented with, TYPE is one of swi or scryer, for the two supported prolog systems respectively. COMMAND is a list, where the first element is the command and the rest are arguments. See 'my-ediprolog-select-system'" :type '(alist :key-type string :value-type (cons (choice (const :tag "Scryer Prolog" :value scryer) (const :tag "SWI Prolog" :value swi)) (repeat string)))) (defun my-ediprolog-select-system (&optional system) "Prompts the user to select a prolog SYSTEM and configures ediprolog to use it. The prolog systems are defined in 'my-ediprolog-system-types'." (interactive (list (completing-read "Select system:" my-ediprolog-system-types))) (let ((pair (alist-get system my-ediprolog-system-types nil nil #'equal))) (setq ediprolog-system (car pair)) (setq ediprolog-program (cadr pair)) (setq ediprolog-program-switches (cddr pair)))) (with-eval-after-load 'prolog (keymap-set prolog-mode-map "C-c C-d" #'my-ediprolog-delete-next-comments) (keymap-set prolog-mode-map "C-c C-b" #'my-ediprolog-return-to-closest-query)) ;;; 99-my-ediprolog.el ends here