1 ;;; nnoo.el --- OO Gnus Backends
2 ;; Copyright (C) 1996 Free Software Foundation, Inc.
4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
7 ;; This file is part of GNU Emacs.
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
28 (eval-when-compile (require 'cl
))
30 (defvar nnoo-definition-alist nil
)
31 (defvar nnoo-state-alist nil
)
33 (defmacro defvoo
(var init
&optional doc
&rest map
)
34 "The same as `defvar', only takes list of variables to MAP to."
37 `(defvar ,var
,init
,doc
)
39 (nnoo-define ',var
',map
)))
40 (put 'defvoo
'lisp-indent-function
2)
41 (put 'defvoo
'lisp-indent-hook
2)
42 (put 'defvoo
'edebug-form-spec
'(var init
&optional doc
&rest map
))
44 (defmacro deffoo
(func args
&rest forms
)
45 "The same as `defun', only register FUNC."
47 (defun ,func
,args
,@forms
)
48 (nnoo-register-function ',func
)))
49 (put 'deffoo
'lisp-indent-function
2)
50 (put 'deffoo
'lisp-indent-hook
2)
51 (put 'deffoo
'edebug-form-spec
'(&define name lambda-list def-body
))
53 (defun nnoo-register-function (func)
54 (let ((funcs (nthcdr 3 (assoc (nnoo-backend func
)
55 nnoo-definition-alist
))))
57 (error "%s belongs to a backend that hasn't been declared" func
))
58 (setcar funcs
(cons func
(car funcs
)))))
60 (defmacro nnoo-declare
(backend &rest parents
)
63 (mapcar (lambda (p) (list p
)) ',parents
)
65 nnoo-definition-alist
)))
66 (put 'nnoo-declare
'lisp-indent-function
1)
67 (put 'nnoo-declare
'lisp-indent-hook
1)
69 (defun nnoo-parents (backend)
70 (nth 1 (assoc backend nnoo-definition-alist
)))
72 (defun nnoo-variables (backend)
73 (nth 2 (assoc backend nnoo-definition-alist
)))
75 (defun nnoo-functions (backend)
76 (nth 3 (assoc backend nnoo-definition-alist
)))
78 (defmacro nnoo-import
(backend &rest imports
)
79 `(nnoo-import-1 ',backend
',imports
))
80 (put 'nnoo-import
'lisp-indent-function
1)
81 (put 'nnoo-import
'lisp-indent-hook
1)
83 (defun nnoo-import-1 (backend imports
)
85 (if (symbolp (car imports
)) (pop imports
) 'nnoo-parent-function
))
86 imp functions function
)
87 (while (setq imp
(pop imports
))
90 (nnoo-functions (car imp
))))
92 (unless (fboundp (setq function
93 (nnoo-symbol backend
(nnoo-rest-symbol
95 (eval `(deffoo ,function
(&rest args
)
96 (,call-function
',backend
',(car functions
) args
))))
99 (defun nnoo-parent-function (backend function args
)
100 (let* ((pbackend (nnoo-backend function
)))
101 (nnoo-change-server pbackend
(nnoo-current-server backend
)
102 (cdr (assq pbackend
(nnoo-parents backend
))))
103 (apply function args
)))
105 (defun nnoo-execute (backend function
&rest args
)
106 "Execute FUNCTION on behalf of BACKEND."
107 (let* ((pbackend (nnoo-backend function
)))
108 (nnoo-change-server pbackend
(nnoo-current-server backend
)
109 (cdr (assq pbackend
(nnoo-parents backend
))))
110 (apply function args
)))
112 (defmacro nnoo-map-functions
(backend &rest maps
)
113 `(nnoo-map-functions-1 ',backend
',maps
))
114 (put 'nnoo-map-functions
'lisp-indent-function
1)
115 (put 'nnoo-map-functions
'lisp-indent-hook
1)
117 (defun nnoo-map-functions-1 (backend maps
)
119 (while (setq m
(pop maps
))
122 (while (< i
(length (cdr m
)))
123 (if (numberp (nth i
(cdr m
)))
124 (push `(nth ,i args
) margs
)
125 (push (nth i
(cdr m
)) margs
))
127 (eval `(deffoo ,(nnoo-symbol backend
(nnoo-rest-symbol (car m
)))
129 (nnoo-parent-function ',backend
',(car m
)
130 ,(cons 'list
(nreverse margs
))))))))
132 (defun nnoo-backend (symbol)
133 (string-match "^[^-]+-" (symbol-name symbol
))
134 (intern (substring (symbol-name symbol
) 0 (1- (match-end 0)))))
136 (defun nnoo-rest-symbol (symbol)
137 (string-match "^[^-]+-" (symbol-name symbol
))
138 (intern (substring (symbol-name symbol
) (match-end 0))))
140 (defun nnoo-symbol (backend symbol
)
141 (intern (format "%s-%s" backend symbol
)))
143 (defun nnoo-define (var map
)
144 (let* ((backend (nnoo-backend var
))
145 (def (assq backend nnoo-definition-alist
))
146 (parents (nth 1 def
)))
148 (error "%s belongs to a backend that hasn't been declared." var
))
149 (setcar (nthcdr 2 def
)
150 (delq (assq var
(nth 2 def
)) (nth 2 def
)))
151 (setcar (nthcdr 2 def
)
152 (cons (cons var
(symbol-value var
))
155 (nconc (assq (nnoo-backend (car map
)) parents
)
156 (list (list (pop map
) var
))))))
158 (defun nnoo-change-server (backend server defs
)
159 (let* ((bstate (cdr (assq backend nnoo-state-alist
)))
160 (sdefs (assq backend nnoo-definition-alist
))
161 (current (car bstate
))
162 (parents (nnoo-parents backend
))
165 (push (setq bstate
(list backend nil
))
168 (if (equal server current
)
170 (nnoo-push-server backend current
)
171 (setq state
(or (cdr (assoc server
(cddr bstate
)))
172 (nnoo-variables backend
)))
174 (set (caar state
) (cdar state
))
176 (setcar bstate server
)
177 (unless (cdr (assoc server
(cddr bstate
)))
179 (set (caar defs
) (cadar defs
))
183 (caar parents
) server
184 (mapcar (lambda (def) (list (car def
) (symbol-value (cadr def
))))
189 (defun nnoo-push-server (backend current
)
190 (let ((bstate (assq backend nnoo-state-alist
))
191 (defs (nnoo-variables backend
)))
192 ;; Remove the old definition.
193 (setcdr (cdr bstate
) (delq (assoc current
(cddr bstate
)) (cddr bstate
)))
196 (push (cons (caar defs
) (symbol-value (caar defs
)))
199 (nconc bstate
(list (cons current state
))))))
201 (defun nnoo-current-server-p (backend server
)
202 (equal (nnoo-current-server backend
) server
))
204 (defun nnoo-current-server (backend)
205 (nth 1 (assq backend nnoo-state-alist
)))
207 (defun nnoo-close-server (backend &optional server
)
209 (setq server
(nnoo-current-server backend
)))
211 (let* ((bstate (cdr (assq backend nnoo-state-alist
)))
212 (defs (assoc server
(cdr bstate
))))
215 (setcdr bstate
(delq defs
(cdr bstate
)))
218 (set (car (pop defs
)) nil
)))))
221 (defun nnoo-close (backend)
222 (setq nnoo-state-alist
223 (delq (assq backend nnoo-state-alist
)
227 (defun nnoo-status-message (backend server
)
228 (nnheader-get-report backend
))
230 (defun nnoo-server-opened (backend server
)
231 (and (nnoo-current-server-p backend server
)
233 (buffer-name nntp-server-buffer
)))
235 (defmacro nnoo-define-basics
(backend)
237 (nnoo-define-basics-1 ',backend
)))
239 (defun nnoo-define-basics-1 (backend)
240 (let ((functions '(close-server server-opened status-message
)))
242 (eval `(deffoo ,(nnoo-symbol backend
(car functions
))
244 (,(nnoo-symbol 'nnoo
(pop functions
)) ',backend server
)))))
245 (eval `(deffoo ,(nnoo-symbol backend
'open-server
)
246 (server &optional defs
)
247 (nnoo-change-server ',backend server defs
))))
251 ;;; nnoo.el ends here.