用Org-mode实践《奇特的一生》

《奇特的一生》

《奇特的一生》是一本传记体小说,描述了俄罗斯科学家柳比歇夫如何运用 时间统计法 度过了他的一生。所谓时间统计法,说起来实在不起眼:统计自己做 每件事情 的纯时间, “工作中的任何间歇,我都要创除。我计算的是纯时间,”柳比歇夫写道,“纯时间要比毛时间少得多。所谓毛时间,就是你花在这项工作上的时间。 ” 柳比歇夫典型的时间统计日记是这样的:

乌里扬诺夫斯克。一九六四年四月八日。
分类昆虫学:鉴定袋蛾,结束——二小时二十分。
开始写关于袋蛾的报告——一小时五分(1.0)。
附加工作:给达维陀娃和布里亚赫尔写信,六页——三小时二十分(0.5)。
路途往返——0.5。
休息——剃胡子。《乌里扬诺夫斯克真理报》——十五分,
《消息报》——十分,
《文学报》——二十分;
阿·托尔斯泰的《吸血鬼》,六十六页——一小时三十分。
听里姆斯基-柯萨科夫的沙皇的未婚妻。
基本工作合计——六小时四十五分。”

其中记录了一天当中各项活动花费的“纯时间”,最后合计了第一类工作(科研活动)的时间。此外,每月和每年,柳比歇夫都对自己的时间统计日记进行进一步汇总统计,将自己时间的花费清楚明了地列于眼前。正是这样一个简单的方法帮助柳比歇夫实现了“奇特的一生”。一般,柳比歇夫每天能有七、八个小时的 纯学术工作时间,最高纪录是十一小时三十分。

我们每个人一天的纯工作时间到底有多少呢?约摸估算一番,我想能达到柳比歇夫这个数字的少之又少。两小时?三小时?事实上,因为人对自己时间利用的估计是如此的不靠谱,实际的纯工作时间可能比你想像得还要少得多。物理学家Michael Nielsen在一篇文章中写道:

一个同事曾告诉我,他的一个朋友在一段时间里用码表记录自己每周做研究工作的时间。令他震惊的是,除去每天当中他陷入的所有其他事情–中断,邮件,上网,电话,没成效的会议,和朋友聊天等,他平均每天只用了半小时在研究工作上。如果说这是许多研究者的典型情况,我并不对此感到意外。

彼德.德鲁克在《卓有成效的管理者》中也谈到:

某公司的董事长,十分肯定地对我说他的时间大致分成三个部分:1/3用于与公司高级管理人员研讨业务;1/3用于接待重要客户;其余1/3则用于参加各种社会活动。但是,等实际记录了六个星期之后,跟他原来的估计比较,结果发现在上述三个方面,他几乎没花什么时间……这份时间记录是由他的秘书记下来的,当秘书把记录送给他看时,他简直一点儿都不能相信。

因此,看似简单的时间统计法恰恰蕴含了深刻的力量。唯有通过实际的统计数字,我们才能自知。我刚知道这个方法时,试过在纸上记录做每件事的起止时间,但总觉得统计起来麻烦。但事实上,不做统计,根本没法发挥这个方法的真正效果。

Org-mode

Org-mode是编辑器Emacs下的一个模式(现在也有了一个Vim下的克隆)。Emacs是一个古老的编辑器,以往只在部分程序员当中流行,因为可定制性极高,可用大量快捷键操作。虽然使用既有的配置文件入门并不困难,但我绝不认为这个编辑器适合所有人,也不认为它会流行起来。本文的方法只适合对电脑技术有一定好奇心和探索精神的人,对于Emacs和Org-mode的基础知识,可参考yibie的文章及相关参考资料。如果你是程序员,即使对Emacs没兴趣,不妨也可读下去,最后可用自己喜欢的方式实现一个类似的系统。

Org-mode最初被设计用于记录大纲式笔记,和Markdown语言类似,在纯文本的基础上加上一些简单的语法来实现排版,比如用*来表示各级标题:

 
* 大标题
** 中标题
*** 小标题

随着系统的进化,不断开发出TODO,行程表,导出等强大的功能。现在的Org-mode集笔记、计划和写作功能于一身,这篇Blog就是在Org-mode下写成后直接发布到Wordpress中的(使用org2blog)。

todo.org

由于Org-mode超强的可定制性,几乎所有的时间管理流程都可以通过它实现。在网上也可以找到很多使用Org-mode实现GTD的文章。这里介绍的是我自己使用的方法。我自己只使用一个todo.org文件来管理及记录任务。

