123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859 |
- ;;; org-mouse.el --- Better mouse support for org-mode
- ;; Copyright (c) 2006 Piotr Zielinski
- ;;
- ;; Author: Piotr Zielinski <piotr dot zielinski at gmail dot com>
- ;; Version: 0.18
- ;; $Id: org-mouse.el 254 2006-10-26 21:15:52Z pz215 $
- ;;
- ;; The latest version of this file is available from
- ;;
- ;; http://www.cl.cam.ac.uk/~pz215/files/org-mouse.el
- ;;
- ;; This file is *NOT* part of GNU Emacs.
- ;; This file is distributed under the same terms as GNU Emacs.
- ;; This program is free software; you can redistribute it and/or
- ;; modify it under the terms of the GNU General Public License as
- ;; published by the Free Software Foundation; either version 2 of
- ;; the License, or (at your option) any later version.
- ;; This program is distributed in the hope that it will be
- ;; useful, but WITHOUT ANY WARRANTY; without even the implied
- ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- ;; PURPOSE. See the GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public
- ;; License along with this program; if not, write to the Free
- ;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- ;; MA 02111-1307 USA
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;;; Commentary:
- ;;
- ;; Org-mouse provides better mouse support for org-mode. Org-mode is
- ;; a mode for keeping notes, maintaining ToDo lists, and doing project
- ;; planning with a fast and effective plain-text system. It is
- ;; available from
- ;;
- ;; http://staff.science.uva.nl/~dominik/Tools/org/
- ;;
- ;; Org-mouse implements the following features:
- ;; * following links with the left mouse button (in Emacs 22)
- ;; * subtree expansion/collapse (org-cycle) with the left mouse button
- ;; * several context menus on the right mouse button:
- ;; + general text
- ;; + headlines
- ;; + timestamps
- ;; + priorities
- ;; + links
- ;; + tags
- ;; * promoting/demoting/moving subtrees with mouse-3
- ;; + if the drag starts and ends in the same line then promote/demote
- ;; + otherwise move the subtree
- ;; * date/time extraction from selected text (requires a python script)
- ;; (eg. select text from your email and click "Add Appointment")
- ;;
- ;; The python script that automatically extracts date/time information
- ;; from a piece of English text is available from:
- ;;
- ;; http://www.cl.cam.ac.uk/~pz215/files/timeparser.py
- ;;
- ;; Use
- ;; ------------
- ;;
- ;; To use this package, put the following line in your .emacs:
- ;;
- ;; (require 'org-mouse)
- ;;
- ;; Tested with Emacs 22.0.50, org-mode 4.33
- ;; Fixme:
- ;; + deal with folding / unfolding issues
- ;; TODO (This list is only theoretical, if you'd like to have some
- ;; 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)
- ;; + ctrl-c ctrl-c, for example, renumber the current list
- ;; + internal links
- ;; Please email me with new feature suggestions / bugs
- ;; History:
- ;;
- ;; Version 0.19
- ;; + added support for dragging URLs to the org-buffer
- ;;
- ;; Version 0.18
- ;; + added support for agenda blocks
- ;;
- ;; Version 0.17
- ;; + toggle checkboxes with a single click
- ;;
- ;; Version 0.16
- ;; + added support for checkboxes
- ;;
- ;; Version 0.15
- ;; + org-mode now works with the Agenda buffer as well
- ;;
- ;; Version 0.14
- ;; + added a menu option that converts plain list items to outline items
- ;;
- ;; Version 0.13
- ;; + "Insert Heading" now inserts a sibling heading if the point is
- ;; on "***" and a child heading otherwise
- ;;
- ;; Version 0.12
- ;; + compatible with Emacs 21
- ;; + custom agenda commands added to the main menu
- ;; + moving trees should now work between windows in the same frame
- ;;
- ;; Version 0.11
- ;; + fixed org-mouse-at-link (thanks to Carsten)
- ;; + removed [follow-link] bindings
- ;;
- ;; Version 0.10
- ;; + added a menu option to remove highlights
- ;; + compatible with org-mode 4.21 now
- ;;
- ;; Version 0.08:
- ;; + trees can be moved/promoted/demoted by dragging with the right
- ;; mouse button (mouse-3)
- ;; + small changes in the above function
- ;;
- ;; Versions 0.01 -- 0.07: (I don't remember)
- (eval-when-compile (require 'cl))
- (defvar org-mouse-plain-list-regexp "\\([ \t]*\\)\\([-+*]\\|[0-9]+[.)]\\) ")
- (defvar org-mouse-direct t)
- (defgroup org-mouse nil
- "Org-mouse"
- :tag "Org Mouse."
- :group 'org)
- (defcustom org-mouse-punctuation ":"
- ""
- :group 'org-mouse
- :type 'string)
- (defun org-mouse-re-search-line (regexp)
- "Searches the current line for a given regular expression."
- (beginning-of-line)
- (re-search-forward regexp (point-at-eol) t))
- (defun org-mouse-end-headline ()
- "Go to the end of current headline (ignoring tags)."
- (interactive)
- (end-of-line)
- (skip-chars-backward "\t ")
- (when (looking-back ":[A-Za-z]+:")
- (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)
- (or (not mark-active)
- (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))
- (if (functionp org-mouse-context-menu-function)
- (funcall org-mouse-context-menu-function)
- (mouse-major-mode-menu event prefix))
- )
- (setq this-command 'mouse-save-then-kill)
- (mouse-save-then-kill event)))
- (defun org-mouse-line-position ()
- "Returns :beginning :middle :end"
- (cond
- ((eolp) :end)
- ((org-mouse-bolp) :begin)
- (t :middle)))
- (defun org-mouse-empty-line ()
- (save-excursion (beginning-of-line) (looking-at "[ \t]*$")))
- (defun org-mouse-next-heading ()
- "Goes to the next heading and if there is none, it ensures that the point is at the beginning of an empty line."
- (unless (outline-next-heading)
- (beginning-of-line)
- (unless (org-mouse-empty-line)
- (end-of-line)
- (newline))))
- (defun org-mouse-insert-heading ()
- (interactive)
- (case (org-mouse-line-position)
- (:begin (beginning-of-line)
- (org-insert-heading))
- (t (org-mouse-next-heading)
- (org-insert-heading))))
- (defun org-mouse-timestamp-today (&optional shift units)
- (interactive)
- (flet ((org-read-date (x &optional y) (current-time)))
- (org-time-stamp nil))
- (when shift
- (org-timestamp-change shift units)))
- (defun org-mouse-keyword-menu (keywords function &optional selected itemformat)
- (mapcar
- (lambda (keyword)
- (vector (cond
- ((functionp itemformat) (funcall itemformat keyword))
- ((stringp itemformat) (format itemformat keyword))
- (t keyword))
- `(funcall ,function ,keyword)
- :style (cond
- ((null selected) t)
- ((functionp selected) 'toggle)
- (t 'radio))
- :selected `(if (functionp ,selected)
- (funcall ,selected ,keyword)
- (equal ,selected ,keyword))))
- keywords))
-
- (defun org-mouse-remove-match-and-spaces ()
- (interactive)
- (replace-match "")
- (when (looking-at " +")
- (replace-match "")))
-
- (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])))
-
- (defvar org-mouse-context-menu-function nil)
- (make-variable-buffer-local 'org-mouse-context-menu-function)
- (defun org-mouse-show-headlines ()
- (interactive)
- (let ((this-command 'org-cycle)
- (last-command 'org-cycle)
- (org-cycle-global-status nil))
- (org-cycle '(4))
- (org-cycle '(4))))
- (defun org-mouse-show-overview ()
- (interactive)
- (let ((org-cycle-global-status nil))
- (org-cycle '(4))))
- (defun org-mouse-set-priority (priority)
- (flet ((read-char-exclusive () priority))
- (org-priority)))
- (defvar org-mouse-priority-regexp "\\[#\\([A-Z]\\)\\]"
- "Regular expression matching the priority indicator. Differs from `org-priority-regexp' in that it doesn't contain the leading '.*?'.")
- (defun org-mouse-get-priority (&optional default)
- (save-excursion
- (if (org-mouse-re-search-line org-mouse-priority-regexp)
- (match-string 1)
- (when default (char-to-string org-default-priority)))))
- (defun org-mouse-at-link ()
- (and (eq (get-text-property (point) 'face) 'org-link)
- (save-excursion
- (goto-char (previous-single-property-change (point) 'face))
- (or (looking-at org-bracket-link-regexp)
- (looking-at org-angle-link-re)
- (looking-at org-plain-link-re)))))
- (defun org-mouse-delete-timestamp ()
- "Deletes the current timestamp as well as the preceding
- SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
- (when (or (org-at-date-range-p) (org-at-timestamp-p))
- (replace-match "") ; delete the timestamp
- (skip-chars-backward " :A-Z")
- (when (looking-at " *[A-Z][A-Z]+:")
- (replace-match ""))))
- (defun org-mouse-looking-at (regexp skipchars &optional movechars)
- (save-excursion
- (let ((point (point)))
- (if (looking-at regexp) t
- (skip-chars-backward skipchars)
- (forward-char (or movechars 0))
- (when (looking-at regexp)
- (> (match-end 0) point))))))
-
- (defun org-mouse-priority-list ()
- (let ((ret) (current org-lowest-priority))
- (while (>= current ?A)
- (push (char-to-string current) ret)
- (decf current))
- ret))
- (defun org-mouse-tag-menu () ;todo
- (append
- (let ((tags (org-split-string (org-get-tags) ":")))
- (org-mouse-keyword-menu
- (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
- `(lambda (tag)
- (org-mouse-set-tags
- (sort (if (member tag (quote ,tags))
- (delete tag (quote ,tags))
- (cons tag (quote ,tags)))
- 'string-lessp)))
- `(lambda (tag) (member tag (quote ,tags)))
- ))
- '("--"
- ["Align Tags Here" (org-set-tags nil t) t]
- ["Align Tags in Buffer" (org-set-tags t t) t]
- ["Set Tags ..." (org-set-tags) t])))
-
- (defun org-mouse-set-tags (tags)
- (save-excursion
- ;; remove existing tags first
- (beginning-of-line)
- (when (org-mouse-re-search-line ":\\(\\([A-Za-z_]+:\\)+\\)")
- (replace-match ""))
- ;; set new tags if any
- (when tags
- (end-of-line)
- (insert " :" (mapconcat 'identity tags ":") ":")
- (org-set-tags nil t))))
-
- (defun org-mouse-insert-checkbox ()
- (interactive)
- (and (org-at-item-p)
- (goto-char (match-end 0))
- (unless (org-at-item-checkbox-p)
- (delete-horizontal-space)
- (insert " [ ] "))))
- (defun org-mouse-agenda-type (type)
- (case type
- ('tags "Tags: ")
- ('todo "TODO: ")
- ('tags-tree "Tags tree: ")
- ('todo-tree "TODO tree: ")
- ('occur-tree "Occur tree: ")
- (t "Agenda command ???")))
- (defun org-mouse-clip-text (text maxlength)
- (if (> (length text) maxlength)
- (concat (substring text 0 (- maxlength 3)) "...")
- text))
- (defun org-mouse-popup-global-menu ()
- (popup-menu
- `("Main Menu"
- ["Show Overview" org-mouse-show-overview t]
- ["Show Headlines" org-mouse-show-headlines t]
- ["Show All" show-all t]
- ["Remove Highlights" org-remove-occur-highlights
- :visible org-occur-highlights]
- "--"
- ["Check Deadlines"
- (if (functionp 'org-check-deadlines-and-todos)
- (org-check-deadlines-and-todos org-deadline-warning-days)
- (org-check-deadlines org-deadline-warning-days)) t]
- ["Check TODOs" org-show-todo-tree t]
- ("Check Tags"
- ,@(org-mouse-keyword-menu
- (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
- '(lambda (tag) (org-tags-sparse-tree nil tag)))
- "--"
- ["Custom Tag ..." org-tags-sparse-tree t])
- ["Check Phrase ..." org-occur]
- "--"
- ["Display Agenda" org-agenda-list t]
- ["Display Timeline" org-timeline t]
- ["Display TODO List" org-todo-list t]
- ("Display Tags"
- ,@(org-mouse-keyword-menu
- (sort (mapcar 'car (org-get-buffer-tags)) 'string-lessp)
- '(lambda (tag) (org-tags-view nil tag)))
- "--"
- ["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)
- (eval `(flet ((read-char-exclusive () (string-to-char ,key)))
- (org-agenda nil))))
- nil
- '(lambda (key)
- (let ((entry (assoc key org-agenda-custom-commands)))
- (org-mouse-clip-text
- (cond
- ((stringp (nth 1 entry)) (nth 1 entry))
- ((stringp (nth 2 entry))
- (concat (org-mouse-agenda-type (nth 1 entry))
- (nth 2 entry)))
- (t "Agenda Command '%s'"))
- 30))))
- ;; )
- "--"
- ["Delete Blank Lines" delete-blank-lines
- :visible (org-mouse-empty-line)]
- ["Insert Checkbox" org-mouse-insert-checkbox
- :visible (and (org-at-item-p) (not (org-at-item-checkbox-p)))]
- ["Insert Checkboxes"
- (org-mouse-for-each-item 'org-mouse-insert-checkbox)
- :visible (and (org-at-item-p) (not (org-at-item-checkbox-p)))]
- ["Plain List to Outline" org-mouse-transform-to-outline
- :visible (org-at-item-p)])))
-
- ; ["Jump" org-goto])))
- (defun org-mouse-get-context (contextlist context)
- (let ((contextdata (find-if (lambda (x) (eq (car x) context)) contextlist)))
- (when contextdata
- (save-excursion
- (goto-char (nth 1 contextdata))
- ; (looking-at regexp)))))
- (re-search-forward ".*" (nth 2 contextdata))))))
- (defun org-mouse-for-each-item (function)
- (save-excursion
- (ignore-errors
- (while t (org-previous-item)))
- (ignore-errors
- (while t
- (funcall function)
- (org-next-item)))))
- (defun org-mouse-bolp ()
- "Returns true if there only spaces, tabs, and '*', between the beginning of line and the point"
- (save-excursion
- (skip-chars-backward " \t*") (bolp)))
-
- (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))
- ad-do-it))
- (defun org-mouse-context-menu ()
- (let ((stamp-prefixes (list org-deadline-string org-scheduled-string))
- (contextlist (org-context)))
- (flet ((get-context (context) (org-mouse-get-context contextlist context)))
- (cond
- ((or (eolp)
- (and (looking-at " \\|\t") (looking-back " \\|\t")))
- (org-mouse-popup-global-menu))
- ;; ((get-context :todo-keyword)
- ((get-context :checkbox)
- (popup-menu
- '(nil
- ["Toggle" org-toggle-checkbox t]
- ["Remove" org-mouse-remove-match-and-spaces t]
- ""
- ["All Clear" (org-mouse-for-each-item
- (lambda ()
- (when (save-excursion (org-at-item-checkbox-p))
- (replace-match "[ ]"))))]
- ["All Set" (org-mouse-for-each-item
- (lambda ()
- (when (save-excursion (org-at-item-checkbox-p))
- (replace-match "[X]"))))]
- ["All Toggle" (org-mouse-for-each-item 'org-toggle-checkbox) t]
- ["All Remove" (org-mouse-for-each-item
- (lambda ()
- (when (save-excursion (org-at-item-checkbox-p))
- (org-mouse-remove-match-and-spaces))))]
- )))
- ((and (org-mouse-looking-at "\\b\\w+" "a-zA-Z0-9_")
- (member (match-string 0) org-todo-keywords))
- (popup-menu
- `(nil
- ,@(org-mouse-keyword-replace-menu org-todo-keywords)
- "--"
- ["Check TODOs" org-show-todo-tree t]
- ["Display TODO List" org-todo-list t]
- )))
- ((and (org-mouse-looking-at "\\b[A-Z]+:" "A-Z")
- (member (match-string 0) stamp-prefixes))
- (popup-menu
- `(nil
- ,@(org-mouse-keyword-replace-menu stamp-prefixes)
- "--"
- ["Check Deadlines" org-check-deadlines t]
- )))
- ((org-mouse-looking-at org-mouse-priority-regexp "[]A-Z#") ; priority
- (popup-menu `(nil ,@(org-mouse-keyword-replace-menu
- (org-mouse-priority-list) 1 "Priority %s"))))
- ((org-mouse-at-link)
- (popup-menu
- '(nil
- ["Open" org-open-at-point t]
- ["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))]
- ; ["Paste file link" ((insert "file:") (yank))]
- )))
- ((org-mouse-looking-at ":\\([A-Za-z0-9_]+\\):" "A-Za-z0-9_" -1) ;tags
- (popup-menu
- `(nil
- [,(format "Display '%s'" (match-string 1))
- (org-tags-view nil ,(match-string 1))]
- [,(format "Narrow to '%s'" (match-string 1))
- (org-tags-sparse-tree nil ,(match-string 1))]
- "--"
- ,@(org-mouse-tag-menu))))
- ((org-at-timestamp-p)
- (popup-menu
- '(nil
- ["Show Day" org-open-at-point t]
- ["Change Timestamp" org-time-stamp t]
- ["Delete Timestamp" (org-mouse-delete-timestamp) t]
- ["Compute Time Range" org-evaluate-time-range (org-at-date-range-p)]
- "--"
- ["Set for Today" org-mouse-timestamp-today]
- ["Set for Tomorrow" (org-mouse-timestamp-today 1 'day)]
- ["Set in 1 Week" (org-mouse-timestamp-today 7 'day)]
- ["Set in 2 Weeks" (org-mouse-timestamp-today 14 'day)]
- ["Set in a Month" (org-mouse-timestamp-today 1 'month)]
- "--"
- ["+ 1 Day" (org-timestamp-change 1 'day)]
- ["+ 1 Week" (org-timestamp-change 7 'day)]
- ["+ 1 Month" (org-timestamp-change 1 'month)]
- "--"
- ["- 1 Day" (org-timestamp-change -1 'day)]
- ["- 1 Week" (org-timestamp-change -7 'day)]
- ["- 1 Month" (org-timestamp-change -1 'month)])))
- ((and (assq :headline contextlist) (not (eolp)))
- (let ((priority (org-mouse-get-priority t)))
- (popup-menu
- `("Headline Menu"
- ("Tags and Priorities"
- ,@(org-mouse-keyword-menu
- (org-mouse-priority-list)
- '(lambda (keyword)
- (org-mouse-set-priority (string-to-char keyword)))
- priority "Priority %s")
- "--"
- ,@(org-mouse-tag-menu))
- ["Show Tags"
- (with-current-buffer org-mouse-main-buffer (org-agenda-show-tags))
- :visible (not org-mouse-direct)]
- ["Show Priority"
- (with-current-buffer org-mouse-main-buffer (org-agenda-show-priority))
- :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
- (org-mouse-re-search-line org-deadline-regexp)))]
- ["Schedule Task"
- (progn (org-mouse-end-headline) (insert " ") (org-schedule))
- :active (not (save-excursion
- (org-mouse-re-search-line org-scheduled-regexp)))]
- ["Insert Timestamp"
- (progn (org-mouse-end-headline) (insert " ") (org-time-stamp nil)) t]
- ; ["Timestamp (inactive)" org-time-stamp-inactive t]
- "--"
- ["Archive Subtree" org-archive-subtree]
- ["Cut Subtree" org-cut-special]
- ["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
- (org-mouse-popup-global-menu))))))
-
- ;; (defun org-mouse-at-regexp (regexp)
- ;; (save-excursion
- ;; (let ((point (point))
- ;; (bol (progn (beginning-of-line) (point)))
- ;; (eol (progn (end-of-line) (point))))
- ;; (goto-char point)
- ;; (re-search-backward regexp bol 1)
- ;; (and (not (eolp))
- ;; (progn (forward-char)
- ;; (re-search-forward regexp eol t))
- ;; (<= (match-beginning 0) point)))))
- (defun org-mouse-in-region-p (pos)
- (and 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))
- (org-mouse-in-region-p (posn-point (event-start event))))
- (mouse-drag-region event)))
- (add-hook 'org-mode-hook
- '(lambda ()
- (setq org-mouse-context-menu-function 'org-mouse-context-menu)
- ; (define-key org-mouse-map [follow-link] 'mouse-face)
- (define-key org-mouse-map (if (featurep 'xemacs) [button3] [mouse-3]) nil)
- (define-key org-mode-map [mouse-3] 'org-mouse-show-context-menu)
- (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-mouse-map [drag-mouse-3] 'org-mouse-move-tree)
- (define-key org-mouse-map [down-mouse-3] 'org-mouse-move-tree-start)
- (font-lock-add-keywords nil
- `((,outline-regexp
- 0 `(face org-link mouse-face highlight keymap ,org-mouse-map)
- 'prepend)
- ("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +"
- (1 `(face org-link keymap ,org-mouse-map mouse-face highlight) 'prepend))
- ("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(\\[[ X]\\]\\)"
- (2 `(face bold keymap ,org-mouse-map mouse-face highlight) t)))
- t)
- (defadvice org-open-at-point (around org-mouse-open-at-point activate)
- (let ((context (org-context)))
- (cond
- ((assq :headline-stars context) (org-cycle))
- ((assq :checkbox context) (org-toggle-checkbox))
- ((assq :item-bullet context)
- (let ((org-cycle-include-plain-lists t)) (org-cycle)))
- (t ad-do-it))))))
- (defun org-mouse-move-tree-start (event)
- (interactive "e")
- (message "Same line: promote/demote, (***):move before, (text): make a child"))
- (defun org-mouse-make-marker (position)
- (with-current-buffer (window-buffer (posn-window position))
- (copy-marker (posn-point position))))
- (defun org-mouse-move-tree (event)
- ;; todo: handle movements between different buffers
- (interactive "e")
- (save-excursion
- (let* ((start (org-mouse-make-marker (event-start event)))
- (end (org-mouse-make-marker (event-end event)))
- (sbuf (marker-buffer start))
- (ebuf (marker-buffer end)))
- (when (and sbuf ebuf)
- (set-buffer sbuf)
- (goto-char start)
- (org-back-to-heading)
- (if (and (eq sbuf ebuf)
- (equal
- (point)
- (save-excursion (goto-char end) (org-back-to-heading) (point))))
- ;; if the same line then promote/demote
- (if (>= end start) (org-demote-subtree) (org-promote-subtree))
- ;; if different lines then move
- (org-cut-subtree)
-
- (set-buffer ebuf)
- (goto-char end)
- (org-back-to-heading)
- (when (and (eq sbuf ebuf)
- (equal
- (point)
- (save-excursion (goto-char start)
- (org-back-to-heading) (point))))
- (outline-end-of-subtree)
- (end-of-line)
- (if (eobp) (newline) (forward-char)))
-
- (when (looking-at outline-regexp)
- (let ((level (- (match-end 0) (match-beginning 0))))
- (when (> end (match-end 0))
- (outline-end-of-subtree)
- (end-of-line)
- (if (eobp) (newline) (forward-char))
- (setq level (1+ level)))
- (org-paste-subtree level)
- (save-excursion
- (outline-end-of-subtree)
- (when (bolp) (delete-char -1))))))))))
- (defun org-mouse-transform-to-outline ()
- (interactive)
- (org-back-to-heading)
- (let ((minlevel 1000)
- (replace-text (concat (match-string 0) "* ")))
- (beginning-of-line 2)
- (save-excursion
- (while (not (or (eobp) (looking-at outline-regexp)))
- (when (looking-at org-mouse-plain-list-regexp)
- (setq minlevel (min minlevel (- (match-end 1) (match-beginning 1)))))
- (forward-line)))
- (while (not (or (eobp) (looking-at outline-regexp)))
- (when (and (looking-at org-mouse-plain-list-regexp)
- (eq minlevel (- (match-end 1) (match-beginning 1))))
- (replace-match replace-text))
- (forward-line))))
-
-
-
- (defun org-mouse-do-remotely (command)
- ; (org-agenda-check-no-diary)
- (when (get-text-property (point) 'org-marker)
- (let* ((anticol (- (point-at-eol) (point)))
- (marker (get-text-property (point) 'org-marker))
- (buffer (marker-buffer marker))
- (pos (marker-position marker))
- (hdmarker (get-text-property (point) 'org-hd-marker))
- (buffer-read-only nil)
- (newhead "--- removed ---")
- (org-mouse-direct nil)
- (org-mouse-main-buffer (current-buffer)))
- (when (eq (with-current-buffer buffer major-mode) 'org-mode)
- (let ((endmarker (save-excursion
- (set-buffer buffer)
- (outline-end-of-subtree)
- (forward-char 1)
- (copy-marker (point)))))
- (with-current-buffer buffer
- (widen)
- (goto-char pos)
- (org-show-hidden-entry)
- (save-excursion
- (and (outline-next-heading)
- (org-flag-heading nil))) ; show the next heading
- (org-back-to-heading)
- (setq marker (copy-marker (point)))
- (goto-char (max (point-at-bol) (- (point-at-eol) anticol)))
- (funcall command)
- (unless (eq (marker-position marker) (marker-position endmarker))
- (setq newhead (org-get-heading))))
-
- (beginning-of-line 1)
- (save-excursion
- (org-agenda-change-all-lines newhead hdmarker 'fixface)))
- t))))
- (defun org-mouse-agenda-context-menu ()
- (or (org-mouse-do-remotely 'org-mouse-context-menu)
- (popup-menu
- '("Agenda"
- ("Agenda Files")
- "--"
- ["Rebuild Buffer" org-agenda-redo t]
- ["New Diary Entry"
- org-agenda-diary-entry (org-agenda-check-type nil 'agenda 'timeline)]
- "--"
- ["Goto Today" org-agenda-goto-today
- (org-agenda-check-type nil 'agenda 'timeline)]
- ["Display Calendar" org-agenda-goto-calendar
- (org-agenda-check-type nil 'agenda 'timeline)]
- ("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)]
- "--"
- ["Create iCalendar file" org-export-icalendar-combine-agenda-files t])
- "--"
- ["Day View" org-agenda-day-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (equal org-agenda-ndays 1)]
- ["Week View" org-agenda-week-view
- :active (org-agenda-check-type nil 'agenda)
- :style radio :selected (equal org-agenda-ndays 7)]
- "--"
- ["Show Logbook entries" org-agenda-log-mode
- :style toggle :selected org-agenda-show-log
- :active (org-agenda-check-type nil 'agenda 'timeline)]
- ["Include Diary" org-agenda-toggle-diary
- :style toggle :selected org-agenda-include-diary
- :active (org-agenda-check-type nil 'agenda)]
- ["Use Time Grid" org-agenda-toggle-time-grid
- :style toggle :selected org-agenda-use-time-grid
- :active (org-agenda-check-type nil 'agenda)]
- ["Follow Mode" org-agenda-follow-mode
- :style toggle :selected org-agenda-follow-mode]
- "--"
- ["Quit" org-agenda-quit t]
- ["Exit and Release Buffers" org-agenda-exit t]
- ))))
- ; (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)))
- (provide 'org-mouse)
-
|