NEW: For a prettier blog interface, see the Wordpress version!

Tasks
Priorities - A: high, B: medium, C: low; Status - _: unfinished, X: finished, C: cancelled, P: pending, o: in progress, >: delegated. Covey quadrants - Q1 & Q3: urgent, Q1 & Q2: important
BXUpdate xtla : E-Mail from Stefan Reichör (2005.06.02)
BXChange to BBDB aliases instead of (2005.05.06)
BXWrite BBDB/Planner code for (2005.05.06)
BXModify my note markup code for more blockish-ness (2005.04.21 planner emacs)
BXModify my task markup code to make it tabular (2005.04.21 planner emacs)
BCMigrate the rest of my configuration to XEmacs (2005.04.21)
Notes

20. (semi)form letters: hooray for open source!: 23:35

Categories: 2005.07.10:3 -- Permalink
I needed to write 31 thank-you-for-attending-my-send-off-party e-mail messages. Instead of having a generic letter that I'd send to lots of people all listed in To: or Bcc:, I decided to personalize it a bit by including their nicknames, two-year goals, and a personal message I'd add to each letter in different places.

Fortunately, my mail client was up to the task. One of the benefits of having both your contact information and your mail client in an easily-programmable environment is that you can hack together a quick program to do exactly what you want.

I had typed everyone's two-year-plans into my contact information manager's Notes field following a special format. It was the work of a few minutes to record and run a macro that extracted the data and created a signature for each person who attended my send-off party.

I then wrote a couple of short functions that looped over the currently displayed contact records and drafted messages for each of them following a template.

This resulted in 31 drafts I could edit and send without hassles. Much fun!

For future reference (and for the handful of Emacs geeks or learners in the audience), here's the code I used to make it all happen:

