prolog.el 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. ;; Major mode for editing Prolog, and for running Prolog under Emacs
  2. ;; Copyright (C) 1986 Free Software Foundation, Inc.
  3. ;; Author Masanobu UMEDA (umerin@flab.fujitsu.junet)
  4. ;; This file is part of GNU Emacs.
  5. ;; GNU Emacs is distributed in the hope that it will be useful,
  6. ;; but WITHOUT ANY WARRANTY. No author or distributor
  7. ;; accepts responsibility to anyone for the consequences of using it
  8. ;; or for whether it serves any particular purpose or works at all,
  9. ;; unless he says so in writing. Refer to the GNU Emacs General Public
  10. ;; License for full details.
  11. ;; Everyone is granted permission to copy, modify and redistribute
  12. ;; GNU Emacs, but only under the conditions described in the
  13. ;; GNU Emacs General Public License. A copy of this license is
  14. ;; supposed to have been given to you along with GNU Emacs so you
  15. ;; can know your rights and responsibilities. It should be in a
  16. ;; file named COPYING. Among other things, the copyright notice
  17. ;; and this notice must be preserved on all copies.
  18. (defvar prolog-mode-syntax-table nil)
  19. (defvar prolog-mode-abbrev-table nil)
  20. (defvar prolog-mode-map nil)
  21. (defvar prolog-consult-string "reconsult(user).\n"
  22. "*(Re)Consult mode (for C-Prolog and Quintus Prolog). ")
  23. (defvar prolog-compile-string "compile(user).\n"
  24. "*Compile mode (for Quintus Prolog).")
  25. (defvar prolog-eof-string "end_of_file.\n"
  26. "*String that represents end of file for prolog.
  27. nil means send actual operaing system end of file.")
  28. (defvar prolog-indent-width 4)
  29. (if prolog-mode-syntax-table
  30. ()
  31. (let ((table (make-syntax-table)))
  32. (modify-syntax-entry ?_ "w" table)
  33. (modify-syntax-entry ?\\ "\\" table)
  34. (modify-syntax-entry ?/ "." table)
  35. (modify-syntax-entry ?* "." table)
  36. (modify-syntax-entry ?+ "." table)
  37. (modify-syntax-entry ?- "." table)
  38. (modify-syntax-entry ?= "." table)
  39. (modify-syntax-entry ?% "<" table)
  40. (modify-syntax-entry ?< "." table)
  41. (modify-syntax-entry ?> "." table)
  42. (modify-syntax-entry ?\' "\"" table)
  43. (setq prolog-mode-syntax-table table)))
  44. (define-abbrev-table 'prolog-mode-abbrev-table ())
  45. (defun prolog-mode-variables ()
  46. (set-syntax-table prolog-mode-syntax-table)
  47. (setq local-abbrev-table prolog-mode-abbrev-table)
  48. (make-local-variable 'paragraph-start)
  49. (setq paragraph-start (concat "^%%\\|^$\\|" page-delimiter)) ;'%%..'
  50. (make-local-variable 'paragraph-separate)
  51. (setq paragraph-separate paragraph-start)
  52. (make-local-variable 'indent-line-function)
  53. (setq indent-line-function 'prolog-indent-line)
  54. (make-local-variable 'comment-start)
  55. (setq comment-start "%")
  56. (make-local-variable 'comment-start-skip)
  57. (setq comment-start-skip "%+ *")
  58. (make-local-variable 'comment-column)
  59. (setq comment-column 48)
  60. (make-local-variable 'comment-indent-hook)
  61. (setq comment-indent-hook 'prolog-comment-indent))
  62. (defun prolog-mode-commands (map)
  63. (define-key map "\t" 'prolog-indent-line)
  64. (define-key map "\e\C-x" 'prolog-consult-region))
  65. (if prolog-mode-map
  66. nil
  67. (setq prolog-mode-map (make-sparse-keymap))
  68. (prolog-mode-commands prolog-mode-map))
  69. (defun prolog-mode ()
  70. "Major mode for editing Prolog code for Prologs.
  71. Blank lines and `%%...' separate paragraphs. `%'s start comments.
  72. Commands:
  73. \\{prolog-mode-map}
  74. Entry to this mode calls the value of prolog-mode-hook
  75. if that value is non-nil."
  76. (interactive)
  77. (kill-all-local-variables)
  78. (use-local-map prolog-mode-map)
  79. (setq major-mode 'prolog-mode)
  80. (setq mode-name "Prolog")
  81. (prolog-mode-variables)
  82. (run-hooks 'prolog-mode-hook))
  83. (defun prolog-indent-line (&optional whole-exp)
  84. "Indent current line as Prolog code.
  85. With argument, indent any additional lines of the same clause
  86. rigidly along with this one (not yet)."
  87. (interactive "p")
  88. (let ((indent (prolog-indent-level))
  89. (pos (- (point-max) (point))) beg)
  90. (beginning-of-line)
  91. (setq beg (point))
  92. (skip-chars-forward " \t")
  93. (if (zerop (- indent (current-column)))
  94. nil
  95. (delete-region beg (point))
  96. (indent-to indent))
  97. (if (> (- (point-max) pos) (point))
  98. (goto-char (- (point-max) pos)))
  99. ))
  100. (defun prolog-indent-level ()
  101. "Compute prolog indentation level."
  102. (save-excursion
  103. (beginning-of-line)
  104. (skip-chars-forward " \t")
  105. (cond
  106. ((looking-at "%%%") 0) ;Large comment starts
  107. ((looking-at "%[^%]") comment-column) ;Small comment starts
  108. ((bobp) 0) ;Beginning of buffer
  109. (t
  110. (let ((empty t) ind more less)
  111. (if (looking-at ")")
  112. (setq less t) ;Find close
  113. (setq less nil))
  114. ;; See previous indentation
  115. (while empty
  116. (forward-line -1)
  117. (beginning-of-line)
  118. (if (bobp) (setq empty nil))
  119. (skip-chars-forward " \t")
  120. (if (not (or (looking-at "%[^%]") (looking-at "\n")))
  121. (setq empty nil)))
  122. (setq ind (current-column)) ;Beginning of clause
  123. ;; See its beginning
  124. (if (looking-at "%%[^%]")
  125. ind
  126. ;; Real prolog code
  127. (if (looking-at "(")
  128. (setq more t) ;Find open
  129. (setq more nil))
  130. ;; See its tail
  131. (end-of-prolog-clause)
  132. (or (bobp) (forward-char -1))
  133. (cond ((looking-at "[,(;>]")
  134. (if (and more (looking-at "[^,]"))
  135. (+ ind prolog-indent-width) ;More indentation
  136. (max tab-width ind))) ;Same indentation
  137. ((looking-at "-") tab-width) ;TAB
  138. ((or less (looking-at "[^.]"))
  139. (max (- ind prolog-indent-width) 0)) ;Less indentation
  140. (t 0)) ;No indentation
  141. )))
  142. )))
  143. (defun end-of-prolog-clause ()
  144. "Go to end of clause in this line."
  145. (beginning-of-line 1)
  146. (let* ((eolpos (save-excursion (end-of-line) (point))))
  147. (if (re-search-forward comment-start-skip eolpos 'move)
  148. (goto-char (match-beginning 0)))
  149. (skip-chars-backward " \t")))
  150. (defun prolog-comment-indent ()
  151. "Compute prolog comment indentation."
  152. (cond ((looking-at "%%%") 0)
  153. ((looking-at "%%") (prolog-indent-level))
  154. (t
  155. (save-excursion
  156. (skip-chars-backward " \t")
  157. (max (1+ (current-column)) ;Insert one space at least
  158. comment-column)))
  159. ))
  160. ;;;
  161. ;;; Inferior prolog mode
  162. ;;;
  163. (defvar inferior-prolog-mode-map nil)
  164. ;; Moved into inferior-prolog-mode
  165. ;;(if inferior-prolog-mode-map
  166. ;; nil
  167. ;; (setq inferior-prolog-mode-map (copy-alist shell-mode-map))
  168. ;; (prolog-mode-commands inferior-prolog-mode-map))
  169. (defun inferior-prolog-mode ()
  170. "Major mode for interacting with an inferior Prolog process.
  171. The following commands are available:
  172. \\{inferior-prolog-mode-map}
  173. Entry to this mode calls the value of prolog-mode-hook with no arguments,
  174. if that value is non-nil. Likewise with the value of shell-mode-hook.
  175. prolog-mode-hook is called after shell-mode-hook.
  176. You can send text to the inferior Prolog from other buffers
  177. using the commands send-region, send-string and \\[prolog-consult-region].
  178. Commands:
  179. Tab indents for Prolog; with argument, shifts rest
  180. of expression rigidly with the current line.
  181. Paragraphs are separated only by blank lines and '%%'. '%'s start comments.
  182. Return at end of buffer sends line as input.
  183. Return not at end copies rest of line to end and sends it.
  184. \\[shell-send-eof] sends end-of-file as input.
  185. \\[kill-shell-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
  186. \\[interrupt-shell-subjob] interrupts the shell or its current subjob if any.
  187. \\[stop-shell-subjob] stops, likewise. \\[quit-shell-subjob] sends quit signal, likewise."
  188. (interactive)
  189. (kill-all-local-variables)
  190. (setq major-mode 'inferior-prolog-mode)
  191. (setq mode-name "Inferior Prolog")
  192. (setq mode-line-process '(": %s"))
  193. (prolog-mode-variables)
  194. (require 'shell)
  195. (if inferior-prolog-mode-map
  196. nil
  197. (setq inferior-prolog-mode-map (copy-alist shell-mode-map))
  198. (prolog-mode-commands inferior-prolog-mode-map))
  199. (use-local-map inferior-prolog-mode-map)
  200. (make-local-variable 'last-input-start)
  201. (setq last-input-start (make-marker))
  202. (make-local-variable 'last-input-end)
  203. (setq last-input-end (make-marker))
  204. (make-variable-buffer-local 'shell-prompt-pattern)
  205. (setq shell-prompt-pattern "^| [ ?][- ] *") ;Set prolog prompt pattern
  206. (run-hooks 'shell-mode-hook 'prolog-mode-hook))
  207. (defun run-prolog ()
  208. "Run an inferior Prolog process, input and output via buffer *prolog*."
  209. (interactive)
  210. (require 'shell)
  211. (switch-to-buffer (make-shell "prolog" "prolog"))
  212. (inferior-prolog-mode))
  213. (defun prolog-consult-region (compile beg end)
  214. "Send the region to the Prolog process made by M-x run-prolog.
  215. If COMPILE (prefix arg) is not nil,
  216. use compile mode rather than consult mode."
  217. (interactive "P\nr")
  218. (save-excursion
  219. (if compile
  220. (send-string "prolog" prolog-compile-string)
  221. (send-string "prolog" prolog-consult-string))
  222. (send-region "prolog" beg end)
  223. (send-string "prolog" "\n") ;May be unnecessary
  224. (if prolog-eof-string
  225. (send-string "prolog" prolog-eof-string)
  226. (process-send-eof "prolog")))) ;Send eof to prolog process.
  227. (defun prolog-consult-region-and-go (compile beg end)
  228. "Send the region to the inferior Prolog, and switch to *prolog* buffer.
  229. If COMPILE (prefix arg) is not nil,
  230. use compile mode rather than consult mode."
  231. (interactive "P\nr")
  232. (prolog-consult-region compile beg end)
  233. (switch-to-buffer "*prolog*"))