talk.el 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. ;;; talk.el --- allow several users to talk to each other through Emacs
  2. ;; Copyright (C) 1995, 2001-2012 Free Software Foundation, Inc.
  3. ;; Maintainer: FSF
  4. ;; Keywords: comm, frames
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs 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
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;; This is a multi-user talk package that runs in Emacs.
  18. ;; Use talk-connect to bring a new person into the conversation.
  19. ;;; Code:
  20. (defvar talk-display-alist nil
  21. "Alist of displays on which Emacs talk is now running.
  22. Each element has the form (DISPLAY FRAME BUFFER).")
  23. ;;;###autoload
  24. (defun talk-connect (display)
  25. "Connect to display DISPLAY for the Emacs talk group."
  26. (interactive "sTalk to display: ")
  27. ;; Make sure we have an entry for the current display.
  28. (let ((mydisp (cdr (assq 'display (frame-parameters (selected-frame))))))
  29. (talk-add-display mydisp))
  30. ;; Make sure we have an entry for the specified display.
  31. (talk-add-display display)
  32. ;; Add the new buffers to all talk frames.
  33. (talk-update-buffers))
  34. ;;;###autoload
  35. (defun talk ()
  36. "Connect to the Emacs talk group from the current X display or tty frame."
  37. (interactive)
  38. (let ((type (frame-live-p (selected-frame))))
  39. (if (or (eq type t) (eq type 'x))
  40. (talk-add-display
  41. (terminal-name (frame-terminal (selected-frame))))
  42. (error "Unknown frame type")))
  43. (talk-update-buffers))
  44. (defun talk-add-display (display)
  45. (let* ((elt (assoc display talk-display-alist))
  46. (name (concat "*talk-" display "*"))
  47. frame buffer)
  48. (if (and elt (frame-live-p (nth 1 elt)))
  49. (setq frame (nth 1 elt))
  50. (setq frame (make-frame-on-display display (list (cons 'name name)))))
  51. (if (not (and elt (buffer-name (get-buffer (setq buffer (nth 2 elt))))))
  52. (setq buffer (get-buffer-create name)))
  53. (add-to-list 'delete-frame-functions 'talk-handle-delete-frame)
  54. (setq talk-display-alist
  55. (cons (list display frame buffer) (delq elt talk-display-alist)))))
  56. (defun talk-handle-delete-frame (frame)
  57. (dolist (d talk-display-alist)
  58. (when (eq (nth 1 d) frame)
  59. (setq talk-display-alist (delq d talk-display-alist))
  60. (talk-update-buffers))))
  61. (defun talk-disconnect ()
  62. "Disconnect this display from the Emacs talk group."
  63. (interactive)
  64. (let* ((mydisp (cdr (assq 'display (frame-parameters (selected-frame)))))
  65. (elt (assoc mydisp talk-display-alist)))
  66. (delete-frame (nth 1 elt))
  67. (kill-buffer (nth 2 elt))
  68. (setq talk-display-alist (delq elt talk-display-alist))
  69. (talk-update-buffers)))
  70. (defun talk-update-buffers ()
  71. "Update all the talk frames so that each shows all the talk buffers."
  72. (let ((tail talk-display-alist))
  73. (while tail
  74. (let ((frame (nth 1 (car tail)))
  75. (this-buffer (nth 2 (car tail)))
  76. (buffers
  77. (mapcar (function (lambda (elt) (nth 2 elt)))
  78. talk-display-alist)))
  79. ;; Put this display's own talk buffer
  80. ;; at the front of the list.
  81. (setq buffers (cons this-buffer (delq this-buffer buffers)))
  82. (talk-split-up-frame frame buffers))
  83. (setq tail (cdr tail)))))
  84. (defun talk-split-up-frame (frame buffers)
  85. "Split FRAME into equal-sized windows displaying the buffers in BUFFERS.
  86. Select the first of these windows, displaying the first of the buffers."
  87. (let ((lines-per-buffer (/ (frame-height frame) (length buffers)))
  88. (old-frame (selected-frame)))
  89. (unwind-protect
  90. (progn
  91. (select-frame frame)
  92. (select-window (frame-first-window frame))
  93. (delete-other-windows)
  94. (while (progn
  95. (switch-to-buffer (car buffers))
  96. (setq buffers (cdr buffers)))
  97. (split-window-below lines-per-buffer)
  98. (other-window 1))
  99. (select-window (frame-first-window frame)))
  100. (select-frame old-frame))))
  101. (provide 'talk)
  102. ;;; talk.el ends here