gds-server.el 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. ;;; gds-server.el -- infrastructure for running GDS server processes
  2. ;;;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
  3. ;;;;
  4. ;;;; This library is free software; you can redistribute it and/or
  5. ;;;; modify it under the terms of the GNU Lesser General Public
  6. ;;;; License as published by the Free Software Foundation; either
  7. ;;;; version 2.1 of the License, or (at your option) any later
  8. ;;;; version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free
  17. ;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. ;;;; 02111-1307 USA
  19. ;;;; Customization group setup.
  20. (defgroup gds nil
  21. "Customization options for Guile Emacs frontend."
  22. :group 'scheme)
  23. ;;;; Communication with the (ice-9 gds-server) subprocess.
  24. ;; Subprocess output goes into the `*GDS Process*' buffer, and
  25. ;; is then read from there one form at a time. `gds-read-cursor' is
  26. ;; the buffer position of the start of the next unread form.
  27. (defvar gds-read-cursor nil)
  28. ;; The guile executable used by the GDS server process.
  29. (defcustom gds-guile-program "guile"
  30. "*The guile executable used by the GDS server process."
  31. :type 'string
  32. :group 'gds)
  33. (defcustom gds-scheme-directory nil
  34. "Where GDS's Scheme code is, if not in one of the standard places."
  35. :group 'gds
  36. :type '(choice (const :tag "nil" nil) directory))
  37. (defun gds-start-server (procname port-or-path protocol-handler &optional bufname)
  38. "Start a GDS server process called PROCNAME, listening on TCP port
  39. or Unix domain socket PORT-OR-PATH. PROTOCOL-HANDLER should be a
  40. function that accepts and processes one protocol form. Optional arg
  41. BUFNAME specifies the name of the buffer that is used for process
  42. output; if not specified the buffer name is the same as the process
  43. name."
  44. (with-current-buffer (get-buffer-create (or bufname procname))
  45. (erase-buffer)
  46. (let* ((code (format "(begin
  47. %s
  48. (use-modules (ice-9 gds-server))
  49. (run-server %S))"
  50. (if gds-scheme-directory
  51. (concat "(set! %load-path (cons "
  52. (format "%S" gds-scheme-directory)
  53. " %load-path))")
  54. "")
  55. port-or-path))
  56. (process-connection-type nil) ; use a pipe
  57. (proc (start-process procname
  58. (current-buffer)
  59. gds-guile-program
  60. "-q"
  61. "--debug"
  62. "-c"
  63. code)))
  64. (set (make-local-variable 'gds-read-cursor) (point-min))
  65. (set (make-local-variable 'gds-protocol-handler) protocol-handler)
  66. (set-process-filter proc (function gds-filter))
  67. (set-process-sentinel proc (function gds-sentinel))
  68. (set-process-coding-system proc 'latin-1-unix)
  69. (process-kill-without-query proc)
  70. proc)))
  71. ;; Subprocess output filter: inserts normally into the process buffer,
  72. ;; then tries to reread the output one form at a time and delegates
  73. ;; processing of each form to `gds-protocol-handler'.
  74. (defun gds-filter (proc string)
  75. (with-current-buffer (process-buffer proc)
  76. (save-excursion
  77. (goto-char (process-mark proc))
  78. (insert-before-markers string))
  79. (goto-char gds-read-cursor)
  80. (while (let ((form (condition-case nil
  81. (read (current-buffer))
  82. (error nil))))
  83. (if form
  84. (save-excursion
  85. (funcall gds-protocol-handler (car form) (cdr form))))
  86. form)
  87. (setq gds-read-cursor (point)))))
  88. ;; Subprocess sentinel: do nothing. (Currently just here to avoid
  89. ;; inserting un-`read'able process status messages into the process
  90. ;; buffer.)
  91. (defun gds-sentinel (proc event)
  92. )
  93. ;;;; The end!
  94. (provide 'gds-server)
  95. ;;; gds-server.el ends here.