help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Tag based dired?


From: Mathias Dahl
Subject: Re: Tag based dired?
Date: Tue, 27 Jun 2006 16:58:56 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (windows-nt)

Xiao-Yong Jin <xj2106NO@SPAMcolumbia.edu> writes:

> Hi all, I'm wondering if there is some kind of tag or label support in
> dired.
>
> Nowadays tagging or labeling is used widely on the Internet.  Blogs
> and wikis has various tag support.  And gmail has its flexible
> labeling support.  So does the f-spot.  I did some search on the web
> and there is no file manager that really supports tags well.  
>
> So far I use org-mode to organize my staff as well as my files.
> Because you can add various tags to a subject in org-mode, it's easy
> to manager all the files.  However, it's not easy to handle files
> using file links in org-mode.
>
> I think it would be much better if one could give various labels to
> files, and organize and search files using labels, especially in dired
> or even wdired.
>
> I want to ask if there are some easy way to implement this feature in
> emacs?  This file tagging idea is very rough now and I would like to
> do some research to make it more concrete.  And if it's possible, I
> want to implement it as a plugin to dired?

I just couldn't hold myself and created a small hack that might be
useful (hopefully I will find a use for it myself too so that I can
convince myself that the time was well spent.) :)

Here we go:

;;; file-props.el --- Add file properties to your files
;;
;; Copyright (C) 2006 Mathias Dahl
;;
;; Version: 0.1
;; Keywords: search, convenience, files
;; Author: Mathias Dahl <mathias.rem0veth1s.dahl@gmail.com>

;; This file is not 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 2, 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; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:
;;
;; file-props.el provides a way to "tag" or "label" your files.
;; Actually, the functionality is generic and supports adding any type
;; of property to your files.  Right now "tags" and a "comment" can be
;; added.
;;
;; After having added this meta data you can use it to find files in
;; different ways.  Provided is a command to list all files having a
;; certain tag in a dired buffer.
;;
;; NOTE: This is not stable yet, it is a proof-of-concept, to see if
;; it could be useful.  Use at own your risk.
;;
;;; Installation:
;;
;; Place this file in your `load-path'.
;;
;; Put this in your .emacs file:
;;
;; (require 'file-props)
;; (file-props-load-properties)
;;
;; NOTE: If you don't load the properties file it will be overwritten
;; with only the properties you define in this session.  I'm not sure
;; if this is the best approach though.  One could make file-props.el
;; automactially load all file properties when it is loaded.
;;
;;; Usage:
;;
;; - Adding tags:
;;
;; In dired, mark a couple of files and type M-x
;; file-props-dired-add-tags RET.
;;
;; On the prompt, enter one or more tags, separated with a comma and
;; type RET.
;;
;; - Finding files:
;;
;; Type M-x file-props-find-tags-dired RET.
;;
;; Enter a tag and type RET.
;;
;; You will be presented with a dired buffer containing the files
;; having the tag you searched for.
;;
;; - Other uses:
;;
;; Currently, the only other command is `file-props-dired-add-comment'
;; which will add a comment property to the file.  The idea is that
;; while tags are used to categorize or label your files, a comment is
;; more specific and can act as the description of the file.
;;
;; As explained above, tags and comments are just examples of meta
;; data you might want to add to your files, other types of data
;; should be easy to add if you want.  Look at
;; `file-props-dired-add-tags' and `file-props-dired-add-comment' for
;; examples.
;;
;;
;;; History:
;; 
;;
;; Version 0.1, 2006-06-27
;;
;; * First release.
;;

;;; Code:

(defgroup file-props nil
  "File properties lets you add different kinds of properties or
meta-data to files and have these properties saved to a central
data file.  This information can be used to mark file having a
certain meta-data in Dired."
  :group 'Convenience)


(defcustom file-props-data-file "~/.emacs.d/file-props"
  "File in which the file properties are saved."
  :type 'file
  :group 'file-props)


(defvar file-props-list nil
  "List containing the file properties.")


(defun file-props-add-property (file property value)
  "For FILE, set PROPERTY to VALUE.
If the property does not exist, it will be created.  If it
exists, the value will be overwritten."
  (unless (assoc file file-props-list)
    (setq file-props-list (append file-props-list (list (list file nil)))))
  (setcdr (assoc file file-props-list)
          (plist-put (cdr (assoc file file-props-list)) property value)))


(defun file-props-save-properties ()
  "Save file properties.
Save file properties to file `file-props-data-file'."
  (with-temp-file (expand-file-name file-props-data-file)
    (prin1 file-props-list (current-buffer))))


(defun file-props-load-properties ()
  "Load all file properties.
Load all file properties from file `file-props-data-file'.  If
the files does not exist, no harm is done; it will be created
when file properties are added to files."
  (let ((file (expand-file-name file-props-data-file))
        buf)
    (if (not (file-exists-p file))
        (message "File properties data file does not exist")
      (setq buf (find-file-noselect
                 file))
      (setq file-props-list (read buf))
      (kill-buffer buf))))


(defun file-props-dired-add-tags ()
  "Add file tags to current or marked files."
  (interactive)
  (let ((tags-string (read-string "Enter tags, separated by a comma: ")))
    (mapc
     (lambda (x)
       (file-props-add-property x 'tags (split-string tags-string ",")))
     (dired-get-marked-files)))
  ;; Don't save to file if there are no properties.  This works as a
  ;; kind of security measure, making sure that the data file is not
  ;; overwritten with no data if the user by mistake did not load the
  ;; old properties before adding new ones.  If anyone can come up
  ;; with a better approach than this, please don't hesitate to
  ;; contact me.
  (if file-props-list
      (file-props-save-properties)))


(defun file-props-dired-add-comment ()
  "Add file comment to current or marked files."
  (interactive)
  (let ((comment (read-string "Enter comment: ")))
    (mapc
     (lambda (x)
       (file-props-add-property x 'comment comment))
     (dired-get-marked-files)))
  (file-props-save-properties))


(defun file-props-list-all-tags ()
  "Return all unique tags for all files."
  (unless file-props-list
    (file-props-load-properties))
  (let (all-tags)
    (mapc
     (lambda (x)
       (let ((tags (plist-get (cdr x) 'tags)))
         (mapc
          (lambda (y)
            (unless (member y all-tags)
              (setq all-tags (append all-tags (list y)))))
          tags)))
     file-props-list)
    all-tags))


(defun file-props-find-files-from-tag (tag)
  "Return a list of all files having file tag TAG."
  (let (files)
    (mapc
     (lambda (x)
       (when (member tag (plist-get (cdr x) 'tags))
         (setq files (append files (list (car x))))))
     file-props-list)
    files))


(defun file-props-find-tags-dired ()
  "Search for file tag TAG to find files and list them in dired.
It generates a result like `find-dired' does."
  (interactive)
  (let ((dir (read-directory-name "Set current directory: "))
        (tag (read-string "Tag to search for: ")))
       (dired (cons dir (file-props-find-files-from-tag tag)))))


(provide 'file-props)

;;; file-props.el ends here


reply via email to

[Prev in Thread] Current Thread [Next in Thread]