http://www.mastermindcn.com/wp-content/uploads/2012/02/wpid-todo_basic_outline.png

这就是我的todo.org文件大纲,在Emacs中打开后,移到每个大标题(*)后,按Tab可展开。

http://www.mastermindcn.com/wp-content/uploads/2012/02/wpid-todo_fold_two3.png

以上就是展开Projects及Reading两个分支后的结果。其中Projects项目中有四个二级标题(**),我将Technical English这个子项目展开,得到其中的三级标题(***)。这基本是一个已经完成的项目,所以里面的状态都是DONE了。Reading分支下的5个二级标题(**)都是Todo状态,表示我正在读的书。

下面是对各个一级标题的介绍:

org-mode configuration
主要是对todo.org整个文件的一些配置。
Inbox
GTD中Inbox的概念,快速输入临时事件或突然的想法,释放头脑内存。
Tasks
相当于GTD中的Todo-list,即那些一步就能完成的零散事件,如写这篇文章。
Projects
各种需要多个步骤完成的项目,每个项目在里面是二级标题(**),由各种三级TODO标题(***)组成。当然也可能对项目进行再细分。
Routines
一些每天都要进行的习惯。使用Org-mode可以很好地进行重复。
Remind
需要提醒的事情,比如某个时间点上课。
Reading
正在看的书。
Weekly Review
每周要结束时进行Review,其中有一些代码段,用于进行当周的时间统计。

日程表

为了使用Org-mode的日程表功能,首先需要把todo.org加入到日程表文件中,在配置文件(~/.emacs)中写入:

; 将~/org/todo.org替换为todo.org实际路径
(setq org-agenda-files (list "~/org/todo.org"))

再绑定Org-mode日程表的快捷键。

