Commit e293eea7 authored by David Byers's avatar David Byers
Browse files

Wrote some more unread commands.

Detailed changes:
> 	* review.el (kom-unread-last-normally-read): New command.
> 	(kom-unread-tree): New command.
> 	(kom-unread-comments): New command.
> 	(kom-unread-root): New command.
> 	(kom-unread-root-review): New command.
>
> 	* lyskom-rest.el (lyskom-format-aux-help): Added ?+ format
> 	directive.
> 	(lyskom-insert-error): Handle negative error codes (used for
> 	internal error reporting).
>
> 	* commands1.el (kom-view-previous-commented-text): This command
> 	always did the next-to-last text, regardless of prefix args.
> 	(lyskom-unread-commented-text): New function.
> 	(kom-unread-previous-commented-text): New command.
> 	(kom-unread-commented-text): New command.
>
> 	* review.el (lyskom-unread-by-to): New function.
> 	(kom-unread-more): New command.
> 	(kom-unread-by-to): New command.
>
parent e7368e3f
2003-03-15 David Byers <david.byers@swipnet.se>
Work on bug 984:
* review.el (kom-unread-last-normally-read): New command.
(kom-unread-tree): New command.
(kom-unread-comments): New command.
(kom-unread-root): New command.
(kom-unread-root-review): New command.
* lyskom-rest.el (lyskom-format-aux-help): Added ?+ format
directive.
(lyskom-insert-error): Handle negative error codes (used for
internal error reporting).
* commands1.el (kom-view-previous-commented-text): This command
always did the next-to-last text, regardless of prefix args.
(lyskom-unread-commented-text): New function.
(kom-unread-previous-commented-text): New command.
(kom-unread-commented-text): New command.
* review.el (lyskom-unread-by-to): New function.
(kom-unread-more): New command.
(kom-unread-by-to): New command.
* lyskom-rest.el (kom-initial-digit-unread): New command.
* vars.el.in (lyskom-text-no-prompts-defaults): Added
......
......@@ -344,6 +344,17 @@ See `kom-review-uses-cache'."
(blocking-do 'get-text-stat text-no)))
(lyskom-insert-string 'confusion-what-to-view)))
(def-kom-command kom-unread-commented-text (text-no)
"MArkes the texts that the selected text is a comment to as unread.
This command accepts text number prefix arguments (see
`lyskom-read-text-no-prefix-arg')."
(interactive (list (lyskom-read-text-no-prefix-arg 'unread-commented-q)))
(if text-no
(lyskom-unread-commented-text
(blocking-do 'get-text-stat text-no))
(lyskom-insert-string 'confusion-what-to-mark-unread)))
(def-kom-command kom-view-previous-commented-text (text-no)
"Views the text that the selected text is a comment to. If the
......@@ -365,10 +376,27 @@ See `kom-review-uses-cache'."
(unless kom-review-uses-cache
(cache-del-text-stat text-no))
(lyskom-view-commented-text
(blocking-do 'get-text-stat lyskom-previous-text)))
(blocking-do 'get-text-stat text-no)))
(t (lyskom-insert-string 'confusion-what-to-view))))
(def-kom-command kom-unread-previous-commented-text (text-no)
"Marks the texts that the selected text is a comment to as unread.
Without a prefix argument this will display the text that the
next-to-last text in the buffer is a comment to. With a prefix
argument this command is identical to `kom-unread-commented-text'.
This command accepts text number prefix arguments (see
`lyskom-read-text-no-prefix-arg')"
(interactive (list (lyskom-read-text-no-prefix-arg 'review-commented-q nil
lyskom-previous-text)))
(if text-no
(lyskom-unread-commented-text
(blocking-do 'get-text-stat text-no))
(lyskom-insert-string 'confusion-what-to-mark-unread)))
(defun lyskom-text-stat-commented-texts (text-stat)
"Return a list of the text-nos that TEXT-STAT is a comment or footnote to."
(let* ((misc-info-list (and text-stat
......@@ -411,6 +439,15 @@ See `kom-review-uses-cache'."
t))
(lyskom-insert-string 'no-comment-to))))
(defun lyskom-unread-commented-text (text-stat)
"Marks the texts that TEXT-STAT is a comment to as unread."
(let ((text-nos (lyskom-text-stat-commented-texts text-stat)))
(if text-nos
(lyskom-traverse text-no text-nos
(lyskom-format-insert 'marking-text-unread text-no)
(lyskom-report-command-answer (lyskom-mark-unread text-no)))
(lyskom-insert-string 'no-comment-to-to-unread))))
(defun lyskom-misc-infos-from-list (type list)
"Get all the misc-infos from the misc-info-list LIST with the same type
......
......@@ -803,8 +803,11 @@ Mark the envelope with \"LysKOM bug report\"\n\n")
(set-session-priority . "Set reading level: ")
; From review.el:
(no-unread-done . "You need to unread something before you can unread more.\n")
(no-review-done . "You need to review something before you can review more.\n")
(not-reviewing . "You are currently not reviewing anything.\n")
(unread-how-many . "Unread how many?")
(unread-how-many-more . "Unread how many more?")
(review-how-many . "Review how many?")
(review-how-many-more . "Review how many more?")
(latest-n . "last %#1d")
......@@ -816,6 +819,13 @@ Mark the envelope with \"LysKOM bug report\"\n\n")
(no-get-conf . "You are not allowed to access that conference.\n")
(no-get-pers . "You are not allowed to access that user.\n")
(no-review-info . "You are not allowed to review %#1s\n")
(unread-info . "Unread %#1s")
(unread-info-by-to . "Unread %#1s by %#2P to %#3M.\n")
(unread-more-info-by-to . "Unread %#1s by %#2P to %#3M.\n")
(unread-rest . "the rest")
(unread-more . "%#1d more")
(review-info . "Review %#1s")
(review-info-by-to . "Review %#1s by %#2P to %#3M forwards.\n")
(review-more-info-by-to . "Review %#1s by %#2P to %#3M forwards.\n")
......@@ -1120,7 +1130,7 @@ Send a bug report.\n")
(bad-text-no-prefix . "Unable to translate prefix `%s' to a text number")
(prefix-arg-try-again . "Specify another text or press control-g to abort.\n")
(error-code . "Error code %#2d/%#3S: %#1s.\n")
(error-code . "%#2?+%[Error code %#2d/%#3S: %]%[%]%#1s.\n")
(error-in-kom-do-when-done . "The variable kom-do-when-done has an erroneous value.
You should set it to a better value.\n")
(extended-command . "LysKOM: ")
......@@ -1604,12 +1614,17 @@ You must become an active member of the conference to enter it.\n")
(review-converted-q . "Review which text converted?")
(review-noconversion-q . "Review which text unconverted?")
(unread-commented-q . "Mark the commented for which text as unread?")
(review-commented-q . "Review the commented for which text?")
(review-tree-q . "Review all comments recursively for which text?")
(find-root-q . "Review original text for text?")
(find-root-review-q . "Review tree of which text?")
(review-comments-q . "Review all comments to which text?")
(unread-tree-q . "Unread all comments recursively for which text?")
(unread-root-q . "Unread original text for text?")
(unread-root-review-q . "Unread tree of which text?")
(unread-comments-q . "Unread all comments to which text?")
(confusion-who-to-reply-to . "I can't figure out which text you want to write a private reply to.\n")
(confusion-what-to-answer-to . "I can't figure out which text you want to write a reply to.\n")
......@@ -1639,6 +1654,8 @@ You must become an active member of the conference to enter it.\n")
(confusion-what-to-save . "I can't figure out which text you want to save.\n")
(confusion-what-to-review-mail-headers . "I can't figure out which text's mail headers you want to see.\n")
(confusion-what-to-unread-root . "I can't figure out which text's root you want to mark as unread.\n")
(confusion-what-to-unread-root-review . "I can't figure out which tree you want to mark as unread.\n")
(confusion-what-to-find-root . "I can't figure out which text's root you want to see.\n")
(confusion-what-to-find-root-review . "I can't figure out which tree you want to review.\n")
......@@ -1850,6 +1867,9 @@ environment to one that uses \"%#2s\" to encode text.
(unread-text-q . "Make which text unread? ")
(marking-text-unread . "Marking text %#1n as unread...")
(cant-mark-text-unread . "Couldn't mark %#1n as unread (%#2s)\n")
(confusion-what-to-mark-unread . "I can't figure out what text you want to mark as unread.\n")
(no-comment-to-to-unread . "There is no commented text to mark as unread.\n")
))
......@@ -2056,6 +2076,16 @@ environment to one that uses \"%#2s\" to encode text.
(kom-redirect-comments . "Redirect comments")
(kom-copy-options . "Copy options")
(kom-mark-unread . "Unread text")
(kom-unread-by-to . "Unread last")
(kom-unread-more . "Unread more")
(kom-unread-commented-text . "Unread (the) commented (text)")
(kom-unread-previous-commented-text . "Unread (the) previously commented (text)")
(kom-unread-comments . "Unread all comments")
(kom-unread-tree . "Unread all comments recursively")
(kom-unread-root . "Unread original (text)")
(kom-unread-root-review . "Unread tree")
(kom-unread-last-normally-read
. "Unread again")
))
(lyskom-language-var global lyskom-language-codes en
......@@ -2396,6 +2426,16 @@ environment to one that uses \"%#2s\" to encode text.
(define-key lyskom-en-unread-prefix (kbd "7") 'kom-initial-digit-unread)
(define-key lyskom-en-unread-prefix (kbd "8") 'kom-initial-digit-unread)
(define-key lyskom-en-unread-prefix (kbd "9") 'kom-initial-digit-unread)
(define-key lyskom-en-unread-prefix (kbd "c") 'kom-unread-commented-text)
(define-key lyskom-en-unread-prefix (kbd "C") 'kom-unread-previous-commented-text)
(define-key lyskom-en-unread-prefix (kbd "a ?") 'lyskom-help)
(define-key lyskom-en-unread-prefix (kbd "a c") 'kom-unread-comments)
(define-key lyskom-en-unread-prefix (kbd "a r") 'kom-unread-tree)
(define-key lyskom-en-unread-prefix (kbd "g") 'kom-unread-last-normally-read)
(define-key lyskom-en-unread-prefix (kbd "o") 'kom-unread-root)
(define-key lyskom-en-unread-prefix (kbd "l") 'kom-unread-by-to)
(define-key lyskom-en-unread-prefix (kbd "M") 'kom-unread-more)
(define-key lyskom-en-unread-prefix (kbd "r") 'kom-unread-root-review)
(define-key lyskom-en-review-prefix (kbd "SPC") 'kom-view)
(define-key lyskom-en-review-prefix (kbd "0") 'kom-initial-digit-view)
......@@ -4183,6 +4223,8 @@ be saved in the server. Otherwise it will be saved in your .emacs.")
(error-52 . "Feature disabled in the server")
(error-53 . "Unable to send message")
(error-54 . "Invalid membership type")
(error--1 . "You are not a member of any recipient")
))
(lyskom-language-var global lyskom-unread-mode-line en
......
......@@ -373,29 +373,36 @@ that support making text unread."
"Mark text TEXT-NO in all conferences.
Returns non-nil if successful."
(let ((text-stat (blocking-do 'get-text-stat text-no))
(conf-list nil))
(marked-unread nil))
(and text-stat
(not (lyskom-traverse misc-info (text-stat->misc-info-list text-stat)
(when (memq (misc-info->type misc-info) lyskom-recpt-types-list)
(let* ((mship (lyskom-get-membership (misc-info->recipient-no misc-info)))
(recipient (and mship (blocking-do 'get-conf-stat (misc-info->recipient-no misc-info)))))
(when (and mship recipient)
(if (not (blocking-do 'mark-as-unread
(misc-info->recipient-no misc-info)
(misc-info->local-no misc-info)))
(lyskom-traverse-break 'error)
(when (lyskom-visible-membership mship)
(unless (read-list-enter-text text-no
recipient
lyskom-to-do-list)
(let ((info (lyskom-create-read-info
'CONF
recipient
(membership->priority mship)
(lyskom-create-text-list (list text-no)))))
(read-list-enter-read-info info lyskom-to-do-list)
(if (= lyskom-current-conf (conf-stat->conf-no recipient))
(read-list-enter-read-info info lyskom-reading-list))))))))))))))
(let ((result
(lyskom-traverse misc-info (text-stat->misc-info-list text-stat)
(when (memq (misc-info->type misc-info) lyskom-recpt-types-list)
(let* ((mship (lyskom-get-membership (misc-info->recipient-no misc-info)))
(recipient (and mship (blocking-do 'get-conf-stat (misc-info->recipient-no misc-info)))))
(when (and mship recipient)
(if (not (blocking-do 'mark-as-unread
(misc-info->recipient-no misc-info)
(misc-info->local-no misc-info)))
(lyskom-traverse-break 'error)
(when (lyskom-visible-membership mship)
(setq marked-unread t)
(unless (read-list-enter-text text-no
recipient
lyskom-to-do-list)
(let ((info (lyskom-create-read-info
'CONF
recipient
(membership->priority mship)
(lyskom-create-text-list (list text-no)))))
(read-list-enter-read-info info lyskom-to-do-list)
(if (= lyskom-current-conf (conf-stat->conf-no recipient))
(read-list-enter-read-info info lyskom-reading-list))))))))))))
(cond (result nil)
(marked-unread t)
(t (setq lyskom-errno -1)
nil))))))
;;;; ================================================================
......@@ -1614,7 +1621,7 @@ Deferred insertions are not supported."
;; accordingly
((= format-letter ?\?)
(unless (string-match "[dbz]"
(unless (string-match "[dbz+]"
(format-state->format-string format-state)
(format-state->start format-state))
(lyskom-error "Unknown predicate in format string %s (%d)"
......@@ -1651,6 +1658,14 @@ Deferred insertions are not supported."
format-state
allow-defer)
result nil))
;; Non-negative predicate
((= predicate-type ?+)
(setq format-state
(lyskom-format-do-binary-predicate (not (lyskom-minusp arg))
format-state
allow-defer)
result nil))
)))
((= format-letter ?F)
......
......@@ -66,6 +66,19 @@
(defvar lyskom-last-review-saved-largest nil)
(defvar lyskom-have-review nil)
(defvar lyskom-last-unread-by nil)
(defvar lyskom-last-unread-to nil)
(defvar lyskom-last-unread-num nil)
(defvar lyskom-last-unread-pmark nil)
(defvar lyskom-last-unread-cmark nil)
(defvar lyskom-last-unread-saved-result-list nil)
(defvar lyskom-last-unread-saved-by-list nil)
(defvar lyskom-last-unread-saved-to-list nil)
(defvar lyskom-last-unread-saved-result-size 0)
(defvar lyskom-last-unread-saved-smallest nil)
(defvar lyskom-last-unread-saved-largest nil)
(defvar lyskom-have-unread nil)
(defun lyskom-remove-zeroes (a)
"Returns a copy of list where all zeroes are removed."
......@@ -166,6 +179,55 @@ all review-related functions."
nil
(lyskom-insert-string 'no-such-text)))))))
(def-kom-command kom-unread-more (count)
"Mark more articles unread using the same critera as the last
mark unread performed with `kom-unread-by-to'."
(interactive "P")
(if (not lyskom-have-unread)
(lyskom-format-insert 'no-unread-done)
(let* ((count (or count
(lyskom-read-number
(lyskom-get-string 'unread-how-many-more)
(abs lyskom-last-unread-num))))
(info (progn (if (and (listp count)
(integerp (car count))
(null (cdr count)))
(setq count (car count)))
(cond ((zerop count)
(setq count nil)
(lyskom-get-string 'unread-rest))
((> count 0)
(lyskom-format (lyskom-get-string 'unread-more)
count)))))
(by lyskom-last-unread-by)
(to lyskom-last-unread-to))
(lyskom-format-insert 'unread-more-info-by-to
info
(if (zerop by)
(lyskom-get-string 'anybody)
by)
(if (zerop to)
(lyskom-get-string 'all-confs)
to))
(condition-case arg
(let ((list (lyskom-get-texts-by-to by to count t)))
(setq lyskom-last-unread-num
(if (< lyskom-last-unread-num 0)
(- count)
count))
(if list
(lyskom-traverse text-no list
(unless (lyskom-mark-unread text-no)
(lyskom-format-insert 'cant-mark-text-unread
text-no
(lyskom-get-error-text lyskom-errno))))
(lyskom-insert-string 'no-such-text)))
(lyskom-review-error (if arg
nil
(lyskom-insert-string 'no-such-text)))))))
(def-kom-command kom-review-first (&optional count)
......@@ -280,6 +342,97 @@ all review-related functions."
(lyskom-insert-string 'no-such-text))))))
(def-kom-command kom-unread-by-to (&optional count)
"Mark the last N articles written by a particular author to some
conference as unread. With no author specified, review texts by all
authors. With zero texts specified, review all text. With no conference
specified, review texts to all conferences. With a negative number of
texts, review the last N texts instead of the first (you can use
`kom-unread-first' instead."
(interactive "P")
(lyskom-unread-by-to (or count
(lyskom-read-number
(lyskom-get-string 'unread-how-many) 1))))
(defun lyskom-unread-by-to (count)
"Common function for kom-review-by-to and kom-review-first"
(let* ((info (progn (if (and (listp count)
(integerp (car count))
(null (cdr count)))
(setq count (car count)))
(cond ((zerop count)
(setq count nil)
(lyskom-get-string 'everything))
((> count 0)
(lyskom-format 'latest-n count))
((< count 0)
(lyskom-format 'first-n
(- count))))))
(by (lyskom-read-conf-no
(lyskom-format 'unread-info (lyskom-format 'info-by-whom info))
'(pers) t nil t))
(to (lyskom-read-conf-no
(lyskom-format 'unread-info
(lyskom-format 'info-to-conf info))
'(all)
t
;; If person is not given we must give
;; conf -- Not anymore!
;; (not (zerop by))
(if (or (null lyskom-current-conf)
(zerop lyskom-current-conf))
""
(cons (conf-stat->name
(blocking-do 'get-conf-stat
lyskom-current-conf)) 0))
t)))
(if (not (zerop to))
(cache-del-conf-stat to))
(if (not (zerop by))
(cache-del-pers-stat by))
(lyskom-format-insert 'unread-info-by-to
info
(if (zerop by)
(lyskom-get-string 'anybody)
by)
(if (zerop to)
(lyskom-get-string 'all-confs)
to))
(setq lyskom-last-unread-by by)
(setq lyskom-last-unread-to to)
(setq lyskom-last-unread-num count)
(setq lyskom-last-unread-pmark nil)
(setq lyskom-last-unread-cmark nil)
(setq lyskom-last-unread-saved-result-list nil)
(setq lyskom-last-unread-saved-by-list nil)
(setq lyskom-last-unread-saved-to-list nil)
(setq lyskom-last-unread-saved-result-size 0)
(setq lyskom-last-unread-saved-smallest nil)
(setq lyskom-last-unread-saved-largest nil)
(setq lyskom-have-unread t)
(condition-case arg
(let ((list (lyskom-get-texts-by-to by to count)))
(if list
(lyskom-traverse text-no list
(unless (lyskom-mark-unread text-no)
(lyskom-format-insert 'cant-mark-text-unread
text-no
(lyskom-get-error-text lyskom-errno))))
(lyskom-insert-string 'no-such-text)))
(lyskom-review-error (if arg
nil
(lyskom-insert-string 'no-such-text))))))
;;; ================================================================
;;; lyskom-get-texts-by-to
;;; Author: David Byers
......@@ -1034,6 +1187,42 @@ all review-related functions."
(lyskom-insert-string 'read-text-first)))
(def-kom-command kom-unread-tree (text-no)
"Recursively mark all comments to the selected text as unread.
This command accepts text number prefix arguments \(see
`lyskom-read-text-no-prefix-arg')."
(interactive (list (lyskom-read-text-no-prefix-arg 'unread-tree-q)))
(lyskom-unread-tree text-no nil))
(defun lyskom-unread-tree (text-no visited-list)
"Perform the function of kom-unread-tree."
(let* ((text-stat (blocking-do 'get-text-stat text-no))
(worklist (and text-stat
(lyskom-text-comments text-stat))))
(if (null (car worklist))
(lyskom-format-insert 'no-such-text-no text-no)
(while worklist
(let ((cur (car worklist)))
(setq worklist (cdr worklist))
(unless (memq cur visited-list)
(setq visited-list (cons cur visited-list)
cur (blocking-do 'get-text-stat cur))
(when cur
(when (delq nil (mapcar 'lyskom-get-membership
(lyskom-text-recipients cur)))
(lyskom-format-insert 'marking-text-unread
(text-stat->text-no cur))
(lyskom-report-command-answer
(lyskom-mark-unread (text-stat->text-no cur))))
(lyskom-traverse text-no (lyskom-text-comments cur)
(unless (or (memq text-no visited-list)
(memq text-no worklist)
(setq worklist (cons text-no worklist)))))))))))
visited-list)
(def-kom-command kom-find-root (text-no)
"Finds the root text of the tree containing the selected text.
When there is more than one root, all will be included in a review
......@@ -1072,6 +1261,22 @@ all review-related functions."
(t
(lyskom-insert-string 'confusion-what-to-find-root))))
(def-kom-command kom-unread-root (text-no)
"Finds the root text of the tree containing the selected text
and marks it as unread.
This command accepts text number prefix arguments \(see
`lyskom-read-text-no-prefix-arg')."
(interactive (list (lyskom-read-text-no-prefix-arg 'unread-root-q)))
(if text-no
(let* ((ts (blocking-do 'get-text-stat text-no))
(r (lyskom-find-root ts t)))
(lyskom-traverse text-no r
(lyskom-format-insert 'marking-text-unread text-no)
(lyskom-report-command-answer
(lyskom-mark-unread text-no))))
(lyskom-insert-string 'confusion-what-to-unread-root)))
(def-kom-command kom-find-root-review (text-no)
"Finds the root of the comment tree containing the selected texts
......@@ -1101,6 +1306,23 @@ all review-related functions."
(t (signal 'lyskom-internal-error "Could not find root")))))
(t (lyskom-insert-string 'confusion-what-to-find-root-review))))
(def-kom-command kom-unread-root-review (text-no)
"Finds the root of the comment tree containing the selected texts
and then recursively marks all its comments as unread. For texts with
a single root, this is equivalent to doing `kom-find-root' followed by
`kom-unread-tree'.
This command accepts text number prefix arguments \(see
`lyskom-read-text-no-prefix-arg')."
(interactive (list (lyskom-read-text-no-prefix-arg 'unread-root-review-q)))
(if text-no
(let* ((ts (blocking-do 'get-text-stat text-no))
(start (lyskom-find-root ts t))
(marked nil))
(lyskom-traverse text-no start
(setq marked (lyskom-unread-tree text-no marked))))
(lyskom-insert-string 'confusion-what-to-unread-root-review)))
(defun lyskom-find-root (text-stat &optional all)
"Finds the root text of the tree containing the text TEXT-STAT.
......@@ -1347,6 +1569,57 @@ all review-related functions."
(lyskom-insert-string 'no-such-text))))
(def-kom-command kom-unread-comments (text-no)
"Mark all comments to the selected text text as unread. This
command only marks one level of comments as unread. To mark the
entire comment tree unread, use `kom-unrad-tree' instead.
This command accepts text number prefix arguments \(see
`lyskom-read-text-no-prefix-arg')."
(interactive (list (lyskom-read-text-no-prefix-arg 'unread-comments-q)))
(cond (text-no
(lyskom-unread-comments
(blocking-do 'get-text-stat text-no)))
(t (lyskom-insert-string 'read-text-first))))
(defun lyskom-unread-comments (text-stat)
"Handles the return from the initiate-get-text-stat, displays and builds list."
(let* ((misc-info-list (and text-stat
(text-stat->misc-info-list text-stat)))
(misc-infos (and misc-info-list
(append (lyskom-misc-infos-from-list
'FOOTN-IN misc-info-list)
(lyskom-misc-infos-from-list
'COMM-IN misc-info-list))))
(all-text-nos (and misc-infos
(mapcar
(lambda (misc-info)
(if (equal (misc-info->type misc-info)
'COMM-IN)
(misc-info->comm-in misc-info)
(misc-info->footn-in misc-info)))
misc-infos)))
text-nos)
;; Only try to review texts that we can read.
(while all-text-nos
(if (blocking-do 'get-text-stat (car all-text-nos))
(setq text-nos (cons (car all-text-nos) text-nos)))
(setq all-text-nos (cdr all-text-nos)))
(setq text-nos (nreverse text-nos))
(if text-nos
(lyskom-traverse text-no text-nos
(lyskom-format-insert 'marking-text-unread text-no)
(lyskom-report-command-answer
(lyskom-mark-unread text-no)))
(lyskom-insert-string 'no-such-text))))
;;; ================================================================
;;; ]terse igen - kom-review-last-normally-read
;;;
......@@ -1381,6 +1654,21 @@ all review-related functions."
(lyskom-format-insert 'no-such-text))))
(def-kom-command kom-unread-last-normally-read (no)
"Marks the N texts most recently read using normal commands unread.
After marking a number of texts unread, this will mark the N texts
read prior to that."
(interactive
(list (lyskom-read-number (lyskom-get-string 'read-normally-read) 1)))
(let* ((text-nos (nreverse (nfirst no lyskom-normally-read-texts))))
(if text-nos
(lyskom-traverse text-no text-nos
(lyskom-format-insert 'marking-text-unread text-no)
(lyskom-report-command-answer
(lyskom-mark-unread text-no)))
(lyskom-format-insert 'no-such-text))))