(defun sacha/bbdb-send-form-mail (bbdb-record &optional subject template)
  "Compose a form message to the people indicated by the current BBDB record(s)."
  (interactive (list (if (bbdb-do-all-records-p)
                         (mapcar 'car bbdb-records)
                       (bbdb-current-record))
                     (read-string "Subject: ")
                     (read-string "Template (<NICK>): ")))
  (if (consp bbdb-record)
      (let ((records bbdb-record))
        (while records
          (sacha/bbdb-send-form-mail-1 (car records) subject template)
          (setq records (cdr records))))
    (sacha/bbdb-send-form-mail-1 bbdb-record subject template)))

(defun sacha/bbdb-send-form-mail-1  (bbdb-record &optional subject template)
  "Compose a form message for one person."
    (if bbdb-inside-electric-display
      (bbdb-electric-throw-to-execute
       (list 'sacha/bbdb-send-form-mail bbdb-record subject)))
  ;; else...
  (cond ((null bbdb-record) (error "record unexists"))
        ((null (bbdb-record-net bbdb-record))
         (message "%s record unhas a network addresses." (or (bbdb-record-name bbdb-record) "Unknown")))
        (t (bbdb-send-mail-internal (bbdb-dwim-net-address bbdb-record)
                                    subject (list bbdb-record))
           (goto-char (point-min))
           (when (re-search-forward "--text follows this line--" nil t)
             (forward-line 1)
             (insert template)
             (goto-char (point-min))
             (while (search-forward "<NICK>" nil t)
               (replace-match (or (bbdb-record-getprop bbdb-record 'nick)
                                  (bbdb-record-name bbdb-record))
                              t t))
             (when (bbdb-record-getprop bbdb-record 'signature)
               (goto-char (point-max))
               (insert "\n")
               (let ((p (point)))
                 (insert (bbdb-record-getprop bbdb-record 'signature))
                 (fill-region-as-paragraph p (point))))
             (goto-char (point-min))
             (if (re-search-forward "^Subject: $" nil t) (end-of-line))))))

I used M-x local-set-key to bind sacha/bbdb-send-form-mail to M. * M then applies the function to all displayed records. ../emacs/miniedit.el makes it easy to edit long strings in the minibuffer, and that made the template much easier to write.

Emacs totally rocks. Nothing else has ever given me this much power.

自動車製造は人間の労働者に代わって、コンピューターが組み込まれたロボットによって行われている。 Car manufacturing is carried out by computer-programmed robots in place of human workers.

19. Working with Emacs: 12:12

Categories: 2005.07.01#2 -- Permalink
A recent post on the Philippine Linux Users' Group suggested a separate plug-emacs mailing lists for all the Emacs messages that have popped up recently. The suggester said:
There is a difference between discussion and stroking each other's ego. :)

Working with Emacs is a humbling experience. It brings you face to face with accumulated centuries of developers' work. Emacs involves people in its development to an unusual extent. Working with vi and even Eclipse made me feel more like a user than a co-developer. Working with Emacs made me feel part of the community, even when I was still struggling to make sense of the parentheses.

If in that sense, Emacs worship is considered ego-stroking, then sure, I'm guilty. I can't help but express my appreciation for one of those things that has really changed my life and made free, open source software really meaningful to me. For the culture, really, that made it possible. It's a piece of software, but it's also a conversation with so many developers around the world.

To newbies: if you're curious about the thrills of open source development and you want a nice, easy way to get started, why not try modifying Emacs? It's easy to pick up. All the source code is there, and you can modify it on the fly. We've had complete non-programmers try it out and fall in love with programming. They get thrilled when they share their tweaks and other people respond with comments and suggestions. This is good stuff. Try it out. =)

I suppose Emacs is off-topic. After all, it's cross-platform, not Linux-specific. I could easily be extolling the wonders of Emacs on Mac OS X, Microsoft Windows, or BSD. Emacs doesn't require Linux. (Neither does Apache, but you don't see people waxing lyrical about web servers that often, do you?) The flood of Emacs-related posts that deluge the list whenever someone unwittingly brings up the topic is probably incomprehensible to people who've never tried Emacs or tried Emacs as just an editor and didn't like it.

Still, I want to share what makes open source real for me. Not kernel hacking, which is still too intimidating despite the existence of projects like kernel-janitor. Not network or system administration, which I don't have the patience to do. Just the free and flexible customization of something I use everyday and the thrill of sharing these customizations with other people in a community that spans the world.

I guess that's why I post on PLUG instead of plug-misc. I don't think PLUG should just be a venue for asking and answering technical questions, but also for sharing nifty hacks and examples of how far a Linux system can be pushed. Other people push their systems in terms of hardware and services. I push mine in terms of how well it can fit me, how well it can anticipate my needs.

I want to stroke other people's egos. I want people to discover how they can contribute to free and open source software, to experience the thrill of seeing their code out there and being used. Open source development isn't just for PHP wizards or C freaks who can contribute to existing projects or launch an entirely new project on their own. Maybe--just maybe!--people who thought themselves just users of a text editor will be inspired to think about how they can start customizing their own.

コンピュータを使えば時間に節約になる。 Computers will save you a lot of time.

clair ching says:

I can't help but agree with you. Emacs is the way that I appreciated FOSS more compared to GNU/Linux per se. Why? It's because I easily felt part of the community of Emacs users and hackers on the Emacs Wiki. That kind of interaction makes it less scary for newbies, IMHO. I mean, not all people on the Emacs Wiki are very friendly, I suppose, but the ones I have interacted with as I was learning to use various tools and modes available showed me that I can do something for the FOSS community, which is to write about what I learn. I don't even know ELISP but at least I know that my blog entries are helpful to others too. =)

I guess we have been too giddy over Emacs on the PLUG mailing list that is why someone suggested that. Well, I know I have always been giddy about it but I can't help myself! ^_^ Emacs is wonderful...

Besides there are so many hacks in Emacs that make FOSS usage, learning and advocacy so much fun! Like the Planner mode that allows me to somewhat organize my life, my thoughts, my schedule. Eshell allows me to do some things without opening a separate terminal. In Planner, I also store my notes on advocacy and my blog entry drafts. I also listen to music on Emacs. And when something goes wrong on whatever mode I am using, I can email the maintainer immediately, to tell him/her what happened so that the bug can be fixed, etc. I try to be as detailed as possible when I do that. So I guess that is my contribution. =)

In any case, I also enjoy the company of people using Emacs, not just because we talk about Emacs but because I am learning so much about you guys =)

18. Planner support for action-lock.el: 08:42

action-lock.el is part of HOWM. The following code enables Planner-style links _anywhere_. Add it to your ~/.emacs and use M-x action-lock-mode to turn action locking on.
(add-to-list 'action-lock-default-rules
             (list (with-planner emacs-wiki-url-or-name-regexp)
                   'planner-action-lock-follow-name-at-point))
(setq action-lock-rules action-lock-default-rules)
(defvar planner-action-lock-default-directory planner-directory "Expand files relative to this directory.")
(defun planner-action-lock-follow-name-at-point (&optional other-window)
  (let ((link-name (match-string 0))
        (base-buffer (current-buffer))
        ;; the name of the buffer that contains the link.  check
        ;; whether buffer-name is a WikiName, else make it one
        (parent-name (or (emacs-wiki-page-name)
                         (concat "[[" (buffer-name) "]]"))))
    (with-planner
      (let ((link (emacs-wiki-wiki-link-target link-name)))
        (if (emacs-wiki-wiki-url-p link)
            (emacs-wiki-browse-url link other-window)
          ;; The name list is current since the last time the buffer was
          ;; highlighted
          (let* ((base (emacs-wiki-wiki-base link-name))
                 (file (emacs-wiki-page-file base))
                 (tag  (and (not (emacs-wiki-wiki-url-p link))
                            (emacs-wiki-wiki-tag link)))
                 (find-file-function (if other-window
                                         'find-file-other-window
                                       'find-file))
                 (parent-allowed-backlink-p
                  (not (string-match
                        emacs-wiki-exclude-backlink-parent-regexp
                        parent-name)))
                 (parent-backlink (and parent-allowed-backlink-p
				   (emacs-wiki-get-current-backlink)))
                 (newbuf
                  (funcall find-file-function
                           (or file
                               (expand-file-name
                                       base
                                       (or planner-action-lock-default-directory
                                           (and (buffer-file-name)
                                                (file-name-directory
                                                 (buffer-file-name)))
                                           default-directory)))))
                 (emacs-wiki-create-backlinks
                  (and emacs-wiki-create-backlinks parent-allowed-backlink-p))
                 (make-link-p (and emacs-wiki-create-backlinks
                                   ;; insert backlink only in new files
                                   (null file)
                                   (not (string-match
                                         emacs-wiki-exclude-backlink-regexp
                                         (emacs-wiki-page-name
                                          (buffer-file-name newbuf)))))))
            (when tag
              (goto-char (point-min))
              (re-search-forward (concat "^\\.?#" tag) nil t))
            (when refresh-buffer
              (when make-link-p
                (emacs-wiki-insert-backlink parent-name parent-backlink))
              ;; todo: is with-current-buffer necessary here?
              (with-current-buffer newbuf
                (add-hook 'after-save-hook
                          'emacs-wiki-refresh-buffers-once t t)
                ;; save the new file to avoid another backlink if the
                ;; buffer is visited again before being saved
                (when (or make-link-p
                          (and (null file)
                               (not parent-allowed-backlink-p)))
                  ;; set modified status to t: pages with excluded
                  ;; parents may not be modified, but we want to save
                  ;; anyway
                  (set-buffer-modified-p t)
                  (save-buffer))))))))))

コンピュータの知識はすべての科学」にとって基本である。 Knowledge of computers is basic to all sciences.

17. Emacs snippet for pmwiki attachments: 13:44

Categories: 2005.06.16#2 -- Permalink
(defun sacha/dired-marked-images-as-attach ()
  "Return a list of images ready to be inserted into a pmwiki page."
  (interactive)
  (kill-new (mapconcat
             (lambda (item)
               (concat "Attach:" (file-name-nondirectory item)))
             (dired-get-marked-files)
             "\n")))

16. Automatically scheduling tasks onto TaskPool: 10:52

(defadvice planner-create-task-from-buffer (before paul activate)
  "Automatically schedule task onto TaskPool as well as other projects."
  (if plan-page
      (unless (string-match plan-page "TaskPool")
        (setq plan-page (concat plan-page planner-multi-separator "TaskPool")))
    (setq plan-page "TaskPool")))

Here's another snippet that will unschedule tasks from TaskPool when you mark them completed with C-c C-x (planner-task-done). Nifty stuff, huh?

(defadvice planner-task-done (after paul activate)
  "Remove completed tasks from the TaskPool if that still leaves them linked."
  (let ((info (planner-current-task-info)))
    (when (planner-task-link-text info)
      ;; If it is linked to TaskPool _and_ at least one other thing
      (if (string-match planner-multi-separator (planner-task-link-text info))
          (planner-multi-replan-task
           (planner-multi-make-link (planner-multi-filter-links "^TaskPool$" (planner-multi-task-link-as-list info) t)))
        ;; Else if it has a date and is linked to TaskPool
        (if (and (planner-task-date info)
                 (string= (planner-task-link info) "TaskPool"))
            (planner-replan-task nil))))))

原始的な計算機が、コンピューターの開発されるずっと以前に存在していた。 Primitive calculating machines existed long before computers were developed.

15. Adding an arbitrary extension to your planner files: 16:55

Do you want all of your planner files to have a TXT extension so that they'll be searched by tools such as Google Desktop or Apple Spotlight?

Use the 'rename' tool to add .txt extensions to all of your files, or use the following code to rename all of your planner files from a running Planner setup:

(defun my-rename-planner-files ()
  "Rename all my planner files to .txt if they don't have that extension yet."
  (interactive)
  (mapcar
   (lambda (file)
     (unless (string-match "\\.txt$" (cdr file))
       (rename-file (cdr file) (concat (cdr file) ".txt"))
       (message "%s" (cdr file))))
   (planner-file-alist))
  (with-planner
    (emacs-wiki-refresh-file-alist)))

Then add this to your ~/.emacs before you load Planner:

(setq emacs-wiki-ignored-extensions-regexp "\\.txt")

(defadvice emacs-wiki-find-file (around extension activate)
  "Open the Emacs Wiki page WIKI by name.
If COMMAND is non-nil, it is the function used to visit the file.
If DIRECTORY is non-nil, it is the directory in which the Wiki
page will be created if it does not already exist."
  (unless (interactive-p)
    (setq wiki (cons wiki
                     (cdr (assoc wiki (emacs-wiki-file-alist))))))
  ;; At this point, `wiki' is (GIVEN-PAGE FOUND-FILE).
  (if (cdr wiki)
      (let ((buffer (funcall (or command 'find-file) (cdr wiki))))
        (if (= (prefix-numeric-value current-prefix-arg) 16)
            (with-current-buffer buffer
              (set (make-variable-buffer-local 'emacs-wiki-directories)
                   (cons (file-name-directory (cdr wiki))
                         emacs-wiki-directories))
              (set (make-variable-buffer-local 'emacs-wiki-file-alist)
                   nil)))
        buffer)
    (let* ((dirname (or directory
                        (emacs-wiki-maybe t)
                        (car emacs-wiki-directories)))
           (filename (expand-file-name (car wiki) dirname)))
      (unless (file-exists-p dirname)
        (make-directory dirname t))
      (funcall (or command 'find-file) (concat filename ".txt")))))

新しいパソコンを買うつもりで金を溜めているんだ。 I am saving money in order to buy a new personal computer.

14. xtla and Gnus: 18:01

There is a feature in xtla.el to send/review patches via gnus.

To set it up, you need the following lines for your .emacs:

(tla-insinuate-gnus)
(setq tla-apply-patch-mapping
      '(((nil "planner" nil  nil nil) "~/work/planner-dev/")))

Replace ~/work/planner-dev/ with your planner working directory

The patches are sent as .tar.gz files.

When you receive such a patch (I will send one soon), You can hit
K t v to view the patch
K t a to apply the patch

I can even provide a log message in the mail. You can insert the log message via C-c C-p in the tla-log-edit buffer.

E-Mail from Stefan Reichör

その限られた性能のために私はコンピユーターに幻滅を感じている。 Its limited capability has disenchanted me with computer.

13. Task management with Emacs: Text files: 09:58

With the wealth of code available for Emacs and the ease of customization it provides, you're certain to find a task management tool that fits the way you think. Over the next few days, I'll provide a quick run-through of the methods I've tried out.

The simplest way to get started with Emacs for task management is to keep your TODOs in a plain text file, like ~/TODO. You can keep this text file in any format you want. To make it easier for you to see what you need to do, you can keep active TODOs near the top and completed tasks near the bottom.

If you load your TODO file every time you start up Emacs, then you'll be sure to check it every day. Put the following line in your ~/.emacs to have it automatically loaded when you start:

(find-file "~/TODO")

You'll also want to make it easy to open during an Emacs session. If your TODO file is just a keyboard shortcut away, you'll find it easier to keep all of your reminders in the file. Here's a snippet that shows the TODO file in the current window.

(defun my/todo ()
 "Bring up the TODO file."
 (interactive)
 (find-file "~/TODO")
 (goto-char (point-min)))

;; Now bind it to a convenient shortcut key
(global-set-key (kbd "<f5> <f5>") 'my/todo)

Now you can hit F5 F5 to show your TODO. If you want your TODO file to show up in another window, remove that and use this snippet instead:

(defun my/todo ()
 "Bring up the TODO file."
 (interactive)
 (find-file-other-window "~/TODO")
 (goto-char (point-min)))

;; Now bind it to a convenient shortcut key
(global-set-key (kbd "<f5> <f5>") 'my/todo)

If you want to be able to add stuff to your TODO without getting distracted from your work, add this to your ~/.emacs:

(defun my/add-todo (task)
 "Add a line to the TODO file."
 (interactive "MTask: ")
 (with-current-buffer (find-file-noselect "~/TODO")
   (goto-char (point-min))
   (insert task "\n")
   (save-buffer)))
(global-set-key (kbd "<f5> t") 'my/add-todo)

See? Emacs is fun and easy to configure. You can store your tasks in a plain text file and then add keyboard shortcuts to make your tasks easier to manage.

There are many sophisticated task management packages for Emacs. I'll write about one of them tomorrow. In the meantime, if you want to find out what task manager I _really_ like using, you can check out PlannerMode! =)

何社製のコンピューターをお使いですか。 What make of computer do you use?

12. BBDB tags: 01:52

Right, that thing looks like a good idea. It should be easy to hack into BBDB. I'll need to actually tag people, and then write an Emacs Lisp script that scans through all of the records, gathers them into categories, and then creates the list.

HEY. This might actually work. Here's a quick test of

ateneo Charles Yeung,Sean Uy,Ryan Kristoffer Tan,Stephanie Sy,Bit Santos,Jerome Punzalan
pisay Jerome Punzalan,clair ching,mario carreon
linux Eric Pareja,Jared Odulio,Chris G. Haravata,levi guerrero,Zak B. Elep,clair ching,Dean Michael Berris,Jan Alonzo
blog Charles Yeung,Sean Uy,Ryan Kristoffer Tan,Stephanie Sy,Aaditya Sood,Bit Santos,Raven,Jerome Punzalan,Richard Plana,Phillip Pearson,Eric Pareja,Jared Odulio,Celsus Kintanar,Jan Michael Ibanez,Mark A. Hershberger,Chris G. Haravata,levi guerrero,Cha Gascon,Sim Gamboa, III,Marcelle Fabie,Zak B. Elep,David Edmondson,edelgado,Dominique Cimafranca,clair ching,Sean Champ,Dean Michael Berris,Jason Banico,John S. J. Anderson,Jan Alonzo
debian Federico Sevilla III,Paul Lussier,Angus Lees,Frederik Fouvry,Zak B. Elep,Joe Corneli,clair ching,Sean Champ,Miles Bader,Jan Alonzo,Jesse Alama
emacs Manoj Srivastava,Paul Lussier,Lukhas,Angus Lees,Mario Lang,Jan Michael Ibanez,Mark A. Hershberger,Frederik Fouvry,clair ching,Miles Bader,Ethan Aubin,John S. J. Anderson,Jesse Alama
planner Paul Lussier,Mark A. Hershberger,Frederik Fouvry,Zak B. Elep,Joe Corneli,clair ching,Ethan Aubin,John S. J. Anderson,Jesse Alama
Use C-o to add a "tags" field to your BBDB records. This should be a space-delimited list of (case-sensitive for now). Call M-x sacha/planner-bbdb-insert- to produce a list like the one above.
(defun sacha/bbdb-get-tags (record)
  "Return the tags for RECORD as a list."
  (let ((tags (bbdb-record-getprop record 'tags)))
    (when tags (split-string tags))))

(defun sacha/bbdb-test-tags (query tags)
  "Return non-nil if QUERY is a subset of TAGS."
  (let ((result t))
    (while (and result query)
      (unless (member (car query) tags)
        (setq result nil))
      (setq query (cdr query)))
    result))

(defun sacha/bbdb-search-tags-internal (records tags)
  "Return a list of RECORDS matching TAGS."
  (when (stringp tags) (setq tags (split-string tags)))
  (let (result)
    (while records
      (when (sacha/bbdb-test-tags tags
                                  (sacha/bbdb-get-tags (car records)))
        (setq result (cons (car records) result)))
      (setq records (cdr records)))
    result))

(defun sacha/bbdb-search-tags (tags)
  "Display all the records that match TAGS."
  (interactive "MTags: ")
  (bbdb-display-records (sacha/bbdb-search-tags-internal (bbdb-records) tags)))

(defun sacha/planner-bbdb-link (record)
  "Return a link to RECORD."
  (or (bbdb-record-getprop record 'plan)
      ;; From a BBDB entry with a plan page; use that. Yay!
      (concat "[[bbdb://"
              (emacs-wiki-replace-regexp-in-string
               " " "."
               (bbdb-record-name record))
              "][" (bbdb-record-name record)
              "]]")))

(defun sacha/bbdb-get-tags-index ()
  "Return a list of tags and records."
  (let ((tags-alist '())
        (records (bbdb-records))
        tags
        entry
        list
        link)
    (while records
      (setq tags (sacha/bbdb-get-tags (car records)))
      (while tags
        (setq entry (assoc (car tags) tags-alist))
        (setq list (cdr entry))
        (add-to-list 'list (car records))
        (if entry
            (setcdr entry list)
          (add-to-list 'tags-alist (cons (car tags) list)))
        (setq tags (cdr tags)))
      (setq records (cdr records)))
    tags-alist))

(defun sacha/planner-bbdb-insert-tags-alist (&optional tag-alist)
  "Insert TAG-ALIST into the current buffer."
  (interactive)
  (unless tag-alist (setq tag-alist (sacha/bbdb-get-tags-index)))
  (insert (mapconcat
           (lambda (item)
             (concat (car item) " | "
                     (mapconcat
                      'sacha/planner-bbdb-link
                      (cdr item)
                      ",")))
           tag-alist
           "\n")))

To think that only took me an hour of leisurely coding (including my contact information)...

昨年度のコンピューターからの利益は、今年度分よりも10%近く多かった。 Profit on computers for the previous year was nearly ten percent higher than the current year.

11. sacha/emacs-wiki-markup-string: 16:21

Categories: 2005.04.20:4 -- Permalink
(defun sacha/emacs-wiki-markup-string (string)
  "Mark up STRING according to `emacs-wiki-publishing-rules'.
No header or footer is added."
  (let ((emacs-wiki-project emacs-wiki-current-project))
    (with-temp-buffer
      (emacs-wiki-mode)
      (insert string)
      (let ((emacs-wiki-publishing-header "")
            (emacs-wiki-publishing-footer ""))
        (emacs-wiki-replace-markup))
      (buffer-string))))

../emacs/emacs-wiki-config.el

うちの猫は台所にいます。 Our cat is in the kitchen.

10. Lightning completion and highlight completion: 00:28

Categories: 2005.04.11:1 -- Permalink
A stray mention in #emacs led me to http://www.math.washington.edu/~palmieri/Emacs/ , which has Emacs Lisp code for lightning completion and highlight completion. Both are pretty interesting, and I wonder how I can put them to good use. Hmmm...

私はこの猫の世話をしなければならない。 I have to look after this cat.

9. Modification of johnsu01's scoring: 15:44

The following code allows you to sort tasks based on regexp matches against the line. It's fairly simple, but may give people ideas about fancier task sorting.
(setq planner-sort-tasks-key-function 'planner-sort-tasks-by-score)

(defvar planner-score-rules '(("read" . 50))
  "Alist of planner scoring rules of the form (regexp . score-value).
Tasks with higher scores are listed first.")

(defun planner-sort-tasks-by-score ()
  "Sort tasks by the rule in the table."
  (let ((score 0)
        (case-fold-search t)
        (line (buffer-substring-no-properties (line-beginning-position)
                                              (line-end-position))))
    (mapc
     (lambda (item)
       (when (string-match (car item) line)
         (setq score (- score (cdr item)))))
     planner-score-rules)
    score))

8. Managing my mail: 15:38

I use Gnus, one of the many mail/news clients available for Emacs. The following features help me manage the volume of mail I get each day.
Mail splitting

Yes, yes, the Gmail way is to keep everything in one folder and then use searches to filter your messages. Still, I like being able to glance at my screen and see 2 personal messages and 3 planner-related messages.

Topics and group hiding

I use Gnus topics to divide my mail into folders and subfolders. Mail groups are hidden unless they have mail. Some groups like mail.misc and mail.planner are generally useful, so I keep them visible even if they don't have unread mail.

Scoring

Gnus allows you to automatically score threads and messages up and down based on various criteria. You can set it to completely hide boring messages, show them in a different color, show interesting messages in a different color, etc.

On most mailing lists and newsgroups, I don't bother reading message bodies. I just scan through subjects, hitting k to kill entire threads I don't find interesting. Gnus remembers what threads I've killed, marks them as read, and scores them down automatically. It also scores up messages containing certain keywords, replies to my posts, and threads I found interesting.

Integration with my contacts

I put interesting people in my BBDB contact database. Gnus indicates messages from them with a little + beside their name in the message summary. If someone I know is interested in a thread, I might find it interesting as well.

Hiding and article washing

I've set Gnus up to hide quoted text. This makes browsing through threads much easier because I can concentrate only on the the new parts. I can hit a few keys to expose sections of the quoted text if the replies aren't immediately obvious from the context.

I can also set it up to remove ads at the bottom of messages, particularly long signatures, To: lines with more than N recipients, that sort of thing. I can tell it to strip out HTML, too.

Displaying parent article

Sometimes I'll jump into the middle of a thread. I can use ^ to get to the parent message.

Searching

I use swish++ to index and search through my personal and planner-related mail.

Planner hyperlinks

Most of my tasks come in through e-mail. Planner lets me keep track of my TODOs easily by automatically hyperlinking to the mail message I'm looking at when I create a task. Dealing with a few items on my TODO list is much easier than going through a large inbox! =)

7. flashcard-import-from-kill: 10:17

The following code snippet makes it easier for me to import segments from my dictionary files. It uses ../emacs/flashcard.el.
(defun flashcard-import-from-kill (deck)
  "Import cards for DECK from the clipboard, which should be colon-separated.

Question : Answer"
  (interactive (list flashcard-deck))
  (unless (eq major-mode 'flashcard-mode)
    (error "You're not in a deckfile."))
  (with-temp-buffer
    (yank)
    (goto-char (point-min))
    (while (re-search-forward "^ *\\(.*\\) +: +\\(.*\\)$" nil t)
      (flashcard-add-card deck
                          (flashcard-make-card (match-string 1)
                                               (match-string 2)))))
  (when (and (interactive-p)
             (not flashcard-card))
    (flashcard-ask)))

../emacs/flashcard-config.el

6. Nifty Japanese stuff: Kakasi: 10:36

Kakasi is an external utility for converting Japanese text between coding systems. It can also add furigana after kanji or convert a text file to romaji.

Debian users can apt-get install kakasi kakasi-dic. There's an Emacs interface, a Perl module (Text::Kakasi), and a Ruby library.

5. highlight-tail-mode: 09:24

Categories: emacs tips -- Permalink
I just ran across highlight-tail.el from gnu.emacs.sources. It leaves a colored trail behind your inserts, fading over time. Completely useless (although it does give you a visual sign of how much you've been typing) but altogether cute. Why we have stuff like this, I don't know--but it's cool anyway!

Chat on sterling.freenode.net%23emacs

4. More Emacs evangelization: flashcard: 15:43

Categories: 2005.01.14:1 -- Permalink
Aris and I are both struggling with far too much kanji. I used a combination of kdrill to gain familiarity with kanji and ../emacs/flashcard.el to drill the meaning into my brain, as flashcard.el requires me to get a question right 5 times in a row before considering it solved. Aris searched the Internet for flashcard programs on Windows and played around with things like Kanji Gold and King Kanji, but couldn't figure out how to import our wordlist into them. Kanji Gold looked promising as it also used EDICT, but I couldn't figure out the magic number at the end of the dictionary entry. With over 200 words in our word list, there was no way we were going to enter those things one by one!

I told him to download Emacs and grab Jorgen Schaefer's flashcard.el from my ../emacs directory. I then grabbed the dictionary file that Kanji Gold couldn't recognized, replaced [ with : to get flashcard to recognize it without problems, then set up a deck for him. I tweaked the default faces a bit--they're horrible on light-colored displays. I copied the suggested feedback config and explained the pigeonhole method to him. I tweaked the checking function so that it checked for substrings and treated empty input as a definitely incorrect answer. He wanted the answers displayed all the time, so I coded that in as well.

The initial word list was too big, so I copied 9 words and put them into a file, then imported them into a deck. Later, when he finishes this deck, I'll show him how to create another colon file and import it. I'll also ask him if he wants to tweak the number of compartments.

He's asked me if I can get YM working in the text editor as well. I'm currently tunneled through Richi's host, but I think I can open a local tunnel for him as well, if he feels like using ERC. 'course, normal YM just might work, and chances are there's a YM-specific client somewhere in Emacs.

I've made no efforts to hide Emacs' complexity. I lean over and drop into Lisp code in front of him because I want him to have a working environment up and running as soon as possible. Who knows? Maybe he'll use Emacs even after the internship. =)

He looks like he's having fun, and certainly appreciates the fact that I can hack the editor to fit how he wants to do things. He wants to match the readings, too, which means I'll need to figure out how leim works under Windows. I'll do that on Monday.

3. Emacs for Authors: 12:54

http://www.therandymon.com/papers/emacs-for-writers.pdf

A book writer has written a guide on how to use Emacs in lieu of mainstream word processors. Check it out!

Post from R. Wood on comp.emacs

2. two-mode-mode: Multiple modes in one Emacs buffer: 12:50

two-mode-mode allows you to switch between two major modes in a single buffer. You can find it at http://www.dedasys.com/freesoftware/files/two-mode-mode.el If you need to deal with more modes, check out Multiple Major Modes at http://mmm-mode.sourceforge.net .

1. xtla goodness ([[EmacsTips#note19][EmacsTips:19]]"[[emacs]]) : 18:42

Categories: None -- Permalink
I used xtla to browse my TLA archives today. xtla's bookmarks and missing patch summary made merging missing patches much easier. I used m to mark interesting patches and . r to replay the marked patches. Great stuff.

In related news, I'll really need to migrate the archive. At 98414 characters, our ChangeLog is now 1/5 of the size of the source code (457478 bytes). Dev's changelog is much bigger--147672 bytes.

Previous day | Next day

I'd love to hear about any questions, comments, suggestions or links that you might have. Your comments will not be posted on this website immediately, but will be e-mailed to me first. You can use this form to get in touch with me, or e-mail me at [email protected] .

Page: emacs
Updated: 2005-07-1011:35:5911:35:59-0400
NOTE: ANTI-SPAM MEASURE NOW IN PLACE. Please answer the following question with the right number in order to send me your comment.
What is two minus one? (hint: one ;) )
Name:
E-mail:
URL:
Comments: