1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

merge trunk

This commit is contained in:
Kenichi Handa 2010-09-02 09:58:05 +09:00
commit 7e7e8cfe01
21 changed files with 431 additions and 1691 deletions

View file

@ -1,3 +1,7 @@
2010-09-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
* gnus.texi (HTML): Document gnus-max-image-proportion.
2010-08-31 Lars Magne Ingebrigtsen <larsi@gnus.org>
* gnus.texi (HTML): Document gnus-blocked-images.

View file

@ -721,7 +721,6 @@ Document Groups
Combined Groups
* Virtual Groups:: Combining articles from many groups.
* Kibozed Groups:: Looking through parts of the newsfeed for articles.
Email Based Diary
@ -2624,15 +2623,6 @@ default a group pointing to the most recent articles will be created
(@code{gnus-group-recent-archive-directory}), but given a prefix, a full
group will be created from @code{gnus-group-archive-directory}.
@item G k
@kindex G k (Group)
@findex gnus-group-make-kiboze-group
@cindex nnkiboze
Make a kiboze group. You will be prompted for a name, for a regexp to
match groups to be ``included'' in the kiboze group, and a series of
strings to match on headers (@code{gnus-group-make-kiboze-group}).
@xref{Kibozed Groups}.
@item G D
@kindex G D (Group)
@findex gnus-group-enter-directory
@ -4420,8 +4410,7 @@ which point to the ``real'' message files (if mbox is used, copies are
made). Since mairix already presents search results in such a virtual
mail folder, it is very well suited for using it as an external program
for creating @emph{smart} mail folders, which represent certain mail
searches. This is similar to a Kiboze group (@pxref{Kibozed Groups}),
but much faster.
searches.
@node nnmairix requirements
@subsubsection nnmairix requirements
@ -12515,6 +12504,14 @@ directory, the oldest files will be deleted. The default is 500MB.
@vindex gnus-html-frame-width
The width to use when rendering HTML. The default is 70.
@item gnus-max-image-proportion
@vindex gnus-max-image-proportion
How big pictures displayed are in relation to the window they're in.
A value of 0.7 (the default) means that they are allowed to take up
70% of the width and height of the window. If they are larger than
this, and Emacs supports it, then the images will be rescaled down to
fit these criteria.
@end table
To use this, make sure that you have @code{w3m} and @code{curl}
@ -18925,7 +18922,6 @@ groups.
@menu
* Virtual Groups:: Combining articles from many groups.
* Kibozed Groups:: Looking through parts of the newsfeed for articles.
@end menu
@ -19015,58 +19011,6 @@ from component groups---group parameters, for instance, are not
inherited.
@node Kibozed Groups
@subsection Kibozed Groups
@cindex nnkiboze
@cindex kibozing
@dfn{Kibozing} is defined by the @acronym{OED} as ``grepping through
(parts of) the news feed''. @code{nnkiboze} is a back end that will
do this for you. Oh joy! Now you can grind any @acronym{NNTP} server
down to a halt with useless requests! Oh happiness!
@kindex G k (Group)
To create a kibozed group, use the @kbd{G k} command in the group
buffer.
The address field of the @code{nnkiboze} method is, as with
@code{nnvirtual}, a regexp to match groups to be ``included'' in the
@code{nnkiboze} group. That's where most similarities between
@code{nnkiboze} and @code{nnvirtual} end.
In addition to this regexp detailing component groups, an
@code{nnkiboze} group must have a score file to say what articles are
to be included in the group (@pxref{Scoring}).
@kindex M-x nnkiboze-generate-groups
@findex nnkiboze-generate-groups
You must run @kbd{M-x nnkiboze-generate-groups} after creating the
@code{nnkiboze} groups you want to have. This command will take time.
Lots of time. Oodles and oodles of time. Gnus has to fetch the
headers from all the articles in all the component groups and run them
through the scoring process to determine if there are any articles in
the groups that are to be part of the @code{nnkiboze} groups.
Please limit the number of component groups by using restrictive
regexps. Otherwise your sysadmin may become annoyed with you, and the
@acronym{NNTP} site may throw you off and never let you back in again.
Stranger things have happened.
@code{nnkiboze} component groups do not have to be alive---they can be dead,
and they can be foreign. No restrictions.
@vindex nnkiboze-directory
The generation of an @code{nnkiboze} group means writing two files in
@code{nnkiboze-directory}, which is @file{~/News/kiboze/} by default.
One contains the @acronym{NOV} header lines for all the articles in
the group, and the other is an additional @file{.newsrc} file to store
information on what groups have been searched through to find
component articles.
Articles marked as read in the @code{nnkiboze} group will have
their @acronym{NOV} lines removed from the @acronym{NOV} file.
@node Email Based Diary
@section Email Based Diary
@cindex diary
@ -27414,10 +27358,6 @@ cluttering up the @file{.emacs} file.
You can set the process mark on both groups and articles and perform
operations on all the marked items (@pxref{Process/Prefix}).
@item
You can grep through a subset of groups and create a group from the
results (@pxref{Kibozed Groups}).
@item
You can list subsets of groups according to, well, anything
(@pxref{Listing Groups}).
@ -29126,8 +29066,7 @@ As the variables for the other back ends, there are
@code{nnfolder-nov-is-evil}, @code{nnimap-nov-is-evil},
@code{nnml-nov-is-evil}, and @code{nnspool-nov-is-evil}. Note that a
non-@code{nil} value for @code{gnus-nov-is-evil} overrides all those
variables.@footnote{Although the back ends @code{nnkiboze}, and
@code{nnwfm} don't have their own nn*-nov-is-evil.}
variables.
@end table

View file

@ -1,3 +1,13 @@
2010-09-01 Stefan Monnier <monnier@iro.umontreal.ca>
* simple.el (blink-paren-function): Move from C to here.
(blink-paren-post-self-insert-function): New function.
(post-self-insert-hook): Use it.
* emacs-lisp/pcase.el (pcase-split-memq):
Fix overenthusiastic optimisation.
(pcase-u1): Handle the case of a lambda pred.
2010-08-31 Kenichi Handa <handa@m17n.org>
* international/mule-cmds.el (standard-display-european-internal):

View file

@ -290,9 +290,13 @@ MATCH is the pattern that needs to be matched, of the form:
(defun pcase-split-memq (elems pat)
;; Based on pcase-split-eq.
(cond
;; The same match will give the same result.
;; The same match will give the same result, but we don't know how
;; to check it.
;; (???
;; (cons :pcase-succeed nil))
;; A match for one of the elements may succeed or fail.
((and (eq (car-safe pat) '\`) (member (cadr pat) elems))
(cons :pcase-succeed nil))
nil)
;; A different match will fail if this one succeeds.
((and (eq (car-safe pat) '\`)
;; (or (integerp (cadr pat)) (symbolp (cadr pat))
@ -383,18 +387,20 @@ and otherwise defers to REST which is a list of branches of the form
`(,(cadr upat) ,sym)
(let* ((exp (cadr upat))
;; `vs' is an upper bound on the vars we need.
(vs (pcase-fgrep (mapcar #'car vars) exp)))
(if vs
;; Let's not replace `vars' in `exp' since it's
;; too difficult to do it right, instead just
;; let-bind `vars' around `exp'.
`(let ,(mapcar (lambda (var)
(list var (cdr (assq var vars))))
vs)
;; FIXME: `vars' can capture `sym'. E.g.
;; (pcase x ((and `(,x . ,y) (pred (fun x)))))
(,@exp ,sym))
`(,@exp ,sym))))
(vs (pcase-fgrep (mapcar #'car vars) exp))
(call (if (functionp exp)
`(,exp ,sym) `(,@exp ,sym))))
(if (null vs)
call
;; Let's not replace `vars' in `exp' since it's
;; too difficult to do it right, instead just
;; let-bind `vars' around `exp'.
`(let ,(mapcar (lambda (var)
(list var (cdr (assq var vars))))
vs)
;; FIXME: `vars' can capture `sym'. E.g.
;; (pcase x ((and `(,x . ,y) (pred (fun x)))))
,call))))
(pcase-u1 matches code vars then-rest)
(pcase-u else-rest))))
((symbolp upat)

View file

@ -1,3 +1,69 @@
2010-09-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
* nnwfm.el: Removed.
* nnlistserv.el: Removed.
2010-09-01 Teodor Zlatanov <tzz@lifelogs.com>
* gnus-html.el (gnus-html-image-url-blocked-p): New function.
(gnus-html-prefetch-images, gnus-html-wash-tags): Use it.
2010-09-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
* nnkiboze.el: Removed.
* nndb.el: Removed.
* gnus-html.el (gnus-html-put-image): Use the deleted text as the image
alt text.
(gnus-html-rescale-image): Try to get the rescaling logic right for
images that are just wide and not tall.
* gnus.el (gnus-string-or): Fix the syntax to not use eval or
overshadow variable bindings.
2010-09-01 Teodor Zlatanov <tzz@lifelogs.com>
* gnus-html.el (gnus-html-wash-tags)
(gnus-html-schedule-image-fetching, gnus-html-prefetch-images): Add
extra logging.
2010-09-01 Lars Magne Ingebrigtsen <larsi@gnus.org>
* gnus-html.el (gnus-html-wash-tags): Delete the IMG_ALT region.
(gnus-max-image-proportion): New variable.
(gnus-html-rescale-image): New function.
(gnus-html-put-image): Rescale images.
2010-09-01 Stefan Monnier <monnier@iro.umontreal.ca>
Fix up some byte-compiler warnings.
* gnus.el (gnus-group-find-parameter, gnus-kill-save-kill-buffer):
* gnus-cite.el (gnus-article-highlight-citation, gnus-dissect-cited-text)
(gnus-article-fill-cited-article, gnus-article-hide-citation)
(gnus-article-hide-citation-in-followups, gnus-cite-toggle):
* gnus-group.el (gnus-group-set-mode-line, gnus-group-quit)
(gnus-group-set-info, gnus-add-mark): Use with-current-buffer.
(gnus-group-update-group): Use save-excursion and with-current-buffer.
2010-09-01 Katsumi Yamaoka <yamaoka@jpl.org>
* gnus-html.el (gnus-article-html): Decode contents by charset.
2010-09-01 Katsumi Yamaoka <yamaoka@jpl.org>
* gnus-html.el (gnus-html-cache-directory, gnus-html-cache-size)
(gnus-html-frame-width, gnus-blocked-images)
* message.el (message-prune-recipient-rules): Add custom version.
* gnus-sum.el (gnus-auto-expirable-marks): Bump custom version.
* gnus-ems.el (gnus-process-get, gnus-process-put): New compatibility
functions.
* gnus-html.el (gnus-html-curl-sentinel): Replace process-get with
gnus-process-get.
2010-08-31 Julien Danjou <julien@danjou.info> (tiny change)
* nnimap.el (nnimap-request-newgroups): Use nnimap-request-list-method

View file

@ -407,9 +407,7 @@ lines matches `message-cite-prefix-regexp' with the same prefix.
Lines matching `gnus-cite-attribution-suffix' and perhaps
`gnus-cite-attribution-prefix' are considered attribution lines."
(interactive (list 'force))
(save-excursion
(unless same-buffer
(set-buffer gnus-article-buffer))
(with-current-buffer (if same-buffer (current-buffer) gnus-article-buffer)
(gnus-cite-parse-maybe force)
(let ((buffer-read-only nil)
(alist gnus-cite-prefix-alist)
@ -462,8 +460,7 @@ Lines matching `gnus-cite-attribution-suffix' and perhaps
(defun gnus-dissect-cited-text ()
"Dissect the article buffer looking for cited text."
(save-excursion
(set-buffer gnus-article-buffer)
(with-current-buffer gnus-article-buffer
(gnus-cite-parse-maybe nil t)
(let ((alist gnus-cite-prefix-alist)
prefix numbers number marks m)
@ -523,8 +520,7 @@ Lines matching `gnus-cite-attribution-suffix' and perhaps
"Do word wrapping in the current article.
If WIDTH (the numerical prefix), use that text width when filling."
(interactive (list t current-prefix-arg))
(save-excursion
(set-buffer gnus-article-buffer)
(with-current-buffer gnus-article-buffer
(let ((buffer-read-only nil)
(inhibit-point-motion-hooks t)
(marks (gnus-dissect-cited-text))
@ -578,67 +574,66 @@ always hide."
(interactive (append (gnus-article-hidden-arg) (list 'force)))
(gnus-set-format 'cited-opened-text-button t)
(gnus-set-format 'cited-closed-text-button t)
(save-excursion
(set-buffer gnus-article-buffer)
(let ((buffer-read-only nil)
marks
(inhibit-point-motion-hooks t)
(props (nconc (list 'article-type 'cite)
gnus-hidden-properties))
(point (point-min))
found beg end start)
(while (setq point
(text-property-any point (point-max)
'gnus-callback
'gnus-article-toggle-cited-text))
(setq found t)
(goto-char point)
(gnus-article-toggle-cited-text
(get-text-property point 'gnus-data) arg)
(forward-line 1)
(setq point (point)))
(unless found
(setq marks (gnus-dissect-cited-text))
(while marks
(setq beg nil
end nil)
(while (and marks (string= (cdar marks) ""))
(setq marks (cdr marks)))
(when marks
(setq beg (caar marks)))
(while (and marks (not (string= (cdar marks) "")))
(setq marks (cdr marks)))
(when marks
(with-current-buffer gnus-article-buffer
(let ((buffer-read-only nil)
marks
(inhibit-point-motion-hooks t)
(props (nconc (list 'article-type 'cite)
gnus-hidden-properties))
(point (point-min))
found beg end start)
(while (setq point
(text-property-any point (point-max)
'gnus-callback
'gnus-article-toggle-cited-text))
(setq found t)
(goto-char point)
(gnus-article-toggle-cited-text
(get-text-property point 'gnus-data) arg)
(forward-line 1)
(setq point (point)))
(unless found
(setq marks (gnus-dissect-cited-text))
(while marks
(setq beg nil
end nil)
(while (and marks (string= (cdar marks) ""))
(setq marks (cdr marks)))
(when marks
(setq beg (caar marks)))
(while (and marks (not (string= (cdar marks) "")))
(setq marks (cdr marks)))
(when marks
(setq end (caar marks)))
;; Skip past lines we want to leave visible.
(when (and beg end gnus-cited-lines-visible)
(goto-char beg)
(forward-line (if (consp gnus-cited-lines-visible)
(car gnus-cited-lines-visible)
gnus-cited-lines-visible))
(if (>= (point) end)
(setq beg nil)
(setq beg (point-marker))
(when (consp gnus-cited-lines-visible)
(goto-char end)
(forward-line (- (cdr gnus-cited-lines-visible)))
(if (<= (point) beg)
(setq beg nil)
;; Skip past lines we want to leave visible.
(when (and beg end gnus-cited-lines-visible)
(goto-char beg)
(forward-line (if (consp gnus-cited-lines-visible)
(car gnus-cited-lines-visible)
gnus-cited-lines-visible))
(if (>= (point) end)
(setq beg nil)
(setq beg (point-marker))
(when (consp gnus-cited-lines-visible)
(goto-char end)
(forward-line (- (cdr gnus-cited-lines-visible)))
(if (<= (point) beg)
(setq beg nil)
(setq end (point-marker))))))
(when (and beg end)
(gnus-add-wash-type 'cite)
;; We use markers for the end-points to facilitate later
;; wrapping and mangling of text.
(setq beg (set-marker (make-marker) beg)
end (set-marker (make-marker) end))
(gnus-add-text-properties-when 'article-type nil beg end props)
(goto-char beg)
(when (and gnus-cite-blank-line-after-header
(not (save-excursion (search-backward "\n\n" nil t))))
(insert "\n"))
(put-text-property
(setq start (point-marker))
(progn
(when (and beg end)
(gnus-add-wash-type 'cite)
;; We use markers for the end-points to facilitate later
;; wrapping and mangling of text.
(setq beg (set-marker (make-marker) beg)
end (set-marker (make-marker) end))
(gnus-add-text-properties-when 'article-type nil beg end props)
(goto-char beg)
(when (and gnus-cite-blank-line-after-header
(not (save-excursion (search-backward "\n\n" nil t))))
(insert "\n"))
(put-text-property
(setq start (point-marker))
(progn
(gnus-article-add-button
(point)
(progn (eval gnus-cited-closed-text-button-line-format-spec)
@ -646,8 +641,8 @@ always hide."
`gnus-article-toggle-cited-text
(list (cons beg end) start))
(point))
'article-type 'annotation)
(set-marker beg (point))))))))
'article-type 'annotation)
(set-marker beg (point))))))))
(defun gnus-article-toggle-cited-text (args &optional arg)
"Toggle hiding the text in REGION.
@ -750,11 +745,9 @@ See also the documentation for `gnus-article-highlight-citation'."
(defun gnus-article-hide-citation-in-followups ()
"Hide cited text in non-root articles."
(interactive)
(save-excursion
(set-buffer gnus-article-buffer)
(with-current-buffer gnus-article-buffer
(let ((article (cdr gnus-article-current)))
(unless (save-excursion
(set-buffer gnus-summary-buffer)
(unless (with-current-buffer gnus-summary-buffer
(gnus-article-displayed-root-p article))
(gnus-article-hide-citation)))))
@ -1097,8 +1090,7 @@ See also the documentation for `gnus-article-highlight-citation'."
(gnus-overlay-put overlay 'face face))))))
(defun gnus-cite-toggle (prefix)
(save-excursion
(set-buffer gnus-article-buffer)
(with-current-buffer gnus-article-buffer
(gnus-cite-parse-maybe nil t)
(let ((buffer-read-only nil)
(numbers (cdr (assoc prefix gnus-cite-prefix-alist)))

View file

@ -305,26 +305,39 @@
(setq start end
end nil))))))
(if (fboundp 'set-process-plist)
(progn
(defalias 'gnus-set-process-plist 'set-process-plist)
(defalias 'gnus-process-plist 'process-plist))
(defun gnus-set-process-plist (process plist)
"Replace the plist of PROCESS with PLIST. Returns PLIST."
(put 'gnus-process-plist process plist))
(defun gnus-process-plist (process)
"Return the plist of PROCESS."
;; Remove those of dead processes from `gnus-process-plist'
;; to prevent it from growing.
(let ((plist (symbol-plist 'gnus-process-plist))
proc)
(while (setq proc (car plist))
(if (and (processp proc)
(memq (process-status proc) '(open run)))
(setq plist (cddr plist))
(setcar plist (caddr plist))
(setcdr plist (or (cdddr plist) '(nil))))))
(get 'gnus-process-plist process)))
(eval-and-compile
(if (fboundp 'set-process-plist)
(progn
(defalias 'gnus-set-process-plist 'set-process-plist)
(defalias 'gnus-process-plist 'process-plist)
(defalias 'gnus-process-get 'process-get)
(defalias 'gnus-process-put 'process-put))
(defun gnus-set-process-plist (process plist)
"Replace the plist of PROCESS with PLIST. Returns PLIST."
(put 'gnus-process-plist process plist))
(defun gnus-process-plist (process)
"Return the plist of PROCESS."
;; Remove those of dead processes from `gnus-process-plist'
;; to prevent it from growing.
(let ((plist (symbol-plist 'gnus-process-plist))
proc)
(while (setq proc (car plist))
(if (and (processp proc)
(memq (process-status proc) '(open run)))
(setq plist (cddr plist))
(setcar plist (caddr plist))
(setcdr plist (or (cdddr plist) '(nil))))))
(get 'gnus-process-plist process))
(defun gnus-process-get (process propname)
"Return the value of PROCESS' PROPNAME property.
This is the last value stored with `(gnus-process-put PROCESS PROPNAME VALUE)'."
(plist-get (gnus-process-plist process) propname))
(defun gnus-process-put (process propname value)
"Change PROCESS' PROPNAME property to VALUE.
It can be retrieved with `(gnus-process-get PROCESS PROPNAME)'."
(gnus-set-process-plist process
(plist-put (gnus-process-plist process)
propname value)))))
(provide 'gnus-ems)

View file

@ -660,7 +660,6 @@ simple manner.")
"h" gnus-group-make-help-group
"u" gnus-group-make-useful-group
"a" gnus-group-make-archive-group
"k" gnus-group-make-kiboze-group
"l" gnus-group-nnimap-edit-acl
"m" gnus-group-make-group
"E" gnus-group-edit-group
@ -931,7 +930,6 @@ simple manner.")
["Add the archive group" gnus-group-make-archive-group t]
["Make a doc group..." gnus-group-make-doc-group t]
["Make a web group..." gnus-group-make-web-group t]
["Make a kiboze group..." gnus-group-make-kiboze-group t]
["Make a virtual group..." gnus-group-make-empty-virtual t]
["Add a group to a virtual..." gnus-group-add-to-virtual t]
["Make an ephemeral group..." gnus-group-read-ephemeral-group t]
@ -982,7 +980,6 @@ simple manner.")
["Browse foreign server..." gnus-group-browse-foreign-server t]
["Enter server buffer" gnus-group-enter-server-mode t]
["Expire all expirable articles" gnus-group-expire-all-groups t]
["Generate any kiboze groups" nnkiboze-generate-groups t]
["Gnus version" gnus-version t]
["Save .newsrc files" gnus-group-save-newsrc t]
["Suspend Gnus" gnus-group-suspend t]
@ -1691,72 +1688,66 @@ if it is a string, only list groups matching REGEXP."
"Update all lines where GROUP appear.
If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't
already."
;; Can't use `save-excursion' here, so we do it manually.
(let ((buf (current-buffer))
mark)
(set-buffer gnus-group-buffer)
(setq mark (point-marker))
;; The buffer may be narrowed.
(save-restriction
(widen)
(let ((ident (gnus-intern-safe group gnus-active-hashtb))
(loc (point-min))
found buffer-read-only)
;; Enter the current status into the dribble buffer.
(let ((entry (gnus-group-entry group)))
(when (and entry
(not (gnus-ephemeral-group-p group)))
(gnus-dribble-enter
(concat "(gnus-group-set-info '"
(gnus-prin1-to-string (nth 2 entry))
")"))))
;; Find all group instances. If topics are in use, each group
;; may be listed in more than once.
(while (setq loc (text-property-any
loc (point-max) 'gnus-group ident))
(setq found t)
(goto-char loc)
(let ((gnus-group-indentation (gnus-group-group-indentation)))
(gnus-delete-line)
(gnus-group-insert-group-line-info group)
(save-excursion
(forward-line -1)
(gnus-run-hooks 'gnus-group-update-group-hook)))
(setq loc (1+ loc)))
(unless (or found visible-only)
;; No such line in the buffer, find out where it's supposed to
;; go, and insert it there (or at the end of the buffer).
(if gnus-goto-missing-group-function
(funcall gnus-goto-missing-group-function group)
(let ((entry (cddr (gnus-group-entry group))))
(while (and entry (car entry)
(not
(gnus-goto-char
(text-property-any
(point-min) (point-max)
'gnus-group (gnus-intern-safe
(caar entry) gnus-active-hashtb)))))
(setq entry (cdr entry)))
(or entry (goto-char (point-max)))))
;; Finally insert the line.
(let ((gnus-group-indentation (gnus-group-group-indentation)))
(gnus-group-insert-group-line-info group)
(save-excursion
(forward-line -1)
(gnus-run-hooks 'gnus-group-update-group-hook))))
(when gnus-group-update-group-function
(funcall gnus-group-update-group-function group))
(gnus-group-set-mode-line)))
(goto-char mark)
(set-marker mark nil)
(set-buffer buf)))
(with-current-buffer gnus-group-buffer
(save-excursion
;; The buffer may be narrowed.
(save-restriction
(widen)
(let ((ident (gnus-intern-safe group gnus-active-hashtb))
(loc (point-min))
found buffer-read-only)
;; Enter the current status into the dribble buffer.
(let ((entry (gnus-group-entry group)))
(when (and entry
(not (gnus-ephemeral-group-p group)))
(gnus-dribble-enter
(concat "(gnus-group-set-info '"
(gnus-prin1-to-string (nth 2 entry))
")"))))
;; Find all group instances. If topics are in use, each group
;; may be listed in more than once.
(while (setq loc (text-property-any
loc (point-max) 'gnus-group ident))
(setq found t)
(goto-char loc)
(let ((gnus-group-indentation (gnus-group-group-indentation)))
(gnus-delete-line)
(gnus-group-insert-group-line-info group)
(save-excursion
(forward-line -1)
(gnus-run-hooks 'gnus-group-update-group-hook)))
(setq loc (1+ loc)))
(unless (or found visible-only)
;; No such line in the buffer, find out where it's supposed to
;; go, and insert it there (or at the end of the buffer).
(if gnus-goto-missing-group-function
(funcall gnus-goto-missing-group-function group)
(let ((entry (cddr (gnus-group-entry group))))
(while (and entry (car entry)
(not
(gnus-goto-char
(text-property-any
(point-min) (point-max)
'gnus-group (gnus-intern-safe
(caar entry)
gnus-active-hashtb)))))
(setq entry (cdr entry)))
(or entry (goto-char (point-max)))))
;; Finally insert the line.
(let ((gnus-group-indentation (gnus-group-group-indentation)))
(gnus-group-insert-group-line-info group)
(save-excursion
(forward-line -1)
(gnus-run-hooks 'gnus-group-update-group-hook))))
(when gnus-group-update-group-function
(funcall gnus-group-update-group-function group))
(gnus-group-set-mode-line))))))
(defun gnus-group-set-mode-line ()
"Update the mode line in the group buffer."
(when (memq 'group gnus-updated-mode-lines)
;; Yes, we want to keep this mode line updated.
(save-excursion
(set-buffer gnus-group-buffer)
(with-current-buffer gnus-group-buffer
(let* ((gformat (or gnus-group-mode-line-format-spec
(gnus-set-format 'group-mode)))
(gnus-tmp-news-server (cadr gnus-select-method))
@ -1769,8 +1760,7 @@ already."
(and gnus-dribble-buffer
(buffer-name gnus-dribble-buffer)
(buffer-modified-p gnus-dribble-buffer)
(save-excursion
(set-buffer gnus-dribble-buffer)
(with-current-buffer gnus-dribble-buffer
(not (zerop (buffer-size))))))
(mode-string (eval gformat)))
;; Say whether the dribble buffer has been modified.
@ -3123,41 +3113,6 @@ mail messages or news articles in files that have numeric names."
(gnus-group-real-name group)
(list 'nndir (gnus-group-real-name group) (list 'nndir-directory dir)))))
(defvar nnkiboze-score-file)
(declare-function nnkiboze-score-file "nnkiboze" (group))
(defun gnus-group-make-kiboze-group (group address scores)
"Create an nnkiboze group.
The user will be prompted for a name, a regexp to match groups, and
score file entries for articles to include in the group."
(interactive
(list
(read-string "nnkiboze group name: ")
(read-string "Source groups (regexp): ")
(let ((headers (mapcar 'list
'("subject" "from" "number" "date" "message-id"
"references" "chars" "lines" "xref"
"followup" "all" "body" "head")))
scores header regexp regexps)
(while (not (equal "" (setq header (completing-read
"Match on header: " headers nil t))))
(setq regexps nil)
(while (not (equal "" (setq regexp (read-string
(format "Match on %s (regexp): "
header)))))
(push (list regexp nil nil 'r) regexps))
(push (cons header regexps) scores))
scores)))
(gnus-group-make-group group "nnkiboze" address)
(let* ((nnkiboze-current-group group)
(score-file (car (nnkiboze-score-file "")))
(score-dir (file-name-directory score-file)))
(unless (file-exists-p score-dir)
(make-directory score-dir))
(with-temp-file score-file
(let (emacs-lisp-mode-hook)
(gnus-pp scores)))))
(defun gnus-group-add-to-virtual (n vgroup)
"Add the current group to a virtual group."
(interactive
@ -4433,8 +4388,7 @@ The hook `gnus-exit-gnus-hook' is called before actually exiting."
(gnus-run-hooks 'gnus-exit-gnus-hook)
(gnus-configure-windows 'group t)
(when (and (gnus-buffer-live-p gnus-dribble-buffer)
(not (zerop (save-excursion
(set-buffer gnus-dribble-buffer)
(not (zerop (with-current-buffer gnus-dribble-buffer
(buffer-size)))))
(gnus-dribble-enter
";;; Gnus was exited on purpose without saving the .newsrc files."))
@ -4495,13 +4449,11 @@ and the second element is the address."
(setcar (nthcdr (1- total) info) part-info)))
(unless entry
;; This is a new group, so we just create it.
(save-excursion
(set-buffer gnus-group-buffer)
(with-current-buffer gnus-group-buffer
(setq method (gnus-info-method info))
(when (gnus-server-equal method "native")
(setq method nil))
(save-excursion
(set-buffer gnus-group-buffer)
(with-current-buffer gnus-group-buffer
(if method
;; It's a foreign group...
(gnus-group-make-group
@ -4565,8 +4517,7 @@ and the second element is the address."
"Mark ARTICLE in GROUP with MARK, whether the group is displayed or not."
(let ((buffer (gnus-summary-buffer-name group)))
(if (gnus-buffer-live-p buffer)
(save-excursion
(set-buffer (get-buffer buffer))
(with-current-buffer (get-buffer buffer)
(gnus-summary-add-mark article mark))
(gnus-add-marked-articles group (cdr (assq mark gnus-article-mark-lists))
(list article)))))

View file

@ -34,24 +34,38 @@
(defcustom gnus-html-cache-directory (nnheader-concat gnus-directory "html-cache/")
"Where Gnus will cache images it downloads from the web."
:version "24.1"
:group 'gnus-art
:type 'directory)
(defcustom gnus-html-cache-size 500000000
"The size of the Gnus image cache."
:version "24.1"
:group 'gnus-art
:type 'integer)
(defcustom gnus-html-frame-width 70
"What width to use when rendering HTML."
:version "24.1"
:group 'gnus-art
:type 'integer)
(defcustom gnus-blocked-images "."
"Images that have URLs matching this regexp will be blocked."
:version "24.1"
:group 'gnus-art
:type 'regexp)
(defcustom gnus-max-image-proportion 0.7
"How big pictures displayed are in relation to the window they're in.
A value of 0.7 means that they are allowed to take up 70% of the
width and height of the window. If they are larger than this,
and Emacs supports it, then the images will be rescaled down to
fit these criteria."
:version "24.1"
:group 'gnus-art
:type 'float)
;;;###autoload
(defun gnus-article-html (handle)
(let ((article-buffer (current-buffer)))
@ -62,7 +76,13 @@
(let* ((coding-system-for-read 'utf-8)
(coding-system-for-write 'utf-8)
(default-process-coding-system
(cons coding-system-for-read coding-system-for-write)))
(cons coding-system-for-read coding-system-for-write))
(charset (mail-content-type-get (mm-handle-type handle)
'charset)))
(when (and charset
(setq charset (mm-charset-to-coding-system charset))
(not (eq charset 'ascii)))
(mm-decode-coding-region (point-min) (point-max) charset))
(call-process-region (point-min) (point-max)
"w3m"
nil article-buffer nil
@ -97,8 +117,9 @@
(cond
;; Fetch and insert a picture.
((equal tag "img_alt")
(when (string-match "src=\"\\([^\"]+\\)" parameters)
(when (string-match "src=\"\\([^\"]+\\)" parameters)
(setq url (match-string 1 parameters))
(gnus-message 8 "Fetching image URL %s" url)
(if (string-match "^cid:\\(.*\\)" url)
;; URLs with cid: have their content stashed in other
;; parts of the MIME structure, so just insert them
@ -111,17 +132,18 @@
(setq image (gnus-create-image (buffer-string)
nil t))))
(when image
(delete-region start end)
(gnus-put-image image)))
(let ((string (buffer-substring start end)))
(delete-region start end)
(gnus-put-image image (gnus-string-or string "*")))))
;; Normal, external URL.
(when (or (null gnus-blocked-images)
(not (string-match gnus-blocked-images url)))
(unless (gnus-html-image-url-blocked-p url)
(let ((file (gnus-html-image-id url)))
(if (file-exists-p file)
;; It's already cached, so just insert it.
(when (gnus-html-put-image file (point))
(let ((string (buffer-substring start end)))
;; Delete the ALT text.
(delete-region start end))
(delete-region start end)
(gnus-html-put-image file (point) string))
;; We don't have it, so schedule it for fetching
;; asynchronously.
(push (list url
@ -132,6 +154,7 @@
((equal tag "a")
(when (string-match "href=\"\\([^\"]+\\)" parameters)
(setq url (match-string 1 parameters))
(gnus-message 8 "Fetching link URL %s" url)
(gnus-article-add-button start end
'browse-url url
url)
@ -140,6 +163,10 @@
(gnus-overlay-put overlay 'gnus-button-url url)
(when gnus-article-mouse-face
(gnus-overlay-put overlay 'mouse-face gnus-article-mouse-face)))))
;; The upper-case IMG_ALT is apparently just an artifact that
;; should be deleted.
((equal tag "IMG_ALT")
(delete-region start end))
;; Whatever. Just ignore the tag.
(t
))
@ -153,6 +180,7 @@
(gnus-html-schedule-image-fetching (current-buffer) (nreverse images)))))
(defun gnus-html-schedule-image-fetching (buffer images)
(gnus-message 8 "Scheduling image fetching in buffer %s, images %s" buffer images)
(let* ((url (caar images))
(process (start-process
"images" nil "curl"
@ -171,8 +199,8 @@
(defun gnus-html-curl-sentinel (process event)
(when (string-match "finished" event)
(let* ((images (process-get process 'images))
(buffer (process-get process 'buffer))
(let* ((images (gnus-process-get process 'images))
(buffer (gnus-process-get process 'buffer))
(spec (pop images))
(file (gnus-html-image-id (car spec))))
(when (and (buffer-live-p buffer)
@ -182,13 +210,14 @@
;; article before the image arrived.
(not (= (marker-position (cadr spec)) (point-min))))
(with-current-buffer buffer
(let ((inhibit-read-only t))
(when (gnus-html-put-image file (cadr spec))
(delete-region (1+ (cadr spec)) (caddr spec))))))
(let ((inhibit-read-only t)
(string (buffer-substring (cadr spec) (caddr spec))))
(delete-region (cadr spec) (caddr spec))
(gnus-html-put-image file (cadr spec) string))))
(when images
(gnus-html-schedule-image-fetching buffer images)))))
(defun gnus-html-put-image (file point)
(defun gnus-html-put-image (file point string)
(when (display-graphic-p)
(let ((image (ignore-errors
(gnus-create-image file))))
@ -202,13 +231,40 @@
(= (car (image-size image t)) 30)
(= (cdr (image-size image t)) 30))))
(progn
(gnus-put-image image)
(gnus-put-image (gnus-html-rescale-image image)
(gnus-string-or string "*"))
t)
(insert string)
(when (fboundp 'find-image)
(gnus-put-image (find-image
'((:type xpm :file "lock-broken.xpm")))))
'((:type xpm :file "lock-broken.xpm")))
(gnus-string-or string "*")))
nil)))))
(defun gnus-html-rescale-image (image)
(if (or (not (fboundp 'imagemagick-types))
(not (get-buffer-window (current-buffer))))
image
(let* ((width (car (image-size image t)))
(height (cdr (image-size image t)))
(edges (window-pixel-edges (get-buffer-window (current-buffer))))
(window-width (truncate (* gnus-max-image-proportion
(- (nth 2 edges) (nth 0 edges)))))
(window-height (truncate (* gnus-max-image-proportion
(- (nth 3 edges) (nth 1 edges)))))
scaled-image)
(when (> width window-width)
(setq window-height (truncate (* window-height
(/ (* 1.0 window-width) width)))))
(or
(cond ((> height window-height)
(create-image file 'imagemagick nil
:height window-height))
((> width window-width)
(create-image file 'imagemagick nil
:width window-width)))
image))))
(defun gnus-html-prune-cache ()
(let ((total-size 0)
files)
@ -227,6 +283,15 @@
(decf total-size (cadr file))
(delete-file (nth 2 file)))))))
(defun gnus-html-image-url-blocked-p (url)
"Find out if URL is blocked by `gnus-blocked-images'."
(let ((ret (and gnus-blocked-images
(string-match gnus-blocked-images url))))
(when ret
(gnus-message 8 "Image URL %s is blocked by gnus-blocked-images regex %s" url gnus-blocked-images))
ret))
;;;###autoload
(defun gnus-html-prefetch-images (summary)
(let (blocked-images urls)
@ -236,12 +301,11 @@
(save-match-data
(while (re-search-forward "<img.*src=[\"']\\([^\"']+\\)" nil t)
(let ((url (match-string 1)))
(when (or (null blocked-images)
(not (string-match blocked-images url)))
(unless (file-exists-p (gnus-html-image-id url))
(push url urls)
(push (gnus-html-image-id url) urls)
(push "-o" urls)))))
(unless (gnus-html-image-url-blocked-p url)
(unless (file-exists-p (gnus-html-image-id url))
(push url urls)
(push (gnus-html-image-id url) urls)
(push "-o" urls)))))
(let ((process
(apply 'start-process
"images" nil "curl"

View file

@ -663,7 +663,7 @@ string with the suggested prefix."
gnus-low-score-mark gnus-ancient-mark gnus-read-mark
gnus-duplicate-mark)
"*The list of marks converted into expiration if a group is auto-expirable."
:version "21.1"
:version "24.1"
:group 'gnus-summary
:type '(repeat character))

View file

@ -1740,14 +1740,11 @@ slower."
("nneething" none address prompt-address physical-address)
("nndoc" none address prompt-address)
("nnbabyl" mail address respool)
("nnkiboze" post virtual)
("nndraft" post-mail)
("nnfolder" mail respool address)
("nngateway" post-mail address prompt-address physical-address)
("nnweb" none)
("nnrss" none)
("nnwfm" none)
("nnlistserv" none)
("nnagent" post-mail)
("nnimap" post-mail address prompt-address physical-address)
("nnmaildir" mail respool address)
@ -3289,12 +3286,12 @@ with a `subscribed' parameter."
(defmacro gnus-string-or (&rest strings)
"Return the first element of STRINGS that is a non-blank string.
STRINGS will be evaluated in normal `or' order."
`(gnus-string-or-1 ',strings))
`(gnus-string-or-1 (list ,@strings)))
(defun gnus-string-or-1 (strings)
(let (string)
(while strings
(setq string (eval (pop strings)))
(setq string (pop strings))
(if (string-match "^[ \t]*$" string)
(setq string nil)
(setq strings nil)))
@ -3937,8 +3934,7 @@ If SYMBOL, return the value of that symbol in the group parameters.
If you call this function inside a loop, consider using the faster
`gnus-group-fast-parameter' instead."
(save-excursion
(set-buffer gnus-group-buffer)
(with-current-buffer gnus-group-buffer
(if symbol
(gnus-group-fast-parameter group symbol allow-list)
(nconc
@ -4097,8 +4093,7 @@ Returns the number of articles marked as read."
(defun gnus-kill-save-kill-buffer ()
(let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name)))
(when (get-file-buffer file)
(save-excursion
(set-buffer (get-file-buffer file))
(with-current-buffer (get-file-buffer file)
(when (buffer-modified-p)
(save-buffer))
(kill-buffer (current-buffer))))))

View file

@ -252,6 +252,7 @@ included. Organization and User-Agent are optional."
(defcustom message-prune-recipient-rules nil
"Rules for how to prune the list of recipients when doing wide replies.
This is a list of regexps and regexp matches."
:version "24.1"
:group 'message-mail
:group 'message-headers
:link '(custom-manual "(message)Wide Reply")

View file

@ -1,325 +0,0 @@
;;; nndb.el --- nndb access for Gnus
;; Copyright (C) 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2006, 2007,
;; 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
;; Kai Grossjohann <grossjohann@ls6.informatik.uni-dortmund.de>
;; Joe Hildebrand <joe.hildebrand@ilg.com>
;; David Blacka <davidb@rwhois.net>
;; Keywords: news
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; This was based upon Kai Grossjohan's shamessly snarfed code and
;;; further modified by Joe Hildebrand. It has been updated for Red
;;; Gnus.
;; TODO:
;;
;; * Fix bug where server connection can be lost and impossible to regain
;; This hasn't happened to me in a while; think it was fixed in Rgnus
;;
;; * make it handle different nndb servers seemlessly
;;
;; * Optimize expire if FORCE
;;
;; * Optimize move (only expire once)
;;
;; * Deal with add/deletion of groups
;;
;; * make the backend TOUCH an article when marked as expireable (will
;; make article expire 'expiry' days after that moment).
;;; Code:
;; For Emacs < 22.2.
(eval-and-compile
(unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
;;-
;; Register nndb with known select methods.
(require 'gnus-start)
(unless (assoc "nndb" gnus-valid-select-methods)
(gnus-declare-backend "nndb" 'mail 'respool 'address 'prompt-address))
(require 'nnmail)
(require 'nnheader)
(require 'nntp)
(eval-when-compile (require 'cl))
;; Declare nndb as derived from nntp
(nnoo-declare nndb nntp)
;; Variables specific to nndb
;;- currently not used but just in case...
(defvoo nndb-deliver-program "nndel"
"*The program used to put a message in an NNDB group.")
(defvoo nndb-server-side-expiry nil
"If t, expiry calculation will occur on the server side.")
(defvoo nndb-set-expire-date-on-mark nil
"If t, the expiry date for a given article will be set to the time
it was marked as expireable; otherwise the date will be the time the
article was posted to nndb")
;; Variables copied from nntp
(defvoo nndb-server-opened-hook '(nntp-send-authinfo-from-file)
"Like nntp-server-opened-hook."
nntp-server-opened-hook)
(defvoo nndb-address "localhost"
"*The name of the NNDB server."
nntp-address)
(defvoo nndb-port-number 9000
"*Port number to connect to."
nntp-port-number)
;; change to 'news if you are actually using nndb for news
(defvoo nndb-article-type 'mail)
(defvoo nndb-status-string nil "" nntp-status-string)
(defconst nndb-version "nndb 0.7"
"Version numbers of this version of NNDB.")
;;; Interface functions.
(nnoo-define-basics nndb)
;;------------------------------------------------------------------
;; this function turns the lisp list into a string list. There is
;; probably a more efficient way to do this.
(defun nndb-build-article-string (articles)
(let (art-string art)
(while articles
(setq art (pop articles))
(setq art-string (concat art-string art " ")))
art-string))
(defun nndb-build-expire-rest-list (total expire)
(let (art rest)
(while total
(setq art (pop total))
(if (memq art expire)
()
(push art rest)))
rest))
;;
(deffoo nndb-request-type (group &optional article)
nndb-article-type)
;; nndb-request-update-info does not exist and is not needed
;; nndb-request-update-mark does not exist; it should be used to TOUCH
;; articles as they are marked exipirable
(defun nndb-touch-article (group article)
(nntp-send-command nil "X-TOUCH" article))
(deffoo nndb-request-update-mark
(group article mark)
"Sets the expiry date for ARTICLE in GROUP to now, if the mark is 'E'"
(if (and nndb-set-expire-date-on-mark (string-equal mark "E"))
(nndb-touch-article group article))
mark)
;; nndb-request-create-group -- currently this isn't necessary; nndb
;; creates groups on demand.
;; todo -- use some other time than the creation time of the article
;; best is time since article has been marked as expirable
(defun nndb-request-expire-articles-local
(articles &optional group server force)
"Let gnus do the date check and issue the delete commands."
(let (msg art delete-list (num-delete 0) rest)
(nntp-possibly-change-group group server)
(while articles
(setq art (pop articles))
(nntp-send-command "^\\([23]\\|^423\\).*\n" "X-DATE" art)
(setq msg (nndb-status-message))
(if (string-match "^423" msg)
()
(or (string-match "'\\(.+\\)'" msg)
(error "Not a valid response for X-DATE command: %s"
msg))
(if (nnmail-expired-article-p
group
(date-to-time (substring msg (match-beginning 1) (match-end 1)))
force)
(progn
(setq delete-list (concat delete-list " " (int-to-string art)))
(setq num-delete (1+ num-delete)))
(push art rest))))
(if (> (length delete-list) 0)
(progn
(nnheader-message 5 "Deleting %s article(s) from %s"
(int-to-string num-delete) group)
(nntp-send-command "^[23].*\n" "X-DELETE" delete-list))
)
(nnheader-message 5 "")
(nconc rest articles)))
(defun nndb-get-remote-expire-response ()
(let (list)
(set-buffer nntp-server-buffer)
(goto-char (point-min))
(if (looking-at "^[34]")
;; x-expire returned error--presume no articles were expirable)
(setq list nil)
;; otherwise, pull all of the following numbers into the list
(re-search-forward "follows\r?\n?" nil t)
(while (re-search-forward "^[0-9]+$" nil t)
(push (string-to-number (match-string 0)) list)))
list))
(defun nndb-request-expire-articles-remote
(articles &optional group server force)
"Let the nndb backend expire articles"
(let (days art-string delete-list (num-delete 0))
(nntp-possibly-change-group group server)
;; first calculate the wait period in days
(setq days (or (and nnmail-expiry-wait-function
(funcall nnmail-expiry-wait-function group))
nnmail-expiry-wait))
;; now handle the special cases
(cond (force
(setq days 0))
((eq days 'never)
;; This isn't an expirable group.
(setq days -1))
((eq days 'immediate)
(setq days 0)))
;; build article string
(setq art-string (concat days " " (nndb-build-article-string articles)))
(nntp-send-command "^\.\r?\n\\|^[345].*\n" "X-EXPIRE" art-string)
(setq delete-list (nndb-get-remote-expire-response))
(setq num-delete (length delete-list))
(if (> num-delete 0)
(nnheader-message 5 "Deleting %s article(s) from %s"
(int-to-string num-delete) group))
(nndb-build-expire-rest-list articles delete-list)))
(deffoo nndb-request-expire-articles
(articles &optional group server force)
"Expires ARTICLES from GROUP on SERVER.
If FORCE, delete regardless of exiration date, otherwise use normal
expiry mechanism."
(if nndb-server-side-expiry
(nndb-request-expire-articles-remote articles group server force)
(nndb-request-expire-articles-local articles group server force)))
;; _Something_ defines it...
(declare-function nndb-request-article "nndb" t t)
(deffoo nndb-request-move-article
(article group server accept-form &optional last move-is-internal)
"Move ARTICLE (a number) from GROUP on SERVER.
Evals ACCEPT-FORM in current buffer, where the article is.
Optional LAST is ignored."
;; we guess that the second arg in accept-form is the new group,
;; which it will be for nndb, which is all that matters anyway
(let ((new-group (nth 1 accept-form)) result)
(nntp-possibly-change-group group server)
;; use the move command for nndb-to-nndb moves
(if (string-match "^nndb" new-group)
(let ((new-group-name (gnus-group-real-name new-group)))
(nntp-send-command "^[23].*\n" "X-MOVE" article new-group-name)
(cons new-group article))
;; else move normally
(let ((artbuf (get-buffer-create " *nndb move*")))
(and
(nndb-request-article article group server artbuf)
(save-excursion
(set-buffer artbuf)
(insert-buffer-substring nntp-server-buffer)
(setq result (eval accept-form))
(kill-buffer (current-buffer))
result)
(nndb-request-expire-articles (list article)
group
server
t))
result)
)))
(deffoo nndb-request-accept-article (group server &optional last)
"The article in the current buffer is put into GROUP."
(nntp-possibly-change-group group server)
(let (art msg)
(when (nntp-send-command "^[23].*\r?\n" "ACCEPT" group)
(nnheader-insert "")
(nntp-send-buffer "^[23].*\n"))
(set-buffer nntp-server-buffer)
(setq msg (buffer-string))
(or (string-match "^\\([0-9]+\\)" msg)
(error "nndb: %s" msg))
(setq art (substring msg (match-beginning 1) (match-end 1)))
(nnheader-message 5 "nndb: accepted %s" art)
(list art)))
(deffoo nndb-request-replace-article (article group buffer)
"ARTICLE is the number of the article in GROUP to be replaced with the contents of the BUFFER."
(set-buffer buffer)
(when (nntp-send-command "^[23].*\r?\n" "X-REPLACE" (int-to-string article))
(nnheader-insert "")
(nntp-send-buffer "^[23.*\n")
(list (int-to-string article))))
; nndb-request-delete-group does not exist
; todo -- maybe later
; nndb-request-rename-group does not exist
; todo -- maybe later
;; -- standard compatibility functions
(deffoo nndb-status-message (&optional server)
"Return server status as a string."
(set-buffer nntp-server-buffer)
(buffer-string))
;; Import stuff from nntp
(nnoo-import nndb
(nntp))
(provide 'nndb)
;; arch-tag: 83bd6fb4-58d9-4fed-a901-c6c625ad5f8a
;;; nndb.el ends here

View file

@ -263,10 +263,10 @@
;; I have tried to make the code expandable. Basically, it is divided
;; into two layers. The upper layer is somewhat like the `nnvirtual'
;; or `nnkiboze' backends: given a specification of what articles to
;; show from another backend, it creates a group containing exactly
;; those articles. The lower layer issues a query to a search engine
;; and produces such a specification of what articles to show from the
;; backend: given a specification of what articles to show from
;; another backend, it creates a group containing exactly those
;; articles. The lower layer issues a query to a search engine and
;; produces such a specification of what articles to show from the
;; other backend.
;; The interface between the two layers consists of the single

View file

@ -1,391 +0,0 @@
;;; nnkiboze.el --- select virtual news access for Gnus
;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; The other access methods (nntp, nnspool, etc) are general news
;; access methods. This module relies on Gnus and can't be used
;; separately.
;;; Code:
(require 'nntp)
(require 'nnheader)
(require 'gnus)
(require 'gnus-score)
(require 'nnoo)
(require 'mm-util)
(eval-when-compile (require 'cl))
(nnoo-declare nnkiboze)
(defvoo nnkiboze-directory (nnheader-concat gnus-directory "kiboze/")
"nnkiboze will put its files in this directory.")
(defvoo nnkiboze-level 9
"The maximum level to be searched for articles.")
(defvoo nnkiboze-remove-read-articles t
"If non-nil, nnkiboze will remove read articles from the kiboze group.")
(defvoo nnkiboze-ephemeral nil
"If non-nil, don't store any data anywhere.")
(defvoo nnkiboze-scores nil
"Score rules for generating the nnkiboze group.")
(defvoo nnkiboze-regexp nil
"Regexp for matching component groups.")
(defvoo nnkiboze-file-coding-system mm-text-coding-system
"Coding system for nnkiboze files.")
(defconst nnkiboze-version "nnkiboze 1.0")
(defvoo nnkiboze-current-group nil)
(defvoo nnkiboze-status-string "")
(defvoo nnkiboze-headers nil)
;;; Interface functions.
(nnoo-define-basics nnkiboze)
(deffoo nnkiboze-retrieve-headers (articles &optional group server fetch-old)
(nnkiboze-possibly-change-group group)
(unless gnus-nov-is-evil
(if (stringp (car articles))
'headers
(let ((nov (nnkiboze-nov-file-name)))
(when (file-exists-p nov)
(save-excursion
(set-buffer nntp-server-buffer)
(erase-buffer)
(let ((nnheader-file-coding-system nnkiboze-file-coding-system))
(nnheader-insert-file-contents nov))
(nnheader-nov-delete-outside-range
(car articles) (car (last articles)))
'nov))))))
(deffoo nnkiboze-request-article (article &optional newsgroup server buffer)
(nnkiboze-possibly-change-group newsgroup)
(if (not (numberp article))
;; This is a real kludge. It might not work at times, but it
;; does no harm I think. The only alternative is to offer no
;; article fetching by message-id at all.
(nntp-request-article article newsgroup gnus-nntp-server buffer)
(let* ((header (gnus-summary-article-header article))
(xref (mail-header-xref header))
num group)
(unless xref
(error "nnkiboze: No xref"))
(unless (string-match " \\([^ ]+\\):\\([0-9]+\\)" xref)
(error "nnkiboze: Malformed xref"))
(setq num (string-to-number (match-string 2 xref))
group (match-string 1 xref))
(or (with-current-buffer buffer
(or (and gnus-use-cache (gnus-cache-request-article num group))
(gnus-agent-request-article num group)))
(gnus-request-article num group buffer)))))
(deffoo nnkiboze-request-scan (&optional group server)
(nnkiboze-possibly-change-group group)
(nnkiboze-generate-group (concat "nnkiboze:" group)))
(deffoo nnkiboze-request-group (group &optional server dont-check)
"Make GROUP the current newsgroup."
(nnkiboze-possibly-change-group group)
(if dont-check
t
(let ((nov-file (nnkiboze-nov-file-name))
beg end total)
(save-excursion
(set-buffer nntp-server-buffer)
(erase-buffer)
(unless (file-exists-p nov-file)
(nnkiboze-request-scan group))
(if (not (file-exists-p nov-file))
(nnheader-report 'nnkiboze "Can't select group %s" group)
(let ((nnheader-file-coding-system nnkiboze-file-coding-system))
(nnheader-insert-file-contents nov-file))
(if (zerop (buffer-size))
(nnheader-insert "211 0 0 0 %s\n" group)
(goto-char (point-min))
(when (looking-at "[0-9]+")
(setq beg (read (current-buffer))))
(goto-char (point-max))
(when (re-search-backward "^[0-9]" nil t)
(setq end (read (current-buffer))))
(setq total (count-lines (point-min) (point-max)))
(nnheader-insert "211 %d %d %d %s\n" total beg end group)))))))
(deffoo nnkiboze-close-group (group &optional server)
(nnkiboze-possibly-change-group group)
;; Remove NOV lines of articles that are marked as read.
(when (and (file-exists-p (nnkiboze-nov-file-name))
nnkiboze-remove-read-articles)
(let ((coding-system-for-write nnkiboze-file-coding-system))
(with-temp-file (nnkiboze-nov-file-name)
(let ((cur (current-buffer))
(nnheader-file-coding-system nnkiboze-file-coding-system))
(nnheader-insert-file-contents (nnkiboze-nov-file-name))
(goto-char (point-min))
(while (not (eobp))
(if (not (gnus-article-read-p (read cur)))
(forward-line 1)
(gnus-delete-line))))))
(setq nnkiboze-current-group nil)))
(deffoo nnkiboze-open-server (server &optional defs)
(unless (assq 'nnkiboze-regexp defs)
(push `(nnkiboze-regexp ,server)
defs))
(nnoo-change-server 'nnkiboze server defs))
(deffoo nnkiboze-request-delete-group (group &optional force server)
(nnkiboze-possibly-change-group group)
(when force
(let ((files (nconc
(nnkiboze-score-file group)
(list (nnkiboze-nov-file-name)
(nnkiboze-nov-file-name ".newsrc")))))
(while files
(and (file-exists-p (car files))
(file-writable-p (car files))
(delete-file (car files)))
(setq files (cdr files)))))
(setq nnkiboze-current-group nil)
t)
(nnoo-define-skeleton nnkiboze)
;;; Internal functions.
(defun nnkiboze-possibly-change-group (group)
(setq nnkiboze-current-group group))
(defun nnkiboze-prefixed-name (group)
(gnus-group-prefixed-name group '(nnkiboze "")))
;;;###autoload
(defun nnkiboze-generate-groups ()
"\"Usage: emacs -batch -l nnkiboze -f nnkiboze-generate-groups\".
Finds out what articles are to be part of the nnkiboze groups."
(interactive)
(let ((mail-sources nil)
(gnus-use-dribble-file nil)
(gnus-read-active-file t)
(gnus-expert-user t))
(gnus))
(let* ((gnus-newsrc-alist (gnus-copy-sequence gnus-newsrc-alist))
(newsrc (cdr gnus-newsrc-alist))
gnus-newsrc-hashtb info)
(gnus-make-hashtable-from-newsrc-alist)
;; We have copied all the newsrc alist info over to local copies
;; so that we can mess all we want with these lists.
(while (setq info (pop newsrc))
(when (string-match "nnkiboze" (gnus-info-group info))
;; For each kiboze group, we call this function to generate
;; it.
(nnkiboze-generate-group (gnus-info-group info) t))))
(save-excursion
(set-buffer gnus-group-buffer)
(gnus-group-list-groups)))
(defun nnkiboze-score-file (group)
(list (expand-file-name
(concat (file-name-as-directory gnus-kill-files-directory)
(nnheader-translate-file-chars
(concat (nnkiboze-prefixed-name nnkiboze-current-group)
"." gnus-score-file-suffix))))))
(defun nnkiboze-generate-group (group &optional inhibit-list-groups)
(let* ((info (gnus-get-info group))
(newsrc-file (concat nnkiboze-directory
(nnheader-translate-file-chars
(concat group ".newsrc"))))
(nov-file (concat nnkiboze-directory
(nnheader-translate-file-chars
(concat group ".nov"))))
method nnkiboze-newsrc gname newsrc active
ginfo lowest glevel orig-info nov-buffer
;; Bind various things to nil to make group entry faster.
(gnus-expert-user t)
(gnus-large-newsgroup nil)
(gnus-score-find-score-files-function 'nnkiboze-score-file)
;; Use only nnkiboze-score-file!
(gnus-score-use-all-scores nil)
(gnus-use-scoring t)
(gnus-verbose (min gnus-verbose 3))
gnus-select-group-hook gnus-summary-prepare-hook
gnus-thread-sort-functions gnus-show-threads
gnus-visual gnus-suppress-duplicates num-unread)
(unless info
(error "No such group: %s" group))
;; Load the kiboze newsrc file for this group.
(when (file-exists-p newsrc-file)
(load newsrc-file))
(let ((coding-system-for-write nnkiboze-file-coding-system))
(gnus-make-directory (file-name-directory nov-file))
(with-temp-file nov-file
(mm-disable-multibyte)
(when (file-exists-p nov-file)
(insert-file-contents nov-file))
(setq nov-buffer (current-buffer))
;; Go through the active hashtb and add new all groups that match the
;; kiboze regexp.
(mapatoms
(lambda (group)
(and (string-match nnkiboze-regexp
(setq gname (symbol-name group))) ; Match
(not (assoc gname nnkiboze-newsrc)) ; It isn't registered
(numberp (car (symbol-value group))) ; It is active
(or (> nnkiboze-level 7)
(and (setq glevel
(gnus-info-level (gnus-get-info gname)))
(>= nnkiboze-level glevel)))
(not (string-match "^nnkiboze:" gname)) ; Exclude kibozes
(push (cons gname (1- (car (symbol-value group))))
nnkiboze-newsrc)))
gnus-active-hashtb)
;; `newsrc' is set to the list of groups that possibly are
;; component groups to this kiboze group. This list has elements
;; on the form `(GROUP . NUMBER)', where NUMBER is the highest
;; number that has been kibozed in GROUP in this kiboze group.
(setq newsrc nnkiboze-newsrc)
(while newsrc
(if (not (setq active (gnus-active (caar newsrc))))
;; This group isn't active after all, so we remove it from
;; the list of component groups.
(setq nnkiboze-newsrc (delq (car newsrc) nnkiboze-newsrc))
(setq lowest (cdar newsrc))
;; Ok, we have a valid component group, so we jump to it.
(switch-to-buffer gnus-group-buffer)
(gnus-group-jump-to-group (caar newsrc))
(gnus-message 3 "nnkiboze: Checking %s..." (caar newsrc))
(setq ginfo (gnus-get-info (gnus-group-group-name))
orig-info (gnus-copy-sequence ginfo)
num-unread (gnus-group-unread (caar newsrc)))
(unwind-protect
(progn
;; We set all list of article marks to nil. Since we operate
;; on copies of the real lists, we can destroy anything we
;; want here.
(when (nth 3 ginfo)
(setcar (nthcdr 3 ginfo) nil))
;; We set the list of read articles to be what we expect for
;; this kiboze group -- either nil or `(1 . LOWEST)'.
(when ginfo
(setcar (nthcdr 2 ginfo)
(and (not (= lowest 1)) (cons 1 lowest))))
(when (and (or (not ginfo)
(> (length (gnus-list-of-unread-articles
(car ginfo)))
0))
(progn
(ignore-errors
(gnus-group-select-group nil))
(eq major-mode 'gnus-summary-mode)))
;; We are now in the group where we want to be.
(setq method (gnus-find-method-for-group
gnus-newsgroup-name))
(when (eq method gnus-select-method)
(setq method nil))
;; We go through the list of scored articles.
(while gnus-newsgroup-scored
(when (> (caar gnus-newsgroup-scored) lowest)
;; If it has a good score, then we enter this article
;; into the kiboze group.
(nnkiboze-enter-nov
nov-buffer
(gnus-summary-article-header
(caar gnus-newsgroup-scored))
gnus-newsgroup-name))
(setq gnus-newsgroup-scored (cdr gnus-newsgroup-scored)))
;; That's it. We exit this group.
(when (eq major-mode 'gnus-summary-mode)
(kill-buffer (current-buffer)))))
;; Restore the proper info.
(when ginfo
(setcdr ginfo (cdr orig-info)))
(setcar (gnus-group-entry (caar newsrc)) num-unread)))
(setcdr (car newsrc) (cdr active))
(gnus-message 3 "nnkiboze: Checking %s...done" (caar newsrc))
(setq newsrc (cdr newsrc)))))
;; We save the kiboze newsrc for this group.
(gnus-make-directory (file-name-directory newsrc-file))
(with-temp-file newsrc-file
(mm-disable-multibyte)
(insert "(setq nnkiboze-newsrc '")
(gnus-prin1 nnkiboze-newsrc)
(insert ")\n"))
(unless inhibit-list-groups
(save-excursion
(set-buffer gnus-group-buffer)
(gnus-group-list-groups)))
t))
(defun nnkiboze-enter-nov (buffer header group)
(save-excursion
(set-buffer buffer)
(goto-char (point-max))
(let ((prefix (gnus-group-real-prefix group))
(oheader (copy-sequence header))
article)
(if (zerop (forward-line -1))
(progn
(setq article (1+ (read (current-buffer))))
(forward-line 1))
(setq article 1))
(mail-header-set-number oheader article)
(with-temp-buffer
(insert (or (mail-header-xref oheader) ""))
(goto-char (point-min))
(if (re-search-forward " [^ ]+:[0-9]+" nil t)
(goto-char (match-beginning 0))
(or (eobp) (forward-char 1)))
;; The first Xref has to be the group this article
;; really came for - this is the article nnkiboze
;; will request when it is asked for the article.
(insert " " group ":"
(int-to-string (mail-header-number header)) " ")
(while (re-search-forward " [^ ]+:[0-9]+" nil t)
(goto-char (1+ (match-beginning 0)))
(insert prefix))
(mail-header-set-xref oheader (buffer-string)))
(nnheader-insert-nov oheader))))
(defun nnkiboze-nov-file-name (&optional suffix)
(concat (file-name-as-directory nnkiboze-directory)
(nnheader-translate-file-chars
(concat (nnkiboze-prefixed-name nnkiboze-current-group)
(or suffix ".nov")))))
(provide 'nnkiboze)
;; arch-tag: 66068271-bdc9-4801-bcde-779702e73a05
;;; nnkiboze.el ends here

View file

@ -1,152 +0,0 @@
;;; nnlistserv.el --- retrieving articles via web mailing list archives
;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news, mail
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(eval-when-compile (require 'cl))
(require 'nnoo)
(require 'mm-url)
(require 'nnweb)
(nnoo-declare nnlistserv
nnweb)
(defvoo nnlistserv-directory (nnheader-concat gnus-directory "nnlistserv/")
"Where nnlistserv will save its files."
nnweb-directory)
(defvoo nnlistserv-name 'kk
"What search engine type is being used."
nnweb-type)
(defvoo nnlistserv-type-definition
'((kk
(article . nnlistserv-kk-wash-article)
(map . nnlistserv-kk-create-mapping)
(search . nnlistserv-kk-search)
(address . "http://www.itk.ntnu.no/ansatte/Andresen_Trond/kk-f/%s/")
(pages "fra160396" "fra160796" "fra061196" "fra160197"
"fra090997" "fra040797" "fra130397" "nye")
(index . "date.html")
(identifier . nnlistserv-kk-identity)))
"Type-definition alist."
nnweb-type-definition)
(defvoo nnlistserv-search nil
"Search string to feed to DejaNews."
nnweb-search)
(defvoo nnlistserv-ephemeral-p nil
"Whether this nnlistserv server is ephemeral."
nnweb-ephemeral-p)
;;; Internal variables
;;; Interface functions
(nnoo-define-basics nnlistserv)
(nnoo-import nnlistserv
(nnweb))
;;; Internal functions
;;;
;;; KK functions.
;;;
(defun nnlistserv-kk-create-mapping ()
"Perform the search and create a number-to-url alist."
(save-excursion
(set-buffer nnweb-buffer)
(let ((case-fold-search t)
(active (or (cadr (assoc nnweb-group nnweb-group-alist))
(cons 1 0)))
(pages (nnweb-definition 'pages))
map url page subject from )
(while (setq page (pop pages))
(erase-buffer)
(when (funcall (nnweb-definition 'search) page)
;; Go through all the article hits on this page.
(goto-char (point-min))
(mm-url-decode-entities)
(goto-char (point-min))
(while (re-search-forward "^<li> *<a href=\"\\([^\"]+\\)\"><b>\\([^\\>]+\\)</b></a> *<[^>]+><i>\\([^>]+\\)<" nil t)
(setq url (match-string 1)
subject (match-string 2)
from (match-string 3))
(setq url (concat (format (nnweb-definition 'address) page) url))
(unless (nnweb-get-hashtb url)
(push
(list
(incf (cdr active))
(make-full-mail-header
(cdr active) subject from ""
(concat "<" (nnweb-identifier url) "@kk>")
nil 0 0 url))
map)
(nnweb-set-hashtb (cadar map) (car map))
(nnheader-message 5 "%s %s %s" (cdr active) (point) pages)))))
;; Return the articles in the right order.
(setq nnweb-articles
(sort (nconc nnweb-articles map) 'car-less-than-car)))))
(defun nnlistserv-kk-wash-article ()
(let ((case-fold-search t)
(headers '(sent name email subject id))
sent name email subject id)
(mm-url-decode-entities)
(while headers
(goto-char (point-min))
(re-search-forward (format "<!-- %s=\"\\([^\"]+\\)" (car headers)) nil t)
(set (pop headers) (match-string 1)))
(goto-char (point-min))
(search-forward "<!-- body" nil t)
(delete-region (point-min) (progn (forward-line 1) (point)))
(goto-char (point-max))
(search-backward "<!-- body" nil t)
(delete-region (point-max) (progn (beginning-of-line) (point)))
(mm-url-remove-markup)
(goto-char (point-min))
(insert (format "From: %s <%s>\n" name email)
(format "Subject: %s\n" subject)
(format "Message-ID: %s\n" id)
(format "Date: %s\n\n" sent))))
(defun nnlistserv-kk-search (search)
(mm-url-insert
(concat (format (nnweb-definition 'address) search)
(nnweb-definition 'index)))
t)
(defun nnlistserv-kk-identity (url)
"Return an unique identifier based on URL."
url)
(provide 'nnlistserv)
;; arch-tag: 7705176f-d332-4a5e-a520-d0d319445617
;;; nnlistserv.el ends here

View file

@ -1,432 +0,0 @@
;;; nnwfm.el --- interfacing with a web forum
;; Copyright (C) 2000, 2002, 2003, 2004, 2005,
;; 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; Keywords: news
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Note: You need to have `url' and `w3' installed for this
;; backend to work.
;;; Code:
(eval-when-compile (require 'cl))
(require 'nnoo)
(require 'message)
(require 'gnus-util)
(require 'gnus)
(require 'nnmail)
(require 'mm-util)
(require 'mm-url)
(require 'nnweb)
(autoload 'w3-parse-buffer "w3-parse")
(nnoo-declare nnwfm)
(defvoo nnwfm-directory (nnheader-concat gnus-directory "wfm/")
"Where nnwfm will save its files.")
(defvoo nnwfm-address ""
"The address of the Ultimate bulletin board.")
;;; Internal variables
(defvar nnwfm-groups-alist nil)
(defvoo nnwfm-groups nil)
(defvoo nnwfm-headers nil)
(defvoo nnwfm-articles nil)
(defvar nnwfm-table-regexp
"postings.*editpost\\|forumdisplay\\|Forum[0-9]+/HTML\\|getbio")
;;; Interface functions
(nnoo-define-basics nnwfm)
(deffoo nnwfm-retrieve-headers (articles &optional group server fetch-old)
(nnwfm-possibly-change-server group server)
(unless gnus-nov-is-evil
(let* ((last (car (last articles)))
(did nil)
(start 1)
(entry (assoc group nnwfm-groups))
(sid (nth 2 entry))
(topics (nth 4 entry))
(mapping (nth 5 entry))
(old-total (or (nth 6 entry) 1))
(nnwfm-table-regexp "Thread.asp")
headers article subject score from date lines parent point
contents tinfo fetchers map elem a href garticles topic old-max
inc datel table string current-page total-contents pages
farticles forum-contents parse furl-fetched mmap farticle
thread-id tables hstuff bstuff time)
(setq map mapping)
(while (and (setq article (car articles))
map)
(while (and map
(or (> article (caar map))
(< (cadar map) (caar map))))
(pop map))
(when (setq mmap (car map))
(setq farticle -1)
(while (and article
(<= article (nth 1 mmap)))
;; Do we already have a fetcher for this topic?
(if (setq elem (assq (nth 2 mmap) fetchers))
;; Yes, so we just add the spec to the end.
(nconc elem (list (cons article
(+ (nth 3 mmap) (incf farticle)))))
;; No, so we add a new one.
(push (list (nth 2 mmap)
(cons article
(+ (nth 3 mmap) (incf farticle))))
fetchers))
(pop articles)
(setq article (car articles)))))
;; Now we have the mapping from/to Gnus/nnwfm article numbers,
;; so we start fetching the topics that we need to satisfy the
;; request.
(if (not fetchers)
(save-excursion
(set-buffer nntp-server-buffer)
(erase-buffer))
(setq nnwfm-articles nil)
(mm-with-unibyte-buffer
(dolist (elem fetchers)
(erase-buffer)
(setq subject (nth 2 (assq (car elem) topics))
thread-id (nth 0 (assq (car elem) topics)))
(mm-url-insert
(concat nnwfm-address
(format "Item.asp?GroupID=%d&ThreadID=%d" sid
thread-id)))
(goto-char (point-min))
(setq tables (caddar
(caddar
(cdr (caddar
(caddar
(ignore-errors
(w3-parse-buffer (current-buffer)))))))))
(setq tables (cdr (caddar (memq (assq 'div tables) tables))))
(setq contents nil)
(dolist (table tables)
(when (eq (car table) 'table)
(setq table (caddar (caddar (caddr table)))
hstuff (delete ":link" (nnweb-text (car table)))
bstuff (car (caddar (cdr table)))
from (car hstuff))
(when (nth 2 hstuff)
(setq time (nnwfm-date-to-time (nth 2 hstuff)))
(push (list from time bstuff) contents))))
(setq contents (nreverse contents))
(dolist (art (cdr elem))
(push (list (car art)
(nth (1- (cdr art)) contents)
subject)
nnwfm-articles))))
(setq nnwfm-articles
(sort nnwfm-articles 'car-less-than-car))
;; Now we have all the articles, conveniently in an alist
;; where the key is the Gnus article number.
(dolist (articlef nnwfm-articles)
(setq article (nth 0 articlef)
contents (nth 1 articlef)
subject (nth 2 articlef))
(setq from (nth 0 contents)
date (message-make-date (nth 1 contents)))
(push
(cons
article
(make-full-mail-header
article subject
from (or date "")
(concat "<" (number-to-string sid) "%"
(number-to-string article)
"@wfm>")
"" 0
(/ (length (mapconcat 'identity (nnweb-text (nth 2 contents)) ""))
70)
nil nil))
headers))
(setq nnwfm-headers (sort headers 'car-less-than-car))
(save-excursion
(set-buffer nntp-server-buffer)
(mm-with-unibyte-current-buffer
(erase-buffer)
(dolist (header nnwfm-headers)
(nnheader-insert-nov (cdr header))))))
'nov)))
(deffoo nnwfm-request-group (group &optional server dont-check)
(nnwfm-possibly-change-server nil server)
(when (not nnwfm-groups)
(nnwfm-request-list))
(unless dont-check
(nnwfm-create-mapping group))
(let ((elem (assoc group nnwfm-groups)))
(cond
((not elem)
(nnheader-report 'nnwfm "Group does not exist"))
(t
(nnheader-report 'nnwfm "Opened group %s" group)
(nnheader-insert
"211 %d %d %d %s\n" (cadr elem) 1 (cadr elem)
(prin1-to-string group))))))
(deffoo nnwfm-request-close ()
(setq nnwfm-groups-alist nil
nnwfm-groups nil))
(deffoo nnwfm-request-article (article &optional group server buffer)
(nnwfm-possibly-change-server group server)
(let ((contents (cdr (assq article nnwfm-articles))))
(when (setq contents (nth 2 (car contents)))
(save-excursion
(set-buffer (or buffer nntp-server-buffer))
(erase-buffer)
(nnweb-insert-html contents)
(goto-char (point-min))
(insert "Content-Type: text/html\nMIME-Version: 1.0\n")
(let ((header (cdr (assq article nnwfm-headers))))
(mm-with-unibyte-current-buffer
(nnheader-insert-header header)))
(nnheader-report 'nnwfm "Fetched article %s" article)
(cons group article)))))
(deffoo nnwfm-request-list (&optional server)
(nnwfm-possibly-change-server nil server)
(mm-with-unibyte-buffer
(mm-url-insert
(if (string-match "/$" nnwfm-address)
(concat nnwfm-address "Group.asp")
nnwfm-address))
(let* ((nnwfm-table-regexp "Thread.asp")
(contents (w3-parse-buffer (current-buffer)))
sid elem description articles a href group forum
a1 a2)
(dolist (row (cdr (nth 2 (car (nth 2 (nnwfm-find-forum-table
contents))))))
(setq row (nth 2 row))
(when (setq a (nnweb-parse-find 'a row))
(setq group (car (last (nnweb-text a)))
href (cdr (assq 'href (nth 1 a))))
(setq description (car (last (nnweb-text (nth 1 row)))))
(setq articles
(string-to-number
(gnus-replace-in-string
(car (last (nnweb-text (nth 3 row)))) "," "")))
(when (and href
(string-match "GroupId=\\([0-9]+\\)" href))
(setq forum (string-to-number (match-string 1 href)))
(if (setq elem (assoc group nnwfm-groups))
(setcar (cdr elem) articles)
(push (list group articles forum description nil nil nil nil)
nnwfm-groups))))))
(nnwfm-write-groups)
(nnwfm-generate-active)
t))
(deffoo nnwfm-request-newgroups (date &optional server)
(nnwfm-possibly-change-server nil server)
(nnwfm-generate-active)
t)
(nnoo-define-skeleton nnwfm)
;;; Internal functions
(defun nnwfm-new-threads-p (group time)
"See whether we want to fetch the threads for GROUP written before TIME."
(let ((old-time (nth 7 (assoc group nnwfm-groups))))
(or (null old-time)
(time-less-p old-time time))))
(defun nnwfm-create-mapping (group)
(let* ((entry (assoc group nnwfm-groups))
(sid (nth 2 entry))
(topics (nth 4 entry))
(mapping (nth 5 entry))
(old-total (or (nth 6 entry) 1))
(current-time (current-time))
(nnwfm-table-regexp "Thread.asp")
(furls (list (concat nnwfm-address
(format "Thread.asp?GroupId=%d" sid))))
fetched-urls
contents forum-contents a subject href
garticles topic tinfo old-max inc parse elem date
url time)
(mm-with-unibyte-buffer
(while furls
(erase-buffer)
(push (car furls) fetched-urls)
(mm-url-insert (pop furls))
(goto-char (point-min))
(while (re-search-forward " wr(" nil t)
(forward-char -1)
(setq elem (message-tokenize-header
(gnus-replace-in-string
(buffer-substring
(1+ (point))
(progn
(forward-sexp 1)
(1- (point))))
"\\\\[\"\\\\]" "")))
(push (list
(string-to-number (nth 1 elem))
(gnus-replace-in-string (nth 2 elem) "\"" "")
(string-to-number (nth 5 elem)))
forum-contents))
(when (re-search-forward "href=\"\\(Thread.*DateLast=\\([^\"]+\\)\\)"
nil t)
(setq url (match-string 1)
time (nnwfm-date-to-time (gnus-url-unhex-string
(match-string 2))))
(when (and (nnwfm-new-threads-p group time)
(not (member
(setq url (concat
nnwfm-address
(mm-url-decode-entities-string url)))
fetched-urls)))
(push url furls))))
;; The main idea here is to map Gnus article numbers to
;; nnwfm article numbers. Say there are three topics in
;; this forum, the first with 4 articles, the seconds with 2,
;; and the third with 1. Then this will translate into 7 Gnus
;; article numbers, where 1-4 comes from the first topic, 5-6
;; from the second and 7 from the third. Now, then next time
;; the group is entered, there's 2 new articles in topic one
;; and 1 in topic three. Then Gnus article number 8-9 be 5-6
;; in topic one and 10 will be the 2 in topic three.
(dolist (elem (nreverse forum-contents))
(setq subject (nth 1 elem)
topic (nth 0 elem)
garticles (nth 2 elem))
(if (setq tinfo (assq topic topics))
(progn
(setq old-max (cadr tinfo))
(setcar (cdr tinfo) garticles))
(setq old-max 0)
(push (list topic garticles subject) topics)
(setcar (nthcdr 4 entry) topics))
(when (not (= old-max garticles))
(setq inc (- garticles old-max))
(setq mapping (nconc mapping
(list
(list
old-total (1- (incf old-total inc))
topic (1+ old-max)))))
(incf old-max inc)
(setcar (nthcdr 5 entry) mapping)
(setcar (nthcdr 6 entry) old-total))))
(setcar (nthcdr 7 entry) current-time)
(setcar (nthcdr 1 entry) (1- old-total))
(nnwfm-write-groups)
mapping))
(defun nnwfm-possibly-change-server (&optional group server)
(nnwfm-init server)
(when (and server
(not (nnwfm-server-opened server)))
(nnwfm-open-server server))
(unless nnwfm-groups-alist
(nnwfm-read-groups)
(setq nnwfm-groups (cdr (assoc nnwfm-address
nnwfm-groups-alist)))))
(deffoo nnwfm-open-server (server &optional defs connectionless)
(nnheader-init-server-buffer)
(if (nnwfm-server-opened server)
t
(unless (assq 'nnwfm-address defs)
(setq defs (append defs (list (list 'nnwfm-address server)))))
(nnoo-change-server 'nnwfm server defs)))
(defun nnwfm-read-groups ()
(setq nnwfm-groups-alist nil)
(let ((file (expand-file-name "groups" nnwfm-directory)))
(when (file-exists-p file)
(mm-with-unibyte-buffer
(insert-file-contents file)
(goto-char (point-min))
(setq nnwfm-groups-alist (read (current-buffer)))))))
(defun nnwfm-write-groups ()
(setq nnwfm-groups-alist
(delq (assoc nnwfm-address nnwfm-groups-alist)
nnwfm-groups-alist))
(push (cons nnwfm-address nnwfm-groups)
nnwfm-groups-alist)
(with-temp-file (expand-file-name "groups" nnwfm-directory)
(prin1 nnwfm-groups-alist (current-buffer))))
(defun nnwfm-init (server)
"Initialize buffers and such."
(unless (file-exists-p nnwfm-directory)
(gnus-make-directory nnwfm-directory)))
(defun nnwfm-generate-active ()
(save-excursion
(set-buffer nntp-server-buffer)
(erase-buffer)
(dolist (elem nnwfm-groups)
(insert (prin1-to-string (car elem))
" " (number-to-string (cadr elem)) " 1 y\n"))))
(defun nnwfm-find-forum-table (contents)
(catch 'found
(nnwfm-find-forum-table-1 contents)))
(defun nnwfm-find-forum-table-1 (contents)
(dolist (element contents)
(unless (stringp element)
(when (and (eq (car element) 'table)
(nnwfm-forum-table-p element))
(throw 'found element))
(when (nth 2 element)
(nnwfm-find-forum-table-1 (nth 2 element))))))
(defun nnwfm-forum-table-p (parse)
(when (not (apply 'gnus-or
(mapcar
(lambda (p)
(nnweb-parse-find 'table p))
(nth 2 parse))))
(let ((href (cdr (assq 'href (nth 1 (nnweb-parse-find 'a parse 20)))))
case-fold-search)
(when (and href (string-match nnwfm-table-regexp href))
t))))
(defun nnwfm-date-to-time (date)
(let ((time (mapcar #'string-to-number (split-string date "[\\.\\+ :]"))))
(encode-time 0 (nth 4 time) (nth 3 time)
(nth 0 time) (nth 1 time)
(if (< (nth 2 time) 70)
(+ 2000 (nth 2 time))
(+ 1900 (nth 2 time))))))
(provide 'nnwfm)
;; Local Variables:
;; coding: iso-8859-1
;; End:
;; arch-tag: d813966a-4211-4557-ad11-d1ac2bc86536
;;; nnwfm.el ends here

View file

@ -2349,7 +2349,7 @@ You may also want to set `hfy-page-header' and `hfy-page-footer'."
;;;### (autoloads (hfy-fallback-colour-values htmlfontify-load-rgb-file)
;;;;;; "hfy-cmap" "hfy-cmap.el" "3de2db2d213813bb3afe170ffd66cdde")
;;;;;; "hfy-cmap" "hfy-cmap.el" "7e622e4b131ea5efbe9d258f719822d6")
;;; Generated autoloads from hfy-cmap.el
(autoload 'htmlfontify-load-rgb-file "hfy-cmap" "\

View file

@ -5609,7 +5609,23 @@ it skips the contents of comments that end before point."
(message "Matches %s"
(substring-no-properties open-paren-line-string)))))))))
(setq blink-paren-function 'blink-matching-open)
(defvar blink-paren-function 'blink-matching-open
"Function called, if non-nil, whenever a close parenthesis is inserted.
More precisely, a char with closeparen syntax is self-inserted.")
(defun blink-paren-post-self-insert-function ()
(when (and (eq (char-before) last-command-event) ; Sanity check.
(memq (char-syntax last-command-event) '(?\) ?\$))
blink-paren-function
(not executing-kbd-macro)
(not noninteractive))
(funcall blink-paren-function)))
(add-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function
;; Most likely, this hook is nil, so this arg doesn't matter,
;; but I use it as a reminder that this function usually
;; likes to be run after others since it does `sit-for'.
'append)
;; This executes C-g typed while Emacs is waiting for a command.
;; Quitting out of a program does not go through here;

View file

@ -1,3 +1,11 @@
2010-09-01 Stefan Monnier <monnier@iro.umontreal.ca>
* cmds.c (Vblink_paren_function): Remove.
(internal_self_insert): Make it insert N chars at a time.
Don't call blink-paren-function.
(Fself_insert_command): Adjust accordingly.
(syms_of_cmds): Don't declare blink-paren-function.
2010-08-31 Kenichi Handa <handa@m17n.org>
* dispextern.h (FACE_FOR_CHAR): Use an ASCII face for 8-bit

View file

@ -32,7 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "dispextern.h"
#include "frame.h"
Lisp_Object Qkill_forward_chars, Qkill_backward_chars, Vblink_paren_function;
Lisp_Object Qkill_forward_chars, Qkill_backward_chars;
/* A possible value for a buffer's overwrite-mode variable. */
Lisp_Object Qoverwrite_mode_binary;
@ -304,36 +304,16 @@ After insertion, the value of `auto-fill-function' is called if the
{
int character = translate_char (Vtranslation_table_for_input,
XINT (last_command_event));
if (XINT (n) >= 2 && NILP (current_buffer->overwrite_mode))
{
XSETFASTINT (n, XFASTINT (n) - 2);
/* The first one might want to expand an abbrev. */
internal_self_insert (character, 1);
/* The bulk of the copies of this char can be inserted simply.
We don't have to handle a user-specified face specially
because it will get inherited from the first char inserted. */
Finsert_char (make_number (character), n, Qt);
/* The last one might want to auto-fill. */
internal_self_insert (character, 0);
}
else
while (XINT (n) > 0)
{
int val;
/* Ok since old and new vals both nonneg */
XSETFASTINT (n, XFASTINT (n) - 1);
val = internal_self_insert (character, XFASTINT (n) != 0);
if (val == 2)
nonundocount = 0;
frame_make_pointer_invisible ();
}
int val = internal_self_insert (character, XFASTINT (n));
if (val == 2)
nonundocount = 0;
frame_make_pointer_invisible ();
}
return Qnil;
}
/* Insert character C. If NOAUTOFILL is nonzero, don't do autofill
even if it is enabled.
/* Insert N times character C
If this insertion is suitable for direct output (completely simple),
return 0. A value of 1 indicates this *might* not have been simple.
@ -343,12 +323,12 @@ static Lisp_Object Qexpand_abbrev;
static Lisp_Object Qpost_self_insert_hook, Vpost_self_insert_hook;
static int
internal_self_insert (int c, int noautofill)
internal_self_insert (int c, int n)
{
int hairy = 0;
Lisp_Object tem;
register enum syntaxcode synt;
Lisp_Object overwrite, string;
Lisp_Object overwrite;
/* Length of multi-byte form of C. */
int len;
/* Working buffer and pointer for multi-byte form of C. */
@ -391,32 +371,22 @@ internal_self_insert (int c, int noautofill)
/* This is the character after point. */
int c2 = FETCH_CHAR (PT_BYTE);
/* Column the cursor should be placed at after this insertion.
The correct value should be calculated only when necessary. */
int target_clm = 0;
/* Overwriting in binary-mode always replaces C2 by C.
Overwriting in textual-mode doesn't always do that.
It inserts newlines in the usual way,
and inserts any character at end of line
or before a tab if it doesn't use the whole width of the tab. */
if (EQ (overwrite, Qoverwrite_mode_binary)
|| (c != '\n'
&& c2 != '\n'
&& ! (c2 == '\t'
&& XINT (current_buffer->tab_width) > 0
&& XFASTINT (current_buffer->tab_width) < 20
&& (target_clm = ((int) current_column () /* iftc */
+ XINT (Fchar_width (make_number (c)))),
target_clm % XFASTINT (current_buffer->tab_width)))))
if (EQ (overwrite, Qoverwrite_mode_binary))
chars_to_delete = n;
else if (c != '\n' && c2 != '\n')
{
int pos = PT;
int pos_byte = PT_BYTE;
/* Column the cursor should be placed at after this insertion.
The correct value should be calculated only when necessary. */
int target_clm = ((int) current_column () /* iftc */
+ n * XINT (Fchar_width (make_number (c))));
if (target_clm == 0)
chars_to_delete = 1;
else
{
/* The actual cursor position after the trial of moving
to column TARGET_CLM. It is greater than TARGET_CLM
if the TARGET_CLM is middle of multi-column
@ -428,14 +398,18 @@ internal_self_insert (int c, int noautofill)
chars_to_delete = PT - pos;
if (actual_clm > target_clm)
{
/* We will delete too many columns. Let's fill columns
{ /* We will delete too many columns. Let's fill columns
by spaces so that the remaining text won't move. */
EMACS_INT actual = PT_BYTE;
DEC_POS (actual);
if (FETCH_CHAR (actual) == '\t')
/* Rather than add spaces, let's just keep the tab. */
chars_to_delete--;
else
spaces_to_insert = actual_clm - target_clm;
}
}
SET_PT_BOTH (pos, pos_byte);
hairy = 2;
}
hairy = 2;
}
@ -474,16 +448,30 @@ internal_self_insert (int c, int noautofill)
if (chars_to_delete)
{
string = make_string_from_bytes (str, 1, len);
int mc = ((NILP (current_buffer->enable_multibyte_characters)
&& SINGLE_BYTE_CHAR_P (c))
? UNIBYTE_TO_CHAR (c) : c);
Lisp_Object string = Fmake_string (make_number (n), make_number (mc));
if (spaces_to_insert)
{
tem = Fmake_string (make_number (spaces_to_insert),
make_number (' '));
string = concat2 (tem, string);
string = concat2 (string, tem);
}
replace_range (PT, PT + chars_to_delete, string, 1, 1, 1);
Fforward_char (make_number (1 + spaces_to_insert));
Fforward_char (make_number (n + spaces_to_insert));
}
else if (n > 1)
{
USE_SAFE_ALLOCA;
unsigned char *strn, *p;
SAFE_ALLOCA (strn, unsigned char*, n * len);
for (p = strn; n > 0; n--, p += len)
memcpy (p, str, len);
insert_and_inherit (strn, p - strn);
SAFE_FREE ();
}
else
insert_and_inherit (str, len);
@ -491,7 +479,6 @@ internal_self_insert (int c, int noautofill)
if ((CHAR_TABLE_P (Vauto_fill_chars)
? !NILP (CHAR_TABLE_REF (Vauto_fill_chars, c))
: (c == ' ' || c == '\n'))
&& !noautofill
&& !NILP (current_buffer->auto_fill_function))
{
Lisp_Object tem;
@ -509,13 +496,6 @@ internal_self_insert (int c, int noautofill)
hairy = 2;
}
if ((synt == Sclose || synt == Smath)
&& !NILP (Vblink_paren_function) && INTERACTIVE
&& !noautofill)
{
call0 (Vblink_paren_function);
hairy = 2;
}
/* Run hooks for electric keys. */
call1 (Vrun_hooks, Qpost_self_insert_hook);
@ -547,11 +527,6 @@ syms_of_cmds (void)
This run is run after inserting the charater. */);
Vpost_self_insert_hook = Qnil;
DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function,
doc: /* Function called, if non-nil, whenever a close parenthesis is inserted.
More precisely, a char with closeparen syntax is self-inserted. */);
Vblink_paren_function = Qnil;
defsubr (&Sforward_point);
defsubr (&Sforward_char);
defsubr (&Sbackward_char);