Browse Source

org-agenda: rework ndays and span handling

* org-agenda.el (org-agenda-custom-commands-local-options):
Allow org-agenda-span to be a symbol.
(org-agenda-ndays): Make obsolete.
(org-agenda-span): New variable superseding org-agenda-ndays.
(org-agenda-menu): Use org-agenda-current-span.
(org-agenda-current-span): New local variable storing current
span.
(org-agenda-list): Take a span instead of ndays as argument.
This function is now responsible for computing the ndays based
on span.
(org-agenda-ndays-to-span): Return span only if number of days
really matches.
(org-agenda-span-to-ndays): New function.
(org-agenda-manipulate-query): Use org-agenda-compute-starting-span.
(org-agenda-goto-today): Use org-agenda-compute-starting-span.
(org-agenda-later): Do not give compute a new span, use the
current one.
(org-agenda-day-view, org-agenda-week-view)
(org-agenda-month-view, org-agenda-year-view): Stop touching
org-agenda-ndays.
(org-agenda-change-time-span): Only compute starting-span.
(org-agenda-compute-starting-span): New function derived from
the old org-agenda-compute-time-span.
(org-agenda-set-mode-name): Compute mode based on
org-agenda-current-span.
(org-agenda-span-name): New function.

* org-mouse.el: Replace Replace org-agenda-ndays by
org-agenda-current-span.

* org.texi, orgguide.texi: Replace org-agenda-ndays by
org-agenda-span. Add a paragraph about org-agenda-span and say that
org-agenda-ndays is now deprecated.

This patch is pretty huge, so I'll give a bit of context about it.

I'm weird, but I used org-agenda-ndays set to 14. Unfortunately, this
settings was interpreted as a month view. Pressing 'f' key to see later,
would show me the next month, which was not at all what I wanted.

On the same idea, day view or week view would change my org-agenda-ndays
settings, which I think is not a good idea. Changing user setting is *bad*.
:-)

So I rewrote the things this way:
- Rename org-agenda-span to org-agenda-current-span
 Which has the same meaning has before, except it can be numeric.
- Rename org-agenda-ndays to org-agenda-span
 I think the name is better choosen. You can set it to a symbol instead of
 only a numeric value. That means you can set it to 'month and it will show
 you the number of days of the current month in your agenda. Better than
 30. But you can still set it to 30, or 31, or whatever you want.
- Do not change org-agenda-span. Never.
- Use org-agenda-current-span for navigation.
 That means if you press 'f', it will shows you really the next
 org-agenda-current-span ndays, and not something based on "I think you
 want a weekly view".
Julien Danjou 14 years ago
parent
commit
0d0edd6d21
4 changed files with 152 additions and 122 deletions
  1. 13 8
      doc/org.texi
  2. 3 3
      doc/orgguide.texi
  3. 134 109
      lisp/org-agenda.el
  4. 2 2
      lisp/org-mouse.el

+ 13 - 8
doc/org.texi

@@ -6966,16 +6966,22 @@ paper agenda, showing all the tasks for the current week or day.
 @table @kbd
 @table @kbd
 @cindex org-agenda, command
 @cindex org-agenda, command
 @orgcmd{C-c a a,org-agenda-list}
 @orgcmd{C-c a a,org-agenda-list}
-@vindex org-agenda-ndays
 Compile an agenda for the current week from a list of Org files.  The agenda
 Compile an agenda for the current week from a list of Org files.  The agenda
 shows the entries for each day.  With a numeric prefix@footnote{For backward
 shows the entries for each day.  With a numeric prefix@footnote{For backward
 compatibility, the universal prefix @kbd{C-u} causes all TODO entries to be
 compatibility, the universal prefix @kbd{C-u} causes all TODO entries to be
 listed before the agenda.  This feature is deprecated, use the dedicated TODO
 listed before the agenda.  This feature is deprecated, use the dedicated TODO
 list, or a block agenda instead (@pxref{Block agenda}).}  (like @kbd{C-u 2 1
 list, or a block agenda instead (@pxref{Block agenda}).}  (like @kbd{C-u 2 1
-C-c a a}) you may set the number of days to be displayed (see also the
-variable @code{org-agenda-ndays})
+C-c a a}) you may set the number of days to be displayed.
 @end table
 @end table
 
 
