Fix bug #7398 with truncated glyphs in w32 tooltips.
[bpt/emacs.git] / lisp / org / org-mouse.el
CommitLineData
36ad1553
CD
1;;; org-mouse.el --- Better mouse support for org-mode
2
f2d6ead6
GM
3;; Copyright (C) 2006, 2007, 2008, 2009, 2010
4;; Free Software Foundation, Inc.
36ad1553
CD
5;;
6;; Author: Piotr Zielinski <piotr dot zielinski at gmail dot com>
7;; Maintainer: Carsten Dominik <carsten at orgmode dot org>
afe98dfa 8;; Version: 7.3
36ad1553
CD
9;;
10;; This file is part of GNU Emacs.
11;;
b1fc2b50 12;; GNU Emacs is free software: you can redistribute it and/or modify
36ad1553 13;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
36ad1553
CD
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
b1fc2b50 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
36ad1553
CD
24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25;;
26;;; Commentary:
27;;
28;; Org-mouse provides mouse support for org-mode.
29;;
30;; http://orgmode.org
31;;
32;; Org-mouse implements the following features:
33;; * following links with the left mouse button (in Emacs 22)
34;; * subtree expansion/collapse (org-cycle) with the left mouse button
35;; * several context menus on the right mouse button:
36;; + general text
37;; + headlines
38;; + timestamps
39;; + priorities
40;; + links
41;; + tags
42;; * promoting/demoting/moving subtrees with mouse-3
43;; + if the drag starts and ends in the same line then promote/demote
20908596 44;; + otherwise move the subtree
36ad1553
CD
45;;
46;; Use
47;; ---
48;;
49;; To use this package, put the following line in your .emacs:
50;;
51;; (require 'org-mouse)
52;;
53
33306645 54;; FIXME:
36ad1553
CD
55;; + deal with folding / unfolding issues
56
57;; TODO (This list is only theoretical, if you'd like to have some
58;; feature implemented or a bug fix please send me an email, even if
59;; something similar appears in the list below. This will help me get
60;; the priorities right.):
61;;
62;; + org-store-link, insert link
63;; + org tables
64;; + occur with the current word/tag (same menu item)
65;; + ctrl-c ctrl-c, for example, renumber the current list
66;; + internal links
67
68;; Please email the maintainer with new feature suggestions / bugs
69
70;; History:
71;;
33306645 72;; Since version 5.10: Changes are listed in the general org-mode docs.
36ad1553
CD
73;;
74;; Version 5.09
75;; + Version number synchronization with Org-mode.
76;;
77;; Version 0.25
78;; + made compatible with org-mode 4.70 (thanks to Carsten for the patch)
79;;
80;; Version 0.24
81;; + minor changes to the table menu
82;;
83;; Version 0.23
84;; + preliminary support for tables and calculation marks
85;; + context menu support for org-agenda-undo & org-sort-entries
86;;
87;; Version 0.22
88;; + handles undo support for the agenda buffer (requires org-mode >=4.58)
89;;
90;; Version 0.21
91;; + selected text activates its context menu
92;; + shift-middleclick or right-drag inserts the text from the clipboard in the form of a link
93;;
94;; Version 0.20
20908596 95;; + the new "TODO Status" submenu replaces the "Cycle TODO" menu item
36ad1553
CD
96;; + the TODO menu can now list occurrences of a specific TODO keyword
97;; + #+STARTUP line is now recognized
98;;
99;; Version 0.19
100;; + added support for dragging URLs to the org-buffer
101;;
102;; Version 0.18
103;; + added support for agenda blocks
104;;
105;; Version 0.17
106;; + toggle checkboxes with a single click
107;;
108;; Version 0.16
109;; + added support for checkboxes
110;;
111;; Version 0.15
112;; + org-mode now works with the Agenda buffer as well
113;;
114;; Version 0.14
115;; + added a menu option that converts plain list items to outline items
116;;
20908596 117;; Version 0.13
36ad1553
CD
118;; + "Insert Heading" now inserts a sibling heading if the point is
119;; on "***" and a child heading otherwise
20908596 120;;
36ad1553
CD
121;; Version 0.12
122;; + compatible with Emacs 21
123;; + custom agenda commands added to the main menu
124;; + moving trees should now work between windows in the same frame
125;;
126;; Version 0.11
127;; + fixed org-mouse-at-link (thanks to Carsten)
128;; + removed [follow-link] bindings
129;;
130;; Version 0.10
131;; + added a menu option to remove highlights
132;; + compatible with org-mode 4.21 now
133;;
20908596 134;; Version 0.08:
36ad1553
CD
135;; + trees can be moved/promoted/demoted by dragging with the right
136;; mouse button (mouse-3)
137;; + small changes in the above function
138;;
139;; Versions 0.01 -- 0.07: (I don't remember)
140
86fbb8ca
CD
141;;; Code:
142
36ad1553
CD
143(eval-when-compile (require 'cl))
144(require 'org)
145
20908596
CD
146(defvar org-agenda-allow-remote-undo)
147(defvar org-agenda-undo-list)
148(defvar org-agenda-custom-commands)
149(declare-function org-agenda-change-all-lines "org-agenda"
d60b1ba1 150 (newhead hdmarker &optional fixface just-this))
20908596 151(declare-function org-verify-change-for-undo "org-agenda" (l1 l2))
afe98dfa 152(declare-function org-apply-on-list "org-list" (function init-value &rest args))
20908596 153
36ad1553
CD
154(defvar org-mouse-plain-list-regexp "\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) "
155 "Regular expression that matches a plain list.")
156(defvar org-mouse-direct t
157 "Internal variable indicating whether the current action is direct.
158
159If t, then the current action has been invoked directly through the buffer
160it is intended to operate on. If nil, then the action has been invoked
161indirectly, for example, through the agenda buffer.")
162
163(defgroup org-mouse nil
164 "Mouse support for org-mode."
165 :tag "Org Mouse"
166 :group 'org)
167
168(defcustom org-mouse-punctuation ":"
169 "Punctuation used when inserting text by drag and drop."
170 :group 'org-mouse
171 :type 'string)
172
71d35b24
CD
173(defcustom org-mouse-features
174 '(context-menu yank-link activate-stars activate-bullets activate-checkboxes)
175 "The features of org-mouse that should be activated.
176Changing this variable requires a restart of Emacs to get activated."
177 :group 'org-mouse
178 :type '(set :greedy t
179 (const :tag "Mouse-3 shows context menu" context-menu)
180 (const :tag "C-mouse-1 and mouse-3 move trees" move-tree)
181 (const :tag "S-mouse-2 and drag-mouse-3 yank link" yank-link)
182 (const :tag "Activate headline stars" activate-stars)
183 (const :tag "Activate item bullets" activate-bullets)
ff4be292 184 (const :tag "Activate checkboxes" activate-checkboxes)))
36ad1553
CD
185
186(defun org-mouse-re-search-line (regexp)
187 "Search the current line for a given regular expression."
188 (beginning-of-line)
189 (re-search-forward regexp (point-at-eol) t))
190
191(defun org-mouse-end-headline ()
192 "Go to the end of current headline (ignoring tags)."
193 (interactive)
194 (end-of-line)
195 (skip-chars-backward "\t ")
ed21c5c8 196 (when (org-looking-back ":[A-Za-z]+:")
36ad1553
CD
197 (skip-chars-backward ":A-Za-z")
198 (skip-chars-backward "\t ")))
199
200(defvar org-mouse-context-menu-function nil
201 "Function to create the context menu.
202The value of this variable is the function invoked by
203`org-mouse-context-menu' as the context menu.")
204(make-variable-buffer-local 'org-mouse-context-menu-function)
205
206(defun org-mouse-show-context-menu (event prefix)
207 "Invoke the context menu.
208
209If the value of `org-mouse-context-menu-function' is a function, then
20908596 210this function is called. Otherwise, the current major mode menu is used."
36ad1553
CD
211 (interactive "@e \nP")
212 (if (and (= (event-click-count event) 1)
20908596 213 (or (not mark-active)
36ad1553
CD
214 (sit-for (/ double-click-time 1000.0))))
215 (progn
33306645 216 (select-window (posn-window (event-start event)))
36ad1553
CD
217 (when (not (org-mouse-mark-active))
218 (goto-char (posn-point (event-start event)))
219 (when (not (eolp)) (save-excursion (run-hooks 'post-command-hook)))
220 (let ((redisplay-dont-pause t))
221 (sit-for 0)))
222 (if (functionp org-mouse-context-menu-function)
223 (funcall org-mouse-context-menu-function event)
0e47efc5
GM
224 (if (fboundp 'mouse-menu-major-mode-map)
225 (popup-menu (mouse-menu-major-mode-map) event prefix)
0bd48b37
CD
226 (org-no-warnings ; don't warn about fallback, obsolete since 23.1
227 (mouse-major-mode-menu event prefix)))))
36ad1553
CD
228 (setq this-command 'mouse-save-then-kill)
229 (mouse-save-then-kill event)))
230
36ad1553 231(defun org-mouse-line-position ()
86fbb8ca 232 "Return `:beginning' or `:middle' or `:end', depending on the point position.
36ad1553
CD
233
234If the point is at the end of the line, return `:end'.
235If the point is separated from the beginning of the line only by white
236space and *'s (`org-mouse-bolp'), return `:beginning'. Otherwise,
237return `:middle'."
238 (cond
239 ((eolp) :end)
240 ((org-mouse-bolp) :beginning)
241 (t :middle)))
242
243(defun org-mouse-empty-line ()
244 "Return non-nil iff the line contains only white space."
245 (save-excursion (beginning-of-line) (looking-at "[ \t]*$")))
246
247(defun org-mouse-next-heading ()
248 "Go to the next heading.
249If there is none, ensure that the point is at the beginning of an empty line."
250 (unless (outline-next-heading)
251 (beginning-of-line)
252 (unless (org-mouse-empty-line)
253 (end-of-line)
254 (newline))))
255
256(defun org-mouse-insert-heading ()
257 "Insert a new heading, as `org-insert-heading'.
258
259If the point is at the :beginning (`org-mouse-line-position') of the line,
260insert the new heading before the current line. Otherwise, insert it
261after the current heading."
262 (interactive)
263 (case (org-mouse-line-position)
264 (:beginning (beginning-of-line)
265 (org-insert-heading))
266 (t (org-mouse-next-heading)
267 (org-insert-heading))))
268
20908596
CD
269(defun org-mouse-timestamp-today (&optional shift units)
270 "Change the timestamp into SHIFT UNITS in the future.
36ad1553
CD
271
272For the acceptable UNITS, see `org-timestamp-change'."
273 (interactive)
274 (flet ((org-read-date (&rest rest) (current-time)))
275 (org-time-stamp nil))
276 (when shift
277 (org-timestamp-change shift units)))
278
279(defun org-mouse-keyword-menu (keywords function &optional selected itemformat)
280 "A helper function.
281
282Returns a menu fragment consisting of KEYWORDS. When a keyword
283is selected by the user, FUNCTION is called with the selected
284keyword as the only argument.
285
286If SELECTED is nil, then all items are normal menu items. If
287SELECTED is a function, then each item is a checkbox, which is
288enabled for a given keyword iff (funcall SELECTED keyword) return
289non-nil. If SELECTED is neither nil nor a function, then the
290items are radio buttons. A radio button is enabled for the
20908596 291keyword `equal' to SELECTED.
36ad1553
CD
292
293ITEMFORMAT governs formatting of the elements of KEYWORDS. If it
294is a function, it is invoked with the keyword as the only
295argument. If it is a string, it is interpreted as the format
296string to (format ITEMFORMAT keyword). If it is neither a string
86fbb8ca 297nor a function, elements of KEYWORDS are used directly."
20908596
CD
298 (mapcar
299 `(lambda (keyword)
36ad1553
CD
300 (vector (cond
301 ((functionp ,itemformat) (funcall ,itemformat keyword))
302 ((stringp ,itemformat) (format ,itemformat keyword))
303 (t keyword))
304 (list 'funcall ,function keyword)
20908596 305 :style (cond
36ad1553
CD
306 ((null ,selected) t)
307 ((functionp ,selected) 'toggle)
308 (t 'radio))
20908596 309 :selected (if (functionp ,selected)
36ad1553
CD
310 (and (funcall ,selected keyword) t)
311 (equal ,selected keyword))))
312 keywords))
20908596 313
36ad1553
CD
314(defun org-mouse-remove-match-and-spaces ()
315 "Remove the match, make just one space around the point."
316 (interactive)
317 (replace-match "")
318 (just-one-space))
319
320(defvar rest)
20908596 321(defun org-mouse-replace-match-and-surround (newtext &optional fixedcase
36ad1553
CD
322 literal string subexp)
323 "The same as `replace-match', but surrounds the replacement with spaces."
324 (apply 'replace-match rest)
325 (save-excursion
20908596 326 (goto-char (match-beginning (or subexp 0)))
36ad1553 327 (just-one-space)
20908596 328 (goto-char (match-end (or subexp 0)))
36ad1553 329 (just-one-space)))
20908596 330
36ad1553
CD
331
332(defun org-mouse-keyword-replace-menu (keywords &optional group itemformat
333 nosurround)
334 "A helper function.
335
336Returns a menu fragment consisting of KEYWORDS. When a keyword
337is selected, group GROUP of the current match is replaced by the
338keyword. The method ensures that both ends of the replacement
339are separated from the rest of the text in the buffer by
33306645 340individual spaces (unless NOSURROUND is non-nil).
36ad1553
CD
341
342The final entry of the menu is always \"None\", which removes the
343match.
344
345ITEMFORMAT governs formatting of the elements of KEYWORDS. If it
346is a function, it is invoked with the keyword as the only
347argument. If it is a string, it is interpreted as the format
348string to (format ITEMFORMAT keyword). If it is neither a string
86fbb8ca 349nor a function, elements of KEYWORDS are used directly."
36ad1553 350 (setq group (or group 0))
20908596 351 (let ((replace (org-mouse-match-closure
36ad1553
CD
352 (if nosurround 'replace-match
353 'org-mouse-replace-match-and-surround))))
354 (append
20908596 355 (org-mouse-keyword-menu
36ad1553
CD
356 keywords
357 `(lambda (keyword) (funcall ,replace keyword t t nil ,group))
358 (match-string group)
359 itemformat)
20908596 360 `(["None" org-mouse-remove-match-and-spaces
36ad1553
CD
361 :style radio
362 :selected ,(not (member (match-string group) keywords))]))))
20908596 363
36ad1553
CD
364(defun org-mouse-show-headlines ()
365 "Change the visibility of the current org buffer to only show headlines."
20908596
CD
366 (interactive)
367 (let ((this-command 'org-cycle)
36ad1553
CD
368 (last-command 'org-cycle)
369 (org-cycle-global-status nil))
370 (org-cycle '(4))
371 (org-cycle '(4))))
372
373(defun org-mouse-show-overview ()
374 "Change visibility of current org buffer to first-level headlines only."
20908596 375 (interactive)
36ad1553
CD
376 (let ((org-cycle-global-status nil))
377 (org-cycle '(4))))
378
379(defun org-mouse-set-priority (priority)
380 "Set the priority of the current headline to PRIORITY."
381 (flet ((read-char-exclusive () priority))
382 (org-priority)))
383
384(defvar org-mouse-priority-regexp "\\[#\\([A-Z]\\)\\]"
385 "Regular expression matching the priority indicator.
386Differs from `org-priority-regexp' in that it doesn't contain the
387leading '.*?'.")
388
389(defun org-mouse-get-priority (&optional default)
390 "Return the priority of the current headline.
391DEFAULT is returned if no priority is given in the headline."
20908596 392 (save-excursion
36ad1553
CD
393 (if (org-mouse-re-search-line org-mouse-priority-regexp)
394 (match-string 1)
395 (when default (char-to-string org-default-priority)))))
396
397;; (defun org-mouse-at-link ()
398;; (and (eq (get-text-property (point) 'face) 'org-link)
399;; (save-excursion
400;; (goto-char (previous-single-property-change (point) 'face))
401;; (or (looking-at org-bracket-link-regexp)
402;; (looking-at org-angle-link-re)
403;; (looking-at org-plain-link-re)))))
404
405
406(defun org-mouse-delete-timestamp ()
407 "Deletes the current timestamp as well as the preceding keyword.
408SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
409 (when (or (org-at-date-range-p) (org-at-timestamp-p))
410 (replace-match "") ; delete the timestamp
411 (skip-chars-backward " :A-Z")
412 (when (looking-at " *[A-Z][A-Z]+:")
413 (replace-match ""))))
414
20908596 415(defun org-mouse-looking-at (regexp skipchars &optional movechars)
36ad1553
CD
416 (save-excursion
417 (let ((point (point)))
418 (if (looking-at regexp) t
419 (skip-chars-backward skipchars)
420 (forward-char (or movechars 0))
421 (when (looking-at regexp)
422 (> (match-end 0) point))))))
20908596 423
36ad1553 424(defun org-mouse-priority-list ()
20908596 425 (loop for priority from ?A to org-lowest-priority
36ad1553
CD
426 collect (char-to-string priority)))
427
c8d0cf5c
CD
428(defun org-mouse-todo-menu (state)
429 "Create the menu with TODO keywords."
430 (append
431 (let ((kwds org-todo-keywords-1))
432 (org-mouse-keyword-menu
433 kwds
434 `(lambda (kwd) (org-todo kwd))
435 (lambda (kwd) (equal state kwd))))))
436
36ad1553 437(defun org-mouse-tag-menu () ;todo
86fbb8ca 438 "Create the tags menu."
36ad1553 439 (append
71d35b24 440 (let ((tags (org-get-tags)))
20908596 441 (org-mouse-keyword-menu
36ad1553 442 (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
20908596
CD
443 `(lambda (tag)
444 (org-mouse-set-tags
445 (sort (if (member tag (quote ,tags))
36ad1553
CD
446 (delete tag (quote ,tags))
447 (cons tag (quote ,tags)))
448 'string-lessp)))
449 `(lambda (tag) (member tag (quote ,tags)))
450 ))
451 '("--"
452 ["Align Tags Here" (org-set-tags nil t) t]
453 ["Align Tags in Buffer" (org-set-tags t t) t]
454 ["Set Tags ..." (org-set-tags) t])))
20908596 455
36ad1553 456
36ad1553
CD
457(defun org-mouse-set-tags (tags)
458 (save-excursion
459 ;; remove existing tags first
460 (beginning-of-line)
461 (when (org-mouse-re-search-line ":\\(\\([A-Za-z_]+:\\)+\\)")
462 (replace-match ""))
463
464 ;; set new tags if any
465 (when tags
466 (end-of-line)
467 (insert " :" (mapconcat 'identity tags ":") ":")
468 (org-set-tags nil t))))
20908596 469
36ad1553
CD
470(defun org-mouse-insert-checkbox ()
471 (interactive)
472 (and (org-at-item-p)
473 (goto-char (match-end 0))
474 (unless (org-at-item-checkbox-p)
475 (delete-horizontal-space)
476 (insert " [ ] "))))
477
478(defun org-mouse-agenda-type (type)
479 (case type
480 ('tags "Tags: ")
481 ('todo "TODO: ")
482 ('tags-tree "Tags tree: ")
483 ('todo-tree "TODO tree: ")
484 ('occur-tree "Occur tree: ")
485 (t "Agenda command ???")))
486
487
488(defun org-mouse-list-options-menu (alloptions &optional function)
20908596 489 (let ((options (save-match-data
36ad1553
CD
490 (split-string (match-string-no-properties 1)))))
491 (print options)
492 (loop for name in alloptions
20908596
CD
493 collect
494 (vector name
36ad1553 495 `(progn
20908596
CD
496 (replace-match
497 (mapconcat 'identity
36ad1553
CD
498 (sort (if (member ',name ',options)
499 (delete ',name ',options)
500 (cons ',name ',options))
501 'string-lessp)
502 " ")
503 nil nil nil 1)
504 (when (functionp ',function) (funcall ',function)))
505 :style 'toggle
506 :selected (and (member name options) t)))))
507
508(defun org-mouse-clip-text (text maxlength)
509 (if (> (length text) maxlength)
510 (concat (substring text 0 (- maxlength 3)) "...")
511 text))
512
513(defun org-mouse-popup-global-menu ()
20908596 514 (popup-menu
36ad1553
CD
515 `("Main Menu"
516 ["Show Overview" org-mouse-show-overview t]
517 ["Show Headlines" org-mouse-show-headlines t]
518 ["Show All" show-all t]
519 ["Remove Highlights" org-remove-occur-highlights
520 :visible org-occur-highlights]
521 "--"
20908596 522 ["Check Deadlines"
36ad1553
CD
523 (if (functionp 'org-check-deadlines-and-todos)
524 (org-check-deadlines-and-todos org-deadline-warning-days)
525 (org-check-deadlines org-deadline-warning-days)) t]
526 ["Check TODOs" org-show-todo-tree t]
20908596
CD
527 ("Check Tags"
528 ,@(org-mouse-keyword-menu
36ad1553
CD
529 (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
530 '(lambda (tag) (org-tags-sparse-tree nil tag)))
531 "--"
532 ["Custom Tag ..." org-tags-sparse-tree t])
533 ["Check Phrase ..." org-occur]
534 "--"
535 ["Display Agenda" org-agenda-list t]
536 ["Display Timeline" org-timeline t]
537 ["Display TODO List" org-todo-list t]
20908596
CD
538 ("Display Tags"
539 ,@(org-mouse-keyword-menu
36ad1553
CD
540 (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
541 '(lambda (tag) (org-tags-view nil tag)))
542 "--"
543 ["Custom Tag ..." org-tags-view t])
544 ["Display Calendar" org-goto-calendar t]
545 "--"
20908596 546 ,@(org-mouse-keyword-menu
36ad1553 547 (mapcar 'car org-agenda-custom-commands)
20908596
CD
548 '(lambda (key)
549 (eval `(flet ((read-char-exclusive () (string-to-char ,key)))
36ad1553 550 (org-agenda nil))))
20908596 551 nil
36ad1553
CD
552 '(lambda (key)
553 (let ((entry (assoc key org-agenda-custom-commands)))
20908596 554 (org-mouse-clip-text
36ad1553
CD
555 (cond
556 ((stringp (nth 1 entry)) (nth 1 entry))
20908596 557 ((stringp (nth 2 entry))
36ad1553
CD
558 (concat (org-mouse-agenda-type (nth 1 entry))
559 (nth 2 entry)))
560 (t "Agenda Command '%s'"))
561 30))))
562 "--"
20908596 563 ["Delete Blank Lines" delete-blank-lines
36ad1553
CD
564 :visible (org-mouse-empty-line)]
565 ["Insert Checkbox" org-mouse-insert-checkbox
566 :visible (and (org-at-item-p) (not (org-at-item-checkbox-p)))]
20908596 567 ["Insert Checkboxes"
36ad1553
CD
568 (org-mouse-for-each-item 'org-mouse-insert-checkbox)
569 :visible (and (org-at-item-p) (not (org-at-item-checkbox-p)))]
570 ["Plain List to Outline" org-mouse-transform-to-outline
571 :visible (org-at-item-p)])))
572
20908596 573
36ad1553
CD
574(defun org-mouse-get-context (contextlist context)
575 (let ((contextdata (assq context contextlist)))
576 (when contextdata
20908596 577 (save-excursion
36ad1553
CD
578 (goto-char (second contextdata))
579 (re-search-forward ".*" (third contextdata))))))
580
afe98dfa
CD
581(defun org-mouse-for-each-item (funct)
582 ;; Functions called by `org-apply-on-list' need an argument
583 (let ((wrap-fun (lambda (c) (funcall funct))))
584 (when (org-in-item-p)
585 (org-apply-on-list wrap-fun nil))))
36ad1553
CD
586
587(defun org-mouse-bolp ()
86fbb8ca
CD
588 "Return true if there only spaces, tabs, and '*' before point.
589This means, between the beginning of line and the point."
36ad1553
CD
590 (save-excursion
591 (skip-chars-backward " \t*") (bolp)))
20908596 592
36ad1553
CD
593(defun org-mouse-insert-item (text)
594 (case (org-mouse-line-position)
20908596
CD
595 (:beginning ; insert before
596 (beginning-of-line)
36ad1553
CD
597 (looking-at "[ \t]*")
598 (open-line 1)
ce4fdcb9 599 (org-indent-to-column (- (match-end 0) (match-beginning 0)))
36ad1553 600 (insert "+ "))
20908596 601
36ad1553 602 (:middle ; insert after
20908596
CD
603 (end-of-line)
604 (newline t)
36ad1553
CD
605 (indent-relative)
606 (insert "+ "))
607
608 (:end ; insert text here
20908596 609 (skip-chars-backward " \t")
36ad1553 610 (kill-region (point) (point-at-eol))
ed21c5c8 611 (unless (org-looking-back org-mouse-punctuation)
36ad1553 612 (insert (concat org-mouse-punctuation " ")))))
20908596 613
36ad1553
CD
614 (insert text)
615 (beginning-of-line))
616
617(defadvice dnd-insert-text (around org-mouse-dnd-insert-text activate)
618 (if (eq major-mode 'org-mode)
619 (org-mouse-insert-item text)
620 ad-do-it))
621
622(defadvice dnd-open-file (around org-mouse-dnd-open-file activate)
623 (if (eq major-mode 'org-mode)
624 (org-mouse-insert-item uri)
625 ad-do-it))
626
627(defun org-mouse-match-closure (function)
628 (let ((match (match-data t)))
20908596 629 `(lambda (&rest rest)
36ad1553
CD
630 (save-match-data
631 (set-match-data ',match)
632 (apply ',function rest)))))
633
36ad1553
CD
634(defun org-mouse-match-todo-keyword ()
635 (save-excursion
636 (org-back-to-heading)
637 (if (looking-at outline-regexp) (goto-char (match-end 0)))
638 (or (looking-at (concat " +" org-todo-regexp " *"))
639 (looking-at " \\( *\\)"))))
640
641(defun org-mouse-yank-link (click)
642 (interactive "e")
643 ;; Give temporary modes such as isearch a chance to turn off.
644 (run-hooks 'mouse-leave-buffer-hook)
645 (mouse-set-point click)
646 (setq mouse-selection-click-count 0)
647 (delete-horizontal-space)
648 (insert-for-yank (concat " [[" (current-kill 0) "]] ")))
649
650(defun org-mouse-context-menu (&optional event)
651 (let ((stamp-prefixes (list org-deadline-string org-scheduled-string))
652 (contextlist (org-context)))
653 (flet ((get-context (context) (org-mouse-get-context contextlist context)))
654 (cond
655 ((org-mouse-mark-active)
656 (let ((region-string (buffer-substring (region-beginning) (region-end))))
657 (popup-menu
658 `(nil
659 ["Sparse Tree" (org-occur ',region-string)]
660 ["Find in Buffer" (occur ',region-string)]
20908596 661 ["Grep in Current Dir"
36ad1553 662 (grep (format "grep -rnH -e '%s' *" ',region-string))]
20908596 663 ["Grep in Parent Dir"
36ad1553
CD
664 (grep (format "grep -rnH -e '%s' ../*" ',region-string))]
665 "--"
20908596 666 ["Convert to Link"
36ad1553
CD
667 (progn (save-excursion (goto-char (region-beginning)) (insert "[["))
668 (save-excursion (goto-char (region-end)) (insert "]]")))]
669 ["Insert Link Here" (org-mouse-yank-link ',event)]))))
670
671 ((save-excursion (beginning-of-line) (looking-at "#\\+STARTUP: \\(.*\\)"))
20908596
CD
672 (popup-menu
673 `(nil
36ad1553
CD
674 ,@(org-mouse-list-options-menu (mapcar 'car org-startup-options)
675 'org-mode-restart))))
20908596 676 ((or (eolp)
36ad1553 677 (and (looking-at "\\( \\|\t\\)\\(+:[0-9a-zA-Z_:]+\\)?\\( \\|\t\\)+$")
ed21c5c8 678 (org-looking-back " \\|\t")))
36ad1553
CD
679 (org-mouse-popup-global-menu))
680 ((get-context :checkbox)
20908596
CD
681 (popup-menu
682 '(nil
36ad1553
CD
683 ["Toggle" org-toggle-checkbox t]
684 ["Remove" org-mouse-remove-match-and-spaces t]
685 ""
686 ["All Clear" (org-mouse-for-each-item
687 (lambda ()
688 (when (save-excursion (org-at-item-checkbox-p))
689 (replace-match "[ ]"))))]
690 ["All Set" (org-mouse-for-each-item
691 (lambda ()
692 (when (save-excursion (org-at-item-checkbox-p))
693 (replace-match "[X]"))))]
694 ["All Toggle" (org-mouse-for-each-item 'org-toggle-checkbox) t]
695 ["All Remove" (org-mouse-for-each-item
696 (lambda ()
697 (when (save-excursion (org-at-item-checkbox-p))
698 (org-mouse-remove-match-and-spaces))))]
699 )))
700 ((and (org-mouse-looking-at "\\b\\w+" "a-zA-Z0-9_")
c8d0cf5c 701 (member (match-string 0) org-todo-keywords-1))
20908596 702 (popup-menu
36ad1553 703 `(nil
c8d0cf5c 704 ,@(org-mouse-todo-menu (match-string 0))
20908596 705 "--"
36ad1553
CD
706 ["Check TODOs" org-show-todo-tree t]
707 ["List all TODO keywords" org-todo-list t]
20908596 708 [,(format "List only %s" (match-string 0))
36ad1553
CD
709 (org-todo-list (match-string 0)) t]
710 )))
711 ((and (org-mouse-looking-at "\\b[A-Z]+:" "A-Z")
712 (member (match-string 0) stamp-prefixes))
20908596
CD
713 (popup-menu
714 `(nil
715 ,@(org-mouse-keyword-replace-menu stamp-prefixes)
36ad1553
CD
716 "--"
717 ["Check Deadlines" org-check-deadlines t]
718 )))
719 ((org-mouse-looking-at org-mouse-priority-regexp "[]A-Z#") ; priority
20908596 720 (popup-menu `(nil ,@(org-mouse-keyword-replace-menu
36ad1553
CD
721 (org-mouse-priority-list) 1 "Priority %s" t))))
722 ((get-context :link)
723 (popup-menu
724 '(nil
725 ["Open" org-open-at-point t]
726 ["Open in Emacs" (org-open-at-point t) t]
727 "--"
c8d0cf5c 728 ["Copy link" (org-kill-new (match-string 0))]
20908596
CD
729 ["Cut link"
730 (progn
36ad1553
CD
731 (kill-region (match-beginning 0) (match-end 0))
732 (just-one-space))]
733 "--"
734 ["Grep for TODOs"
735 (grep (format "grep -nH -i 'todo\\|fixme' %s*" (match-string 2)))]
736; ["Paste file link" ((insert "file:") (yank))]
737 )))
738 ((org-mouse-looking-at ":\\([A-Za-z0-9_]+\\):" "A-Za-z0-9_" -1) ;tags
20908596
CD
739 (popup-menu
740 `(nil
36ad1553
CD
741 [,(format "Display '%s'" (match-string 1))
742 (org-tags-view nil ,(match-string 1))]
743 [,(format "Sparse Tree '%s'" (match-string 1))
744 (org-tags-sparse-tree nil ,(match-string 1))]
745 "--"
746 ,@(org-mouse-tag-menu))))
747 ((org-at-timestamp-p)
20908596 748 (popup-menu
36ad1553
CD
749 '(nil
750 ["Show Day" org-open-at-point t]
751 ["Change Timestamp" org-time-stamp t]
752 ["Delete Timestamp" (org-mouse-delete-timestamp) t]
753 ["Compute Time Range" org-evaluate-time-range (org-at-date-range-p)]
754 "--"
755 ["Set for Today" org-mouse-timestamp-today]
756 ["Set for Tomorrow" (org-mouse-timestamp-today 1 'day)]
757 ["Set in 1 Week" (org-mouse-timestamp-today 7 'day)]
758 ["Set in 2 Weeks" (org-mouse-timestamp-today 14 'day)]
759 ["Set in a Month" (org-mouse-timestamp-today 1 'month)]
760 "--"
761 ["+ 1 Day" (org-timestamp-change 1 'day)]
762 ["+ 1 Week" (org-timestamp-change 7 'day)]
763 ["+ 1 Month" (org-timestamp-change 1 'month)]
764 "--"
765 ["- 1 Day" (org-timestamp-change -1 'day)]
766 ["- 1 Week" (org-timestamp-change -7 'day)]
767 ["- 1 Month" (org-timestamp-change -1 'month)])))
768 ((get-context :table-special)
769 (let ((mdata (match-data)))
770 (incf (car mdata) 2)
771 (store-match-data mdata))
772 (message "match: %S" (match-string 0))
20908596
CD
773 (popup-menu `(nil ,@(org-mouse-keyword-replace-menu
774 '(" " "!" "^" "_" "$" "#" "*" "'") 0
36ad1553
CD
775 (lambda (mark)
776 (case (string-to-char mark)
777 (? "( ) Nothing Special")
778 (?! "(!) Column Names")
779 (?^ "(^) Field Names Above")
780 (?_ "(^) Field Names Below")
781 (?$ "($) Formula Parameters")
782 (?# "(#) Recalculation: Auto")
783 (?* "(*) Recalculation: Manual")
784 (?' "(') Recalculation: None"))) t))))
785 ((assq :table contextlist)
786 (popup-menu
787 '(nil
788 ["Align Table" org-ctrl-c-ctrl-c]
789 ["Blank Field" org-table-blank-field]
790 ["Edit Field" org-table-edit-field]
791 "--"
792 ("Column"
793 ["Move Column Left" org-metaleft]
794 ["Move Column Right" org-metaright]
795 ["Delete Column" org-shiftmetaleft]
796 ["Insert Column" org-shiftmetaright]
797 "--"
798 ["Enable Narrowing" (setq org-table-limit-column-width (not org-table-limit-column-width)) :selected org-table-limit-column-width :style toggle])
799 ("Row"
800 ["Move Row Up" org-metaup]
801 ["Move Row Down" org-metadown]
802 ["Delete Row" org-shiftmetaup]
803 ["Insert Row" org-shiftmetadown]
804 ["Sort lines in region" org-table-sort-lines (org-at-table-p)]
805 "--"
806 ["Insert Hline" org-table-insert-hline])
807 ("Rectangle"
808 ["Copy Rectangle" org-copy-special]
809 ["Cut Rectangle" org-cut-special]
810 ["Paste Rectangle" org-paste-special]
811 ["Fill Rectangle" org-table-wrap-region])
812 "--"
813 ["Set Column Formula" org-table-eval-formula]
814 ["Set Field Formula" (org-table-eval-formula '(4))]
815 ["Edit Formulas" org-table-edit-formulas]
816 "--"
817 ["Recalculate Line" org-table-recalculate]
818 ["Recalculate All" (org-table-recalculate '(4))]
819 ["Iterate All" (org-table-recalculate '(16))]
820 "--"
821 ["Toggle Recalculate Mark" org-table-rotate-recalc-marks]
822 ["Sum Column/Rectangle" org-table-sum
823 :active (or (org-at-table-p) (org-region-active-p))]
824 ["Field Info" org-table-field-info]
825 ["Debug Formulas"
826 (setq org-table-formula-debug (not org-table-formula-debug))
827 :style toggle :selected org-table-formula-debug]
828 )))
829 ((and (assq :headline contextlist) (not (eolp)))
830 (let ((priority (org-mouse-get-priority t)))
831 (popup-menu
832 `("Headline Menu"
20908596
CD
833 ("Tags and Priorities"
834 ,@(org-mouse-keyword-menu
835 (org-mouse-priority-list)
836 '(lambda (keyword)
36ad1553
CD
837 (org-mouse-set-priority (string-to-char keyword)))
838 priority "Priority %s")
839 "--"
840 ,@(org-mouse-tag-menu))
841 ("TODO Status"
c8d0cf5c 842 ,@(org-mouse-todo-menu (org-get-todo-state)))
20908596 843 ["Show Tags"
36ad1553
CD
844 (with-current-buffer org-mouse-main-buffer (org-agenda-show-tags))
845 :visible (not org-mouse-direct)]
20908596 846 ["Show Priority"
36ad1553
CD
847 (with-current-buffer org-mouse-main-buffer (org-agenda-show-priority))
848 :visible (not org-mouse-direct)]
849 ,@(if org-mouse-direct '("--") nil)
850 ["New Heading" org-mouse-insert-heading :visible org-mouse-direct]
20908596
CD
851 ["Set Deadline"
852 (progn (org-mouse-end-headline) (insert " ") (org-deadline))
853 :active (not (save-excursion
36ad1553 854 (org-mouse-re-search-line org-deadline-regexp)))]
20908596
CD
855 ["Schedule Task"
856 (progn (org-mouse-end-headline) (insert " ") (org-schedule))
857 :active (not (save-excursion
36ad1553 858 (org-mouse-re-search-line org-scheduled-regexp)))]
20908596 859 ["Insert Timestamp"
36ad1553
CD
860 (progn (org-mouse-end-headline) (insert " ") (org-time-stamp nil)) t]
861; ["Timestamp (inactive)" org-time-stamp-inactive t]
862 "--"
863 ["Archive Subtree" org-archive-subtree]
864 ["Cut Subtree" org-cut-special]
865 ["Copy Subtree" org-copy-special]
866 ["Paste Subtree" org-paste-special :visible org-mouse-direct]
20908596 867 ("Sort Children"
36ad1553
CD
868 ["Alphabetically" (org-sort-entries nil ?a)]
869 ["Numerically" (org-sort-entries nil ?n)]
870 ["By Time/Date" (org-sort-entries nil ?t)]
871 "--"
872 ["Reverse Alphabetically" (org-sort-entries nil ?A)]
873 ["Reverse Numerically" (org-sort-entries nil ?N)]
874 ["Reverse By Time/Date" (org-sort-entries nil ?T)])
875 "--"
876 ["Move Trees" org-mouse-move-tree :active nil]
877 ))))
20908596 878 (t
36ad1553
CD
879 (org-mouse-popup-global-menu))))))
880
881;; (defun org-mouse-at-regexp (regexp)
882;; (save-excursion
883;; (let ((point (point))
33306645
CD
884;; (bol (progn (beginning-of-line) (point)))
885;; (eol (progn (end-of-line) (point))))
886;; (goto-char point)
887;; (re-search-backward regexp bol 1)
888;; (and (not (eolp))
889;; (progn (forward-char)
890;; (re-search-forward regexp eol t))
891;; (<= (match-beginning 0) point)))))
36ad1553
CD
892
893(defun org-mouse-mark-active ()
894 (and mark-active transient-mark-mode))
895
896(defun org-mouse-in-region-p (pos)
20908596
CD
897 (and (org-mouse-mark-active)
898 (>= pos (region-beginning))
36ad1553
CD
899 (< pos (region-end))))
900
901(defun org-mouse-down-mouse (event)
902 (interactive "e")
903 (setq this-command last-command)
904 (unless (and (= 1 (event-click-count event))
905 (org-mouse-in-region-p (posn-point (event-start event))))
906 (mouse-drag-region event)))
907
908(add-hook 'org-mode-hook
909 '(lambda ()
910 (setq org-mouse-context-menu-function 'org-mouse-context-menu)
911
71d35b24 912 (when (memq 'context-menu org-mouse-features)
86fbb8ca
CD
913 (org-defkey org-mouse-map [mouse-3] nil)
914 (org-defkey org-mode-map [mouse-3] 'org-mouse-show-context-menu))
915 (org-defkey org-mode-map [down-mouse-1] 'org-mouse-down-mouse)
71d35b24 916 (when (memq 'context-menu org-mouse-features)
86fbb8ca
CD
917 (org-defkey org-mouse-map [C-drag-mouse-1] 'org-mouse-move-tree)
918 (org-defkey org-mouse-map [C-down-mouse-1] 'org-mouse-move-tree-start))
71d35b24 919 (when (memq 'yank-link org-mouse-features)
86fbb8ca
CD
920 (org-defkey org-mode-map [S-mouse-2] 'org-mouse-yank-link)
921 (org-defkey org-mode-map [drag-mouse-3] 'org-mouse-yank-link))
71d35b24 922 (when (memq 'move-tree org-mouse-features)
86fbb8ca
CD
923 (org-defkey org-mouse-map [drag-mouse-3] 'org-mouse-move-tree)
924 (org-defkey org-mouse-map [down-mouse-3] 'org-mouse-move-tree-start))
71d35b24
CD
925
926 (when (memq 'activate-stars org-mouse-features)
927 (font-lock-add-keywords
928 nil
20908596
CD
929 `((,outline-regexp
930 0 `(face org-link mouse-face highlight keymap ,org-mouse-map)
71d35b24 931 'prepend))
33306645 932 t))
71d35b24
CD
933
934 (when (memq 'activate-bullets org-mouse-features)
935 (font-lock-add-keywords
936 nil
937 `(("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +"
938 (1 `(face org-link keymap ,org-mouse-map mouse-face highlight)
939 'prepend)))
33306645 940 t))
71d35b24
CD
941
942 (when (memq 'activate-checkboxes org-mouse-features)
943 (font-lock-add-keywords
944 nil
945 `(("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[ X]\\]\\)"
36ad1553 946 (2 `(face bold keymap ,org-mouse-map mouse-face highlight) t)))
33306645 947 t))
36ad1553
CD
948
949 (defadvice org-open-at-point (around org-mouse-open-at-point activate)
950 (let ((context (org-context)))
20908596 951 (cond
36ad1553
CD
952 ((assq :headline-stars context) (org-cycle))
953 ((assq :checkbox context) (org-toggle-checkbox))
954 ((assq :item-bullet context)
955 (let ((org-cycle-include-plain-lists t)) (org-cycle)))
956 (t ad-do-it))))))
957
958(defun org-mouse-move-tree-start (event)
959 (interactive "e")
960 (message "Same line: promote/demote, (***):move before, (text): make a child"))
961
962
963(defun org-mouse-make-marker (position)
964 (with-current-buffer (window-buffer (posn-window position))
965 (copy-marker (posn-point position))))
966
967(defun org-mouse-move-tree (event)
968 ;; todo: handle movements between different buffers
969 (interactive "e")
970 (save-excursion
971 (let* ((start (org-mouse-make-marker (event-start event)))
972 (end (org-mouse-make-marker (event-end event)))
973 (sbuf (marker-buffer start))
974 (ebuf (marker-buffer end)))
975
976 (when (and sbuf ebuf)
977 (set-buffer sbuf)
978 (goto-char start)
979 (org-back-to-heading)
980 (if (and (eq sbuf ebuf)
20908596 981 (equal
36ad1553
CD
982 (point)
983 (save-excursion (goto-char end) (org-back-to-heading) (point))))
984 ;; if the same line then promote/demote
985 (if (>= end start) (org-demote-subtree) (org-promote-subtree))
986 ;; if different lines then move
987 (org-cut-subtree)
20908596 988
36ad1553
CD
989 (set-buffer ebuf)
990 (goto-char end)
991 (org-back-to-heading)
992 (when (and (eq sbuf ebuf)
20908596 993 (equal
36ad1553 994 (point)
20908596 995 (save-excursion (goto-char start)
36ad1553
CD
996 (org-back-to-heading) (point))))
997 (outline-end-of-subtree)
998 (end-of-line)
999 (if (eobp) (newline) (forward-char)))
20908596 1000
36ad1553
CD
1001 (when (looking-at outline-regexp)
1002 (let ((level (- (match-end 0) (match-beginning 0))))
1003 (when (> end (match-end 0))
1004 (outline-end-of-subtree)
1005 (end-of-line)
1006 (if (eobp) (newline) (forward-char))
1007 (setq level (1+ level)))
1008 (org-paste-subtree level)
1009 (save-excursion
1010 (outline-end-of-subtree)
1011 (when (bolp) (delete-char -1))))))))))
1012
1013
1014(defun org-mouse-transform-to-outline ()
1015 (interactive)
1016 (org-back-to-heading)
1017 (let ((minlevel 1000)
1018 (replace-text (concat (match-string 0) "* ")))
1019 (beginning-of-line 2)
1020 (save-excursion
1021 (while (not (or (eobp) (looking-at outline-regexp)))
1022 (when (looking-at org-mouse-plain-list-regexp)
1023 (setq minlevel (min minlevel (- (match-end 1) (match-beginning 1)))))
1024 (forward-line)))
1025 (while (not (or (eobp) (looking-at outline-regexp)))
1026 (when (and (looking-at org-mouse-plain-list-regexp)
1027 (eq minlevel (- (match-end 1) (match-beginning 1))))
1028 (replace-match replace-text))
1029 (forward-line))))
1030
1031(defvar _cmd) ;dynamically scoped from `org-with-remote-undo'.
1032
1033(defun org-mouse-do-remotely (command)
1034; (org-agenda-check-no-diary)
1035 (when (get-text-property (point) 'org-marker)
1036 (let* ((anticol (- (point-at-eol) (point)))
1037 (marker (get-text-property (point) 'org-marker))
1038 (buffer (marker-buffer marker))
1039 (pos (marker-position marker))
1040 (hdmarker (get-text-property (point) 'org-hd-marker))
1041 (buffer-read-only nil)
1042 (newhead "--- removed ---")
1043 (org-mouse-direct nil)
1044 (org-mouse-main-buffer (current-buffer)))
1045 (when (eq (with-current-buffer buffer major-mode) 'org-mode)
81ad75af 1046 (let ((endmarker (with-current-buffer buffer
8bfe682a
CD
1047 (outline-end-of-subtree)
1048 (forward-char 1)
1049 (copy-marker (point)))))
36ad1553
CD
1050 (org-with-remote-undo buffer
1051 (with-current-buffer buffer
1052 (widen)
1053 (goto-char pos)
1054 (org-show-hidden-entry)
1055 (save-excursion
1056 (and (outline-next-heading)
1057 (org-flag-heading nil))) ; show the next heading
1058 (org-back-to-heading)
1059 (setq marker (copy-marker (point)))
1060 (goto-char (max (point-at-bol) (- (point-at-eol) anticol)))
1061 (funcall command)
1062 (message "_cmd: %S" _cmd)
1063 (message "this-command: %S" this-command)
1064 (unless (eq (marker-position marker) (marker-position endmarker))
1065 (setq newhead (org-get-heading))))
20908596 1066
36ad1553
CD
1067 (beginning-of-line 1)
1068 (save-excursion
1069 (org-agenda-change-all-lines newhead hdmarker 'fixface))))
1070 t))))
1071
1072(defun org-mouse-agenda-context-menu (&optional event)
1073 (or (org-mouse-do-remotely 'org-mouse-context-menu)
20908596 1074 (popup-menu
36ad1553
CD
1075 '("Agenda"
1076 ("Agenda Files")
1077 "--"
1078 ["Undo" (progn (message "last command: %S" last-command) (setq this-command 'org-agenda-undo) (org-agenda-undo))
20908596 1079 :visible (if (eq last-command 'org-agenda-undo)
36ad1553
CD
1080 org-agenda-pending-undo-list
1081 org-agenda-undo-list)]
1082 ["Rebuild Buffer" org-agenda-redo t]
20908596 1083 ["New Diary Entry"
36ad1553
CD
1084 org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline) t]
1085 "--"
20908596 1086 ["Goto Today" org-agenda-goto-today
36ad1553 1087 (org-agenda-check-type nil 'agenda 'timeline) t]
20908596 1088 ["Display Calendar" org-agenda-goto-calendar
36ad1553
CD
1089 (org-agenda-check-type nil 'agenda 'timeline) t]
1090 ("Calendar Commands"
20908596 1091 ["Phases of the Moon" org-agenda-phases-of-moon
36ad1553 1092 (org-agenda-check-type nil 'agenda 'timeline)]
20908596 1093 ["Sunrise/Sunset" org-agenda-sunrise-sunset
36ad1553 1094 (org-agenda-check-type nil 'agenda 'timeline)]
20908596 1095 ["Holidays" org-agenda-holidays
36ad1553 1096 (org-agenda-check-type nil 'agenda 'timeline)]
20908596 1097 ["Convert" org-agenda-convert-date
36ad1553
CD
1098 (org-agenda-check-type nil 'agenda 'timeline)]
1099 "--"
1100 ["Create iCalendar file" org-export-icalendar-combine-agenda-files t])
1101 "--"
20908596 1102 ["Day View" org-agenda-day-view
36ad1553
CD
1103 :active (org-agenda-check-type nil 'agenda)
1104 :style radio :selected (equal org-agenda-ndays 1)]
20908596 1105 ["Week View" org-agenda-week-view
36ad1553
CD
1106 :active (org-agenda-check-type nil 'agenda)
1107 :style radio :selected (equal org-agenda-ndays 7)]
1108 "--"
1109 ["Show Logbook entries" org-agenda-log-mode
20908596 1110 :style toggle :selected org-agenda-show-log
36ad1553
CD
1111 :active (org-agenda-check-type nil 'agenda 'timeline)]
1112 ["Include Diary" org-agenda-toggle-diary
20908596 1113 :style toggle :selected org-agenda-include-diary
36ad1553
CD
1114 :active (org-agenda-check-type nil 'agenda)]
1115 ["Use Time Grid" org-agenda-toggle-time-grid
1116 :style toggle :selected org-agenda-use-time-grid
1117 :active (org-agenda-check-type nil 'agenda)]
1118 ["Follow Mode" org-agenda-follow-mode
1119 :style toggle :selected org-agenda-follow-mode]
1120 "--"
1121 ["Quit" org-agenda-quit t]
1122 ["Exit and Release Buffers" org-agenda-exit t]
1123 ))))
1124
1125(defun org-mouse-get-gesture (event)
1126 (let ((startxy (posn-x-y (event-start event)))
1127 (endxy (posn-x-y (event-end event))))
1128 (if (< (car startxy) (car endxy)) :right :left)))
1129
1130
1131; (setq org-agenda-mode-hook nil)
20908596 1132(add-hook 'org-agenda-mode-hook
36ad1553
CD
1133 '(lambda ()
1134 (setq org-mouse-context-menu-function 'org-mouse-agenda-context-menu)
86fbb8ca
CD
1135 (org-defkey org-agenda-mode-map [mouse-3] 'org-mouse-show-context-menu)
1136 (org-defkey org-agenda-mode-map [down-mouse-3] 'org-mouse-move-tree-start)
1137 (org-defkey org-agenda-mode-map [C-mouse-4] 'org-agenda-earlier)
1138 (org-defkey org-agenda-mode-map [C-mouse-5] 'org-agenda-later)
1139 (org-defkey org-agenda-mode-map [drag-mouse-3]
36ad1553
CD
1140 '(lambda (event) (interactive "e")
1141 (case (org-mouse-get-gesture event)
1142 (:left (org-agenda-earlier 1))
1143 (:right (org-agenda-later 1)))))))
1144
1145(provide 'org-mouse)
fcd094c7
MB
1146
1147;; arch-tag: ff1ae557-3529-41a3-95c6-baaebdcc280f
b349f79f 1148
86fbb8ca 1149;;; org-mouse.el ends here