diff --git a/org b/org index 05599b837..d657fb2e7 100644 --- a/org +++ b/org @@ -5,7 +5,7 @@ START-INFO-DIR-ENTRY * Org Mode: (org). outline-based notes management and organizer END-INFO-DIR-ENTRY - This manual is for Org-mode (version 4.57). + This manual is for Org-mode (version 4.58). Copyright (C) 2004, 2005, 2006 Free Software Foundation @@ -27,7 +27,7 @@ File: org, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) Org Mode Manual *************** -This manual is for Org-mode (version 4.57). +This manual is for Org-mode (version 4.58). Copyright (C) 2004, 2005, 2006 Free Software Foundation @@ -161,17 +161,18 @@ Agenda Views * Agenda files:: Files being searched for agenda information * Agenda dispatcher:: Keyboard access to agenda views -* Weekly/Daily agenda:: The calendar page with current tasks -* Global TODO list:: All unfinished action items -* Matching headline tags:: Structured information with fine-tuned search -* Timeline:: Time-sorted view for single file +* Built-in agenda views:: What is available out of the box? * Presentation and sorting:: How agenda items are prepared for display * Agenda commands:: Remote editing of org trees * Custom agenda views:: Defining special searches and views -The weekly/daily agenda +The built-in agenda views -* Calendar/Diary integration:: Integrating Anniversaries and more +* Weekly/Daily agenda:: The calendar page with current tasks +* Global TODO list:: All unfinished action items +* Matching headline tags:: Structured information with fine-tuned search +* Timeline:: Time-sorted view for single file +* Stuck projects:: Find projects you need to review Presentation and sorting @@ -249,6 +250,7 @@ Extensions, Hooks and Hacking * Extensions:: Existing 3rd-part extensions * Dynamic blocks:: Automatically filled blocks +* Special agenda views::  File: org, Node: Introduction, Next: Document structure, Prev: Top, Up: Top @@ -535,7 +537,14 @@ the visibility in the buffer. Reveal context around point, showing the current entry, the following heading and the hierarchy above. Useful for working near a location exposed by a sparse tree command (*note Sparse - trees::) or an agenda command (*note Agenda commands::). + trees::) or an agenda command (*note Agenda commands::). + +`C-c C-x b' + Show the current subtree in an indirect buffer(3), in a separate, + dedicated frame. With positive numerical prefix N, go up to level + N before selecting the subtree. With negative prefix -N, go up N + levels. With `C-u' prefix, don't use the dedicated frame, but + another, new frame. When Emacs first visits an Org-mode file, the global state is set to OVERVIEW, i.e. only the top level headlines are visible. This can be @@ -552,6 +561,11 @@ basis by adding one of the following lines anywhere in the buffer: (2) see the option `org-cycle-global-at-bob'. + (3) The indirect buffer (*note Indirect Buffers: (emacs)Indirect +Buffers.) will contain the entire buffer, but will be narrowed to the +current tree. Editing the indirect buffer will also change the +original buffer, but without affecting visibility in that buffer . +  File: org, Node: Motion, Next: Structure editing, Prev: Visibility cycling, Up: Document structure @@ -2834,7 +2848,9 @@ Once a tags system has been set up, it can be used to collect related information into special lists. `C-c \' - Create a sparse tree with all headlines matching a tags search. + Create a sparse tree with all headlines matching a tags search. + With a `C-u' prefix argument, ignore headlines that are not a TODO + line. `C-c a m' Create a global list of tag matches from all agenda files. *Note @@ -2852,15 +2868,15 @@ it, and `+' is syntactic sugar for positive selection. The AND operator `&' is optional when `+' or `-' is present. Examples: `+WORK-BOSS' - Select all headlines that are tagged `:WORK:', but discard those - also tagged `:BOSS:'. + Select headlines tagged `:WORK:', but discard those also tagged + `:BOSS:'. `WORK|LAPTOP' Selects lines tagged `:WORK:' or `:LAPTOP:'. `WORK|LAPTOP&NIGHT' - Like the previous example, but require the `:LAPTOP:' lines to be - tagged also `NIGHT'. + Like before, but require the `:LAPTOP:' lines to be tagged also + `NIGHT'. If you are using multi-state TODO keywords (*note TODO extensions::), it can be useful to also match on the TODO keyword. @@ -2868,13 +2884,16 @@ This can be done by adding a condition after a slash to a tags match. The syntax is similar to the tag matches, but should be applied with consideration: For example, a positive selection on several TODO keywords can not meaningfully be combined with boolean AND. However, -_negative selection_ combined with AND can be meaningful. Examples: +_negative selection_ combined with AND can be meaningful. To make sure +that only lines are checked that actually have any TODO keyword, use +`C-c a M', or equivalently start the todo part after the slash with `!'. +Examples: `WORK/WAITING' Select `:WORK:'-tagged TODO lines with the specific TODO keyword `WAITING'. -`WORK/-WAITING-NEXT' +`WORK/!-WAITING-NEXT' Select `:WORK:'-tagged TODO lines that are neither `WAITING' nor `NEXT' @@ -2887,6 +2906,11 @@ this case it must be enclosed in curly braces. For example, `WORK+{^BOSS.*}' matches headlines that contain the tag `WORK' and any tag starting with `BOSS'. + You can also require a headline to be of a certain level, by writing +instead of any TAG an expression like `LEVEL=3'. For example, a search +`+LEVEL=3+BOSS/-DONE' lists all level three headlines that have the tag +BOSS and are _not_ marked witht the todo keyword DONE. +  File: org, Node: Agenda views, Next: Embedded LaTeX, Prev: Tags, Up: Top @@ -2900,20 +2924,23 @@ are important for a particular date, this information must be collected, sorted and displayed in an organized way. Org-mode can select items based on various criteria, and display them -in a separate buffer. Five different view types are provided: +in a separate buffer. Six different view types are provided: * an _agenda_ that is like a calendar and shows information for - specific dates + specific dates, * a _TODO list_ that covers all unfinished action items, - * a _tags view_ that shows information based on the tags associated - with headlines in the outline tree, + * a _tags view_, showings headlines based on the tags associated + them, * a _timeline view_ that shows all events in a single Org-mode file, - in time-sorted view + in time-sorted view, - * _custom views_ that are special tag and keyword searches and + * a _stuck projects view_ showing projects that currently don't move + along, and + + * _custom views_ that are special tag/keyword searches and combinations of different views. The extracted information is displayed in a special _agenda buffer_. @@ -2929,10 +2956,7 @@ the window configuration is restored when the agenda exits: * Agenda files:: Files being searched for agenda information * Agenda dispatcher:: Keyboard access to agenda views -* Weekly/Daily agenda:: The calendar page with current tasks -* Global TODO list:: All unfinished action items -* Matching headline tags:: Structured information with fine-tuned search -* Timeline:: Time-sorted view for single file +* Built-in agenda views:: What is available out of the box? * Presentation and sorting:: How agenda items are prepared for display * Agenda commands:: Remote editing of org trees * Custom agenda views:: Defining special searches and views @@ -2974,7 +2998,7 @@ command will actually limit the command to the current file, and ignore `org-agenda-files' until the next dispatcher command.  -File: org, Node: Agenda dispatcher, Next: Weekly/Daily agenda, Prev: Agenda files, Up: Agenda views +File: org, Node: Agenda dispatcher, Next: Built-in agenda views, Prev: Agenda files, Up: Agenda views 8.2 The agenda dispatcher ========================= @@ -2998,6 +3022,9 @@ command. The dispatcher offers the following default commands: `L' Create the timeline view for the current buffer (*note Timeline::). +`# / !' + Create a list of stuck projects (*note Stuck projects::). + `1' Restrict an agenda command to the current buffer. After pressing `1', you still need to press the character selecting the command. @@ -3015,10 +3042,26 @@ blocks together, for example the weekly agenda, the global TODO list and a number of special tags matches. *Note Custom agenda views::.  -File: org, Node: Weekly/Daily agenda, Next: Global TODO list, Prev: Agenda dispatcher, Up: Agenda views +File: org, Node: Built-in agenda views, Next: Presentation and sorting, Prev: Agenda dispatcher, Up: Agenda views -8.3 The weekly/daily agenda -=========================== +8.3 The built-in agenda views +============================= + +In this section we describe the built-in views. + +* Menu: + +* Weekly/Daily agenda:: The calendar page with current tasks +* Global TODO list:: All unfinished action items +* Matching headline tags:: Structured information with fine-tuned search +* Timeline:: Time-sorted view for single file +* Stuck projects:: Find projects you need to review + + +File: org, Node: Weekly/Daily agenda, Next: Global TODO list, Prev: Built-in agenda views, Up: Built-in agenda views + +8.3.1 The weekly/daily agenda +----------------------------- The purpose of the weekly/daily _agenda_ is to act like a page of a paper agenda, showing all the tasks for the current week or day. @@ -3035,15 +3078,8 @@ can change the dates of deadlines and appointments from the agenda buffer. The commands available in the Agenda buffer are listed in *Note Agenda commands::. -* Menu: - -* Calendar/Diary integration:: Integrating Anniversaries and more - - -File: org, Node: Calendar/Diary integration, Prev: Weekly/Daily agenda, Up: Weekly/Daily agenda - -8.3.1 Calendar/Diary integration --------------------------------- +Calendar/Diary integration +.......................... Emacs contains the calendar and diary by Edward M. Reingold. The calendar displays a three-month calendar with holidays from different @@ -3069,10 +3105,10 @@ to other calendars, respectively. `c' can be used to switch back and forth between calendar and agenda.  -File: org, Node: Global TODO list, Next: Matching headline tags, Prev: Weekly/Daily agenda, Up: Agenda views +File: org, Node: Global TODO list, Next: Matching headline tags, Prev: Weekly/Daily agenda, Up: Built-in agenda views -8.4 The global TODO list -======================== +8.3.2 The global TODO list +-------------------------- The global TODO list contains all unfinished TODO items, formatted and collected into a single place. @@ -3115,10 +3151,10 @@ it more compact: the variable `org-agenda-todo-list-sublevels' to get this behavior.  -File: org, Node: Matching headline tags, Next: Timeline, Prev: Global TODO list, Up: Agenda views +File: org, Node: Matching headline tags, Next: Timeline, Prev: Global TODO list, Up: Built-in agenda views -8.5 Matching headline tags -========================== +8.3.3 Matching headline tags +---------------------------- If headlines in the agenda files are marked with _tags_ (*note Tags::), you can select headlines based on the tags that apply to them and @@ -3142,10 +3178,10 @@ collect them into an agenda buffer. Agenda commands::.  -File: org, Node: Timeline, Next: Presentation and sorting, Prev: Matching headline tags, Up: Agenda views +File: org, Node: Timeline, Next: Stuck projects, Prev: Matching headline tags, Up: Built-in agenda views -8.6 Timeline for a single file -============================== +8.3.4 Timeline for a single file +-------------------------------- The timeline summarizes all time-stamped items from a single Org-mode file in a _time-sorted view_. The main purpose of this command is to @@ -3160,9 +3196,48 @@ The commands available in the timeline buffer are listed in *Note Agenda commands::.  -File: org, Node: Presentation and sorting, Next: Agenda commands, Prev: Timeline, Up: Agenda views +File: org, Node: Stuck projects, Prev: Timeline, Up: Built-in agenda views -8.7 Presentation and sorting +8.3.5 Stuck projects +-------------------- + +If you are following a system like David Allen's GTD to organize your +work, one of the "duties" you have is a regular review to make sure +that all projects move along. A _stuck_ project is a project that has +no defined next actions, so it will never show up in the TODO lists +Org-mode produces. During the review, you need to identify such +projects and define next actions for them. + +`C-c a #' + List projects that are stuck. + +`C-c a !' + Customize the variable `org-stuck-projects' to define what a stuck + project is and how to find it. + + You almost certainly will have to configure this view before it will +work for you. The built-in default assumes that all your projects are +level-2 headlines, and that a project is not stuck if it has at least +one entry marked with a todo keyword TODO or NEXT or NEXTACTION. + + Lets assume that you, in your own way of using Org-mode, identify +projects with a tag PROJECT, and that you use a todo keyword MAYBE to +indicate a project that should not be considered yet. Lets further +assume that the todo keyword DONE marks finished projects, and that NEXT +and TODO indicate next actions. Finally, the tag @SHOP indicates +shopping and is a next action even without the NEXT tag. In this case +you would start by identifying elegible projects with a tags/todo match +`+PROJECT/-MAYBE-DONE', and then check for TODO, NEXT and @SHOP in the +subtree to identify projects that are not stuck. The correct +customization for this is + + (setq org-stuck-projects + ("+PROJECT/-MAYBE-DONE" ("NEXT" "TODO") ("@SHOP"))) + + +File: org, Node: Presentation and sorting, Next: Agenda commands, Prev: Built-in agenda views, Up: Agenda views + +8.4 Presentation and sorting ============================ Before displaying items in an agenda view, Org-mode visually prepares @@ -3182,7 +3257,7 @@ associated with the item.  File: org, Node: Categories, Next: Time-of-day specifications, Prev: Presentation and sorting, Up: Presentation and sorting -8.7.1 Categories +8.4.1 Categories ---------------- The category is a broad label assigned to each agenda item. By default, @@ -3199,7 +3274,7 @@ buffer looks best if the category is not longer than 10 characters.  File: org, Node: Time-of-day specifications, Next: Sorting of agenda items, Prev: Categories, Up: Presentation and sorting -8.7.2 Time-of-Day Specifications +8.4.2 Time-of-Day Specifications -------------------------------- Org-mode checks each agenda item for a time-of-day specification. The @@ -3210,8 +3285,8 @@ specified with two time stamps, like In the headline of the entry itself, a time(range) may also appear as plain text (like `12:45' or a `8:30-1pm'. If the agenda integrates the -Emacs diary (*note Calendar/Diary integration::), time specifications -in diary entries are recognized as well. +Emacs diary (*note Weekly/Daily agenda::), time specifications in diary +entries are recognized as well. For agenda display, Org-mode extracts the time and displays it in a standard 24 hour format as part of the prefix. The example times in @@ -3244,7 +3319,7 @@ timed entries are embedded in a time grid, like  File: org, Node: Sorting of agenda items, Prev: Time-of-day specifications, Up: Presentation and sorting -8.7.3 Sorting of agenda items +8.4.3 Sorting of agenda items ----------------------------- Before being inserted into a view, the items are sorted. How this is @@ -3272,7 +3347,7 @@ done depends on the type of view.  File: org, Node: Agenda commands, Next: Custom agenda views, Prev: Presentation and sorting, Up: Agenda views -8.8 Commands in the agenda buffer +8.5 Commands in the agenda buffer ================================= Entries in the agenda buffer are linked back to the org file or diary @@ -3320,6 +3395,13 @@ View/GoTo org file agenda buffers can be set with the variable `org-agenda-start-with-follow-mode'. +`b' + Display the entire subtree of the current item in an indirect + buffer, in a separate, dedicated frame. With positive numerical + prefix N, go up to level N before selecting the subtree. With + negative prefix -N, go up N levels. With `C-u' prefix, don't use + the dedicated frame, but another, new frame. + `l' Toggle Logbook mode. In Logbook mode, entries that where marked DONE while logging was on (variable `org-log-done') are shown in @@ -3338,8 +3420,8 @@ Change display Switch to daily view (just one day displayed). `D' - Toggle the inclusion of diary entries. See *Note Calendar/Diary - integration::. + Toggle the inclusion of diary entries. See *Note Weekly/Daily + agenda::. `g' Toggle the time grid on and off. See also the variables @@ -3372,6 +3454,10 @@ Remote editing `0-9' Digit argument. +`C-_' + Undo a change due to a remote editing command. The change is + undone both in the agenda buffer and in the remote buffer. + `t' Change the TODO state of the item, both in the agenda and in the original org file. @@ -3498,7 +3584,7 @@ Quit and Exit  File: org, Node: Custom agenda views, Prev: Agenda commands, Up: Agenda views -8.9 Custom agenda views +8.6 Custom agenda views ======================= Custom agenda commands serve two purposes: to store and quickly access @@ -3516,7 +3602,7 @@ dispatcher (*note Agenda dispatcher::), just like the default commands.  File: org, Node: Storing searches, Next: Block agenda, Prev: Custom agenda views, Up: Custom agenda views -8.9.1 Storing searches +8.6.1 Storing searches ---------------------- The first application of custom searches is the definition of keyboard @@ -3569,7 +3655,7 @@ example above will therefore define:  File: org, Node: Block agenda, Next: Setting Options, Prev: Storing searches, Up: Custom agenda views -8.9.2 Block agenda +8.6.2 Block agenda ------------------ Another possibility is the construction of agenda views that comprise @@ -3599,7 +3685,7 @@ your agenda for the current week, all TODO items that carry the tag  File: org, Node: Setting Options, Next: Batch processing, Prev: Block agenda, Up: Custom agenda views -8.9.3 Setting Options for custom commands +8.6.3 Setting Options for custom commands ----------------------------------------- Org-mode contains a number of variables regulating agenda construction @@ -3656,7 +3742,7 @@ yourself.  File: org, Node: Batch processing, Prev: Setting Options, Up: Custom agenda views -8.9.4 Creating agenda views in batch processing +8.6.4 Creating agenda views in batch processing ----------------------------------------------- If you want to print or otherwise reprocess agenda views, it can be @@ -4588,8 +4674,8 @@ File: org, Node: Customization, Next: In-buffer settings, Prev: Completion, 12.2 Customization ================== -There are more than 100 variables that can be used to customize -Org-mode. For the sake of compactness of the manual, we are not +There are more than 170 variables that can be used to customize +Org-mode. For the sake of compactness of the manual, I am not describing the variables here. A structured overview of customization variables is available with `M-x org-customize'. Or select `Browse Org Group' from the `Org->Customization' menu. Many settings can also be @@ -4957,11 +5043,6 @@ found too hard to fix. open the file), it does so silently. No error message is displayed. - * The remote-editing commands in the agenda buffer cannot be undone - with `undo' called from within the agenda buffer. But you can go - to the corresponding buffer (using or and execute - `undo' there. - * Recalculating a table line applies the formulas from left to right. If a formula uses _calculated_ fields further down the row, multiple recalculation may be needed to get all fields consistent. @@ -4977,13 +5058,14 @@ Appendix A Extensions, Hooks and Hacking **************************************** This appendix lists extensions for Org-mode written by other authors. -It also covers some aspects where users can easily extend the -functionality of Org-mode. +It also covers some aspects where users can extend the functionality of +Org-mode. * Menu: * Extensions:: Existing 3rd-part extensions * Dynamic blocks:: Automatically filled blocks +* Special agenda views::  File: org, Node: Extensions, Next: Dynamic blocks, Prev: Extensions and Hacking, Up: Extensions and Hacking @@ -5025,7 +5107,7 @@ The following extensions for Org-mode have been written by other people: `http://www.cognition.ens.fr/~guerry/blorg.html'.  -File: org, Node: Dynamic blocks, Prev: Extensions, Up: Extensions and Hacking +File: org, Node: Dynamic blocks, Next: Special agenda views, Prev: Extensions, Up: Extensions and Hacking A.2 Dynamic blocks ================== @@ -5076,6 +5158,60 @@ hook, for example `before-save-hook'. `org-update-all-dblocks' is written in a way that is does nothing in buffers that are not in Org-mode. + +File: org, Node: Special agenda views, Prev: Dynamic blocks, Up: Extensions and Hacking + +A.3 Special Agenda Views +======================== + +Org-mode provides a special hook that can be used to narrow down the +selection made by any of the agenda views. You may specify a function +that is used at each match to verify if the match should indeed be part +of the agenda view, and if not, how much should be skipped. + + Let's say you want to produce a list of projects that contain a +WAITING tag anywhere in the project tree. Let's further assume that +you have marked all tree headings that define a project with the todo +keyword PROJECT. In this case you would run a todo search for the +keyword PROJECT, but skip the match unless there is a WAITING tag +anywhere in the subtree belonging to the project line.. + + To achieve this, you must write a function that searches the subtree +for the tag. If the tag is found, the function must return `nil' to +indicate that this match should not be skipped. If there is no such +tag, return the location of the end of the subtree, to indicate that +search should continue from there. + + (defun my-skip-unless-waiting () + "Skip trees that are not waiting" + (let ((subtree-end (save-excursion (org-end-of-subtree t)))) + (if (re-search-forward ":WAITING:" subtree-end t) + nil ; tag found, do not skip + subtree-end))) ; tag not found, continue after end of subtree + + Furthermore you must write a command that uses `let' to temporarily +puts this function into the variable `org-agenda-skip-function', sets +the header string for the agenda buffer, and calls the todo-list +generator while asking for the specific TODO keyword PROJECT. The +function must also accept one argument MATCH, but it can choose to +ignore it(1) (as we do in the example below). Here is the example: + + (defun my-org-waiting-projects (&optional match) + "Produce a list of projects that contain a WAITING tag. + MATCH is being ignored." + (interactive) + (let ((org-agenda-skip-function 'my-skip-unless-waiting) + (org-agenda-overriding-header "Projects waiting for something: ")) + ;; make the list + (org-todo-list "PROJECT"))) + + ---------- Footnotes ---------- + + (1) MATCH must be present in case you want to define a custom +command for producing this special list. Custom commands always supply +the MATCH argument, but it can be empty if you do not specify it while +defining the command(*note Custom agenda views::). +  File: org, Node: History and Acknowledgments, Next: Index, Prev: Extensions and Hacking, Up: Top @@ -5230,7 +5366,7 @@ Index * agenda: Weekly/Daily agenda. (line 6) * agenda dispatcher: Agenda dispatcher. (line 6) * agenda files: Agenda files. (line 6) -* agenda files, removing buffers: Agenda commands. (line 220) +* agenda files, removing buffers: Agenda commands. (line 231) * agenda views: Agenda views. (line 6) * agenda views, custom: Custom agenda views. (line 6) * agenda, batch production: Batch processing. (line 6) @@ -5248,7 +5384,7 @@ Index * block agenda: Block agenda. (line 6) * blorg.el: Extensions. (line 33) * bold text: Enhancing text. (line 15) -* Boolean logic, for tag searches: Tag searches. (line 21) +* Boolean logic, for tag searches: Tag searches. (line 23) * bug reports: Feedback. (line 6) * bugs: Bugs. (line 6) * C-c C-c, overview: The very busy C-c C-c key. @@ -5258,9 +5394,8 @@ Index * calculations, in tables <1>: Table calculations. (line 6) * calculations, in tables: Built-in table editor. (line 141) -* calendar commands, from agenda: Agenda commands. (line 181) -* calendar integration: Calendar/Diary integration. - (line 6) +* calendar commands, from agenda: Agenda commands. (line 192) +* calendar integration: Weekly/Daily agenda. (line 24) * calendar, for selecting date: The date/time prompt. (line 26) * CamelCase link completion: Completion. (line 6) @@ -5313,14 +5448,13 @@ Index * DEADLINE keyword: Time stamps. (line 53) * deadlines: Time stamps. (line 6) * demotion, of subtrees: Structure editing. (line 6) -* diary entries, creating from agenda: Agenda commands. (line 188) -* diary integration: Calendar/Diary integration. - (line 6) +* diary entries, creating from agenda: Agenda commands. (line 199) +* diary integration: Weekly/Daily agenda. (line 24) * dictionary word completion: Completion. (line 6) * directories, for publishing: Sources and destinations. (line 6) * dispatching agenda commands: Agenda dispatcher. (line 6) -* display changing, in agenda: Agenda commands. (line 59) +* display changing, in agenda: Agenda commands. (line 66) * document structure: Document structure. (line 6) * DONE, final TODO keyword: Per file keywords. (line 20) * editing tables: Tables. (line 6) @@ -5400,6 +5534,7 @@ Index * LaTeX fragments, preview: Processing LaTeX fragments. (line 6) * LaTeX interpretation: Embedded LaTeX. (line 6) +* level, require for tags match: Tag searches. (line 68) * linebreak preservation: Export options. (line 25) * linebreak, forced: Enhancing text. (line 32) * link abbreviations: Link abbreviations. (line 6) @@ -5476,10 +5611,11 @@ Index * region, active <3>: Built-in table editor. (line 171) * region, active: Structure editing. (line 64) -* regular expressions, with tags search: Tag searches. (line 58) +* regular expressions, with tags search: Tag searches. (line 63) * remember.el <1>: Cooperation. (line 33) * remember.el: Remember. (line 6) -* remote editing, from agenda: Agenda commands. (line 100) +* remote editing, from agenda: Agenda commands. (line 107) +* remote editing, undo: Agenda commands. (line 110) * richer text: Enhancing text. (line 6) * RMAIL links: External links. (line 6) * SCHEDULED keyword: Time stamps. (line 40) @@ -5562,7 +5698,7 @@ Index * timestamps, creating: Creating timestamps. (line 6) * TODO items: TODO items. (line 6) * TODO keyword matching: Global TODO list. (line 17) -* TODO keyword matching, with tags search: Tag searches. (line 38) +* TODO keyword matching, with tags search: Tag searches. (line 40) * TODO keywords completion: Completion. (line 6) * TODO list, global: Global TODO list. (line 6) * TODO types: TODO types. (line 6) @@ -5577,6 +5713,7 @@ Index * tty keybindings: TTY keys. (line 6) * types as TODO keywords: TODO types. (line 6) * underlined text: Enhancing text. (line 15) +* undoing remote-editing events: Agenda commands. (line 110) * URL links: External links. (line 6) * USENET links: External links. (line 6) * variables, for customization: Customization. (line 6) @@ -5600,23 +5737,23 @@ Key Index [index] * Menu: -* $: Agenda commands. (line 113) +* $: Agenda commands. (line 124) * ': CDLaTeX mode. (line 43) -* +: Agenda commands. (line 135) -* ,: Agenda commands. (line 127) -* -: Agenda commands. (line 141) -* .: Agenda commands. (line 94) -* :: Agenda commands. (line 121) +* +: Agenda commands. (line 146) +* ,: Agenda commands. (line 138) +* -: Agenda commands. (line 152) +* .: Agenda commands. (line 101) +* :: Agenda commands. (line 132) * <: The date/time prompt. (line 29) -* : Agenda commands. (line 91) +* : Agenda commands. (line 98) * <1>: Agenda commands. (line 41) * <2>: Setting tags. (line 76) * <3>: The date/time prompt. (line 54) * : Built-in table editor. (line 64) -* : Agenda commands. (line 86) +* : Agenda commands. (line 93) * <1>: Agenda commands. (line 28) * : Setting tags. (line 73) * <1>: CDLaTeX mode. (line 23) @@ -5626,18 +5763,20 @@ Key Index (line 57) * <5>: Plain lists. (line 37) * : Visibility cycling. (line 10) -* > <1>: Agenda commands. (line 163) +* > <1>: Agenda commands. (line 174) * >: The date/time prompt. (line 30) * ^: CDLaTeX mode. (line 33) * _: CDLaTeX mode. (line 33) * `: CDLaTeX mode. (line 39) -* a: Agenda commands. (line 124) -* C: Agenda commands. (line 203) -* c: Agenda commands. (line 181) +* a: Agenda commands. (line 135) +* b: Agenda commands. (line 51) +* C: Agenda commands. (line 214) +* c: Agenda commands. (line 192) * C-#: Built-in table editor. (line 161) * C-,: Agenda files. (line 18) +* C-_: Agenda commands. (line 110) * C-a a L: Timeline. (line 10) * C-c !: Creating timestamps. (line 21) * C-c #: Checkboxes. (line 56) @@ -5677,14 +5816,16 @@ Key Index * C-c ^: Structure editing. (line 52) * C-c `: Built-in table editor. (line 187) +* C-c a !: Stuck projects. (line 14) +* C-c a #: Stuck projects. (line 13) * C-c a a: Weekly/Daily agenda. (line 9) * C-c a C: Storing searches. (line 9) * C-c a M: Matching headline tags. (line 15) * C-c a m: Matching headline tags. (line 10) -* C-c a M: Tag searches. (line 14) -* C-c a m: Tag searches. (line 10) +* C-c a M: Tag searches. (line 16) +* C-c a m: Tag searches. (line 12) * C-c a T: Global TODO list. (line 14) * C-c a t <1>: Global TODO list. (line 9) * C-c a t: TODO basics. (line 33) @@ -5702,7 +5843,7 @@ Key Index * C-c C-c <7>: Built-in table editor. (line 54) * C-c C-c: Plain lists. (line 74) -* C-c C-d <1>: Agenda commands. (line 148) +* C-c C-d <1>: Agenda commands. (line 159) * C-c C-d: Creating timestamps. (line 37) * C-c C-e: Exporting. (line 19) * C-c C-e a: ASCII export. (line 9) @@ -5730,16 +5871,17 @@ Key Index * C-c C-q: Built-in table editor. (line 125) * C-c C-r: Visibility cycling. (line 32) -* C-c C-s <1>: Agenda commands. (line 145) +* C-c C-s <1>: Agenda commands. (line 156) * C-c C-s: Creating timestamps. (line 48) * C-c C-t <1>: Clocking work time. (line 26) * C-c C-t: TODO basics. (line 13) * C-c C-u: Motion. (line 18) * C-c C-v: TODO basics. (line 26) * C-c C-w: Creating timestamps. (line 41) +* C-c C-x b: Visibility cycling. (line 38) * C-c C-x C-a: ARCHIVE tag. (line 28) * C-c C-x C-b: Checkboxes. (line 38) -* C-c C-x C-c: Agenda commands. (line 210) +* C-c C-x C-c: Agenda commands. (line 221) * C-c C-x C-d: Clocking work time. (line 34) * C-c C-x C-i: Clocking work time. (line 12) * C-c C-x C-k: Structure editing. (line 39) @@ -5766,7 +5908,7 @@ Key Index * C-c |: Built-in table editor. (line 40) * C-c ~: table.el. (line 18) -* C-k: Agenda commands. (line 107) +* C-k: Agenda commands. (line 118) * C-TAB: ARCHIVE tag. (line 38) * C-u C-c $: Moving subtrees. (line 12) * C-u C-c .: Creating timestamps. (line 16) @@ -5776,16 +5918,16 @@ Key Index * C-u C-c C-x C-a: ARCHIVE tag. (line 31) * C-u C-c C-x C-u <1>: Dynamic blocks. (line 22) * C-u C-c C-x C-u: Clocking work time. (line 69) -* D: Agenda commands. (line 68) -* d: Agenda commands. (line 65) +* D: Agenda commands. (line 75) +* d: Agenda commands. (line 72) * f: Agenda commands. (line 44) -* g: Agenda commands. (line 72) -* H: Agenda commands. (line 207) -* i: Agenda commands. (line 188) -* I: Agenda commands. (line 168) -* l: Agenda commands. (line 51) +* g: Agenda commands. (line 79) +* H: Agenda commands. (line 218) +* i: Agenda commands. (line 199) +* I: Agenda commands. (line 179) +* l: Agenda commands. (line 58) * L: Agenda commands. (line 32) -* M: Agenda commands. (line 194) +* M: Agenda commands. (line 205) * M-: Built-in table editor. (line 82) * M- <1>: Built-in table editor. @@ -5833,29 +5975,29 @@ Key Index * mouse-3 <1>: Agenda commands. (line 28) * mouse-3: Handling links. (line 77) * n: Agenda commands. (line 19) -* O: Agenda commands. (line 170) -* o: Agenda commands. (line 59) -* P: Agenda commands. (line 132) +* O: Agenda commands. (line 181) +* o: Agenda commands. (line 66) +* P: Agenda commands. (line 143) * p: Agenda commands. (line 20) -* q: Agenda commands. (line 217) -* r <1>: Agenda commands. (line 76) +* q: Agenda commands. (line 228) +* r <1>: Agenda commands. (line 83) * r: Global TODO list. (line 20) -* S: Agenda commands. (line 198) -* s: Agenda commands. (line 83) -* S- <1>: Agenda commands. (line 141) +* S: Agenda commands. (line 209) +* s: Agenda commands. (line 90) +* S- <1>: Agenda commands. (line 152) * S- <2>: The date/time prompt. (line 42) * S- <3>: Creating timestamps. (line 58) * S- <4>: Priorities. (line 25) * S-: Plain lists. (line 55) -* S- <1>: Agenda commands. (line 159) +* S- <1>: Agenda commands. (line 170) * S- <2>: The date/time prompt. (line 39) * S- <3>: Creating timestamps. (line 53) * S-: TODO basics. (line 20) * S-: Built-in table editor. (line 176) -* S- <1>: Agenda commands. (line 151) +* S- <1>: Agenda commands. (line 162) * S- <2>: The date/time prompt. (line 36) * S- <3>: Creating timestamps. (line 53) @@ -5863,172 +6005,176 @@ Key Index * S- <1>: Built-in table editor. (line 61) * S-: Visibility cycling. (line 22) -* S- <1>: Agenda commands. (line 135) +* S- <1>: Agenda commands. (line 146) * S- <2>: The date/time prompt. (line 45) * S- <3>: Creating timestamps. (line 58) * S- <4>: Priorities. (line 25) * S-: Plain lists. (line 55) -* T: Agenda commands. (line 116) -* t: Agenda commands. (line 103) -* w: Agenda commands. (line 62) -* x: Agenda commands. (line 220) -* X: Agenda commands. (line 173) +* T: Agenda commands. (line 127) +* t: Agenda commands. (line 114) +* w: Agenda commands. (line 69) +* x: Agenda commands. (line 231) +* X: Agenda commands. (line 184)  Tag Table: Node: Top964 -Node: Introduction10363 -Node: Summary10778 -Node: Installation13690 -Node: Activation15068 -Node: Feedback16317 -Node: Document structure18393 -Node: Outlines19167 -Node: Headlines19827 -Node: Visibility cycling20450 -Ref: Visibility cycling-Footnote-122201 -Ref: Visibility cycling-Footnote-222259 -Node: Motion22309 -Node: Structure editing23093 -Node: Archiving25919 -Node: ARCHIVE tag26477 -Node: Moving subtrees28270 -Node: Sparse trees29311 -Ref: Sparse trees-Footnote-131442 -Ref: Sparse trees-Footnote-231534 -Node: Plain lists31649 -Ref: Plain lists-Footnote-135174 -Ref: Plain lists-Footnote-235531 -Node: Tables35715 -Node: Built-in table editor36263 -Node: Narrow columns44291 -Ref: Narrow columns-Footnote-146230 -Node: Table calculations46276 -Node: Formula syntax47596 -Ref: Formula syntax-Footnote-150501 -Node: Lisp formulas50801 -Node: Column formulas51590 -Node: Advanced features53352 -Node: Named-field formulas56606 -Node: Editing/debugging formulas57246 -Node: Appetizer59004 -Node: orgtbl-mode60107 -Node: table.el60598 -Node: Hyperlinks61575 -Node: Link format62348 -Node: Internal links63641 -Ref: Internal links-Footnote-165630 -Node: Radio targets65762 -Node: CamelCase links66477 -Node: External links67071 -Node: Handling links69202 -Ref: Handling links-Footnote-173854 -Ref: Handling links-Footnote-274091 -Node: Link abbreviations74165 -Node: Search options75844 -Ref: Search options-Footnote-177624 -Node: Custom searches77705 -Node: Remember78753 -Node: TODO items82447 -Node: TODO basics83429 -Node: TODO extensions84956 -Node: Workflow states85751 -Node: TODO types86619 -Ref: TODO types-Footnote-188277 -Node: Per file keywords88359 -Ref: Per file keywords-Footnote-189813 -Node: Priorities90014 -Node: Breaking down tasks91258 -Ref: Breaking down tasks-Footnote-191777 -Node: Checkboxes91873 -Node: Timestamps94628 -Node: Time stamps95089 -Ref: Time stamps-Footnote-198583 -Ref: Time stamps-Footnote-298699 -Node: Creating timestamps98854 -Node: The date/time prompt101480 -Ref: The date/time prompt-Footnote-1103246 -Node: Custom time format103352 -Node: Progress logging104911 -Node: Closing items105440 -Node: Clocking work time106344 -Ref: Clocking work time-Footnote-1109968 -Node: Tags110094 -Node: Tag inheritance110856 -Node: Setting tags111793 -Ref: Setting tags-Footnote-1115992 -Ref: Setting tags-Footnote-2116104 -Node: Tag searches116187 -Node: Agenda views118416 -Node: Agenda files120509 -Ref: Agenda files-Footnote-1121469 -Ref: Agenda files-Footnote-2121618 -Node: Agenda dispatcher121811 -Node: Weekly/Daily agenda123428 -Node: Calendar/Diary integration124393 -Node: Global TODO list125731 -Node: Matching headline tags127891 -Node: Timeline128949 -Node: Presentation and sorting129612 -Node: Categories130390 -Node: Time-of-day specifications131054 -Node: Sorting of agenda items133032 -Node: Agenda commands134314 -Node: Custom agenda views140552 -Node: Storing searches141227 -Node: Block agenda143139 -Node: Setting Options144369 -Node: Batch processing147081 -Node: Embedded LaTeX148211 -Ref: Embedded LaTeX-Footnote-1149303 -Node: Math symbols149493 -Node: Subscripts and Superscripts150258 -Node: LaTeX fragments151102 -Ref: LaTeX fragments-Footnote-1153210 -Node: Processing LaTeX fragments153472 -Node: CDLaTeX mode154418 -Ref: CDLaTeX mode-Footnote-1156902 -Node: Exporting157050 -Node: ASCII export158364 -Node: HTML export159654 -Node: XOXO export162490 -Node: iCalendar export162929 -Node: Text interpretation164752 -Node: Comment lines165231 -Node: Enhancing text165702 -Node: Export options167394 -Node: Publishing169061 -Ref: Publishing-Footnote-1169857 -Node: Configuration170053 -Node: Project alist170771 -Node: Sources and destinations171837 -Node: Selecting files172567 -Node: Publishing action173315 -Node: Publishing options174548 -Node: Publishing links176700 -Node: Project page index178213 -Node: Sample configuration178991 -Node: Simple example179483 -Node: Complex example180156 -Node: Triggering publication182232 -Node: Miscellaneous182917 -Node: Completion183551 -Node: Customization185022 -Node: In-buffer settings185607 -Node: The very busy C-c C-c key189226 -Node: Clean view190870 -Node: TTY keys193447 -Node: Interaction195056 -Node: Cooperation195453 -Node: Conflicts197320 -Node: Bugs198912 -Node: Extensions and Hacking200535 -Node: Extensions201021 -Node: Dynamic blocks202808 -Node: History and Acknowledgments204735 -Node: Index209742 -Node: Key Index236903 +Node: Introduction10454 +Node: Summary10869 +Node: Installation13781 +Node: Activation15159 +Node: Feedback16408 +Node: Document structure18484 +Node: Outlines19258 +Node: Headlines19918 +Node: Visibility cycling20541 +Ref: Visibility cycling-Footnote-122614 +Ref: Visibility cycling-Footnote-222672 +Ref: Visibility cycling-Footnote-322722 +Node: Motion22992 +Node: Structure editing23776 +Node: Archiving26602 +Node: ARCHIVE tag27160 +Node: Moving subtrees28953 +Node: Sparse trees29994 +Ref: Sparse trees-Footnote-132125 +Ref: Sparse trees-Footnote-232217 +Node: Plain lists32332 +Ref: Plain lists-Footnote-135857 +Ref: Plain lists-Footnote-236214 +Node: Tables36398 +Node: Built-in table editor36946 +Node: Narrow columns44974 +Ref: Narrow columns-Footnote-146913 +Node: Table calculations46959 +Node: Formula syntax48279 +Ref: Formula syntax-Footnote-151184 +Node: Lisp formulas51484 +Node: Column formulas52273 +Node: Advanced features54035 +Node: Named-field formulas57289 +Node: Editing/debugging formulas57929 +Node: Appetizer59687 +Node: orgtbl-mode60790 +Node: table.el61281 +Node: Hyperlinks62258 +Node: Link format63031 +Node: Internal links64324 +Ref: Internal links-Footnote-166313 +Node: Radio targets66445 +Node: CamelCase links67160 +Node: External links67754 +Node: Handling links69885 +Ref: Handling links-Footnote-174537 +Ref: Handling links-Footnote-274774 +Node: Link abbreviations74848 +Node: Search options76527 +Ref: Search options-Footnote-178307 +Node: Custom searches78388 +Node: Remember79436 +Node: TODO items83130 +Node: TODO basics84112 +Node: TODO extensions85639 +Node: Workflow states86434 +Node: TODO types87302 +Ref: TODO types-Footnote-188960 +Node: Per file keywords89042 +Ref: Per file keywords-Footnote-190496 +Node: Priorities90697 +Node: Breaking down tasks91941 +Ref: Breaking down tasks-Footnote-192460 +Node: Checkboxes92556 +Node: Timestamps95311 +Node: Time stamps95772 +Ref: Time stamps-Footnote-199266 +Ref: Time stamps-Footnote-299382 +Node: Creating timestamps99537 +Node: The date/time prompt102163 +Ref: The date/time prompt-Footnote-1103929 +Node: Custom time format104035 +Node: Progress logging105594 +Node: Closing items106123 +Node: Clocking work time107027 +Ref: Clocking work time-Footnote-1110651 +Node: Tags110777 +Node: Tag inheritance111539 +Node: Setting tags112476 +Ref: Setting tags-Footnote-1116675 +Ref: Setting tags-Footnote-2116787 +Node: Tag searches116870 +Node: Agenda views119582 +Node: Agenda files121522 +Ref: Agenda files-Footnote-1122482 +Ref: Agenda files-Footnote-2122631 +Node: Agenda dispatcher122824 +Node: Built-in agenda views124515 +Node: Weekly/Daily agenda125093 +Node: Global TODO list127222 +Node: Matching headline tags129395 +Node: Timeline130466 +Node: Stuck projects131132 +Node: Presentation and sorting132831 +Node: Categories133622 +Node: Time-of-day specifications134286 +Node: Sorting of agenda items136257 +Node: Agenda commands137539 +Node: Custom agenda views144239 +Node: Storing searches144914 +Node: Block agenda146826 +Node: Setting Options148056 +Node: Batch processing150768 +Node: Embedded LaTeX151898 +Ref: Embedded LaTeX-Footnote-1152990 +Node: Math symbols153180 +Node: Subscripts and Superscripts153945 +Node: LaTeX fragments154789 +Ref: LaTeX fragments-Footnote-1156897 +Node: Processing LaTeX fragments157159 +Node: CDLaTeX mode158105 +Ref: CDLaTeX mode-Footnote-1160589 +Node: Exporting160737 +Node: ASCII export162051 +Node: HTML export163341 +Node: XOXO export166177 +Node: iCalendar export166616 +Node: Text interpretation168439 +Node: Comment lines168918 +Node: Enhancing text169389 +Node: Export options171081 +Node: Publishing172748 +Ref: Publishing-Footnote-1173544 +Node: Configuration173740 +Node: Project alist174458 +Node: Sources and destinations175524 +Node: Selecting files176254 +Node: Publishing action177002 +Node: Publishing options178235 +Node: Publishing links180387 +Node: Project page index181900 +Node: Sample configuration182678 +Node: Simple example183170 +Node: Complex example183843 +Node: Triggering publication185919 +Node: Miscellaneous186604 +Node: Completion187238 +Node: Customization188709 +Node: In-buffer settings189292 +Node: The very busy C-c C-c key192911 +Node: Clean view194555 +Node: TTY keys197132 +Node: Interaction198741 +Node: Cooperation199138 +Node: Conflicts201005 +Node: Bugs202597 +Node: Extensions and Hacking203991 +Node: Extensions204495 +Node: Dynamic blocks206282 +Node: Special agenda views208238 +Ref: Special agenda views-Footnote-1210519 +Node: History and Acknowledgments210779 +Node: Index215786 +Node: Key Index243028  End Tag Table diff --git a/org-mouse.el b/org-mouse.el index 939b6f114..0c3367a8d 100644 --- a/org-mouse.el +++ b/org-mouse.el @@ -3,8 +3,8 @@ ;; Copyright (c) 2006 Piotr Zielinski ;; ;; Author: Piotr Zielinski -;; Version: 0.18 -;; $Id: org-mouse.el 254 2006-10-26 21:15:52Z pz215 $ +;; Version: 0.21 +;; $Id: org-mouse.el 347 2006-11-12 23:57:50Z pz215 $ ;; ;; The latest version of this file is available from ;; @@ -76,12 +76,7 @@ ;; feature implemented or a bug fix please send me an email, even if ;; something similar appears in the list below. This will help me get ;; the priorities right.): - -;; + The "New Appointment" menu entry seems out of place. Remove it -;; and enhance the time/data selection function so that if the text -;; in the clipboard contains a date/time, then set that date as the -;; default (instead of "today") - +;; ;; + org-store-link, insert link ;; + org tables ;; + occur with the current word/tag (same menu item) @@ -92,6 +87,15 @@ ;; History: ;; +;; Version 0.21 +;; + selected text activates its context menu +;; + shift-middleclick or right-drag inserts the text from the clipboard in the form of a link +;; +;; Version 0.20 +;; + the new "TODO Status" submenu replaces the "Cycle TODO" menu item +;; + the TODO menu can now list occurrences of a specific TODO keyword +;; + #+STARTUP line is now recognized +;; ;; Version 0.19 ;; + added support for dragging URLs to the org-buffer ;; @@ -164,6 +168,7 @@ (skip-chars-backward ":A-Za-z") (skip-chars-backward "\t "))) + (defun org-mouse-show-context-menu (event prefix) (interactive "@e \nP") (if (and (= (event-click-count event) 1) @@ -171,12 +176,13 @@ (sit-for (/ double-click-time 1000.0)))) (progn (select-window (posn-window (event-start event))) - (goto-char (posn-point (event-start event))) - (when (not (eolp)) (save-excursion (run-hooks 'post-command-hook))) - (let ((redisplay-dont-pause t)) - (sit-for 0)) + (when (not (org-mouse-mark-active)) + (goto-char (posn-point (event-start event))) + (when (not (eolp)) (save-excursion (run-hooks 'post-command-hook))) + (let ((redisplay-dont-pause t)) + (sit-for 0))) (if (functionp org-mouse-context-menu-function) - (funcall org-mouse-context-menu-function) + (funcall org-mouse-context-menu-function event) (mouse-major-mode-menu event prefix)) ) (setq this-command 'mouse-save-then-kill) @@ -217,38 +223,52 @@ (org-timestamp-change shift units))) (defun org-mouse-keyword-menu (keywords function &optional selected itemformat) + (message "kmenu: %S" selected) (mapcar - (lambda (keyword) + `(lambda (keyword) (vector (cond - ((functionp itemformat) (funcall itemformat keyword)) - ((stringp itemformat) (format itemformat keyword)) + ((functionp ,itemformat) (funcall ,itemformat keyword)) + ((stringp ,itemformat) (format ,itemformat keyword)) (t keyword)) - `(funcall ,function ,keyword) + (list 'funcall ,function keyword) :style (cond - ((null selected) t) - ((functionp selected) 'toggle) + ((null ,selected) t) + ((functionp ,selected) 'toggle) (t 'radio)) - :selected `(if (functionp ,selected) - (funcall ,selected ,keyword) - (equal ,selected ,keyword)))) + :selected (if (functionp ,selected) + (and (funcall ,selected keyword) t) + (equal ,selected keyword)))) keywords)) (defun org-mouse-remove-match-and-spaces () (interactive) (replace-match "") - (when (looking-at " +") - (replace-match ""))) + (just-one-space)) + +(defun org-mouse-replace-match-and-surround (newtext &optional fixedcase + literal string subexp) + "The same as replace-match, but surrounds the replacement with spaces." + (apply 'replace-match rest) + (save-excursion + (goto-char (match-beginning (or subexp 0))) + (just-one-space) + (goto-char (match-end (or subexp 0))) + (just-one-space))) (defun org-mouse-keyword-replace-menu (keywords &optional group itemformat) (setq group (or group 0)) - (append - (org-mouse-keyword-menu - keywords - `(lambda (keyword) (replace-match keyword t t nil ,group)) - `(match-string ,group) - itemformat) - '(["None" org-mouse-remove-match-and-spaces t]))) + (let ((replace (org-mouse-match-closure + 'org-mouse-replace-match-and-surround))) + (append + (org-mouse-keyword-menu + keywords + `(lambda (keyword) (funcall ,replace keyword t t nil ,group)) + (match-string group) + itemformat) + `(["None" org-mouse-remove-match-and-spaces + :style radio + :selected ,(not (member (match-string group) keywords))])))) (defvar org-mouse-context-menu-function nil) (make-variable-buffer-local 'org-mouse-context-menu-function) @@ -366,6 +386,29 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" (t "Agenda command ???"))) +(defun org-mouse-list-options-menu (alloptions &optional function) + (let ((options (save-match-data + (split-string (match-string-no-properties 1))))) + (print options) + (loop for name in alloptions + collect + (vector name + `(progn + (replace-match + (mapconcat 'identity + (sort (if (member ',name ',options) + (delete ',name ',options) + (cons ',name ',options)) + 'string-lessp) + " ") + nil nil nil 1) + (when (functionp ',function) (funcall ',function))) + :style 'toggle + :selected (and (member name options) t))))) + + + + (defun org-mouse-clip-text (text maxlength) (if (> (length text) maxlength) (concat (substring text 0 (- maxlength 3)) "...") @@ -404,15 +447,6 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" ["Custom Tag ..." org-tags-view t]) ["Display Calendar" org-goto-calendar t] "--" -;; ("Custom Commands" -;; ,@(org-mouse-keyword-menu -;; (mapcar 'car org-agenda-custom-commands) -;; '(lambda (key) -;; (eval `(flet ((read-char-exclusive () (string-to-char ,key))) -;; (let ((current-prefix-arg t)) -;; (org-agenda nil))))) -;; nil "Agenda (TODO) '%s'") -;; "--" ,@(org-mouse-keyword-menu (mapcar 'car org-agenda-custom-commands) '(lambda (key) @@ -466,42 +500,95 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" (save-excursion (skip-chars-backward " \t*") (bolp))) +(defun org-mouse-insert-item (text) + (case (org-mouse-line-position) + (:begin ; insert before + (beginning-of-line) + (looking-at "[ \t]*") + (open-line 1) + (indent-to (- (match-end 0) (match-beginning 0))) + (insert "+ ")) + + (:middle ; insert after + (end-of-line) + (newline t) + (indent-relative) + (insert "+ ")) + + (:end ; insert text here + (skip-chars-backward " \t") + (kill-region (point) (point-at-eol)) + (unless (looking-back org-mouse-punctuation) + (insert (concat org-mouse-punctuation " "))))) + + (insert text) + (beginning-of-line)) + + (defadvice dnd-insert-text (around org-mouse-dnd-insert-text activate) (if (eq major-mode 'org-mode) - (case (org-mouse-line-position) - (:begin ; insert before - (beginning-of-line) - (looking-at "[ \t]*") - (open-line 1) - (indent-to (- (match-end 0) (match-beginning 0))) - (insert "+ ")) - - (:middle ; insert after - (end-of-line) - (newline t) - (indent-relative) - (insert "+ ")) - - (:end ; insert text here - (skip-chars-backward " \t") - (kill-region (point) (point-at-eol)) - (unless (looking-back org-mouse-punctuation) - (insert (concat org-mouse-punctuation " ")))) - - (insert text) - (beginning-of-line)) + (org-mouse-insert-item text) ad-do-it)) -(defun org-mouse-context-menu () +(defadvice dnd-open-file (around org-mouse-dnd-open-file activate) + (if (eq major-mode 'org-mode) + (org-mouse-insert-item uri) + ad-do-it)) + +(defun org-mouse-match-closure (function) + (let ((match (match-data t))) + `(lambda (&rest rest) + (save-match-data + (set-match-data ',match) + (apply ',function rest))))) + +(defun org-mouse-match-todo-keyword () + (save-excursion + (org-back-to-heading) + (if (looking-at outline-regexp) (goto-char (match-end 0))) + (or (looking-at (concat " +" org-todo-regexp " *")) + (looking-at " \\( *\\)")))) + +(defun org-mouse-yank-link (click) + (interactive "e") + ;; Give temporary modes such as isearch a chance to turn off. + (run-hooks 'mouse-leave-buffer-hook) + (mouse-set-point click) + (setq mouse-selection-click-count 0) + (delete-horizontal-space) + (insert-for-yank (concat " [[" (current-kill 0) "]] "))) + + +(defun org-mouse-context-menu (&optional event) (let ((stamp-prefixes (list org-deadline-string org-scheduled-string)) (contextlist (org-context))) (flet ((get-context (context) (org-mouse-get-context contextlist context))) (cond + ((org-mouse-mark-active) + (let ((region-string (buffer-substring (region-beginning) (region-end)))) + (popup-menu + `(nil + ["Sparse Tree" (org-occur ',region-string)] + ["Find in Buffer" (occur ',region-string)] + ["Grep in Current Dir" + (grep (format "grep -rnH -e '%s' *" ',region-string))] + ["Grep in Parent Dir" + (grep (format "grep -rnH -e '%s' ../*" ',region-string))] + "--" + ["Convert to Link" + (progn (save-excursion (goto-char (region-beginning)) (insert "[[")) + (save-excursion (goto-char (region-end)) (insert "]]")))] + ["Insert Link Here" (org-mouse-yank-link ',event)])))) + + ((save-excursion (beginning-of-line) (looking-at "#\\+STARTUP: \\(.*\\)")) + (popup-menu + `(nil + ,@(org-mouse-list-options-menu (mapcar 'car org-startup-options) + 'org-mode-restart)))) ((or (eolp) (and (looking-at " \\|\t") (looking-back " \\|\t"))) (org-mouse-popup-global-menu)) -;; ((get-context :todo-keyword) ((get-context :checkbox) (popup-menu '(nil @@ -529,7 +616,9 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" ,@(org-mouse-keyword-replace-menu org-todo-keywords) "--" ["Check TODOs" org-show-todo-tree t] - ["Display TODO List" org-todo-list t] + ["List all TODO keywords" org-todo-list t] + [,(format "List only %s" (match-string 0)) + (org-todo-list (match-string 0)) t] ))) ((and (org-mouse-looking-at "\\b[A-Z]+:" "A-Z") (member (match-string 0) stamp-prefixes)) @@ -549,7 +638,10 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" ["Open in Emacs" (org-open-at-point t) t] "--" ["Copy link" (kill-new (match-string 0))] - ["Cut link" (kill-region (match-beginning 0) (match-end 0))] + ["Cut link" + (progn + (kill-region (match-beginning 0) (match-end 0)) + (just-one-space))] ; ["Paste file link" ((insert "file:") (yank))] ))) ((org-mouse-looking-at ":\\([A-Za-z0-9_]+\\):" "A-Za-z0-9_" -1) ;tags @@ -557,7 +649,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" `(nil [,(format "Display '%s'" (match-string 1)) (org-tags-view nil ,(match-string 1))] - [,(format "Narrow to '%s'" (match-string 1)) + [,(format "Sparse Tree '%s'" (match-string 1)) (org-tags-sparse-tree nil ,(match-string 1))] "--" ,@(org-mouse-tag-menu)))) @@ -594,6 +686,9 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" priority "Priority %s") "--" ,@(org-mouse-tag-menu)) + ("TODO Status" + ,@(progn (org-mouse-match-todo-keyword) + (org-mouse-keyword-replace-menu org-todo-keywords 1))) ["Show Tags" (with-current-buffer org-mouse-main-buffer (org-agenda-show-tags)) :visible (not org-mouse-direct)] @@ -602,9 +697,6 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" :visible (not org-mouse-direct)] ,@(if org-mouse-direct '("--") nil) ["New Heading" org-mouse-insert-heading :visible org-mouse-direct] -;; ["New Appointment" org-mouse-new-appointment :visible org-mouse-direct] -;; "--" - ["Cycle TODO" org-todo] ["Set Deadline" (progn (org-mouse-end-headline) (insert " ") (org-deadline)) :active (not (save-excursion @@ -622,11 +714,6 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" ["Copy Subtree" org-copy-special] ["Paste Subtree" org-paste-special :visible org-mouse-direct] "--" -;; ["Promote Subtree" org-shiftmetaleft] -;; ["Demote Subtree" org-shiftmetaright] -;; ["Promote Heading" org-metaleft] -;; ["Demote Heading" org-metaright] -;; "--" ["Move Trees" org-mouse-move-tree :active nil] )))) (t @@ -646,14 +733,18 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" ;; (re-search-forward regexp eol t)) ;; (<= (match-beginning 0) point))))) +(defun org-mouse-mark-active () + (and mark-active transient-mark-mode)) + (defun org-mouse-in-region-p (pos) - (and mark-active (>= pos (region-beginning)) (< pos (region-end)))) + (and (org-mouse-mark-active) + (>= pos (region-beginning)) + (< pos (region-end)))) (defun org-mouse-down-mouse (event) (interactive "e") (setq this-command last-command) - (unless (and transient-mark-mode - (= 1 (event-click-count event)) + (unless (and (= 1 (event-click-count event)) (org-mouse-in-region-p (posn-point (event-start event)))) (mouse-drag-region event))) @@ -667,6 +758,8 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" (define-key org-mode-map [down-mouse-1] 'org-mouse-down-mouse) (define-key org-mouse-map [C-drag-mouse-1] 'org-mouse-move-tree) (define-key org-mouse-map [C-down-mouse-1] 'org-mouse-move-tree-start) + (define-key org-mode-map [S-mouse-2] 'org-mouse-yank-link) + (define-key org-mode-map [drag-mouse-3] 'org-mouse-yank-link) (define-key org-mouse-map [drag-mouse-3] 'org-mouse-move-tree) (define-key org-mouse-map [down-mouse-3] 'org-mouse-move-tree-start) @@ -801,7 +894,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" (org-agenda-change-all-lines newhead hdmarker 'fixface))) t)))) -(defun org-mouse-agenda-context-menu () +(defun org-mouse-agenda-context-menu (&optional event) (or (org-mouse-do-remotely 'org-mouse-context-menu) (popup-menu '("Agenda" @@ -809,17 +902,21 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" "--" ["Rebuild Buffer" org-agenda-redo t] ["New Diary Entry" - org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline)] + org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline) t] "--" ["Goto Today" org-agenda-goto-today - (org-agenda-check-type nil 'agenda 'timeline)] + (org-agenda-check-type nil 'agenda 'timeline) t] ["Display Calendar" org-agenda-goto-calendar - (org-agenda-check-type nil 'agenda 'timeline)] + (org-agenda-check-type nil 'agenda 'timeline) t] ("Calendar Commands" - ["Phases of the Moon" org-agenda-phases-of-moon (org-agenda-check-type nil 'agenda 'timeline)] - ["Sunrise/Sunset" org-agenda-sunrise-sunset (org-agenda-check-type nil 'agenda 'timeline)] - ["Holidays" org-agenda-holidays (org-agenda-check-type nil 'agenda 'timeline)] - ["Convert" org-agenda-convert-date (org-agenda-check-type nil 'agenda 'timeline)] + ["Phases of the Moon" org-agenda-phases-of-moon + (org-agenda-check-type nil 'agenda 'timeline)] + ["Sunrise/Sunset" org-agenda-sunrise-sunset + (org-agenda-check-type nil 'agenda 'timeline)] + ["Holidays" org-agenda-holidays + (org-agenda-check-type nil 'agenda 'timeline)] + ["Convert" org-agenda-convert-date + (org-agenda-check-type nil 'agenda 'timeline)] "--" ["Create iCalendar file" org-export-icalendar-combine-agenda-files t]) "--" @@ -847,13 +944,27 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:" )))) +(defun org-mouse-get-gesture (event) + (let ((startxy (posn-x-y (event-start event))) + (endxy (posn-x-y (event-end event)))) + (if (< (car startxy) (car endxy)) :right :left))) + + ; (setq org-agenda-mode-hook nil) (add-hook 'org-agenda-mode-hook '(lambda () -; (define-key org-agenda-keymap [follow-link] 'mouse-face) (setq org-mouse-context-menu-function 'org-mouse-agenda-context-menu) - (define-key org-agenda-keymap - (if (featurep 'xemacs) [button3] [mouse-3]) 'org-mouse-show-context-menu))) + (define-key org-agenda-keymap + (if (featurep 'xemacs) [button3] [mouse-3]) + 'org-mouse-show-context-menu) + (define-key org-agenda-keymap [down-mouse-3] 'org-mouse-move-tree-start) + (define-key org-agenda-keymap [C-mouse-4] 'org-agenda-earlier) + (define-key org-agenda-keymap [C-mouse-5] 'org-agenda-later) + (define-key org-agenda-keymap [drag-mouse-3] + '(lambda (event) (interactive "e") + (case (org-mouse-get-gesture event) + (:left (org-agenda-earlier 1)) + (:right (org-agenda-later 1))))))) (provide 'org-mouse) \ No newline at end of file diff --git a/org.el b/org.el index 1ff8f57f2..7435b7937 100644 --- a/org.el +++ b/org.el @@ -1,11 +1,11 @@ -;;; org.el --- Outline-based notes management and organize +;;;; org.el --- Outline-based notes management and organize ;; Carstens outline-mode for keeping track of everything. ;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/ -;; Version: 4.57a +;; Version: 4.58 ;; ;; This file is part of GNU Emacs. ;; @@ -61,8 +61,14 @@ ;; ;; Recent changes ;; -------------- -;; Version 4.57a -;; - Bug fixes for XEmacs. +;; Version 4.58 +;; - Full undo support in the agenda buffer. +;; - Listing stuck GTD projects (projects without any NEXT ACTIONS). +;; Configure `org-stuck-projects' before using it. +;; - C-c C-x b shows the current subtree in an indirect buffer, in +;; another, dedicated frame. +;; - Custom agenda commands take precedence over builtin commands. +;; - auto-fill for comments works on the Emacs side, XEmacs not yet. ;; ;; Version 4.57 ;; - Sorting of outline items on same level. @@ -131,15 +137,15 @@ (require 'time-date) (require 'easymenu) -;;; Customization variables +;;;; Customization variables -(defvar org-version "4.57a" +(defvar org-version "4.58" "The version number of the file org.el.") (defun org-version () (interactive) (message "Org-mode version %s" org-version)) -;; Compatibility constants +;;; Compatibility constants (defconst org-xemacs-p (featurep 'xemacs)) ; not used by org.el itself (defconst org-format-transports-properties-p (let ((x "a")) @@ -361,6 +367,7 @@ the values `folded', `children', or `subtree'." :group 'org-cycle :type 'hook) + (defgroup org-edit-structure nil "Options concerning structure editing in Org-mode." :tag "Org Edit Structure" @@ -538,7 +545,7 @@ use \\[org-ctrl-c-ctrl-c] to trigger renumbering." When this is set, checkbox statistics is updated each time you either insert a new checkbox with \\[org-insert-todo-heading] or toggle a checkbox with \\[org-ctrl-c-ctrl-c\\]." - :group 'org + :group 'org-plain-lists :type 'boolean) (defgroup org-archive nil @@ -558,7 +565,7 @@ not contribute to the agenda listings." "Non-nil means, the agenda will skip any items located in archived trees. An archived tree is a tree marked with the tag ARCHIVE." :group 'org-archive - :group 'org-agenda-display + :group 'org-agenda-skip :type 'boolean) (defcustom org-cycle-open-archived-trees nil @@ -1323,7 +1330,7 @@ the following lines anywhere in the buffer: #+STARTUP: logging #+STARTUP: nologging" -;; FIXME: in-buffer words for notes??????? + ;; FIXME: in-buffer words for notes??????? :group 'org-todo :type '(choice (const :tag "off" nil) @@ -1520,7 +1527,7 @@ make sure all corresponding TODO items find their way into the list." "The last used completion table for tags.") (defgroup org-agenda nil - "Options concerning agenda display Org-mode." + "Options concerning agenda views in Org-mode." :tag "Org Agenda" :group 'org) @@ -1551,6 +1558,30 @@ agenda file per line." (repeat :tag "List of files" file) (file :tag "Store list in a file\n" :value "~/.agenda_files"))) + +(defcustom org-agenda-confirm-kill 1 + "When set, remote killing from the agenda buffer needs confirmation. +When t, a confirmation is always needed. When a number N, confirmation is +only needed when the text to be killed contains more than N non-white lines." + :group 'org-agenda + :type '(choice + (const :tag "Never" nil) + (const :tag "Always" t) + (number :tag "When more than N lines"))) + +(defcustom org-calendar-to-agenda-key [?c] + "The key to be installed in `calendar-mode-map' for switching to the agenda. +The command `org-calendar-goto-agenda' will be bound to this key. The +default is the character `c' because then `c' can be used to switch back and +forth between agenda and calendar." + :group 'org-agenda + :type 'sexp) + +(defgroup org-agenda-custom-commands nil + "Options concerning agenda views in Org-mode." + :tag "Org Agenda Custom Commands" + :group 'org-agenda) + (defcustom org-agenda-custom-commands '(("w" todo "WAITING")) "Custom commands for the agenda. These commands will be offered on the splash screen displayed by the @@ -1593,7 +1624,7 @@ cmd An agenda command, similar to the above. However, tree commands Each command can carry a list of options, and another set of options can be given for the whole set of commands. Individual command options take precedence over the general options." - :group 'org-agenda + :group 'org-agenda-custom-commands :type '(repeat (choice (list :tag "Single command" @@ -1604,7 +1635,8 @@ precedence over the general options." (const :tag "TODO keyword search (all agenda files)" todo) (const :tag "Tags sparse tree (current buffer)" tags-tree) (const :tag "TODO keyword tree (current buffer)" todo-tree) - (const :tag "Occur tree (current buffer)" occur-tree)) + (const :tag "Occur tree (current buffer)" occur-tree) + (symbol :tag "Other, user-defined function")) (string :tag "Match") (repeat :tag "Local options" (list (variable :tag "Option") (sexp :tag "Value")))) @@ -1632,18 +1664,53 @@ precedence over the general options." (list :tag "TODO keyword search" (const :format "" todo) (string :tag "Match") + (repeat :tag "Local options" + (list (variable :tag "Option") + (sexp :tag "Value")))) + + (list :tag "Other, user-defined function" ; FIXME: untested + (symbol :tag "function") + (string :tag "Match") (repeat :tag "Local options" (list (variable :tag "Option") (sexp :tag "Value")))))) + (repeat :tag "General options" (list (variable :tag "Option") (sexp :tag "Value"))))))) +(defcustom org-stuck-projects + '("+LEVEL=2/-DONE" ("TODO" "NEXT" "NEXTACTION") nil) + "How to identify stuck projects. +This is a list of three items: +1. A tags/todo matcher string that is used to identify a project. + The entire tree below a headline matched by this is considered a project. +2. A list of TODO keywords itentifying non-stuck projects. + If the project subtree contains any headline with one of these todo + keywords, the project is consitered to be not stuck. +3. A list of tags identifying non-stuck projects. + If the project subtree contains any headline with one of these tags, + the project is consitered to be not stuck. + +After defining this variable, you may use \\[org-agenda-list-stuck-projects] +or `C-c a #' to produce the list." + :group 'org-agenda-custom-commands + :type '(list + (string :tag "Tags/TODO match to identify a project") + (repeat :tag "Projects are *not* stuck if they have an entry with TODO keyword any of" (string)) + (repeat :tag "Projects are *not* stuck if they have an entry with TAG being any of" (string)))) + + +(defgroup org-agenda-skip nil + "Options concerning skipping parts of agenda files." + :tag "Org Agenda Skip" + :group 'org-agenda) + (defcustom org-agenda-todo-list-sublevels t "Non-nil means, check also the sublevels of a TODO entry for TODO entries. When nil, the sublevels of a TODO entry are not checked, resulting in potentially much shorter TODO lists." - :group 'org-agenda + :group 'org-agenda-skip :group 'org-todo :type 'boolean) @@ -1651,7 +1718,7 @@ potentially much shorter TODO lists." "Non-nil means, don't show scheduled entries in the global todo list. The idea behind this is that by scheduling it, you have already taken care of this item." - :group 'org-agenda + :group 'org-agenda-skip :group 'org-todo :type 'boolean) @@ -1659,14 +1726,14 @@ of this item." "Non-nil means, don't show near deadline entries in the global todo list. Near means closer than `org-deadline-warning-days' days. The idea behind this is that such items will appear in the agenda anyway." - :group 'org-agenda + :group 'org-agenda-skip :group 'org-todo :type 'boolean) (defcustom org-agenda-skip-scheduled-if-done nil "Non-nil means don't show scheduled items in agenda when they are done. This is relevant for the daily/weekly agenda, not for the TODO list." - :group 'org-agenda + :group 'org-agenda-skip :type 'boolean) (defcustom org-timeline-show-empty-dates 3 @@ -1675,46 +1742,38 @@ When nil, only the days which actually have entries are shown. When t, all days between the first and the last date are shown. When an integer, show also empty dates, but if there is a gap of more than N days, just insert a special line indicating the size of the gap." - :group 'org-agenda + :group 'org-agenda-skip ; FIXME: not quite the right group... :type '(choice (const :tag "None" nil) (const :tag "All" t) (number :tag "at most"))) -(defcustom org-agenda-confirm-kill 1 - "When set, remote killing from the agenda buffer needs confirmation. -When t, a confirmation is always needed. When a number N, confirmation is -only needed when the text to be killed contains more than N non-white lines." - :group 'org-agenda - :type '(choice - (const :tag "Never" nil) - (const :tag "Always" t) - (number :tag "When more than N lines"))) -;; FIXME: This variable could be removed -(defcustom org-agenda-include-all-todo nil - "Set means weekly/daily agenda will always contain all TODO entries. -The TODO entries will be listed at the top of the agenda, before -the entries for specific days." - :group 'org-agenda +(defgroup org-agenda-startup nil + "Options concerning initial settings in the Agenda in Org Mode." + :tag "Org Agenda Startup" + :group 'org-agenda) + +(defcustom org-finalize-agenda-hook nil + "Hook run just before displaying an agenda buffer." + :group 'org-agenda-startup + :type 'hook) + +(defcustom org-agenda-mouse-1-follows-link nil + "Non-nil means, mouse-1 on a link will follow the link in the agenda. +A longer mouse click will still set point. Does not wortk on XEmacs. +Needs to be set before org.el is loaded." + :group 'org-agenda-startup :type 'boolean) -(defcustom org-agenda-include-diary nil - "If non-nil, include in the agenda entries from the Emacs Calendar's diary." - :group 'org-agenda +(defcustom org-agenda-start-with-follow-mode nil + "The initial value of follwo-mode in a newly created agenda window." + :group 'org-agenda-startup :type 'boolean) -(defcustom org-calendar-to-agenda-key [?c] - "The key to be installed in `calendar-mode-map' for switching to the agenda. -The command `org-calendar-goto-agenda' will be bound to this key. The -default is the character `c' because then `c' can be used to switch back and -forth between agenda and calendar." - :group 'org-agenda - :type 'sexp) - -(defgroup org-agenda-setup nil - "Options concerning setting up the Agenda window in Org Mode." - :tag "Org Agenda Window Setup" +(defgroup org-agenda-windows nil + "Options concerning the windows used by the Agenda in Org Mode." + :tag "Org Agenda Windows" :group 'org-agenda) (defcustom org-agenda-window-setup 'reorganize-frame @@ -1729,7 +1788,7 @@ reorganize-frame Show only two windows on the current frame, the current `org-fit-agenda-window' is set, resize the agenda window to try to show as much as possible of the buffer content. See also the variable `org-agenda-restore-windows-after-quit'." - :group 'org-agenda-setup + :group 'org-agenda-windows :type '(choice (const current-window) (const other-frame) @@ -1743,64 +1802,82 @@ the current status is recorded. When the agenda is exited with `q' or `x' and this option is set, the old state is restored. If `org-agenda-window-setup' is `other-frame', the value of this option will be ignored.." - :group 'org-agenda-setup + :group 'org-agenda-windows :type 'boolean) -;; FIXME: I think this variable could be removed. +;; FIXME: I think this variable could be removed, default set to t (defcustom org-select-agenda-window t "Non-nil means, after creating an agenda, move cursor into Agenda window. When nil, cursor will remain in the current window." - :group 'org-agenda-setup + :group 'org-agenda-windows :type 'boolean) -;; FIXME: I think this variable could be removed. +;; FIXME: I think this variable could be removed, default set to t (defcustom org-fit-agenda-window t "Non-nil means, change window size of agenda to fit content. This is only effective if `org-agenda-window-setup' is `reorganize-frame'." - :group 'org-agenda-setup + :group 'org-agenda-windows :type 'boolean) -(defcustom org-finalize-agenda-hook nil - "Hook run just before displaying an agenda buffer." - :group 'org-agenda-setup - :type 'hook) -(defcustom org-agenda-mouse-1-follows-link nil - "Non-nil means, mouse-1 on a link will follow the link in the agenda. -A longer mouse click will still set point. Does not wortk on XEmacs. -Needs to be set before org.el is loaded." - :group 'org-agenda-setup - :type 'boolean) +(defcustom org-indirect-tree-new-frame 'dedicated + "How should indirect tree buffers be displayed? +This applies to indirect buffers created with the commands +\\[org-tree-to-indirect-buffer] and \\[org-agenda-tree-to-indirect-buffer]. +Valid values are: +nil Just display in another window. +t Use a new frame for each indirect buffer created in this way. +dedicated Create one new frame, and re-use it each time the command is + used. This also means that old indirect buffers will be + deleted when a new one is displayed. This is the default." + :group 'org-structure + :group 'org-agenda-windows + :type '(choice + (const :tag "In current frame" nil) + (const :tag "Each time a new frame" t) + (const :tag "One dedicated frame" 'dedicated))) -(defcustom org-agenda-start-with-follow-mode nil - "The initial value of follwo-mode in a newly created agenda window." - :group 'org-agenda-setup - :type 'boolean) - -(defgroup org-agenda-display nil - "Options concerning what to display initially in Agenda." - :tag "Org Agenda Display" +(defgroup org-agenda-daily/weekly nil + "Options concerning the daily/weekly agenda." + :tag "Org Agenda Daily/Weekly" :group 'org-agenda) -(defcustom org-agenda-show-all-dates t - "Non-nil means, `org-agenda' shows every day in the selected range. -When nil, only the days which actually have entries are shown." - :group 'org-agenda-display - :type 'boolean) +(defcustom org-agenda-ndays 7 + "Number of days to include in overview display. +Should be 1 or 7." + :group 'org-agenda-daily/weekly + :type 'number) (defcustom org-agenda-start-on-weekday 1 "Non-nil means, start the overview always on the specified weekday. 0 denotes Sunday, 1 denotes Monday etc. When nil, always start on the current day." - :group 'org-agenda-display + :group 'org-agenda-daily/weekly :type '(choice (const :tag "Today" nil) (number :tag "Weekday No."))) +(defcustom org-agenda-show-all-dates t + "Non-nil means, `org-agenda' shows every day in the selected range. +When nil, only the days which actually have entries are shown." + :group 'org-agenda-daily/weekly + :type 'boolean) -(defcustom org-agenda-ndays 7 - "Number of days to include in overview display. -Should be 1 or 7." - :group 'org-agenda-display - :type 'number) +(defcustom org-agenda-include-diary nil + "If non-nil, include in the agenda entries from the Emacs Calendar's diary." + :group 'org-agenda-daily/weekly + :type 'boolean) + +;; FIXME: This variable could be removed +(defcustom org-agenda-include-all-todo nil + "Set means weekly/daily agenda will always contain all TODO entries. +The TODO entries will be listed at the top of the agenda, before +the entries for specific days." + :group 'org-agenda-daily/weekly + :type 'boolean) + +(defgroup org-agenda-time-grid nil + "Options concerning the time grid in the Org-mode Agenda." + :tag "Org Agenda Time Grid" + :group 'org-agenda) (defcustom org-agenda-use-time-grid t "Non-nil means, show a time grid in the agenda schedule. @@ -1809,7 +1886,7 @@ A time grid is a set of lines for specific times (like every two hours between sorted in between these lines. For details about when the grid will be shown, and what it will look like, see the variable `org-agenda-time-grid'." - :group 'org-agenda-display + :group 'org-agenda-time-grid :type 'boolean) (defcustom org-agenda-time-grid @@ -1830,7 +1907,7 @@ The second item is a string which will be places behing the grid time. The third item is a list of integers, indicating the times that should have a grid line." - :group 'org-agenda-display + :group 'org-agenda-time-grid :type '(list (set :greedy t :tag "Grid Display Options" @@ -1844,6 +1921,11 @@ a grid line." (string :tag "Grid String") (repeat :tag "Grid Times" (integer :tag "Time")))) +(defgroup org-agenda-sorting nil + "Options concerning sorting in the Org-mode Agenda." + :tag "Org Agenda Sorting" + :group 'org-agenda) + (let ((sorting-choice '(choice (const time-up) (const time-down) @@ -1883,7 +1965,7 @@ priority. Leaving out `category-keep' would mean that items will be sorted across categories by priority." - :group 'org-agenda-display + :group 'org-agenda-sorting :type `(choice (repeat :tag "General" ,sorting-choice) (list :tag "Individually" @@ -1901,7 +1983,7 @@ time like 15:30 will be considered as 99:01, i.e. later than any items which do have a time. When nil, the default time is before 0:00. You can use this option to decide if the schedule for today should come before or after timeless agenda entries." - :group 'org-agenda-display + :group 'org-agenda-sorting :type 'boolean) (defgroup org-agenda-prefix nil @@ -3103,8 +3185,7 @@ Also put tags into group 4 if tags are present.") (org-set-font-lock-defaults))) -;; Tell the compiler about dynamically scoped variables, -;; and variables from other packages +;;; Tell the compiler about dynamically scoped variables, or foreign vars (defvar calc-embedded-close-formula) ; defined by the calc package (defvar calc-embedded-open-formula) ; defined by the calc package (defvar font-lock-unfontify-region-function) ; defined by font-lock.el @@ -3158,8 +3239,11 @@ Also put tags into group 4 if tags are present.") (defvar outline-mode-menu-heading) (defvar outline-mode-menu-show) (defvar outline-mode-menu-hide) +(defvar org-agenda-undo-list) ;; Defined later in this file +(defvar org-agenda-pending-undo-list) ;; Defined later in this file +(defvar org-agenda-overriding-header) ;; Defined later in this file -;;; Define the mode +;;;; Define the mode (if (and (not (keymapp outline-mode-map)) (featurep 'allout)) (error "Conflict with outdated version of allout.el. Load org.el before allout.el, or ugrade to newer allout, for example by switching to Emacs 22.")) @@ -3295,7 +3379,7 @@ that will be added to PLIST. Returns the string that was modified." (put 'org-add-props 'lisp-indent-function 2) -;;; Font-Lock stuff +;;;; Font-Lock stuff (defvar org-mouse-map (make-sparse-keymap)) (define-key org-mouse-map @@ -3687,7 +3771,7 @@ between words." rear-nonsticky t invisible t intangible t)))) -;;; Visibility cycling +;;;; Visibility cycling (defvar org-cycle-global-status nil) (make-variable-buffer-local 'org-cycle-global-status) @@ -4054,7 +4138,85 @@ or nil." (setq org-selected-point nil) (throw 'exit nil)) -;;; Promotion, Demotion, Inserting new headlines +;;; Indirect buffer display of subtrees + +(defvar org-indirect-dedicated-frame nil + "This is the frame being used for indirect tree display.") +(defvar org-last-indirect-buffer nil) + +(defun org-tree-to-indirect-buffer (&optional arg) + "Create indirect buffer and narrow it to current subtree. +With numerical prefix arg ARG, go up to this level and then take that tree. +If ARG is negative, go up that many levels. +With a C-u prefix, make a separate frame for this tree (i.e. don't use the +dedicated frame)." + (interactive "P") + (let ((cbuf (current-buffer)) + (pos (point)) + (bname (buffer-name (current-buffer))) + (org-indirect-tree-new-frame + (if (equal arg '(4)) t org-indirect-tree-new-frame)) + beg end level heading) + + (save-excursion + (org-back-to-heading t) + (when (numberp arg) + (setq level (org-outline-level)) + (if (< arg 0) (setq arg (+ level arg))) + (while (> (setq level (org-outline-level)) arg) + (outline-up-heading 1 t))) + (setq beg (point) + heading (org-get-heading)) + (org-end-of-subtree t) (setq end (point))) + (cond + ((eq org-indirect-tree-new-frame 'dedicated) + (raise-frame + (select-frame (or (and org-indirect-dedicated-frame + (frame-live-p org-indirect-dedicated-frame) + org-indirect-dedicated-frame) + (setq org-indirect-dedicated-frame (make-frame))))) + (delete-other-windows) + (if (equal cbuf (buffer-base-buffer)) + ;; Re-use this buffer + (widen) + ;; clean up from last time + (if (buffer-base-buffer (current-buffer)) + (kill-buffer (current-buffer))) + (if (buffer-live-p org-last-indirect-buffer) + (kill-buffer org-last-indirect-buffer)) + ;; make and select the new indirect buffer + (switch-to-buffer + (setq org-last-indirect-buffer (org-get-indirect-buffer cbuf)))) + (org-set-frame-title (concat "Indirect: " heading))) + ((eq org-indirect-tree-new-frame t) + (select-frame (make-frame)) + (delete-other-windows) + (switch-to-buffer (org-get-indirect-buffer cbuf)) + (org-set-frame-title heading)) + (t (pop-to-buffer (org-get-indirect-buffer cbuf)))) + (if (featurep 'xemacs) + (save-excursion (org-mode) (turn-on-font-lock))) + (narrow-to-region beg end) + (show-all) + (goto-char pos))) + +(defun org-get-indirect-buffer (&optional buffer) + (setq buffer (or buffer (current-buffer))) + (let ((n 1) (base (buffer-name buffer)) bname) + (while (buffer-live-p + (get-buffer (setq bname (concat base "-" (number-to-string n))))) + (setq n (1+ n))) + (condition-case nil + (make-indirect-buffer buffer bname 'clone) + (error (make-indirect-buffer buffer bname))))) + +(defun org-set-frame-title (title) + "Set the title of the current frame to the string TITLE." + ;; FIXME: how to name a single frame in XEmacs??? + (unless (featurep 'xemacs) + (modify-frame-parameters (selected-frame) (list (cons 'name title))))) + +;;;; Promotion, Demotion, Inserting new headlines (defvar org-ignore-region nil "To temporarily disable the active region.") @@ -4610,7 +4772,7 @@ If optional TXT is given, check this string instead of the current kill." (progn (org-back-to-heading) (point)) (progn (org-end-of-subtree t) (point))))) -;;; Plain list items +;;;; Plain list items (defun org-at-item-p () "Is point in a line starting a hand-formatted item?" @@ -5293,9 +5455,18 @@ the children that do not contain any open TODO items." (match-beginning 0) (org-end-of-subtree t) pc))) (set-buffer-modified-p bmp))))) +(defvar org-agenda-skip-function nil + "Function to be called at each match during agenda construction. +If this function return nil, the current match should not be skipped. +Otherwise, the function must return a position from where the search +should be continued. +Never set this variable using `setq' or so, because then it will apply +to all future agenda commands. Instead, bind it with `let' to scope +it dynamically into the agenda-constructing command.") + (defun org-agenda-skip () "Throw to `:skip' in places that should be skipped." - (let ((p (point-at-bol))) + (let ((p (point-at-bol)) to) (and org-agenda-skip-archived-trees (get-text-property p :org-archived) (org-end-of-subtree t) @@ -5303,33 +5474,15 @@ the children that do not contain any open TODO items." (and (get-text-property p :org-comment) (org-end-of-subtree t) (throw :skip t)) - (if (equal (char-after p) ?#) (throw :skip t)))) + (if (equal (char-after p) ?#) (throw :skip t)) + (when (and (functionp org-agenda-skip-function) + (setq to (save-excursion + (save-match-data + (funcall org-agenda-skip-function))))) + (goto-char to) + (throw :skip t)))) -(defun org-agenda-toggle-archive-tag () - "Toggle the archive tag for the current entry." - (interactive) - (org-agenda-check-no-diary) - (org-agenda-show) ;;; FIXME This is a stupid hack and should not be needed - (let* ((hdmarker (or (get-text-property (point) 'org-hd-marker) - (org-agenda-error))) - (buffer (marker-buffer hdmarker)) - (pos (marker-position hdmarker)) - (buffer-read-only nil) - newhead) - (with-current-buffer buffer - (widen) - (goto-char pos) - (org-show-context 'agenda) - (save-excursion - (and (outline-next-heading) - (org-flag-heading nil))) ; show the next heading - (call-interactively 'org-toggle-archive-tag) - (end-of-line 1) - (setq newhead (org-get-heading))) - (org-agenda-change-all-lines newhead hdmarker) - (beginning-of-line 1))) - -;;; Dynamic blocks +;;;; Dynamic blocks (defun org-find-dblock (name) "Find the first dynamic block with name NAME in the buffer. @@ -5439,7 +5592,7 @@ This function can be used in a hook." (org-map-dblocks 'org-update-dblock))) -;;; Completion +;;;; Completion (defun org-complete (&optional arg) "Perform completion on word at point. @@ -5541,7 +5694,7 @@ At all other locations, this simply calls `ispell-complete-word'." (error (display-completion-list list))))) (message "Making completion list...%s" "done")))))) -;;; Comments, TODO and DEADLINE +;;;; Comments, TODO and DEADLINE (defun org-toggle-comment () "Change the COMMENT state of an entry." @@ -5950,7 +6103,7 @@ from the `before-change-functions' in the current buffer." (remove-hook 'before-change-functions 'org-remove-occur-highlights 'local)))) -;;; Priorities +;;;; Priorities (defvar org-priority-regexp ".*?\\(\\[#\\([A-Z]\\)\\] ?\\)" "Regular expression matching the priority indicator.") @@ -6020,7 +6173,7 @@ ACTION can be set, up, or down." (* 1000 (- org-lowest-priority (string-to-char (match-string 2 s))))))) -;;; Timestamps +;;;; Timestamps (defvar org-last-changed-timestamp nil) @@ -7028,7 +7181,7 @@ FIXME: describe the elements." (goto-char cont))) (nreverse rtn))) -;;; Agenda, and Diary Integration +;;;; Agenda, and Diary Integration ;;; Define the mode @@ -7051,6 +7204,8 @@ The following commands are available: \\{org-agenda-mode-map}" (interactive) (kill-all-local-variables) + (setq org-agenda-undo-list nil + org-agenda-pending-undo-list nil) (setq major-mode 'org-agenda-mode) (setq mode-name "Org-Agenda") (use-local-map org-agenda-mode-map) @@ -7078,8 +7233,8 @@ The following commands are available: (if (fboundp 'run-mode-hooks) 'run-mode-hooks 'run-hooks) (list 'org-agenda-mode-hook))) -;(substitute-key-definition 'undo 'org-agenda-undo -; org-agenda-mode-map global-map) +(substitute-key-definition 'undo 'org-agenda-undo + org-agenda-mode-map global-map) (define-key org-agenda-mode-map "\C-i" 'org-agenda-goto) (define-key org-agenda-mode-map [(tab)] 'org-agenda-goto) (define-key org-agenda-mode-map "\C-m" 'org-agenda-switch-to) @@ -7089,6 +7244,8 @@ The following commands are available: (define-key org-agenda-mode-map "\C-c\C-o" 'org-agenda-open-link) (define-key org-agenda-mode-map " " 'org-agenda-show) (define-key org-agenda-mode-map "\C-c\C-t" 'org-agenda-todo) +(define-key org-agenda-mode-map "\C-c\C-xb" 'org-agenda-tree-to-indirect-buffer) +(define-key org-agenda-mode-map "b" 'org-agenda-tree-to-indirect-buffer) (define-key org-agenda-mode-map "o" 'delete-other-windows) (define-key org-agenda-mode-map "L" 'org-agenda-recenter) (define-key org-agenda-mode-map "t" 'org-agenda-todo) @@ -7138,8 +7295,8 @@ The following commands are available: (define-key org-agenda-mode-map "H" 'org-agenda-holidays) (define-key org-agenda-mode-map "+" 'org-agenda-priority-up) (define-key org-agenda-mode-map "I" 'org-agenda-clock-in) -(define-key org-agenda-mode-map "O" 'org-clock-out) -(define-key org-agenda-mode-map "X" 'org-clock-cancel) +(define-key org-agenda-mode-map "O" 'org-agenda-clock-out) +(define-key org-agenda-mode-map "X" 'org-agenda-clock-cancel) (define-key org-agenda-mode-map "-" 'org-agenda-priority-down) (define-key org-agenda-mode-map (org-key 'S-up) 'org-agenda-priority-up) (define-key org-agenda-mode-map (org-key 'S-down) 'org-agenda-priority-down) @@ -7166,6 +7323,7 @@ The following commands are available: ["Go To (this window)" org-agenda-switch-to t] ["Follow Mode" org-agenda-follow-mode :style toggle :selected org-agenda-follow-mode :active t] + ["Tree to indirect frame" org-agenda-tree-to-indirect-buffer t] "--" ["Cycle TODO" org-agenda-todo t] ["Archive subtree" org-agenda-archive t] @@ -7215,12 +7373,89 @@ The following commands are available: ["Rebuild buffer" org-agenda-redo t] ["Save all Org-mode Buffers" org-save-all-org-buffers t] "--" -; ["Undo Remote Editing" org-agenda-undo org-agenda-multi-buffer-undo-list] -; "--" + ["Undo Remote Editing" org-agenda-undo org-agenda-undo-list] + "--" ["Quit" org-agenda-quit t] ["Exit and Release Buffers" org-agenda-exit t] )) +;;; Agenda undo + +(defvar org-agenda-allow-remote-undo t + "Non-nil means, allow remote undo from the agenda buffer.") +(defvar org-agenda-undo-list nil + "List of undoable operations in the agenda since last refresh.") +(defvar org-agenda-undo-has-started-in nil + "Buffers that have already seen `undo-start' in the current undo sequence.") +(defvar org-agenda-pending-undo-list nil + "In a series of undo commands, this is the list of remaning undo items.") + +(defmacro org-with-remote-undo (_buffer &rest _body) + "Execute BODY while recording undo information in two buffers." + (declare (indent 1) (debug t)) + `(let ((_cline (org-current-line)) + (_cmd this-command) + (_buf1 (current-buffer)) + (_buf2 ,_buffer) + (_undo1 buffer-undo-list) + (_undo2 (with-current-buffer ,_buffer buffer-undo-list)) + _c1 _c2) + ,@_body + (when org-agenda-allow-remote-undo + (setq _c1 (org-verify-change-for-undo + _undo1 (with-current-buffer _buf1 buffer-undo-list)) + _c2 (org-verify-change-for-undo + _undo2 (with-current-buffer _buf2 buffer-undo-list))) + (when (or _c1 _c2) + ;; make sure there are undo boundaries + (and _c1 (with-current-buffer _buf1 (undo-boundary))) + (and _c2 (with-current-buffer _buf2 (undo-boundary))) + ;; remember which buffer to undo + (push (list _cmd _cline _buf1 _c1 _buf2 _c2) + org-agenda-undo-list))))) + +(defun org-agenda-undo () + "Undo a remote editing step in the agenda. +This undoes changes both in the agenda buffer and in the remote buffer +that have been changed along." + (interactive) + (or org-agenda-allow-remote-undo + (error "Check the variable `org-agenda-allow-remote-undo' to activate remote undo.")) + (if (not (eq this-command last-command)) + (setq org-agenda-undo-has-started-in nil + org-agenda-pending-undo-list org-agenda-undo-list)) + (if (not org-agenda-pending-undo-list) + (error "No further undo information")) + (let* ((entry (pop org-agenda-pending-undo-list)) + buf line cmd rembuf) + (setq cmd (pop entry) line (pop entry)) + (setq rembuf (nth 2 entry)) + (org-with-remote-undo rembuf + (while (bufferp (setq buf (pop entry))) + (if (pop entry) + (with-current-buffer buf + (let ((last-undo-buffer buf) + buffer-read-only) + (unless (memq buf org-agenda-undo-has-started-in) + (push buf org-agenda-undo-has-started-in) + (make-local-variable 'pending-undo-list) + (undo-start)) + (while (and pending-undo-list + (listp pending-undo-list) + (not (car pending-undo-list))) + (pop pending-undo-list)) + (undo-more 1)))))) + (goto-line line) + (message "`%s' undone (buffer %s)" cmd (buffer-name rembuf)))) + +(defun org-verify-change-for-undo (l1 l2) + "Verify that a real change occurred between the undo lists L1 and L2." + (while (and l1 (listp l1) (null (car l1))) (pop l1)) + (while (and l2 (listp l2) (null (car l2))) (pop l2)) + (not (eq l1 l2))) + +;;; Agenda dispatch + (defvar org-agenda-restrict nil) (defvar org-agenda-restrict-begin (make-marker)) (defvar org-agenda-restrict-end (make-marker)) @@ -7254,7 +7489,7 @@ next use of \\[org-agenda]) restricted to the current file." (bfn (buffer-file-name (buffer-base-buffer))) (restrict-ok (and bfn (org-mode-p))) (custom org-agenda-custom-commands) - c entry key type match lprops) + c entry key type match lprops header) ;; Turn off restriction (put 'org-agenda-files 'org-restrict nil) (setq org-agenda-restrict nil) @@ -7266,17 +7501,26 @@ next use of \\[org-agenda]) restricted to the current file." (delete-other-windows) (switch-to-buffer-other-window " *Agenda Commands*") (erase-buffer) - (insert - "Press key for an agenda command: --------------------------------- + (insert (eval-when-compile + (let ((header +"Press key for an agenda command: +-------------------------------- C Configure custom agenda commands a Agenda for current week or day t List of all TODO entries T Entries with special TODO kwd m Match a TAGS query M Like m, but only TODO entries -L Timeline for current buffer C Configure custom agenda commands") +L Timeline for current buffer # List stuck projects (!=configure) +") + (start 0)) + (while (string-match "\\(^\\| \\|(\\)\\(\\S-\\)\\( \\|=\\)" header start) + (setq start (match-end 0)) + (add-text-properties (match-beginning 2) (match-end 2) + '(face bold) header)) + header))) (while (setq entry (pop custom)) (setq key (car entry) type (nth 1 entry) match (nth 2 entry)) (insert (format "\n%-4s%-14s: %s" - key + (org-add-props (copy-sequence key) + '(face bold)) (cond ((stringp type) type) ((eq type 'tags) "Tags query") @@ -7284,6 +7528,7 @@ L Timeline for current buffer C Configure custom agenda commands") ((eq type 'tags-tree) "Tags tree") ((eq type 'todo-tree) "TODO kwd tree") ((eq type 'occur-tree) "Occur tree") + ((functionp type) (symbol-name type)) (t "???")) (if (stringp match) (org-add-props match nil 'face 'org-warning) @@ -7326,16 +7571,6 @@ L Timeline for current buffer C Configure custom agenda commands") (require 'calendar) ; FIXME: can we avoid this for some commands? ;; For example the todo list should not need it (but does...) (cond - ((equal c ?C) (customize-variable 'org-agenda-custom-commands)) - ((equal c ?a) (call-interactively 'org-agenda-list)) - ((equal c ?t) (call-interactively 'org-todo-list)) - ((equal c ?T) (org-call-with-arg 'org-todo-list (or arg '(4)))) - ((equal c ?m) (call-interactively 'org-tags-view)) - ((equal c ?M) (org-call-with-arg 'org-tags-view (or arg '(4)))) - ((equal c ?L) - (unless restrict-ok - (error "This is not an Org-mode file")) - (org-call-with-arg 'org-timeline arg)) ((setq entry (assoc (char-to-string c) org-agenda-custom-commands)) (if (symbolp (nth 1 entry)) (progn @@ -7359,8 +7594,22 @@ L Timeline for current buffer C Configure custom agenda commands") ((eq type 'occur-tree) (org-check-for-org-mode) (org-let lprops '(org-occur match))) + ((fboundp type) + (org-let lprops '(funcall type match))) (t (error "Invalid custom agenda command type %s" type)))) (org-run-agenda-series (cddr entry)))) + ((equal c ?C) (customize-variable 'org-agenda-custom-commands)) + ((equal c ?a) (call-interactively 'org-agenda-list)) + ((equal c ?t) (call-interactively 'org-todo-list)) + ((equal c ?T) (org-call-with-arg 'org-todo-list (or arg '(4)))) + ((equal c ?m) (call-interactively 'org-tags-view)) + ((equal c ?M) (org-call-with-arg 'org-tags-view (or arg '(4)))) + ((equal c ?L) + (unless restrict-ok + (error "This is not an Org-mode file")) + (org-call-with-arg 'org-timeline arg)) + ((equal c ?#) (call-interactively 'org-agenda-list-stuck-projects)) + ((equal c ?!) (customize-variable 'org-stuck-projects)) (t (error "Invalid key")))))) ;; FIXME: what is the meaning of WINDOW????? @@ -7389,6 +7638,9 @@ L Timeline for current buffer C Configure custom agenda commands") ((eq type 'todo) (org-let2 gprops lprops '(org-todo-list match))) + ((fboundp type) + (org-let2 gprops lprops + '(funcall type match))) (t (error "Invalid type in command series")))) (widen) (setq org-agenda-redo-command redo) @@ -7787,22 +8039,25 @@ for a keyword. A numeric prefix directly selects the Nth keyword in (org-check-agenda-file file) (setq rtn (org-agenda-get-day-entries file date :todo)) (setq rtnall (append rtnall rtn)))) - (insert "Global list of TODO items of type: ") - (add-text-properties (point-min) (1- (point)) - (list 'face 'org-level-3)) - (setq pos (point)) - (insert (or org-select-this-todo-keyword "ALL") "\n") - (add-text-properties pos (1- (point)) (list 'face 'org-warning)) - (setq pos (point)) - (unless org-agenda-multi - (insert - "Available with `N r': (0)ALL " - (let ((n 0)) - (mapconcat (lambda (x) - (format "(%d)%s" (setq n (1+ n)) x)) - org-todo-keywords " ")) - "\n")) - (add-text-properties pos (1- (point)) (list 'face 'org-level-3)) + (if org-agenda-overriding-header + (insert (org-add-props (copy-sequence org-agenda-overriding-header) + nil 'face 'org-level-3) "\n") + (insert "Global list of TODO items of type: ") + (add-text-properties (point-min) (1- (point)) + (list 'face 'org-level-3)) + (setq pos (point)) + (insert (or org-select-this-todo-keyword "ALL") "\n") + (add-text-properties pos (1- (point)) (list 'face 'org-warning)) + (setq pos (point)) + (unless org-agenda-multi + (insert + "Available with `N r': (0)ALL " + (let ((n 0)) + (mapconcat (lambda (x) + (format "(%d)%s" (setq n (1+ n)) x)) + org-todo-keywords " ")) + "\n")) + (add-text-properties pos (1- (point)) (list 'face 'org-level-3))) (when rtnall (insert (org-finalize-agenda-entries rtnall) "\n")) (goto-char (point-min)) @@ -7812,6 +8067,55 @@ for a keyword. A numeric prefix directly selects the Nth keyword in (setq buffer-read-only t) (if (not org-select-agenda-window) (select-window win)))) +;;; Finding stuck projects +(defvar org-agenda-skip-regexp nil + "Regular expression used in skipping subtrees for the agenda. +This is basically a temporary global variable that can be set and then +used by user-defined selections using `org-agenda-skip-function'.") + +(defvar org-agenda-overriding-header nil + "When this is set during todo and tags searches, will replace header.") + +(defun org-agenda-skip-subtree-when-regexp-matches () + "Checks if the current subtree contains match for `org-agenda-skip-regexp'. +If yes, it returns the end position of this tree, causing agenda commands +to skip this subtree. This is a function that can be put into +`org-agenda-skip-function' for the duration of a command." + (save-match-data + (let ((end (save-excursion (org-end-of-subtree t))) + skip) + (save-excursion + (setq skip (re-search-forward org-agenda-skip-regexp end t))) + (and skip end)))) + +(defun org-agenda-list-stuck-projects (match) + "Create agenda view for projects that are stuck. +Stuck projects are project that have no next actions. For the definitions +of what a project is and how to check if it stuck, customize the variable +`org-stuck-projects'. +MATCH is being ignored." + (interactive) + (let* ((org-agenda-skip-function 'org-agenda-skip-subtree-when-regexp-matches) + (org-agenda-overriding-header "List of stuck projects: ") + (matcher (nth 0 org-stuck-projects)) + (todo (nth 1 org-stuck-projects)) + (tags (nth 2 org-stuck-projects)) + (todo-re (concat "^\\*+[ \t]+\\(" + (mapconcat 'identity todo "\\|") + "\\)\\>")) + (tags-re (concat "^\\*+.*:\\(" + (mapconcat 'identity tags "\\|") + "\\):[a-zA-Z0-9_@:]*[ \t]*$"))) + + (setq org-agenda-skip-regexp + (cond + ((and todo tags) + (concat todo-re "\\|" tags-re)) + (todo todo-re) + (tags tags-re) + (t (error "No information how to identify unstuck projects")))) + (org-tags-view nil matcher))) + (defun org-check-agenda-file (file) "Make sure FILE exists. If not, ask user what to do." (when (not (file-exists-p file)) @@ -7871,6 +8175,8 @@ When this is the global TODO list, a prefix argument will be interpreted." (window-line (- line (org-current-line (window-start))))) (message "Rebuilding agenda buffer...") (eval org-agenda-redo-command) + (setq org-agenda-undo-list nil + org-agenda-pending-undo-list nil) (message "Rebuilding agenda buffer...done") (goto-line line) (recenter window-line))) @@ -8751,6 +9057,7 @@ the documentation of `org-diary'." ;; Sort the entries by expiration date. (nreverse ee))) +;; FIXME: should I allow spaces around the dash? (defconst org-plain-time-of-day-regexp (concat "\\(\\<[012]?[0-9]" @@ -9089,27 +9396,28 @@ and by additional input from the age of a schedules or deadline entry." (buffer (marker-buffer marker)) (pos (marker-position marker)) dbeg dend (n 0) conf) - (with-current-buffer buffer - (save-excursion - (goto-char pos) - (if (org-mode-p) - (setq dbeg (progn (org-back-to-heading t) (point)) - dend (org-end-of-subtree t)) - (setq dbeg (point-at-bol) - dend (min (point-max) (1+ (point-at-eol))))) - (goto-char dbeg) - (while (re-search-forward "^[ \t]*\\S-" dend t) (setq n (1+ n))))) - (setq conf (or (eq t org-agenda-confirm-kill) - (and (numberp org-agenda-confirm-kill) - (> n org-agenda-confirm-kill)))) - (and conf - (not (y-or-n-p - (format "Delete entry with %d lines in buffer \"%s\"? " - n (buffer-name buffer)))) - (error "Abort")) - (org-remove-subtree-entries-from-agenda buffer dbeg dend) - (with-current-buffer buffer (delete-region dbeg dend)) - (message "Agenda item and source killed"))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (save-excursion + (goto-char pos) + (if (org-mode-p) + (setq dbeg (progn (org-back-to-heading t) (point)) + dend (org-end-of-subtree t)) + (setq dbeg (point-at-bol) + dend (min (point-max) (1+ (point-at-eol))))) + (goto-char dbeg) + (while (re-search-forward "^[ \t]*\\S-" dend t) (setq n (1+ n))))) + (setq conf (or (eq t org-agenda-confirm-kill) + (and (numberp org-agenda-confirm-kill) + (> n org-agenda-confirm-kill)))) + (and conf + (not (y-or-n-p + (format "Delete entry with %d lines in buffer \"%s\"? " + n (buffer-name buffer)))) + (error "Abort")) + (org-remove-subtree-entries-from-agenda buffer dbeg dend) + (with-current-buffer buffer (delete-region dbeg dend)) + (message "Agenda item and source killed")))) (defun org-agenda-archive () "Kill the entry or subtree belonging to the current agenda entry." @@ -9120,14 +9428,15 @@ and by additional input from the age of a schedules or deadline entry." (buffer (marker-buffer marker)) (pos (marker-position marker)) dbeg dend txt n conf) - (with-current-buffer buffer - (if (org-mode-p) - (save-excursion - (goto-char pos) - (org-remove-subtree-entries-from-agenda) - (org-back-to-heading t) - (org-archive-subtree)) - (error "Archiving works only in Org-mode files"))))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (if (org-mode-p) + (save-excursion + (goto-char pos) + (org-remove-subtree-entries-from-agenda) + (org-back-to-heading t) + (org-archive-subtree)) + (error "Archiving works only in Org-mode files")))))) (defun org-remove-subtree-entries-from-agenda (&optional buf beg end) "Remove all lines in the agenda that correspond to a given subtree. @@ -9217,6 +9526,24 @@ If this information is not given, the function uses the tree at point." (defun org-agenda-error () (error "Command not allowed in this line")) +(defun org-agenda-tree-to-indirect-buffer () + "Show the subtree corresponding to the current entry in an indirect buffer. +This calls the command `org-tree-to-indirect-buffer' from the original +Org-mode buffer. +With numerical prefix arg ARG, go up to this level and then take that tree. +With a C-u prefix, make a separate frame for this tree (i.e. don't use the +dedicated frame)." + (interactive) + (org-agenda-check-no-diary) + (let* ((marker (or (get-text-property (point) 'org-marker) + (org-agenda-error))) + (buffer (marker-buffer marker)) + (pos (marker-position marker))) + (with-current-buffer buffer + (save-excursion + (goto-char pos) + (org-tree-to-indirect-buffer))))) + (defvar org-last-heading-marker (make-marker) "Marker pointing to the headline that last changed its TODO state by a remote command from the agenda.") @@ -9235,23 +9562,24 @@ the same tree node, and the headline of the tree node in the Org-mode file." (hdmarker (get-text-property (point) 'org-hd-marker)) (buffer-read-only nil) newhead) - (with-current-buffer buffer - (widen) - (goto-char pos) - (org-show-context 'agenda) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-context 'agenda) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (org-todo arg) + (and (bolp) (forward-char 1)) + (setq newhead (org-get-heading)) + (save-excursion + (org-back-to-heading) + (move-marker org-last-heading-marker (point)))) + (beginning-of-line 1) (save-excursion - (and (outline-next-heading) - (org-flag-heading nil))) ; show the next heading - (org-todo arg) - (and (bolp) (forward-char 1)) - (setq newhead (org-get-heading)) - (save-excursion - (org-back-to-heading) - (move-marker org-last-heading-marker (point)))) - (beginning-of-line 1) - (save-excursion - (org-agenda-change-all-lines newhead hdmarker 'fixface)) - (move-to-column col))) + (org-agenda-change-all-lines newhead hdmarker 'fixface)) + (move-to-column col)))) (defun org-agenda-change-all-lines (newhead hdmarker &optional fixface) "Change all lines in the agenda buffer which match HDMARKER. @@ -9335,18 +9663,19 @@ the same tree node, and the headline of the tree node in the Org-mode file." (hdmarker (get-text-property (point) 'org-hd-marker)) (buffer-read-only nil) newhead) - (with-current-buffer buffer - (widen) - (goto-char pos) - (org-show-context 'agenda) - (save-excursion - (and (outline-next-heading) - (org-flag-heading nil))) ; show the next heading - (funcall 'org-priority force-direction) - (end-of-line 1) - (setq newhead (org-get-heading))) - (org-agenda-change-all-lines newhead hdmarker) - (beginning-of-line 1))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-context 'agenda) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (funcall 'org-priority force-direction) + (end-of-line 1) + (setq newhead (org-get-heading))) + (org-agenda-change-all-lines newhead hdmarker) + (beginning-of-line 1)))) (defun org-get-tags-at (&optional pos) "Get a list of all headline tags applicable at POS. @@ -9382,18 +9711,44 @@ the tags of the current headline come last." (pos (marker-position hdmarker)) (buffer-read-only nil) newhead) - (with-current-buffer buffer - (widen) - (goto-char pos) - (org-show-context 'agenda) - (save-excursion - (and (outline-next-heading) - (org-flag-heading nil))) ; show the next heading - (call-interactively 'org-set-tags) - (end-of-line 1) - (setq newhead (org-get-heading))) - (org-agenda-change-all-lines newhead hdmarker) - (beginning-of-line 1))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-context 'agenda) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (call-interactively 'org-set-tags) + (end-of-line 1) + (setq newhead (org-get-heading))) + (org-agenda-change-all-lines newhead hdmarker) + (beginning-of-line 1)))) + +(defun org-agenda-toggle-archive-tag () + "Toggle the archive tag for the current entry." + (interactive) + (org-agenda-check-no-diary) + (org-agenda-show) ;;; FIXME This is a stupid hack and should not be needed + (let* ((hdmarker (or (get-text-property (point) 'org-hd-marker) + (org-agenda-error))) + (buffer (marker-buffer hdmarker)) + (pos (marker-position hdmarker)) + (buffer-read-only nil) + newhead) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (org-show-context 'agenda) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (call-interactively 'org-toggle-archive-tag) + (end-of-line 1) + (setq newhead (org-get-heading))) + (org-agenda-change-all-lines newhead hdmarker) + (beginning-of-line 1)))) (defun org-agenda-date-later (arg &optional what) "Change the date of this item to one day later." @@ -9404,13 +9759,14 @@ the tags of the current headline come last." (org-agenda-error))) (buffer (marker-buffer marker)) (pos (marker-position marker))) - (with-current-buffer buffer - (widen) - (goto-char pos) - (if (not (org-at-timestamp-p)) - (error "Cannot find time stamp")) - (org-timestamp-change arg (or what 'day))) - (org-agenda-overlay-new-time marker org-last-changed-timestamp) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (if (not (org-at-timestamp-p)) + (error "Cannot find time stamp")) + (org-timestamp-change arg (or what 'day))) + (org-agenda-show-new-time marker org-last-changed-timestamp)) (message "Time stamp changed to %s" org-last-changed-timestamp))) (defun org-agenda-date-earlier (arg &optional what) @@ -9418,8 +9774,9 @@ the tags of the current headline come last." (interactive "p") (org-agenda-date-later (- arg) what)) - -(defun org-agenda-overlay-new-time (marker stamp) +(defun org-agenda-show-new-time (marker stamp) + "Show new date stamp via text properties." + ;; We use text properties to make this undoable (let ((buffer-read-only nil) ovs ov) (setq stamp (concat " => " stamp)) @@ -9427,13 +9784,19 @@ the tags of the current headline come last." (goto-char (point-max)) (while (not (bobp)) (when (equal marker (get-text-property (point) 'org-marker)) - ;; remove any old overlays - (org-find-overlays 'org-new-date (1- (point-at-eol)) 'delete) - ;; put a new overlay (move-to-column (- (window-width) (length stamp)) t) - (setq ov (org-make-overlay (1- (point)) (point-at-eol))) - (org-overlay-put ov 'org-new-date t) - (org-overlay-display ov stamp 'secondary-selection) + (if (featurep 'xemacs) + ;; Use `duplicable' property to trigger undo recording + (let ((ex (make-extent nil nil)) + (gl (make-glyph stamp))) + (set-glyph-face gl 'secondary-selection) + (set-extent-properties + ex (list 'invisible t 'end-glyph gl 'duplicable t)) + (insert-extent ex (1- (point)) (point-at-eol))) + (add-text-properties + (1- (point)) (point-at-eol) + (list 'display (org-add-props stamp nil + 'face 'secondary-selection)))) (beginning-of-line 1)) (beginning-of-line 0))))) @@ -9448,13 +9811,14 @@ be used to request time specification in the time stamp." (org-agenda-error))) (buffer (marker-buffer marker)) (pos (marker-position marker))) - (with-current-buffer buffer - (widen) - (goto-char pos) - (if (not (org-at-timestamp-p)) - (error "Cannot find time stamp")) - (org-time-stamp arg) - (message "Time stamp changed to %s" org-last-changed-timestamp)))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (if (not (org-at-timestamp-p)) + (error "Cannot find time stamp")) + (org-time-stamp arg) + (message "Time stamp changed to %s" org-last-changed-timestamp))))) (defun org-agenda-schedule (arg) "Schedule the item at point." @@ -9467,11 +9831,12 @@ be used to request time specification in the time stamp." (pos (marker-position marker)) (org-insert-labeled-timestamps-at-point nil) ts) - (with-current-buffer buffer - (widen) - (goto-char pos) - (setq ts (org-schedule)) - (message "Item scheduled for %s" ts)))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (setq ts (org-schedule)) + (message "Item scheduled for %s" ts))))) (defun org-agenda-deadline (arg) "Schedule the item at point." @@ -9484,11 +9849,12 @@ be used to request time specification in the time stamp." (pos (marker-position marker)) (org-insert-labeled-timestamps-at-point nil) ts) - (with-current-buffer buffer - (widen) - (goto-char pos) - (setq ts (org-deadline)) - (message "Deadline for this item set to %s" ts)))) + (org-with-remote-undo buffer + (with-current-buffer buffer + (widen) + (goto-char pos) + (setq ts (org-deadline)) + (message "Deadline for this item set to %s" ts))))) (defun org-get-heading () "Return the heading of the current entry, without the stars." @@ -9506,10 +9872,27 @@ be used to request time specification in the time stamp." (let* ((marker (or (get-text-property (point) 'org-marker) (org-agenda-error))) (pos (marker-position marker))) - (with-current-buffer (marker-buffer marker) - (widen) - (goto-char pos) - (org-clock-in)))) + (org-with-remote-undo (marker-buffer marker) + (with-current-buffer (marker-buffer marker) + (widen) + (goto-char pos) + (org-clock-in))))) + +(defun org-agenda-clock-out (&optional arg) + "Stop the currently running clock." + (interactive "P") + (unless (marker-buffer org-clock-marker) + (error "No running clock")) + (org-with-remote-undo (marker-buffer org-clock-marker) + (org-clock-out))) + +(defun org-agenda-clock-cancel (&optional arg) + "Cancel the currently running clock." + (interactive "P") + (unless (marker-buffer org-clock-marker) + (error "No running clock")) + (org-with-remote-undo (marker-buffer org-clock-marker) + (org-clock-cancel))) (defun org-agenda-diary-entry () "Make a diary entry, like the `i' command from the calendar. @@ -9529,6 +9912,7 @@ All the standard commands work: block, weekly etc." (?b . insert-block-diary-entry) (?c . insert-cyclic-diary-entry))))) (oldf (symbol-function 'calendar-cursor-to-date)) +; (buf (get-file-buffer (substitute-in-file-name diary-file))) (point (point)) (mark (or (mark t) (point)))) (unless cmd @@ -9549,7 +9933,7 @@ All the standard commands work: block, weekly etc." (lambda (&optional error) (calendar-gregorian-from-absolute (get-text-property point 'day)))) - (call-interactively cmd)) + (call-interactively cmd)) (fset 'calendar-cursor-to-date oldf))))) @@ -9647,7 +10031,7 @@ This is a command that has to be installed in `calendar-mode-map'." (if (fboundp 'fit-window-to-buffer) (fit-window-to-buffer (get-buffer-window "*Dates*"))))) -;;; Tags +;;;; Tags (defun org-scan-tags (action matcher &optional todo-only) "Scan headline tags with inheritance and produce output ACTION. @@ -9727,15 +10111,22 @@ are included in the output." (org-hide-archived-subtrees (point-min) (point-max))) (nreverse rtn))) -(defun org-tags-sparse-tree (&optional arg match) +(defvar todo-only) ;; dynamically scoped + +(defun org-tags-sparse-tree (&optional todo-only match) "Create a sparse tree according to tags string MATCH. MATCH can contain positive and negative selection of tags, like -\"+WORK+URGENT-WITHBOSS\"." +\"+WORK+URGENT-WITHBOSS\". +If optional argument TODO_ONLY is non-nil, only select lines that are +also TODO lines." (interactive "P") - (org-scan-tags 'sparse-tree (cdr (org-make-tags-matcher match)))) + (org-scan-tags 'sparse-tree (cdr (org-make-tags-matcher match)) todo-only)) +;; FIXME: implement search for a specific level. (defun org-make-tags-matcher (match) "Create the TAGS//TODO matcher form for the selection string MATCH." + ;; todo-only is scoped dynamically into this function, and the function + ;; may change it it the matcher asksk for it. (unless match ;; Get a new match request, with completion (setq org-last-tags-completion-table @@ -9747,14 +10138,19 @@ MATCH can contain positive and negative selection of tags, like ;; Parse the string and create a lisp form (let ((match0 match) - (re "^&?\\([-+:]\\)?\\({[^}]+}\\|[A-Za-z_@0-9]+\\)") + (re "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL=\\([0-9]+\\)\\|[A-Za-z_@0-9]+\\)") minus tag mm tagsmatch todomatch tagsmatcher todomatcher kwd matcher - orterms term orlist re-p) + orterms term orlist re-p level-p) (if (string-match "/+" match) ;; match contains also a todo-matching request - (setq tagsmatch (substring match 0 (match-beginning 0)) - todomatch (substring match (match-end 0))) + (progn + (setq tagsmatch (substring match 0 (match-beginning 0)) + todomatch (substring match (match-end 0))) + (if (string-match "^!" todomatch) + (setq todo-only t todomatch (substring todomatch 1))) + (if (string-match "^\\s-*$" todomatch) + (setq todomatch nil))) ;; only matching tags (setq tagsmatch match todomatch nil)) @@ -9769,12 +10165,15 @@ MATCH can contain positive and negative selection of tags, like (setq minus (and (match-end 1) (equal (match-string 1 term) "-")) tag (match-string 2 term) - term (substring term (match-end 0)) re-p (equal (string-to-char tag) ?{) - mm (if re-p - `(org-match-any-p ,(substring tag 1 -1) tags-list) - `(member ,(downcase tag) tags-list)) - mm (if minus (list 'not mm) mm)) + level-p (match-end 3) + mm (cond + (re-p `(org-match-any-p ,(substring tag 1 -1) tags-list)) + (level-p `(= level ,(string-to-number + (match-string 3 term)))) + (t `(member ,(downcase tag) tags-list))) + mm (if minus (list 'not mm) mm) + term (substring term (match-end 0))) (push mm tagsmatcher)) (push (if (> (length tagsmatcher) 1) (cons 'and tagsmatcher) @@ -9862,16 +10261,19 @@ The prefix arg TODO-ONLY limits the search to TODO entries." (widen)) (setq rtn (org-scan-tags 'agenda matcher todo-only)) (setq rtnall (append rtnall rtn)))))))) - (insert "Headlines with TAGS match: ") - (add-text-properties (point-min) (1- (point)) - (list 'face 'org-level-3)) - (setq pos (point)) - (insert match "\n") - (add-text-properties pos (1- (point)) (list 'face 'org-warning)) - (setq pos (point)) - (unless org-agenda-multi - (insert "Press `C-u r' to search again with new search string\n")) - (add-text-properties pos (1- (point)) (list 'face 'org-level-3)) + (if org-agenda-overriding-header + (insert (org-add-props (copy-sequence org-agenda-overriding-header) + nil 'face 'org-level-3) "\n") + (insert "Headlines with TAGS match: ") + (add-text-properties (point-min) (1- (point)) + (list 'face 'org-level-3)) + (setq pos (point)) + (insert match "\n") + (add-text-properties pos (1- (point)) (list 'face 'org-warning)) + (setq pos (point)) + (unless org-agenda-multi + (insert "Press `C-u r' to search again with new search string\n")) + (add-text-properties pos (1- (point)) (list 'face 'org-level-3))) (when rtnall (insert (org-finalize-agenda-entries rtnall) "\n")) (goto-char (point-min)) @@ -10178,7 +10580,7 @@ Returns the new tags string, or nil to not change the current settings." (org-split-string (org-match-string-no-properties 1) ":")))) (mapcar 'list tags))) -;;; Link Stuff +;;;; Link Stuff (defvar org-create-file-search-functions nil "List of functions to construct the right search string for a file link. @@ -10782,7 +11184,7 @@ onto the ring." message-number) (error "Message not found")))) -;; mh-e integration based on planner-mode +;;; mh-e integration based on planner-mode (defun org-mhe-get-message-real-folder () "Return the name of the current message real folder, so if you use sequences, it will now work." @@ -10887,7 +11289,7 @@ folders." (kill-this-buffer) (error "Message not found")))) -;; BibTeX links +;;; BibTeX links ;; Use the custom search meachnism to construct and use search strings for ;; file links to BibTeX database entries. @@ -11538,7 +11940,7 @@ With three \\[universal-argument] prefixes, negate the meaning of (define-key minibuffer-local-completion-map " " 'self-insert-command) (apply 'completing-read args))) -;;; Hooks for remember.el +;;;; Hooks for remember.el (defvar org-finish-function nil) @@ -11742,7 +12144,7 @@ See also the variable `org-reverse-note-order'." (throw 'exit (cdr entry)))) nil))))) -;;; Tables +;;;; Tables ;; Watch out: Here we are talking about two different kind of tables. ;; Most of the code is for the tables created with the Org-mode table editor. @@ -13840,7 +14242,7 @@ With prefix ARG, apply the new formulas to the table." (goto-char pos) (message "Formula editing aborted without installing changes"))) -;;; The orgtbl minor mode +;;;; The orgtbl minor mode ;; Define a minor mode which can be used in other modes in order to ;; integrate the org-mode table editor. @@ -14119,7 +14521,7 @@ overwritten, and the table is not marked as requiring realignment." (interactive "p") (self-insert-command N)) -;;; Exporting +;;;; Exporting (defconst org-level-max 20) @@ -14309,7 +14711,7 @@ ones and overrule settings in the other lists." (call-interactively (cdr ass)) (error "No command associated with key %c" r1)))) -;; ASCII +;;; ASCII (defconst org-html-entities '(("nbsp") @@ -15050,7 +15452,7 @@ command." (not (get-char-property s 'invisible)))) s)) -;; HTML +;;; HTML (defun org-get-current-options () "Return a string with current options as keyword options. @@ -16323,7 +16725,7 @@ a time), or the day by one (if it does not contain a time)." (setq fmt (if have-time ":%Y%m%dT%H%M%S" ";VALUE=DATE:%Y%m%d")) (concat keyword (format-time-string fmt time)))) -;;; LaTeX stuff +;;;; LaTeX stuff (defvar org-cdlatex-mode-map (make-sparse-keymap) "Keymap for the minor `org-cdlatex-mode'.") @@ -16610,7 +17012,7 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." (delete-file (concat texfilebase e))) pngfile)))) -;;; Key bindings +;;;; Key bindings ;; - Bindings in Org-mode map are currently ;; 0123456789abcdefghijklmnopqrstuvwxyz!?@#$%^&-+*/=()_{}[]:;"|,.<>~`'\t the alphabet @@ -16653,8 +17055,9 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." (define-key org-mode-map (org-key 'S-left) 'org-shiftleft) (define-key org-mode-map (org-key 'S-right) 'org-shiftright) -;; Extra keys for tty access. We only set them when really needed -;; because otherwise the menus don't show the simple keys +;;; Extra keys for tty access. +;; We only set them when really needed because otherwise the +;; menus don't show the simple keys (when (or (featurep 'xemacs) ;; because XEmacs supports multi-device stuff (not window-system)) @@ -16686,6 +17089,7 @@ The images can be removed again with \\[org-ctrl-c-ctrl-c]." (define-key org-mode-map "\C-xns" 'org-narrow-to-subtree) (define-key org-mode-map "\C-c$" 'org-archive-subtree) (define-key org-mode-map "\C-c\C-x\C-a" 'org-toggle-archive-tag) +(define-key org-mode-map "\C-c\C-xb" 'org-tree-to-indirect-buffer) (define-key org-mode-map "\C-c\C-j" 'org-goto) (define-key org-mode-map "\C-c\C-t" 'org-todo) (define-key org-mode-map "\C-c\C-s" 'org-schedule) @@ -17192,7 +17596,9 @@ See the individual commands for more information." ["Cycle Global Visibility" org-shifttab (not (org-at-table-p))] ["Sparse Tree" org-occur t] ["Reveal Context" org-reveal t] - ["Show All" show-all t]) + ["Show All" show-all t] + "--" + ["Subtree to indirect buffer" 'org-tree-to-indirect-buffer t]) "--" ["New Heading" org-insert-heading t] ("Navigate Headings" @@ -17365,7 +17771,7 @@ With optional NODE, go directly to that node." "--") (mapcar 'org-file-menu-entry (org-agenda-files t)))))))) -;;; Documentation +;;;; Documentation (defun org-customize () "Call the customize function with org as argument." @@ -17390,7 +17796,7 @@ With optional NODE, go directly to that node." (message "\"Org\"-menu now contains full customization menu")) (error "Cannot expand menu (outdated version of cus-edit.el)"))) -;;; Miscellaneous stuff +;;;; Miscellaneous stuff (defun org-context () "Return a list of contexts of the current cursor position. @@ -17536,7 +17942,7 @@ return nil." (setq string (replace-match (cdr e) t t string)))) string)) -;; Paragraph filling stuff. +;;;; Paragraph filling stuff. ;; We want this to be just right, so use the full arsenal. (defun org-set-autofill-regexps () @@ -17587,9 +17993,11 @@ return nil." "Return a fill prefix for org-mode files. In particular, this makes sure hanging paragraphs for hand-formatted lists work correctly." -;;FIXME (if (looking-at " *\\([-*+] \\|[0-9]+[.)] \\)?") - (if (looking-at " *\\([-*+] \\|[0-9]+[.)] \\)?\|#\\+[ \t]+") - (make-string (- (match-end 0) (match-beginning 0)) ?\ ))) + (cond ((looking-at "#[ \t]+") + (match-string 0)) + ((looking-at " *\\([-*+] \\|[0-9]+[.)] \\)?") + (make-string (- (match-end 0) (match-beginning 0)) ?\ )) + (t nil))) ;; Functions needed for Emacs/XEmacs region compatibility @@ -17649,7 +18057,7 @@ that can be added." t) "\\'")))) -;; Functions extending outline functionality +;;;; Functions extending outline functionality ;; C-a should go to the beginning of a *visible* line, also in the ;; new outline.el. I guess this should be patched into Emacs? @@ -17798,6 +18206,8 @@ Show the heading too, if it is currently invisible." "\\):[ \t]*" "\\(.+\\)")) +;;;; Repair problems with some other packages + ;; Make `bookmark-jump' show the jump location if it was hidden. (eval-after-load "bookmark" '(if (boundp 'bookmark-after-jump-hook) @@ -17820,9 +18230,11 @@ Show the heading too, if it is currently invisible." (eval-after-load "session" '(add-to-list 'session-globals-exclude 'org-mark-ring)) -;;; Experimental code +;;;; Experimental code -;;; Finish up + + +;;;; Finish up (provide 'org) diff --git a/org.pdf b/org.pdf index e501774f0..d04fbf5ea 100644 Binary files a/org.pdf and b/org.pdf differ diff --git a/org.texi b/org.texi index 6b0097c63..11ecfb9b5 100644 --- a/org.texi +++ b/org.texi @@ -3,8 +3,8 @@ @setfilename ../info/org @settitle Org Mode Manual -@set VERSION 4.57 -@set DATE November 2006 +@set VERSION 4.58 +@set DATE December 2006 @dircategory Emacs @direntry @@ -192,17 +192,18 @@ Agenda Views * Agenda files:: Files being searched for agenda information * Agenda dispatcher:: Keyboard access to agenda views -* Weekly/Daily agenda:: The calendar page with current tasks -* Global TODO list:: All unfinished action items -* Matching headline tags:: Structured information with fine-tuned search -* Timeline:: Time-sorted view for single file +* Built-in agenda views:: What is available out of the box? * Presentation and sorting:: How agenda items are prepared for display * Agenda commands:: Remote editing of org trees * Custom agenda views:: Defining special searches and views -The weekly/daily agenda +The built-in agenda views -* Calendar/Diary integration:: Integrating Anniversaries and more +* Weekly/Daily agenda:: The calendar page with current tasks +* Global TODO list:: All unfinished action items +* Matching headline tags:: Structured information with fine-tuned search +* Timeline:: Time-sorted view for single file +* Stuck projects:: Find projects you need to review Presentation and sorting @@ -280,6 +281,7 @@ Extensions, Hooks and Hacking * Extensions:: Existing 3rd-part extensions * Dynamic blocks:: Automatically filled blocks +* Special agenda views:: @end detailmenu @end menu @@ -621,6 +623,17 @@ Reveal context around point, showing the current entry, the following heading and the hierarchy above. Useful for working near a location exposed by a sparse tree command (@pxref{Sparse trees}) or an agenda command (@pxref{Agenda commands}). +@kindex C-c C-x b +@item C-c C-x b +Show the current subtree in an indirect buffer@footnote{The indirect +buffer (@pxref{Indirect Buffers,Indirect Buffers,Indirect Buffers,emacs,GNU +Emacs Manual}) will contain the entire buffer, but will +be narrowed to the current tree. Editing the indirect buffer will also +change the original buffer, but without affecting visibility in that +buffer .}, in a separate, dedicated frame. With positive numerical +prefix N, go up to level N before selecting the subtree. With negative +prefix -N, go up N levels. With @kbd{C-u} prefix, don't use the +dedicated frame, but another, new frame. @end table When Emacs first visits an Org-mode file, the global state is set to @@ -1348,9 +1361,10 @@ A formula can be any algebraic expression understood by the Emacs @file{calc} package. Note that @file{calc} has the slightly non-standard convention that @samp{/} has lower precedence than @samp{*}, so that @samp{a/b*c} is interpreted as @samp{a/(b*c)}. Before -evaluation by @code{calc-eval} (@pxref{Calling Calc from Your -Programs,calc-eval,Calling calc from Your Lisp Programs,calc,GNU Emacs -Calc Manual}), variable substitution takes place: +evaluation by @code{calc-eval} (@pxref{Calling Calc from +Your Programs,calc-eval,Calling calc from Your Lisp Programs,calc,GNU +Emacs Calc Manual}), +variable substitution takes place: @example $ @r{refers to the current field} @@ -3120,7 +3134,8 @@ information into special lists. @table @kbd @kindex C-c \ @item C-c \ -Create a sparse tree with all headlines matching a tags search. +Create a sparse tree with all headlines matching a tags search. With a +@kbd{C-u} prefix argument, ignore headlines that are not a TODO line. @kindex C-c a m @item C-c a m Create a global list of tag matches from all agenda files. @@ -3142,13 +3157,13 @@ or @samp{-} is present. Examples: @table @samp @item +WORK-BOSS -Select all headlines that are tagged @samp{:WORK:}, but discard those also tagged +Select headlines tagged @samp{:WORK:}, but discard those also tagged @samp{:BOSS:}. @item WORK|LAPTOP Selects lines tagged @samp{:WORK:} or @samp{:LAPTOP:}. @item WORK|LAPTOP&NIGHT -Like the previous example, but require the @samp{:LAPTOP:} lines to be -tagged also @samp{NIGHT}. +Like before, but require the @samp{:LAPTOP:} lines to be tagged also +@samp{NIGHT}. @end table @cindex TODO keyword matching, with tags search @@ -3158,13 +3173,16 @@ adding a condition after a slash to a tags match. The syntax is similar to the tag matches, but should be applied with consideration: For example, a positive selection on several TODO keywords can not meaningfully be combined with boolean AND. However, @emph{negative -selection} combined with AND can be meaningful. Examples: +selection} combined with AND can be meaningful. To make sure that only +lines are checked that actually have any TODO keyword, use @kbd{C-c a +M}, or equivalently start the todo part after the slash with @samp{!}. +Examples: @table @samp @item WORK/WAITING Select @samp{:WORK:}-tagged TODO lines with the specific TODO keyword @samp{WAITING}. -@item WORK/-WAITING-NEXT +@item WORK/!-WAITING-NEXT Select @samp{:WORK:}-tagged TODO lines that are neither @samp{WAITING} nor @samp{NEXT} @item WORK/+WAITING|+NEXT @@ -3178,6 +3196,12 @@ case it must be enclosed in curly braces. For example, @samp{WORK+@{^BOSS.*@}} matches headlines that contain the tag @samp{WORK} and any tag @i{starting} with @samp{BOSS}. +@cindex level, require for tags match +You can also require a headline to be of a certain level, by writing +instead of any TAG an expression like @samp{LEVEL=3}. For example, a +search @samp{+LEVEL=3+BOSS/-DONE} lists all level three headlines that +have the tag BOSS and are @emph{not} marked witht the todo keyword DONE. + @node Agenda views, Embedded LaTeX, Tags, Top @chapter Agenda Views @cindex agenda views @@ -3189,23 +3213,26 @@ are important for a particular date, this information must be collected, sorted and displayed in an organized way. Org-mode can select items based on various criteria, and display them -in a separate buffer. Five different view types are provided: +in a separate buffer. Six different view types are provided: @itemize @bullet @item an @emph{agenda} that is like a calendar and shows information -for specific dates +for specific dates, @item a @emph{TODO list} that covers all unfinished action items, @item -a @emph{tags view} that shows information based on -the tags associated with headlines in the outline tree, +a @emph{tags view}, showings headlines based on +the tags associated them, @item a @emph{timeline view} that shows all events in a single Org-mode file, -in time-sorted view +in time-sorted view, @item -@emph{custom views} that are special tag and keyword searches and +a @emph{stuck projects view} showing projects that currently don't move +along, and +@item +@emph{custom views} that are special tag/keyword searches and combinations of different views. @end itemize @@ -3223,10 +3250,7 @@ window configuration is restored when the agenda exits: @menu * Agenda files:: Files being searched for agenda information * Agenda dispatcher:: Keyboard access to agenda views -* Weekly/Daily agenda:: The calendar page with current tasks -* Global TODO list:: All unfinished action items -* Matching headline tags:: Structured information with fine-tuned search -* Timeline:: Time-sorted view for single file +* Built-in agenda views:: What is available out of the box? * Presentation and sorting:: How agenda items are prepared for display * Agenda commands:: Remote editing of org trees * Custom agenda views:: Defining special searches and views @@ -3267,7 +3291,7 @@ Cycle through agenda file list, visiting one file after the other. The Org menu contains the current list of files and can be used to visit any of them. -@node Agenda dispatcher, Weekly/Daily agenda, Agenda files, Agenda views +@node Agenda dispatcher, Built-in agenda views, Agenda files, Agenda views @section The agenda dispatcher @cindex agenda dispatcher @cindex dispatching agenda commands @@ -3280,13 +3304,15 @@ command. The dispatcher offers the following default commands: @table @kbd @item a Create the calendar-like agenda (@pxref{Weekly/Daily agenda}). -@item t / T +@item t @r{/} T Create a list of all TODO items (@pxref{Global TODO list}). -@item m / M +@item m @r{/} M Create a list of headlines matching a TAGS expression (@pxref{Matching headline tags}). @item L Create the timeline view for the current buffer (@pxref{Timeline}). +@item # @r{/} ! +Create a list of stuck projects (@pxref{Stuck projects}). @item 1 Restrict an agenda command to the current buffer. After pressing @kbd{1}, you still need to press the character selecting the command. @@ -3303,8 +3329,21 @@ possibility to create extended agenda buffers that contain several blocks together, for example the weekly agenda, the global TODO list and a number of special tags matches. @xref{Custom agenda views}. -@node Weekly/Daily agenda, Global TODO list, Agenda dispatcher, Agenda views -@section The weekly/daily agenda +@node Built-in agenda views, Presentation and sorting, Agenda dispatcher, Agenda views +@section The built-in agenda views + +In this section we describe the built-in views. + +@menu +* Weekly/Daily agenda:: The calendar page with current tasks +* Global TODO list:: All unfinished action items +* Matching headline tags:: Structured information with fine-tuned search +* Timeline:: Time-sorted view for single file +* Stuck projects:: Find projects you need to review +@end menu + +@node Weekly/Daily agenda, Global TODO list, Built-in agenda views, Built-in agenda views +@subsection The weekly/daily agenda @cindex agenda @cindex weekly agenda @cindex daily agenda @@ -3328,13 +3367,7 @@ change the dates of deadlines and appointments from the agenda buffer. The commands available in the Agenda buffer are listed in @ref{Agenda commands}. -@menu -* Calendar/Diary integration:: Integrating Anniversaries and more -@end menu - - -@node Calendar/Diary integration, , Weekly/Daily agenda, Weekly/Daily agenda -@subsection Calendar/Diary integration +@subsubheading Calendar/Diary integration @cindex calendar integration @cindex diary integration @@ -3365,8 +3398,8 @@ calendars, respectively. @kbd{c} can be used to switch back and forth between calendar and agenda. -@node Global TODO list, Matching headline tags, Weekly/Daily agenda, Agenda views -@section The global TODO list +@node Global TODO list, Matching headline tags, Weekly/Daily agenda, Built-in agenda views +@subsection The global TODO list @cindex global TODO list @cindex TODO list, global @@ -3417,8 +3450,8 @@ and omit the sublevels from the global list. Configure the variable @code{org-agenda-todo-list-sublevels} to get this behavior. @end itemize -@node Matching headline tags, Timeline, Global TODO list, Agenda views -@section Matching headline tags +@node Matching headline tags, Timeline, Global TODO list, Built-in agenda views +@subsection Matching headline tags @cindex matching, of tags @cindex tags view @@ -3445,8 +3478,8 @@ together with a tags match is also possible, see @ref{Tag searches}. The commands available in the tags list are described in @ref{Agenda commands}. -@node Timeline, Presentation and sorting, Matching headline tags, Agenda views -@section Timeline for a single file +@node Timeline, Stuck projects, Matching headline tags, Built-in agenda views +@subsection Timeline for a single file @cindex timeline, single file @cindex time-sorted view @@ -3467,7 +3500,49 @@ The commands available in the timeline buffer are listed in @ref{Agenda commands}. -@node Presentation and sorting, Agenda commands, Timeline, Agenda views +@node Stuck projects, , Timeline, Built-in agenda views +@subsection Stuck projects + +If you are following a system like David Allen's GTD to organize your +work, one of the ``duties'' you have is a regular review to make sure +that all projects move along. A @emph{stuck} project is a project that +has no defined next actions, so it will never show up in the TODO lists +Org-mode produces. During the review, you need to identify such +projects and define next actions for them. + +@table @kbd +@kindex C-c a # +@item C-c a # +List projects that are stuck. +@kindex C-c a ! +@item C-c a ! +Customize the variable @code{org-stuck-projects} to define what a stuck +project is and how to find it. +@end table + +You almost certainly will have to configure this view before it will +work for you. The built-in default assumes that all your projects are +level-2 headlines, and that a project is not stuck if it has at least +one entry marked with a todo keyword TODO or NEXT or NEXTACTION. + +Lets assume that you, in your own way of using Org-mode, identify +projects with a tag PROJECT, and that you use a todo keyword MAYBE to +indicate a project that should not be considered yet. Lets further +assume that the todo keyword DONE marks finished projects, and that NEXT +and TODO indicate next actions. Finally, the tag @@SHOP indicates +shopping and is a next action even without the NEXT tag. In this case +you would start by identifying elegible projects with a tags/todo match +@samp{+PROJECT/-MAYBE-DONE}, and then check for TODO, NEXT and @@SHOP in +the subtree to identify projects that are not stuck. The correct +customization for this is + +@lisp +(setq org-stuck-projects + ("+PROJECT/-MAYBE-DONE" ("NEXT" "TODO") ("@@SHOP"))) +@end lisp + + +@node Presentation and sorting, Agenda commands, Built-in agenda views, Agenda views @section Presentation and sorting @cindex presentation, of agenda items @@ -3515,7 +3590,7 @@ ranges can be specified with two time stamps, like In the headline of the entry itself, a time(range) may also appear as plain text (like @samp{12:45} or a @samp{8:30-1pm}. If the agenda -integrates the Emacs diary (@pxref{Calendar/Diary integration}), time +integrates the Emacs diary (@pxref{Weekly/Daily agenda}), time specifications in diary entries are recognized as well. For agenda display, Org-mode extracts the time and displays it in a @@ -3636,6 +3711,14 @@ location in the org file. The initial setting for this mode in new agenda buffers can be set with the variable @code{org-agenda-start-with-follow-mode}. +@kindex b +@item b +Display the entire subtree of the current item in an indirect buffer, in +a separate, dedicated frame. With positive numerical prefix N, go up to +level N before selecting the subtree. With negative prefix -N, go up N +levels. With @kbd{C-u} prefix, don't use the dedicated frame, but +another, new frame. + @kindex l @item l Toggle Logbook mode. In Logbook mode, entries that where marked DONE while @@ -3658,7 +3741,7 @@ Switch to daily view (just one day displayed). @kindex D @item D -Toggle the inclusion of diary entries. See @ref{Calendar/Diary integration}. +Toggle the inclusion of diary entries. See @ref{Weekly/Daily agenda}. @kindex g @item g @@ -3697,6 +3780,13 @@ Goto today. @item 0-9 Digit argument. +@cindex undoing remote-editing events +@cindex remote editing, undo +@kindex C-_ +@item C-_ +Undo a change due to a remote editing command. The change is undone +both in the agenda buffer and in the remote buffer. + @kindex t @item t Change the TODO state of the item, both in the agenda and in the @@ -5044,8 +5134,8 @@ Elsewhere, complete dictionary words using ispell. @cindex options, for customization @cindex variables, for customization -There are more than 100 variables that can be used to customize -Org-mode. For the sake of compactness of the manual, we are not +There are more than 170 variables that can be used to customize +Org-mode. For the sake of compactness of the manual, I am not describing the variables here. A structured overview of customization variables is available with @kbd{M-x org-customize}. Or select @code{Browse Org Group} from the @code{Org->Customization} menu. Many @@ -5432,11 +5522,6 @@ When the application called by @kbd{C-c C-o} to open a file link fails (for example because the application does not exist or refuses to open the file), it does so silently. No error message is displayed. @item -The remote-editing commands in the agenda buffer cannot be undone with -@code{undo} called from within the agenda buffer. But you can go to -the corresponding buffer (using @key{TAB} or @key{RET} and execute -@code{undo} there. -@item Recalculating a table line applies the formulas from left to right. If a formula uses @emph{calculated} fields further down the row, multiple recalculation may be needed to get all fields consistent. @@ -5451,12 +5536,13 @@ The exporters work well, but could be made more efficient. @appendix Extensions, Hooks and Hacking This appendix lists extensions for Org-mode written by other authors. -It also covers some aspects where users can easily extend the -functionality of Org-mode. +It also covers some aspects where users can extend the functionality of +Org-mode. @menu * Extensions:: Existing 3rd-part extensions * Dynamic blocks:: Automatically filled blocks +* Special agenda views:: @end menu @node Extensions, Dynamic blocks, Extensions and Hacking, Extensions and Hacking @@ -5496,7 +5582,7 @@ Publish Org-mode files as blogs. @url{http://www.cognition.ens.fr/~guerry/blorg.html}. @end table -@node Dynamic blocks, , Extensions, Extensions and Hacking +@node Dynamic blocks, Special agenda views, Extensions, Extensions and Hacking @section Dynamic blocks Org-mode documents can contain @emph{dynamic blocks}. These are @@ -5555,6 +5641,59 @@ you could add the function @code{org-update-all-dblocks} to a hook, for example @code{before-save-hook}. @code{org-update-all-dblocks} is written in a way that is does nothing in buffers that are not in Org-mode. +@node Special agenda views, , Dynamic blocks, Extensions and Hacking +@section Special Agenda Views + +Org-mode provides a special hook that can be used to narrow down the +selection made by any of the agenda views. You may specify a function +that is used at each match to verify if the match should indeed be part +of the agenda view, and if not, how much should be skipped. + +Let's say you want to produce a list of projects that contain a WAITING +tag anywhere in the project tree. Let's further assume that you have +marked all tree headings that define a project with the todo keyword +PROJECT. In this case you would run a todo search for the keyword +PROJECT, but skip the match unless there is a WAITING tag anywhere in +the subtree belonging to the project line.. + +To achieve this, you must write a function that searches the subtree for +the tag. If the tag is found, the function must return @code{nil} to +indicate that this match should not be skipped. If there is no such +tag, return the location of the end of the subtree, to indicate that +search should continue from there. + +@lisp +(defun my-skip-unless-waiting () + "Skip trees that are not waiting" + (let ((subtree-end (save-excursion (org-end-of-subtree t)))) + (if (re-search-forward ":WAITING:" subtree-end t) + nil ; tag found, do not skip + subtree-end))) ; tag not found, continue after end of subtree +@end lisp + +Furthermore you must write a command that uses @code{let} to temporarily +puts this function into the variable @code{org-agenda-skip-function}, +sets the header string for the agenda buffer, and calls the todo-list +generator while asking for the specific TODO keyword PROJECT. The +function must also accept one argument MATCH, but it can choose to +ignore it@footnote{MATCH must be present in case you want to define a +custom command for producing this special list. Custom commands always +supply the MATCH argument, but it can be empty if you do not specify it +while defining the command(@pxref{Custom agenda +views}).} (as we do in the example below). Here is the example: + +@lisp +(defun my-org-waiting-projects (&optional match) + "Produce a list of projects that contain a WAITING tag. +MATCH is being ignored." + (interactive) + (let ((org-agenda-skip-function 'my-skip-unless-waiting) + (org-agenda-overriding-header "Projects waiting for something: ")) + ;; make the list + (org-todo-list "PROJECT"))) +@end lisp + + @node History and Acknowledgments, Index, Extensions and Hacking, Top @appendix History and Acknowledgments @cindex acknowledgments diff --git a/orgcard.tex b/orgcard.tex index e744d634d..dffb22068 100644 --- a/orgcard.tex +++ b/orgcard.tex @@ -1,5 +1,5 @@ % Reference Card for Org Mode -\def\orgversionnumber{4.57} +\def\orgversionnumber{4.58} \def\year{2006} % %**start of header