unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Kevin Rodgers <ihs_4664@yahoo.com>
Subject: Re: Recent documents: Emacs and GNOME integration
Date: Wed, 24 May 2006 12:52:25 -0600	[thread overview]
Message-ID: <e52a2j$fo5$1@sea.gmane.org> (raw)
In-Reply-To: <E1FgVC8-0004xU-Lh@fencepost.gnu.org>

Richard Stallman wrote:
> If the structure of the recent files list is simple enough,
> maybe it is easy to edit it correctly even without having the
> sophistication to parse xml.  Would someone like to take a look
> and try to write this?

I believe you are correct, but the spec is terribly imprecise:
there is no DTD or schema, no formal specification of the various
elements' content, numerous occurrences of "should", etc.  I sent
a message to the xdg@lists.freedesktop.org mailing list asking for
clarification, but it never even showed up in the archive
(http://lists.freedesktop.org/archives/xdg/).

So here's what I came up with based on the example in the spec:

(provide 'recent-files)

;; See 
http://standards.freedesktop.org/recent-file-spec/recent-file-spec-0.2.html#storage
(defconst recent-files-encoding "UTF-8")
(defconst recent-files-name "~/.recently-used")
(defconst recent-files-limit 500)

(require 'url-util)
(require 'mailcap)

(defun update-recent-file (file &optional mime-type timestamp private
				&rest groups)
   "Add or update FILE's entry in `recent-files-name'."
   (apply 'update-recent-file-item
	 (concat "file://" (mapconcat 'url-hexify-string
				      (split-string (expand-file-name file) "/")
				      "/"))
	 (or mime-type
	     (cdr (assoc (file-name-extension file t) mailcap-mime-extensions)))
	 (or timestamp
	     (format "%.f" (float-time)))
	 private
	 groups))			; (cons "Emacs" groups)

(defun update-recent-file-item (uri mime-type timestamp
				    &optional private &rest groups)
   ;; Replace "<", "&", and ">" by "&lt;", "&amp;", and "&gt;" resp.
   ;; in all string arguments (URI, MIME-TYPE, TIMESTAMP, and GROUPS)
   ;; but not the boolean argument (PRIVATE):
   (setq uri (url-insert-entities-in-string uri)
	mime-type (url-insert-entities-in-string mime-type)
	timestamp (url-insert-entities-in-string timestamp)
	groups (mapcar 'url-insert-entities-in-string groups))
   ;; Make sure recent-file is opened and saved in the correct encoding:
   (let* ((coding-system-for-read (intern (downcase recent-files-encoding)))
	 (coding-system-for-write coding-system-for-read)
	 (coding-system-require-warning t)
	 (recent-buffer (get-file-buffer recent-files-name)))
     (save-excursion
       (set-buffer (or recent-buffer (find-file-noselect 
recent-files-name)))
       (save-restriction
	(widen)
	(when (= (buffer-size) 0)
	  (goto-char (point-min))
	  (insert "<?xml version=\"1.0\" encoding=\""
		  recent-files-encoding
		  "\"?>")
	  (insert "\n" "<RecentFiles>")
	  (insert "\n" "</RecentFiles>"))
	(goto-char (point-min))
	(if (search-forward-regexp (concat "<URI>" (regexp-quote uri) "</URI>")
				   nil t)
	    ;; then: Per the spec, only update the timestamp and add new groups:
	    (progn
	      (search-forward-regexp "<Timestamp>\\(.*\\)</Timestamp>")
	      (replace-match timestamp t t nil 1)
	      (goto-char (match-end 0))	; end-of-line
	      (when groups
		(let (group-start group-end)
		  (if (looking-at "\n*<Groups>")
		      (progn
			(setq group-start (match-end 0))
			(setq group-end (search-forward-regexp "</Groups>")))
		    (insert "\n" "<Groups>")
		    (setq group-start (point))
		    (insert "\n" "</Groups>")
		    (setq group-end (point-marker)))
		  (goto-char group-start)
		  (mapc (lambda (group)
			  (unless (save-excursion
				    (search-forward-regexp
				     (concat "<Group>"
					     (regexp-quote group)
					     "</Group>")
				     nil group-end))
			    (insert "\n" "<Group>" group "</Group>")))
			groups))))
	  ;; else: Insert the new item:
	  (search-forward "</RecentFiles>")
	  (goto-char (match-beginning 0))
	  (insert "<RecentItem>")
	  (insert "\n" "<URI>" uri "</URI>"
		  "\n" "<Mime-Type>" mime-type "</Mime-Type>"
		  "\n" "<Timestamp>" timestamp "</Timestamp>")
	  (when groups
	    (insert "\n" "<Groups>")
	    (mapc (lambda (group)
		    (insert "\n" "<Group>" group "</Group>"))
		  groups)
	    (insert "\n" "</Groups>"))
	  (when private
	    (insert "\n" "<Private/>"))
	  (insert "\n" "</RecentItem>" "\n"))
	(save-buffer))
       (or recent-buffer (kill-buffer (current-buffer))))))

-- 
Kevin

  reply	other threads:[~2006-05-24 18:52 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1147396844.567992.55920@i40g2000cwc.googlegroups.com>
2006-05-13  4:51 ` Recent documents: Emacs and GNOME integration Richard Stallman
2006-05-17  7:50   ` Mathias Dahl
2006-05-17 14:37     ` Piotr Zielinski
2006-05-17 18:50       ` Stuart D. Herring
2006-05-17 19:01         ` Stuart D. Herring
2006-05-17 23:12       ` Richard Stallman
2006-05-24 18:52         ` Kevin Rodgers [this message]
2006-05-25  0:37           ` Richard Stallman
2006-05-25 17:22             ` Bill Wohler
2006-05-26 18:54               ` Kevin Rodgers
2006-05-30 15:46                 ` Stuart D. Herring
     [not found]                   ` <20060530163850.34480.qmail@web51010.mail.yahoo.com>
2006-05-30 18:28                     ` Stuart D. Herring
     [not found]                       ` <20060530195948.37508.qmail@web51014.mail.yahoo.com>
2006-05-30 21:10                         ` Stuart D. Herring
2006-05-25 17:02           ` Stuart D. Herring
2006-05-17 20:08     ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='e52a2j$fo5$1@sea.gmane.org' \
    --to=ihs_4664@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).