(global-set-key "\C-ca" 'org-agenda)

这样按Ctrl-c a a就可以查看Org-mode的周日程表了。不过我一般看当天的,所以自己定制了一个Day Agenda。

http://www.mastermindcn.com/wp-content/uploads/2012/02/wpid-org_agenda_day.png

有关Org-mode Agenda的具体用法可参考其他文章或官网的手册。简而言之,你可以设置TODO项的Schedule,该项在当日就会显示。我一般在每天开始浏览一下所有的TODO项目,将今天需要完成的任务Schedule一下。这样一天中剩下的时间只要看Day Agenda就行了。

计时

本文的重点是时间统计,我推崇Org-mode,最重要的一点即是它能够很方便地进行时间统计。在todo.org中,移到一个条目上,按Ctrl-c Ctrl-x Ctrl-i即可对该条目开始计时,Ctrl-c Ctrl-x Ctrl-o停止当前计时。如果在Agenda中,移到条目按I(大写)即可对该条目开始计时,O(大写)即可停止计时。对于已经对这些基本功能熟练的用户,还可使用以下技巧:

  • 用global-set-key把org-clock-in, org-clock-out, org-clock-cancel这三个功能绑定到全局功能下,这样就不用专门跑到一个Org-mode的buffer里计时了。
  • 加前缀(Ctrl-u)再按Ctrl-c Ctrl-x Ctrl-i,可快速查看最近计时项目,进行快速计时。

计时的重点是只计 纯工作时间 ,只要没在工作就停止计时。对于不在电脑时候的工作,可以先在纸上记录,电脑在手时再补录到todo.org的相应时间记录中。

我在todo.org的头部加入了#+PROPERTY: CLOCK_INTO_DRAWER t,这样,时间记录会放到一个名为LOGBOOK的抽屉(drawer)中,平时看项目时并不展开,所以记录再多也不影响日常操作。

http://www.mastermindcn.com/wp-content/uploads/2012/02/wpid-todo_drawer.png

Tag分类

为了便于统计,使统计信息有意义,有必要对任务进行分类。我用Tag实现分类,可在todo.org的文件头部写下该文件支持的Tag,如:

#+TAGS: { ACADEMIC(a) ENGLISH(e) SCHOOL(s) LEARNING(l) OUTPUT(p) OTHER(o) }

其中括号内代表简写(快捷键),对每个TODO任务,按Ctrl-c Ctrl-q即可赋符Tag,这样就完成了任务的分类。默认设置中,Tag是可以继承的,即子标题自动包含父标题中含有的Tag。

统计

在Day Agenda中,按R(大写)可打开Clockreport,查看当日计时统计,效果如下图所示。

http://www.mastermindcn.com/wp-content/uploads/2012/02/wpid-org_agenda_clockreport.png

不过这样有时略显繁琐,而且体现不出各类任务上所花的时间,为了实现类似柳比歇夫“第一类工作”时间类似的统计,我写了下面这个函数(org-clock-sum-today-by-tags)。

;; used by org-clock-sum-today-by-tags
(defun filter-by-tags ()
   (let ((head-tags (org-get-tags-at)))
     (member current-tag head-tags)))

(defun org-clock-sum-today-by-tags (timerange &optional tstart tend noinsert)
  (interactive "P")
  (let* ((timerange-numeric-value (prefix-numeric-value timerange))
         (files (org-add-archive-files (org-agenda-files)))
         (include-tags '("ACADEMIC" "ENGLISH" "SCHOOL"
                         "LEARNING" "OUTPUT" "OTHER"))
         (tags-time-alist (mapcar (lambda (tag) `(,tag . 0)) include-tags))
         (output-string "")
         (tstart (or tstart
                     (and timerange (equal timerange-numeric-value 4) (- (org-time-today) 86400))
                     (and timerange (equal timerange-numeric-value 16) (org-read-date nil nil nil "Start Date/Time:"))
                     (org-time-today)))
         (tend (or tend
                   (and timerange (equal timerange-numeric-value 16) (org-read-date nil nil nil "End Date/Time:"))
                   (+ tstart 86400)))
         h m file item prompt donesomething)
    (while (setq file (pop files))
      (setq org-agenda-buffer (if (file-exists-p file)
                                  (org-get-agenda-file-buffer file)
                                (error "No such file %s" file)))
      (with-current-buffer org-agenda-buffer
        (dolist (current-tag include-tags)
          (org-clock-sum tstart tend 'filter-by-tags)
          (setcdr (assoc current-tag tags-time-alist)
                  (+ org-clock-file-total-minutes (cdr (assoc current-tag tags-time-alist)))))))
    (while (setq item (pop tags-time-alist))
      (unless (equal (cdr item) 0)
        (setq donesomething t)
        (setq h (/ (cdr item) 60)
              m (- (cdr item) (* 60 h)))
        (setq output-string (concat output-string (format "[-%s-] %.2d:%.2d\n" (car item) h m)))))
    (unless donesomething
      (setq output-string (concat output-string "[-Nothing-] Done nothing!!!\n")))
    (unless noinsert
        (insert output-string))
    output-string))

并把它绑定到Ctrl-c Ctrl-x t按键上。可在当前光标处插入对当天各个分类进行时间统计(代码中的include-tags变量包含了参与统计的tags,可自行更改)。默认的效果是将当天非零的各分类时间统计显示出来。如:

[-ACADEMIC-] 01:24
[-OTHER-] 02:24

如果需要统计的是前一天的,可加前缀(Ctrl-u);如果要指定时间范围,可加两次前缀(Ctrl-u Ctrl-u)。这个函数在周统计中还会用到。我在一个日记文件中会插入每天的Clockreport以及上述分类统计。

周统计

周统计中我查看的内容之一还是Clockreport,在todo.org中任意位置(我是在Weekly Review下)按Ctrl-c Ctrl-x Ctrl-r即可插入一个Clockreport,不过参数需要做一些修改,我使用的是:

#+BEGIN: clocktable :maxlevel 5 :scope agenda-with-archives :block thisweek :fileskip0 t :indent t
#+END:

改动之后,在BEGIN的位置再按一下Ctrl-c Ctrl-c就可以刷新报表了。同时我还查看每个tag的时间报表。参数和上面是一样的,最后加一个类似:tags “ACADEMIC”的参数即可。这些Clockreport,只需插入一次,以后每周用Ctrl-c Ctrl-c刷新即可。

同样的,这样的信息有时候太繁琐了,对于简报,我的做法是在todo.org中嵌入一段如下的Lisp代码:

#+BEGIN_SRC emacs-lisp :results value
(setq week-range (org-clock-special-range 'thisweek nil t))
(org-clock-sum-today-by-tags nil (nth 0 week-range) (nth 1 week-range) t)
#+END_SRC

同时,在配置文件中加入如下语句,使得在Org-mode可直接Evaluate上面的代码。

(org-babel-do-load-languages
    'org-babel-load-languages '((emacs-lisp . t)))

这样,在刚才代码段的位置按Ctrl-c Ctrl-c即可获得各Tag的周时间统计。效果如下所示:

http://www.mastermindcn.com/wp-content/uploads/2012/02/wpid-todo_weekly_review.png

posted on 2013-02-28 21:24  毛小娃  阅读(536)  评论(0编辑  收藏  举报

导航