+@vindex org-agenda-span
+@vindex org-agenda-ndays
+The default number of days displayed in the agenda is set by the variable
+@code{org-agenda-span} (or the obsolete @code{org-agenda-ndays}).  This
+variable can be set to any number of days you want to see by default in the
+agenda, or to a span name, such a @code{day}, @code{week}, @code{month} or
+@code{year}.
+
 Remote editing from the agenda buffer means, for example, that you can
 Remote editing from the agenda buffer means, for example, that you can
 change the dates of deadlines and appointments from the agenda buffer.
 change the dates of deadlines and appointments from the agenda buffer.
 The commands available in the Agenda buffer are listed in @ref{Agenda
 The commands available in the Agenda buffer are listed in @ref{Agenda
@@ -7621,10 +7627,9 @@ argument as well.  For example, @kbd{200712 w} will jump to week 12 in
 be mapped to the interval 1938-2037.
 be mapped to the interval 1938-2037.
 @c
 @c
 @orgcmd{f,org-agenda-later}
 @orgcmd{f,org-agenda-later}
-@vindex org-agenda-ndays
-Go forward in time to display the following @code{org-agenda-ndays} days.
+Go forward in time to display the following @code{org-agenda-current-span} days.
 For example, if the display covers a week, switch to the following week.
 For example, if the display covers a week, switch to the following week.
-With prefix arg, go forward that many times @code{org-agenda-ndays} days.
+With prefix arg, go forward that many times @code{org-agenda-current-span} days.
 @c
 @c
 @orgcmd{b,org-agenda-earlier}
 @orgcmd{b,org-agenda-earlier}
 Go backward in time to display earlier dates.
 Go backward in time to display earlier dates.
@@ -8369,7 +8374,7 @@ or, if you need to modify some parameters@footnote{Quoting depends on the
 system you use, please check the FAQ for examples.}
 system you use, please check the FAQ for examples.}
 @example
 @example
 emacs -eval '(org-batch-store-agenda-views                      \
 emacs -eval '(org-batch-store-agenda-views                      \
-              org-agenda-ndays 30                               \
+              org-agenda-span month                             \
               org-agenda-start-day "2007-11-01"                 \
               org-agenda-start-day "2007-11-01"                 \
               org-agenda-include-diary nil                      \
               org-agenda-include-diary nil                      \
               org-agenda-files (quote ("~/org/project.org")))'  \
               org-agenda-files (quote ("~/org/project.org")))'  \
@@ -14033,7 +14038,7 @@ You may also modify parameters on the fly like this:
 @example
 @example
 emacs -batch -l ~/.emacs                                      \
 emacs -batch -l ~/.emacs                                      \
    -eval '(org-batch-agenda "a"                               \
    -eval '(org-batch-agenda "a"                               \
-            org-agenda-ndays 30                               \
+            org-agenda-span month                             \
             org-agenda-include-diary nil                      \
             org-agenda-include-diary nil                      \
             org-agenda-files (quote ("~/org/project.org")))'  \
             org-agenda-files (quote ("~/org/project.org")))'  \
    | lpr
    | lpr

+ 3 - 3
doc/orgguide.texi

@@ -1931,9 +1931,9 @@ Delete other windows.
 Switch to day/week view. 
 Switch to day/week view. 
 @c
 @c
 @item f @r{and} b
 @item f @r{and} b
-Go forward/backward in time to display the following @code{org-agenda-ndays}
-days.  For example, if the display covers a week, switch to the
-following/previous week.
+Go forward/backward in time to display the following
+@code{org-agenda-current-span} days.  For example, if the display covers a
+week, switch to the following/previous week.
 @c
 @c
 @item .
 @item .
 Go to today.
 Go to today.

+ 134 - 109
lisp/org-agenda.el

@@ -242,8 +242,12 @@ you can \"misuse\" it to also add other text to the header.  However,
 		  (const org-agenda-prefix-format :value "  %-12:c%?-12t% s")
 		  (const org-agenda-prefix-format :value "  %-12:c%?-12t% s")
 		  (string))
 		  (string))
 	    (list :tag "Number of days in agenda"
 	    (list :tag "Number of days in agenda"
-		  (const org-agenda-ndays)
-		  (integer :value 1))
+		  (const org-agenda-span)
+		  (choice (const :tag "Day" 'day)
+			  (const :tag "Week" 'week)
+			  (const :tag "Month" 'month)
+			  (const :tag "Year" 'year)
+			  (integer :tag "Custom")))
 	    (list :tag "Fixed starting date"
 	    (list :tag "Fixed starting date"
 		  (const org-agenda-start-day)
 		  (const org-agenda-start-day)
 		  (string :value "2007-11-01"))
 		  (string :value "2007-11-01"))
@@ -888,12 +892,25 @@ option will be ignored."
   :group 'org-agenda-windows
   :group 'org-agenda-windows
   :type 'boolean)
   :type 'boolean)
 
 
-(defcustom org-agenda-ndays 7
-  "Number of days to include in overview display.
+(defcustom org-agenda-ndays nil
+   "Number of days to include in overview display.
 Should be 1 or 7.
 Should be 1 or 7.
+Obsolete, see `org-agenda-span'."
+   :group 'org-agenda-daily/weekly
+   :type 'integer)
+
+(make-obsolete-variable 'org-agenda-ndays 'org-agenda-span "24.1")
+
+(defcustom org-agenda-span 'week
+  "Number of days to include in overview display.
+Can be day, week, month, year, or any number of days.
 Custom commands can set this variable in the options section."
 Custom commands can set this variable in the options section."
   :group 'org-agenda-daily/weekly
   :group 'org-agenda-daily/weekly
-  :type 'integer)
+  :type '(choice (const :tag "Day" day)
+		 (const :tag "Week" week)
+		 (const :tag "Month" month)
+		 (const :tag "Year" year)
+		 (integer :tag "Custom")))
 
 
 (defcustom org-agenda-start-on-weekday 1
 (defcustom org-agenda-start-on-weekday 1
   "Non-nil means start the overview always on the specified weekday.
   "Non-nil means start the overview always on the specified weekday.
@@ -1825,19 +1842,19 @@ The following commands are available:
     ("View"
     ("View"
      ["Day View" org-agenda-day-view
      ["Day View" org-agenda-day-view
       :active (org-agenda-check-type nil 'agenda)
       :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (equal org-agenda-ndays 1)
+      :style radio :selected (eq org-agenda-current-span 'day)
       :keys "v d  (or just d)"]
       :keys "v d  (or just d)"]
      ["Week View" org-agenda-week-view
      ["Week View" org-agenda-week-view
       :active (org-agenda-check-type nil 'agenda)
       :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (equal org-agenda-ndays 7)
+      :style radio :selected (eq org-agenda-current-span 'week)
       :keys "v w  (or just w)"]
       :keys "v w  (or just w)"]
      ["Month View" org-agenda-month-view
      ["Month View" org-agenda-month-view
       :active (org-agenda-check-type nil 'agenda)
       :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (member org-agenda-ndays '(28 29 30 31))
+      :style radio :selected (eq org-agenda-current-span 'month)
       :keys "v m"]
       :keys "v m"]
      ["Year View" org-agenda-year-view
      ["Year View" org-agenda-year-view
       :active (org-agenda-check-type nil 'agenda)
       :active (org-agenda-check-type nil 'agenda)
-      :style radio :selected (member org-agenda-ndays '(365 366))
+      :style radio :selected (eq org-agenda-current-span 'year)
       :keys "v y"]
       :keys "v y"]
      "--"
      "--"
      ["Include Diary" org-agenda-toggle-diary
      ["Include Diary" org-agenda-toggle-diary
@@ -3323,7 +3340,8 @@ When EMPTY is non-nil, also include days without any entries."
 (defvar org-agenda-last-arguments nil
 (defvar org-agenda-last-arguments nil
   "The arguments of the previous call to `org-agenda'.")
   "The arguments of the previous call to `org-agenda'.")
 (defvar org-starting-day nil) ; local variable in the agenda buffer
 (defvar org-starting-day nil) ; local variable in the agenda buffer
-(defvar org-agenda-span nil) ; local variable in the agenda buffer
+(defvar org-agenda-current-span nil
+  "The current span used in the agenda view.") ; local variable in the agenda buffer
 (defvar org-include-all-loc nil) ; local variable
 (defvar org-include-all-loc nil) ; local variable
 
 
 (defvar org-agenda-entry-types '(:deadline :scheduled :timestamp :sexp)
 (defvar org-agenda-entry-types '(:deadline :scheduled :timestamp :sexp)
@@ -3360,7 +3378,7 @@ somewhat less efficient) way of determining what is included in
 the daily/weekly agenda, see `org-agenda-skip-function'.")
 the daily/weekly agenda, see `org-agenda-skip-function'.")
 
 
 ;;;###autoload
 ;;;###autoload
-(defun org-agenda-list (&optional include-all start-day ndays)
+(defun org-agenda-list (&optional include-all start-day span)
   "Produce a daily/weekly view from all files in variable `org-agenda-files'.
   "Produce a daily/weekly view from all files in variable `org-agenda-files'.
 The view will be for the current day or week, but from the overview buffer
 The view will be for the current day or week, but from the overview buffer
 you will be able to go to other days/weeks.
 you will be able to go to other days/weeks.
@@ -3371,35 +3389,36 @@ This feature is considered obsolete, please use the TODO list or a block
 agenda instead.
 agenda instead.
 
 
 With a numeric prefix argument in an interactive call, the agenda will
 With a numeric prefix argument in an interactive call, the agenda will
-span INCLUDE-ALL days.  Lisp programs should instead specify NDAYS to change
-the number of days.  NDAYS defaults to `org-agenda-ndays'.
+span INCLUDE-ALL days.  Lisp programs should instead specify SPAN to change
+the number of days.  SPAN defaults to `org-agenda-span'.
 
 
 START-DAY defaults to TODAY, or to the most recent match for the weekday
 START-DAY defaults to TODAY, or to the most recent match for the weekday
 given in `org-agenda-start-on-weekday'."
 given in `org-agenda-start-on-weekday'."
   (interactive "P")
   (interactive "P")
   (if (and (integerp include-all) (> include-all 0))
   (if (and (integerp include-all) (> include-all 0))
-      (setq ndays include-all include-all nil))
-  (setq ndays (or ndays org-agenda-ndays)
-	start-day (or start-day org-agenda-start-day))
+      (setq span include-all include-all nil))
+  (setq start-day (or start-day org-agenda-start-day))
   (if org-agenda-overriding-arguments
   (if org-agenda-overriding-arguments
       (setq include-all (car org-agenda-overriding-arguments)
       (setq include-all (car org-agenda-overriding-arguments)
 	    start-day (nth 1 org-agenda-overriding-arguments)
 	    start-day (nth 1 org-agenda-overriding-arguments)
-	    ndays (nth 2 org-agenda-overriding-arguments)))
+	    span (nth 2 org-agenda-overriding-arguments)))
   (if (stringp start-day)
   (if (stringp start-day)
       ;; Convert to an absolute day number
       ;; Convert to an absolute day number
       (setq start-day (time-to-days (org-read-date nil t start-day))))
       (setq start-day (time-to-days (org-read-date nil t start-day))))
-  (setq org-agenda-last-arguments (list include-all start-day ndays))
+  (setq org-agenda-last-arguments (list include-all start-day span))
   (org-compile-prefix-format 'agenda)
   (org-compile-prefix-format 'agenda)
   (org-set-sorting-strategy 'agenda)
   (org-set-sorting-strategy 'agenda)
-  (let* ((org-agenda-start-on-weekday
-	  (if (or (equal ndays 7) (and (null ndays) (equal 7 org-agenda-ndays)))
-	      org-agenda-start-on-weekday nil))
-	 (thefiles (org-agenda-files nil 'ifmode))
-	 (files thefiles)
+  (let* ((span (org-agenda-ndays-to-span (or span org-agenda-ndays org-agenda-span)))
 	 (today (org-agenda-today))
 	 (today (org-agenda-today))
 	 (sd (or start-day today))
 	 (sd (or start-day today))
+	 (ndays (org-agenda-span-to-ndays span sd))
+	 (org-agenda-start-on-weekday
+	  (if (eq ndays 7)
+	      org-agenda-start-on-weekday))
+	 (thefiles (org-agenda-files nil 'ifmode))
+	 (files thefiles)
 	 (start (if (or (null org-agenda-start-on-weekday)
 	 (start (if (or (null org-agenda-start-on-weekday)
-			(< org-agenda-ndays 7))
+			(< ndays 7))
 		    sd
 		    sd
 		  (let* ((nt (calendar-day-of-week
 		  (let* ((nt (calendar-day-of-week
 			      (calendar-gregorian-from-absolute sd)))
 			      (calendar-gregorian-from-absolute sd)))
@@ -3409,24 +3428,19 @@ given in `org-agenda-start-on-weekday'."
 	 (day-numbers (list start))
 	 (day-numbers (list start))
 	 (day-cnt 0)
 	 (day-cnt 0)
 	 (inhibit-redisplay (not debug-on-error))
 	 (inhibit-redisplay (not debug-on-error))
-	 s e rtn rtnall file date d start-pos end-pos todayp nd
+	 s e rtn rtnall file date d start-pos end-pos todayp
 	 clocktable-start clocktable-end filter)
 	 clocktable-start clocktable-end filter)
     (setq org-agenda-redo-command
     (setq org-agenda-redo-command
-	  (list 'org-agenda-list (list 'quote include-all) start-day ndays))
-    ;; Make the list of days
-    (setq ndays (or ndays org-agenda-ndays)
-	  nd ndays)
-    (while (> ndays 1)
-      (push (1+ (car day-numbers)) day-numbers)
-      (setq ndays (1- ndays)))
+	  (list 'org-agenda-list (list 'quote include-all) start-day (list 'quote span)))
+    (dotimes (n (1- ndays))
+      (push (1+ (car day-numbers)) day-numbers))
     (setq day-numbers (nreverse day-numbers))
     (setq day-numbers (nreverse day-numbers))
     (setq clocktable-start (car day-numbers)
     (setq clocktable-start (car day-numbers)
 	  clocktable-end (1+ (or (org-last day-numbers) 0)))
 	  clocktable-end (1+ (or (org-last day-numbers) 0)))
     (org-prepare-agenda "Day/Week")
     (org-prepare-agenda "Day/Week")
     (org-set-local 'org-starting-day (car day-numbers))
     (org-set-local 'org-starting-day (car day-numbers))
     (org-set-local 'org-include-all-loc include-all)
     (org-set-local 'org-include-all-loc include-all)
-    (org-set-local 'org-agenda-span
-		   (org-agenda-ndays-to-span nd))
+    (org-set-local 'org-agenda-current-span (org-agenda-ndays-to-span span))
     (when (and (or include-all org-agenda-include-all-todo)
     (when (and (or include-all org-agenda-include-all-todo)
 	       (member today day-numbers))
 	       (member today day-numbers))
       (setq files thefiles
       (setq files thefiles
@@ -3454,7 +3468,7 @@ given in `org-agenda-start-on-weekday'."
 	(if org-agenda-overriding-header
 	(if org-agenda-overriding-header
 	    (insert (org-add-props (copy-sequence org-agenda-overriding-header)
 	    (insert (org-add-props (copy-sequence org-agenda-overriding-header)
 			nil 'face 'org-agenda-structure) "\n")
 			nil 'face 'org-agenda-structure) "\n")
-	  (insert (capitalize (symbol-name (org-agenda-ndays-to-span nd)))
+	  (insert (org-agenda-span-name span)
 		  "-agenda"
 		  "-agenda"
 		  (if (< (- d2 d1) 350)
 		  (if (< (- d2 d1) 350)
 		      (if (= w1 w2)
 		      (if (= w1 w2)
@@ -3519,7 +3533,7 @@ given in `org-agenda-start-on-weekday'."
 	    (if rtnall (insert
 	    (if rtnall (insert
 			(org-finalize-agenda-entries
 			(org-finalize-agenda-entries
 			 (org-agenda-add-time-grid-maybe
 			 (org-agenda-add-time-grid-maybe
-			  rtnall nd todayp))
+			  rtnall ndays todayp))
 			"\n"))
 			"\n"))
 	    (put-text-property s (1- (point)) 'day d)
 	    (put-text-property s (1- (point)) 'day d)
 	    (put-text-property s (1- (point)) 'org-day-cnt day-cnt))))
 	    (put-text-property s (1- (point)) 'org-day-cnt day-cnt))))
@@ -3560,7 +3574,31 @@ given in `org-agenda-start-on-weekday'."
     (message "")))
     (message "")))
 
 
 (defun org-agenda-ndays-to-span (n)
 (defun org-agenda-ndays-to-span (n)
-  (cond ((< n 7) 'day) ((= n 7) 'week) ((< n 32) 'month) (t 'year)))
+  "Return a span symbol for a span of N days, or N if none matches."
+  (cond ((symbolp n) n)
+	((= n 1) 'day)
+	((= n 7) 'week)
+	(t n)))
+
+(defun org-agenda-span-to-ndays (span start-day)
+  "Return ndays from SPAN starting at START-DAY."
+  (cond ((numberp span) span)
+	((eq span 'day) 1)
+	((eq span 'week) 7)
+	((eq span 'month)
+	 (let ((date (calendar-gregorian-from-absolute start-day)))
+	   (calendar-last-day-of-month (car date) (caddr date))))
+	((eq span 'year)
+	 (let ((date (calendar-gregorian-from-absolute start-day)))
+	   (if (calendar-leap-year-p (caddr date)) 366 365)))))
+
+(defun org-agenda-span-name (span)
+  "Return a SPAN name."
+  (if (null span)
+      ""
+    (if (symbolp span)
+	(capitalize (symbol-name span))
+      (format "%d days" span))))
 
 
 ;;; Agenda word search
 ;;; Agenda word search
 
 
@@ -6000,11 +6038,9 @@ Negative selection means regexp must not match for selection of an entry."
     (cond
     (cond
      (tdpos (goto-char tdpos))
      (tdpos (goto-char tdpos))
      ((eq org-agenda-type 'agenda)
      ((eq org-agenda-type 'agenda)
-      (let* ((sd (org-agenda-today))
-	     (comp (org-agenda-compute-time-span sd org-agenda-span))
+      (let* ((sd (org-agenda-compute-starting-span (org-agenda-today) (or org-agenda-ndays org-agenda-span)))
 	     (org-agenda-overriding-arguments org-agenda-last-arguments))
 	     (org-agenda-overriding-arguments org-agenda-last-arguments))
-	(setf (nth 1 org-agenda-overriding-arguments) (car comp))
-	(setf (nth 2 org-agenda-overriding-arguments) (cdr comp))
+	(setf (nth 1 org-agenda-overriding-arguments) sd)
 	(org-agenda-redo)
 	(org-agenda-redo)
 	(org-agenda-find-same-or-today-or-agenda)))
 	(org-agenda-find-same-or-today-or-agenda)))
      (t (error "Cannot find today")))))
      (t (error "Cannot find today")))))
@@ -6021,28 +6057,28 @@ Negative selection means regexp must not match for selection of an entry."
 With prefix ARG, go forward that many times the current span."
 With prefix ARG, go forward that many times the current span."
   (interactive "p")
   (interactive "p")
   (org-agenda-check-type t 'agenda)
   (org-agenda-check-type t 'agenda)
-  (let* ((span org-agenda-span)
+  (let* ((span org-agenda-current-span)
 	 (sd org-starting-day)
 	 (sd org-starting-day)
 	 (greg (calendar-gregorian-from-absolute sd))
 	 (greg (calendar-gregorian-from-absolute sd))
 	 (cnt (org-get-at-bol 'org-day-cnt))
 	 (cnt (org-get-at-bol 'org-day-cnt))
-	 greg2 nd)
+	 greg2)
     (cond
     (cond
      ((eq span 'day)
      ((eq span 'day)
-      (setq sd (+ arg sd) nd 1))
+      (setq sd (+ arg sd)))
      ((eq span 'week)
      ((eq span 'week)
-      (setq sd (+ (* 7 arg) sd) nd 7))
+      (setq sd (+ (* 7 arg) sd)))
      ((eq span 'month)
      ((eq span 'month)
       (setq greg2 (list (+ (car greg) arg) (nth 1 greg) (nth 2 greg))
       (setq greg2 (list (+ (car greg) arg) (nth 1 greg) (nth 2 greg))
 	    sd (calendar-absolute-from-gregorian greg2))
 	    sd (calendar-absolute-from-gregorian greg2))
-      (setcar greg2 (1+ (car greg2)))
-      (setq nd (- (calendar-absolute-from-gregorian greg2) sd)))
+      (setcar greg2 (1+ (car greg2))))
      ((eq span 'year)
      ((eq span 'year)
       (setq greg2 (list (car greg) (nth 1 greg) (+ arg (nth 2 greg)))
       (setq greg2 (list (car greg) (nth 1 greg) (+ arg (nth 2 greg)))
 	    sd (calendar-absolute-from-gregorian greg2))
 	    sd (calendar-absolute-from-gregorian greg2))
-      (setcar (nthcdr 2 greg2) (1+ (nth 2 greg2)))
-      (setq nd (- (calendar-absolute-from-gregorian greg2) sd))))
+      (setcar (nthcdr 2 greg2) (1+ (nth 2 greg2))))
+     (t
+      (setq sd (+ (* span arg) sd))))
     (let ((org-agenda-overriding-arguments
     (let ((org-agenda-overriding-arguments
-	   (list (car org-agenda-last-arguments) sd nd t)))
+	   (list (car org-agenda-last-arguments) sd span t)))
       (org-agenda-redo)
       (org-agenda-redo)
       (org-agenda-find-same-or-today-or-agenda cnt))))
       (org-agenda-find-same-or-today-or-agenda cnt))))
 
 
@@ -6085,7 +6121,6 @@ With prefix ARG, go backward that many times the current span."
   "Switch to daily view for agenda.
   "Switch to daily view for agenda.
 With argument DAY-OF-YEAR, switch to that day of the year."
 With argument DAY-OF-YEAR, switch to that day of the year."
   (interactive "P")
   (interactive "P")
-  (setq org-agenda-ndays 1)
   (org-agenda-change-time-span 'day day-of-year))
   (org-agenda-change-time-span 'day day-of-year))
 (defun org-agenda-week-view (&optional iso-week)
 (defun org-agenda-week-view (&optional iso-week)
   "Switch to daily view for agenda.
   "Switch to daily view for agenda.
@@ -6095,7 +6130,6 @@ week.  Any digits before this encode a year.  So 200712 means
 week 12 of year 2007.  Years in the range 1938-2037 can also be
 week 12 of year 2007.  Years in the range 1938-2037 can also be
 written as 2-digit years."
 written as 2-digit years."
   (interactive "P")
   (interactive "P")
-  (setq org-agenda-ndays 7)
   (org-agenda-change-time-span 'week iso-week))
   (org-agenda-change-time-span 'week iso-week))
 (defun org-agenda-month-view (&optional month)
 (defun org-agenda-month-view (&optional month)
   "Switch to monthly view for agenda.
   "Switch to monthly view for agenda.
@@ -6120,70 +6154,61 @@ written as 2-digit years."
   "Change the agenda view to SPAN.
   "Change the agenda view to SPAN.
 SPAN may be `day', `week', `month', `year'."
 SPAN may be `day', `week', `month', `year'."
   (org-agenda-check-type t 'agenda)
   (org-agenda-check-type t 'agenda)
-  (if (and (not n) (equal org-agenda-span span))
+  (if (and (not n) (equal org-agenda-current-span span))
       (error "Viewing span is already \"%s\"" span))
       (error "Viewing span is already \"%s\"" span))
   (let* ((sd (or (org-get-at-bol 'day)
   (let* ((sd (or (org-get-at-bol 'day)
 		org-starting-day))
 		org-starting-day))
-	 (computed (org-agenda-compute-time-span sd span n))
+	 (sd (org-agenda-compute-starting-span sd span n))
 	 (org-agenda-overriding-arguments
 	 (org-agenda-overriding-arguments
-	  (list (car org-agenda-last-arguments)
-		(car computed) (cdr computed) t)))
+	  (list (car org-agenda-last-arguments) sd span t)))
     (org-agenda-redo)
     (org-agenda-redo)
     (org-agenda-find-same-or-today-or-agenda))
     (org-agenda-find-same-or-today-or-agenda))
   (org-agenda-set-mode-name)
   (org-agenda-set-mode-name)
   (message "Switched to %s view" span))
   (message "Switched to %s view" span))
 
 
-(defun org-agenda-compute-time-span (sd span &optional n)
-  "Compute starting date and number of days for agenda.
+(defun org-agenda-compute-starting-span (sd span &optional n)
+  "Compute starting date for agenda.
 SPAN may be `day', `week', `month', `year'.  The return value
 SPAN may be `day', `week', `month', `year'.  The return value
 is a cons cell with the starting date and the number of days,
 is a cons cell with the starting date and the number of days,
 so that the date SD will be in that range."
 so that the date SD will be in that range."
   (let* ((greg (calendar-gregorian-from-absolute sd))
   (let* ((greg (calendar-gregorian-from-absolute sd))
 	 (dg (nth 1 greg))
 	 (dg (nth 1 greg))
 	 (mg (car greg))
 	 (mg (car greg))
-	 (yg (nth 2 greg))
-	 nd w1 y1 m1 thisweek)
+	 (yg (nth 2 greg)))
     (cond
     (cond
      ((eq span 'day)
      ((eq span 'day)
       (when n
       (when n
 	(setq sd (+ (calendar-absolute-from-gregorian
 	(setq sd (+ (calendar-absolute-from-gregorian
 		     (list mg 1 yg))
 		     (list mg 1 yg))
-		    n -1)))
-      (setq nd 1))
+		    n -1))))
      ((eq span 'week)
      ((eq span 'week)
       (let* ((nt (calendar-day-of-week
       (let* ((nt (calendar-day-of-week
 		  (calendar-gregorian-from-absolute sd)))
 		  (calendar-gregorian-from-absolute sd)))
 	     (d (if org-agenda-start-on-weekday
 	     (d (if org-agenda-start-on-weekday
 		    (- nt org-agenda-start-on-weekday)
 		    (- nt org-agenda-start-on-weekday)
-		  0)))
+		  0))
+	     y1)
 	(setq sd (- sd (+ (if (< d 0) 7 0) d)))
 	(setq sd (- sd (+ (if (< d 0) 7 0) d)))
 	(when n
 	(when n
 	  (require 'cal-iso)
 	  (require 'cal-iso)
-	  (setq thisweek (car (calendar-iso-from-absolute sd)))
 	  (when (> n 99)
 	  (when (> n 99)
 	    (setq y1 (org-small-year-to-year (/ n 100))
 	    (setq y1 (org-small-year-to-year (/ n 100))
 		  n (mod n 100)))
 		  n (mod n 100)))
 	  (setq sd
 	  (setq sd
 		(calendar-absolute-from-iso
 		(calendar-absolute-from-iso
 		 (list n 1
 		 (list n 1
-		       (or y1 (nth 2 (calendar-iso-from-absolute sd)))))))
-	(setq nd 7)))
+		       (or y1 (nth 2 (calendar-iso-from-absolute sd)))))))))
      ((eq span 'month)
      ((eq span 'month)
-      (when (and n (> n 99))
-	(setq y1 (org-small-year-to-year (/ n 100))
-	      n (mod n 100)))
-      (setq sd (calendar-absolute-from-gregorian
-		(list (or n mg) 1 (or y1 yg)))
-	    nd (- (calendar-absolute-from-gregorian
-		   (list (1+ (or n mg)) 1 (or y1 yg)))
-		  sd)))
+      (let (y1)
+	(when (and n (> n 99))
+	  (setq y1 (org-small-year-to-year (/ n 100))
+		n (mod n 100)))
+	(setq sd (calendar-absolute-from-gregorian
+		  (list (or n mg) 1 (or y1 yg))))))
      ((eq span 'year)
      ((eq span 'year)
       (setq sd (calendar-absolute-from-gregorian
       (setq sd (calendar-absolute-from-gregorian
-		(list 1 1 (or n yg)))
-	    nd (- (calendar-absolute-from-gregorian
-		   (list 1 1 (1+ (or n yg))))
-		  sd))))
-    (cons sd nd)))
+		(list 1 1 (or n yg))))))
+    sd))
 
 
 (defun org-agenda-next-date-line (&optional arg)
 (defun org-agenda-next-date-line (&optional arg)
   "Jump to the next line indicating a date in agenda buffer."
   "Jump to the next line indicating a date in agenda buffer."
@@ -6336,36 +6361,36 @@ When called with a prefix argument, include all archive files as well."
 (defun org-agenda-set-mode-name ()
 (defun org-agenda-set-mode-name ()
   "Set the mode name to indicate all the small mode settings."
   "Set the mode name to indicate all the small mode settings."
   (setq mode-name
   (setq mode-name
-	(concat "Org-Agenda"
-		(if (get 'org-agenda-files 'org-restrict) " []" "")
-		(if (equal org-agenda-ndays 1) " Day"    "")
-		(if (equal org-agenda-ndays 7) " Week"   "")
-		(if org-agenda-follow-mode     " Follow" "")
-		(if org-agenda-entry-text-mode " ETxt"   "")
-		(if org-agenda-include-diary   " Diary"  "")
-		(if org-agenda-include-deadlines " Ddl"  "")
-		(if org-agenda-use-time-grid   " Grid"   "")
-		(if (and (boundp 'org-habit-show-habits)
-			 org-habit-show-habits) " Habit"   "")
-		(if (consp org-agenda-show-log) " LogAll"
-		  (if org-agenda-show-log " Log" ""))
-		(if (or org-agenda-filter (get 'org-agenda-filter
-					       :preset-filter))
-		    (concat " {" (mapconcat
-				  'identity
-				  (append (get 'org-agenda-filter
-					       :preset-filter)
-					  org-agenda-filter) "") "}")
-		  "")
-		(if org-agenda-archives-mode
-		    (if (eq org-agenda-archives-mode t)
-			" Archives"
-		      (format " :%s:" org-archive-tag))
-		  "")
-		(if org-agenda-clockreport-mode
-		    (if (eq org-agenda-clockreport-mode 'with-filter)
-			" Clock{}" " Clock")
-		  "")))
+	(list "Org-Agenda"
+	      (if (get 'org-agenda-files 'org-restrict) " []" "")
+	      " "
+	      '(:eval (org-agenda-span-name org-agenda-current-span))
+	      (if org-agenda-follow-mode     " Follow" "")
+	      (if org-agenda-entry-text-mode " ETxt"   "")
+	      (if org-agenda-include-diary   " Diary"  "")
+	      (if org-agenda-include-deadlines " Ddl"  "")
+	      (if org-agenda-use-time-grid   " Grid"   "")
+	      (if (and (boundp 'org-habit-show-habits)
+		       org-habit-show-habits) " Habit"   "")
+	      (if (consp org-agenda-show-log) " LogAll"
+		(if org-agenda-show-log " Log" ""))
+	      (if (or org-agenda-filter (get 'org-agenda-filter
+					     :preset-filter))
+		  (concat " {" (mapconcat
+				'identity
+				(append (get 'org-agenda-filter
+					     :preset-filter)
+					org-agenda-filter) "") "}")
+		"")
+	      (if org-agenda-archives-mode
+		  (if (eq org-agenda-archives-mode t)
+		      " Archives"
+		    (format " :%s:" org-archive-tag))
+		"")
+	      (if org-agenda-clockreport-mode
+		  (if (eq org-agenda-clockreport-mode 'with-filter)
+		      " Clock{}" " Clock")
+		"")))
   (force-mode-line-update))
   (force-mode-line-update))
 
 
 (defun org-agenda-post-command-hook ()
 (defun org-agenda-post-command-hook ()

+ 2 - 2
lisp/org-mouse.el

@@ -1100,10 +1100,10 @@ This means, between the beginning of line and the point."
 	 "--"
 	 "--"
 	 ["Day View" org-agenda-day-view
 	 ["Day View" org-agenda-day-view
 	  :active (org-agenda-check-type nil 'agenda)
 	  :active (org-agenda-check-type nil 'agenda)
-	  :style radio :selected (equal org-agenda-ndays 1)]
+	  :style radio :selected (eq org-agenda-current-span 'day)]
 	 ["Week View" org-agenda-week-view
 	 ["Week View" org-agenda-week-view
 	  :active (org-agenda-check-type nil 'agenda)
 	  :active (org-agenda-check-type nil 'agenda)
-	  :style radio :selected (equal org-agenda-ndays 7)]
+	  :style radio :selected (eq org-agenda-current-span 'week)]
 	 "--"
 	 "--"
 	 ["Show Logbook entries" org-agenda-log-mode
 	 ["Show Logbook entries" org-agenda-log-mode
 	  :style toggle :selected org-agenda-show-log
 	  :style toggle :selected org-agenda-show-log