update packages
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
;;; org-clock.el --- The time clocking code for Org mode -*- lexical-binding: t; -*-
|
||||
|
||||
;; Copyright (C) 2004-2023 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2004-2025 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Carsten Dominik <carsten.dominik@gmail.com>
|
||||
;; Keywords: outlines, hypermedia, calendar, wp
|
||||
;; Keywords: outlines, hypermedia, calendar, text
|
||||
;; URL: https://orgmode.org
|
||||
;;
|
||||
;; This file is part of GNU Emacs.
|
||||
@@ -36,9 +36,11 @@
|
||||
|
||||
(declare-function calendar-iso-to-absolute "cal-iso" (date))
|
||||
(declare-function notifications-notify "notifications" (&rest params))
|
||||
(declare-function org-element-property "org-element" (property element))
|
||||
(declare-function org-element-type "org-element" (element))
|
||||
(declare-function org-element--cache-active-p "org-element" ())
|
||||
(declare-function org-element-property "org-element-ast" (property node))
|
||||
(declare-function org-element-contents-end "org-element" (node))
|
||||
(declare-function org-element-end "org-element" (node))
|
||||
(declare-function org-element-type "org-element-ast" (node &optional anonymous))
|
||||
(declare-function org-element-type-p "org-element-ast" (node types))
|
||||
(defvar org-element-use-cache)
|
||||
(declare-function org-inlinetask-at-task-p "org-inlinetask" ())
|
||||
(declare-function org-inlinetask-goto-beginning "org-inlinetask" ())
|
||||
@@ -51,6 +53,11 @@
|
||||
(declare-function org-dynamic-block-define "org" (type func))
|
||||
(declare-function w32-notification-notify "w32fns.c" (&rest params))
|
||||
(declare-function w32-notification-close "w32fns.c" (&rest params))
|
||||
(declare-function dbus-list-activatable-names "dbus" (&optional bus))
|
||||
(declare-function dbus-call-method "dbus" (bus service path interface method &rest args))
|
||||
(declare-function dbus-get-property "dbus" (bus service path interface property))
|
||||
(declare-function haiku-notifications-notify "haikuselect.c")
|
||||
(declare-function android-notifications-notify "androidselect.c")
|
||||
|
||||
(defvar org-frame-title-format-backup nil)
|
||||
(defvar org-state)
|
||||
@@ -125,7 +132,7 @@ clocking out."
|
||||
"Rounding minutes when clocking in or out.
|
||||
The default value is 0 so that no rounding is done.
|
||||
When set to a non-integer value, use the car of
|
||||
`org-time-stamp-rounding-minutes', like for setting a time-stamp.
|
||||
`org-timestamp-rounding-minutes', like for setting a timestamp.
|
||||
|
||||
E.g. if `org-clock-rounding-minutes' is set to 5, time is 14:47
|
||||
and you clock in: then the clock starts at 14:45. If you clock
|
||||
@@ -137,7 +144,7 @@ out time will be 14:50."
|
||||
:package-version '(Org . "8.0")
|
||||
:type '(choice
|
||||
(integer :tag "Minutes (0 for no rounding)")
|
||||
(symbol :tag "Use `org-time-stamp-rounding-minutes'" 'same-as-time-stamp)))
|
||||
(const :tag "Use `org-time-stamp-rounding-minutes'" same-as-time-stamp)))
|
||||
|
||||
(defcustom org-clock-out-remove-zero-time-clocks nil
|
||||
"Non-nil means remove the clock line when the resulting time is zero."
|
||||
@@ -344,14 +351,16 @@ For more information, see `org-clocktable-write-default'."
|
||||
:version "24.1"
|
||||
:type 'function)
|
||||
|
||||
;; FIXME: translate es and nl last string "Clock summary at"
|
||||
(defcustom org-clock-clocktable-language-setup
|
||||
'(("en" "File" "L" "Timestamp" "Headline" "Time" "ALL" "Total time" "File time" "Clock summary at")
|
||||
("es" "Archivo" "N" "Fecha y hora" "Tarea" "Tiempo" "TODO" "Tiempo total" "Tiempo archivo" "Clock summary at")
|
||||
("fr" "Fichier" "N" "Horodatage" "En-tête" "Durée" "TOUT" "Durée totale" "Durée fichier" "Horodatage sommaire à")
|
||||
("nl" "Bestand" "N" "Tijdstip" "Hoofding" "Duur" "ALLES" "Totale duur" "Bestandstijd" "Clock summary at")
|
||||
("de" "Datei" "E" "Zeitstempel" "Kopfzeile" "Dauer" "GESAMT"
|
||||
"Gesamtdauer" "Dateizeit" "Erstellt am"))
|
||||
'(("en" "File" "L" "Timestamp" "Headline" "Time" "ALL" "Total time" "File time" "Clock summary at")
|
||||
("de" "Datei" "E" "Zeitstempel" "Kopfzeile" "Dauer" "GESAMT" "Gesamtdauer" "Dateizeit" "Erstellt am")
|
||||
("es" "Archivo" "N" "Fecha y hora" "Tarea" "Duración" "TODO" "Duración total" "Tiempo archivo" "Generado el")
|
||||
("fr" "Fichier" "N" "Horodatage" "En-tête" "Durée" "TOUT" "Durée totale" "Durée fichier" "Horodatage sommaire à")
|
||||
("nl" "Bestand" "N" "Tijdstip" "Rubriek" "Duur" "ALLES" "Totale duur" "Bestandstijd" "Klok overzicht op")
|
||||
("nn" "Fil" "N" "Tidspunkt" "Overskrift" "Tid" "ALLE" "Total tid" "Filtid" "Tidsoversyn")
|
||||
("pl" "Plik" "P" "Data i godzina" "Nagłówek" "Czas" "WSZYSTKO" "Czas całkowity" "Czas pliku" "Poddumowanie zegara na")
|
||||
("pt-BR" "Arquivo" "N" "Data e hora" "Título" "Hora" "TODOS" "Hora total" "Hora do arquivo" "Resumo das horas em")
|
||||
("sk" "Súbor" "L" "Časová značka" "Záhlavie" "Čas" "VŠETKO" "Celkový čas" "Čas súboru" "Časový súhrn pre"))
|
||||
"Terms used in clocktable, translated to different languages."
|
||||
:group 'org-clocktable
|
||||
:version "24.1"
|
||||
@@ -411,8 +420,8 @@ play with them."
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-clock-clocked-in-display 'mode-line
|
||||
"When clocked in for a task, Org can display the current
|
||||
task and accumulated time in the mode line and/or frame title.
|
||||
"Where to display clocked in task and accumulated time when clocked in.
|
||||
|
||||
Allowed values are:
|
||||
|
||||
both displays in both mode line and frame title
|
||||
@@ -438,7 +447,9 @@ This uses the same format as `frame-title-format', which see."
|
||||
:group 'org-clock
|
||||
:type 'sexp)
|
||||
|
||||
(defcustom org-clock-x11idle-program-name "x11idle"
|
||||
(defcustom org-clock-x11idle-program-name
|
||||
(if (executable-find "xprintidle")
|
||||
"xprintidle" "x11idle")
|
||||
"Name of the program which prints X11 idle time in milliseconds.
|
||||
|
||||
you can do \"~$ sudo apt-get install xprintidle\" if you are using
|
||||
@@ -447,8 +458,7 @@ a Debian-based distribution.
|
||||
Alternatively, can find x11idle.c in
|
||||
https://orgmode.org/worg/code/scripts/x11idle.c"
|
||||
:group 'org-clock
|
||||
:version "24.4"
|
||||
:package-version '(Org . "8.0")
|
||||
:package-version '(Org . "9.7")
|
||||
:type 'string)
|
||||
|
||||
(defcustom org-clock-goto-before-context 2
|
||||
@@ -506,7 +516,11 @@ to add an effort property.")
|
||||
(defvar org-clock-in-hook nil
|
||||
"Hook run when starting the clock.")
|
||||
(defvar org-clock-out-hook nil
|
||||
"Hook run when stopping the current clock.")
|
||||
"Hook run when stopping the current clock.
|
||||
The point is at the current clock line when the hook is executed.
|
||||
|
||||
The hook functions can access `org-clock-out-removed-last-clock' to
|
||||
check whether the latest CLOCK line has been cleared.")
|
||||
|
||||
(defvar org-clock-cancel-hook nil
|
||||
"Hook run when canceling the current clock.")
|
||||
@@ -560,6 +574,10 @@ of a different task.")
|
||||
Assume S in the English term to translate. Return S as-is if it
|
||||
cannot be translated."
|
||||
(or (nth (pcase s
|
||||
;; "L" stands for "Level"
|
||||
;; "ALL" stands for a line summarizing clock data across
|
||||
;; all the files, when the clocktable includes multiple
|
||||
;; files.
|
||||
("File" 1) ("L" 2) ("Timestamp" 3) ("Headline" 4) ("Time" 5)
|
||||
("ALL" 6) ("Total time" 7) ("File time" 8) ("Clock summary at" 9))
|
||||
(assoc-string language org-clock-clocktable-language-setup t))
|
||||
@@ -574,6 +592,7 @@ cannot be translated."
|
||||
(org-no-properties (org-get-heading t t t t))))))
|
||||
|
||||
(defun org-clock-menu ()
|
||||
"Pop up org-clock menu."
|
||||
(interactive)
|
||||
(popup-menu
|
||||
'("Clock"
|
||||
@@ -583,7 +602,12 @@ cannot be translated."
|
||||
["Switch task" (lambda () (interactive) (org-clock-in '(4))) :active t :keys "C-u C-c C-x C-i"])))
|
||||
|
||||
(defun org-clock-history-push (&optional pos buffer)
|
||||
"Push a marker to the clock history."
|
||||
"Push point marker to the clock history.
|
||||
When POS is provided, use it as marker point.
|
||||
When BUFFER and POS are provided, use marker at POS in base buffer of
|
||||
BUFFER."
|
||||
;; When buffer is provided, POS must be provided.
|
||||
(cl-assert (or (not buffer) pos))
|
||||
(setq org-clock-history-length (max 1 org-clock-history-length))
|
||||
(let ((m (move-marker (make-marker)
|
||||
(or pos (point)) (org-base-buffer
|
||||
@@ -603,7 +627,10 @@ cannot be translated."
|
||||
(push m org-clock-history)))
|
||||
|
||||
(defun org-clock-save-markers-for-cut-and-paste (beg end)
|
||||
"Save relative positions of markers in region."
|
||||
"Save relative positions of markers in region BEG..END.
|
||||
Save `org-clock-marker', `org-clock-hd-marker',
|
||||
`org-clock-default-task', `org-clock-interrupted-task', and the
|
||||
markers in `org-clock-history'."
|
||||
(org-check-and-save-marker org-clock-marker beg end)
|
||||
(org-check-and-save-marker org-clock-hd-marker beg end)
|
||||
(org-check-and-save-marker org-clock-default-task beg end)
|
||||
@@ -629,6 +656,7 @@ cannot be translated."
|
||||
|
||||
(defun org-clock-select-task (&optional prompt)
|
||||
"Select a task that was recently associated with clocking.
|
||||
PROMPT is the prompt text to be used, as a string.
|
||||
Return marker position of the selected task. Raise an error if
|
||||
there is no recent clock to choose from."
|
||||
(let (och chl sel-list rpl (i 0) s)
|
||||
@@ -639,7 +667,7 @@ there is no recent clock to choose from."
|
||||
(if (zerop chl)
|
||||
(user-error "No recent clock")
|
||||
(save-window-excursion
|
||||
(org-switch-to-buffer-other-window
|
||||
(switch-to-buffer-other-window
|
||||
(get-buffer-create "*Clock Task Select*"))
|
||||
(erase-buffer)
|
||||
(when (marker-buffer org-clock-default-task)
|
||||
@@ -669,8 +697,11 @@ there is no recent clock to choose from."
|
||||
;; `fit-window-to-buffer'
|
||||
(fit-window-to-buffer nil nil (if (< chl 10) chl (+ 5 chl)))
|
||||
(message (or prompt "Select task for clocking:"))
|
||||
(setq cursor-type nil rpl (read-char-exclusive))
|
||||
(kill-buffer)
|
||||
(unwind-protect (setq cursor-type nil rpl (read-char-exclusive))
|
||||
(when-let* ((window (get-buffer-window "*Clock Task Select*" t)))
|
||||
(quit-window 'kill window))
|
||||
(when (get-buffer "*Clock Task Select*")
|
||||
(kill-buffer "*Clock Task Select*")))
|
||||
(cond
|
||||
((eq rpl ?q) nil)
|
||||
((eq rpl ?x) nil)
|
||||
@@ -779,6 +810,7 @@ previous clocking intervals."
|
||||
60)))
|
||||
(+ currently-clocked-time (or org-clock-total-time 0))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-clock-modify-effort-estimate (&optional value)
|
||||
"Add to or set the effort estimate of the item currently being clocked.
|
||||
VALUE can be a number of minutes, or a string with format hh:mm or mm.
|
||||
@@ -855,6 +887,18 @@ use libnotify if available, or fall back on a message."
|
||||
((stringp org-show-notification-handler)
|
||||
(start-process "emacs-timer-notification" nil
|
||||
org-show-notification-handler notification))
|
||||
((fboundp 'haiku-notifications-notify)
|
||||
;; N.B. timeouts are not available under Haiku.
|
||||
(haiku-notifications-notify :title "Org mode message"
|
||||
:body notification
|
||||
:urgency 'low))
|
||||
((fboundp 'android-notifications-notify)
|
||||
;; N.B. timeouts are not available under Haiku or Android.
|
||||
(android-notifications-notify :title "Org mode message"
|
||||
:body notification
|
||||
;; Low urgency notifications
|
||||
;; are by default hidden.
|
||||
:urgency 'normal))
|
||||
((fboundp 'w32-notification-notify)
|
||||
(let ((id (w32-notification-notify
|
||||
:title "Org mode message"
|
||||
@@ -897,7 +941,7 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
|
||||
(if (executable-find "aplay")
|
||||
(start-process "org-clock-play-notification" nil
|
||||
"aplay" file)
|
||||
(condition-case nil
|
||||
(condition-case-unless-debug nil
|
||||
(play-sound-file file)
|
||||
(error (beep t) (beep t))))))))))
|
||||
|
||||
@@ -914,9 +958,11 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward org-clock-re nil t)
|
||||
(push (cons (copy-marker (match-end 1) t)
|
||||
(org-time-string-to-time (match-string 1)))
|
||||
clocks))))
|
||||
(when (save-match-data
|
||||
(org-element-type-p (org-element-at-point) 'clock))
|
||||
(push (cons (copy-marker (match-end 1) t)
|
||||
(org-time-string-to-time (match-string 1)))
|
||||
clocks)))))
|
||||
clocks))
|
||||
|
||||
(defsubst org-is-active-clock (clock)
|
||||
@@ -930,7 +976,7 @@ If CLOCK-SOUND is non-nil, it overrides `org-clock-sound'."
|
||||
`(with-current-buffer (marker-buffer (car ,clock))
|
||||
(org-with-wide-buffer
|
||||
(goto-char (car ,clock))
|
||||
(beginning-of-line)
|
||||
(forward-line 0)
|
||||
,@forms)))
|
||||
|
||||
(defmacro org-with-clock (clock &rest forms)
|
||||
@@ -1036,8 +1082,8 @@ CLOCK is a cons cell of the form (MARKER START-TIME)."
|
||||
(catch 'exit
|
||||
(while (re-search-backward drawer-re beg t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (eq (org-element-type element) 'drawer)
|
||||
(when (> (org-element-property :end element) (car clock))
|
||||
(when (org-element-type-p element 'drawer)
|
||||
(when (> (org-element-end element) (car clock))
|
||||
(org-fold-hide-drawer-toggle 'off nil element))
|
||||
(throw 'exit nil)))))))))))
|
||||
|
||||
@@ -1212,6 +1258,27 @@ If `only-dangling-p' is non-nil, only ask to resolve dangling
|
||||
"Return the current X11 idle time in seconds."
|
||||
(/ (string-to-number (shell-command-to-string org-clock-x11idle-program-name)) 1000))
|
||||
|
||||
(defvar org-logind-dbus-session-path
|
||||
(when (and (boundp 'dbus-runtime-version)
|
||||
(require 'dbus nil t)
|
||||
(member "org.freedesktop.login1" (dbus-list-activatable-names)))
|
||||
(ignore-errors
|
||||
(dbus-call-method
|
||||
:system "org.freedesktop.login1"
|
||||
"/org/freedesktop/login1"
|
||||
"org.freedesktop.login1.Manager"
|
||||
"GetSessionByPID" (emacs-pid))))
|
||||
"D-Bus session path for the elogind interface.")
|
||||
|
||||
(defun org-logind-user-idle-seconds ()
|
||||
"Return the number of idle seconds for the user according to logind."
|
||||
(- (float-time)
|
||||
(/ (dbus-get-property
|
||||
:system "org.freedesktop.login1"
|
||||
org-logind-dbus-session-path
|
||||
"org.freedesktop.login1.Session" "IdleSinceHint")
|
||||
1e6)))
|
||||
|
||||
(defun org-user-idle-seconds ()
|
||||
"Return the number of seconds the user has been idle for.
|
||||
This routine returns a floating point number."
|
||||
@@ -1220,6 +1287,13 @@ This routine returns a floating point number."
|
||||
(org-mac-idle-seconds))
|
||||
((and (eq window-system 'x) org-x11idle-exists-p)
|
||||
(org-x11-idle-seconds))
|
||||
((and
|
||||
org-logind-dbus-session-path
|
||||
(dbus-get-property
|
||||
:system "org.freedesktop.login1"
|
||||
org-logind-dbus-session-path
|
||||
"org.freedesktop.login1.Session" "IdleHint"))
|
||||
(org-logind-user-idle-seconds))
|
||||
(t
|
||||
(org-emacs-idle-seconds))))
|
||||
|
||||
@@ -1277,8 +1351,6 @@ time as the start time. See `org-clock-continuously' to make this
|
||||
the default behavior."
|
||||
(interactive "P")
|
||||
(setq org-clock-notification-was-shown nil)
|
||||
(unless org-element-use-cache
|
||||
(org-refresh-effort-properties))
|
||||
(catch 'abort
|
||||
(let ((interrupting (and (not org-clock-resolving-clocks-due-to-idleness)
|
||||
(org-clocking-p)))
|
||||
@@ -1356,8 +1428,8 @@ the default behavior."
|
||||
(when newstate (org-todo newstate))))
|
||||
((and org-clock-in-switch-to-state
|
||||
(not (looking-at (concat org-outline-regexp "[ \t]*"
|
||||
org-clock-in-switch-to-state
|
||||
"\\>"))))
|
||||
org-clock-in-switch-to-state
|
||||
"\\(?:[ \t]\\|$\\)"))))
|
||||
(org-todo org-clock-in-switch-to-state)))
|
||||
(setq org-clock-heading (org-clock--mode-line-heading))
|
||||
(org-clock-find-position org-clock-in-resume)
|
||||
@@ -1383,12 +1455,15 @@ the default behavior."
|
||||
(sit-for 2)
|
||||
(throw 'abort nil))
|
||||
(t
|
||||
;; Make sure that point moves after clock line upon
|
||||
;; inserting it. Then, users can continue typing even if
|
||||
;; point was right where the clock is inserted.
|
||||
(insert-before-markers-and-inherit "\n")
|
||||
(backward-char 1)
|
||||
(when (and (save-excursion
|
||||
(end-of-line 0)
|
||||
(org-in-item-p)))
|
||||
(beginning-of-line 1)
|
||||
(forward-line 0)
|
||||
(indent-line-to (max 0 (- (current-indentation) 2))))
|
||||
(insert-and-inherit org-clock-string " ")
|
||||
(setq org-clock-effort (org-entry-get (point) org-effort-property))
|
||||
@@ -1408,8 +1483,8 @@ the default behavior."
|
||||
leftover)
|
||||
start-time
|
||||
(org-current-time org-clock-rounding-minutes t)))
|
||||
(setq ts (org-insert-time-stamp org-clock-start-time
|
||||
'with-hm 'inactive))
|
||||
(setq ts (org-insert-timestamp org-clock-start-time
|
||||
'with-hm 'inactive))
|
||||
(org-indent-line)))
|
||||
(move-marker org-clock-marker (point) (buffer-base-buffer))
|
||||
(move-marker org-clock-hd-marker
|
||||
@@ -1445,6 +1520,33 @@ the default behavior."
|
||||
(message "Clock starts at %s - %s" ts org--msg-extra)
|
||||
(run-hooks 'org-clock-in-hook))))))
|
||||
|
||||
(defvar org-clock--auto-clockout-timer-obj nil
|
||||
"Timer object holding the existing clockout timer.")
|
||||
(defun org-clock--auto-clockout-maybe ()
|
||||
"Clock out the currently clocked in task when idle.
|
||||
See `org-clock-auto-clockout-timer' to set the idle time span.
|
||||
|
||||
This function is to be called by a timer."
|
||||
(when (and (numberp org-clock-auto-clockout-timer)
|
||||
org-clock-current-task)
|
||||
(let ((user-idle-seconds (org-user-idle-seconds)))
|
||||
(cond
|
||||
;; Already idle. Clock out.
|
||||
((>= user-idle-seconds org-clock-auto-clockout-timer)
|
||||
(setq org-clock--auto-clockout-timer-obj nil)
|
||||
(org-clock-out))
|
||||
;; Emacs is idle but system is not. Retry assuming that system will remain idle.
|
||||
((>= (org-emacs-idle-seconds) org-clock-auto-clockout-timer)
|
||||
(setq org-clock--auto-clockout-timer-obj
|
||||
(run-with-timer
|
||||
(- org-clock-auto-clockout-timer user-idle-seconds)
|
||||
nil #'org-clock--auto-clockout-maybe)))
|
||||
;; Emacs is not idle. Check again next time we are idle.
|
||||
(t
|
||||
(setq org-clock--auto-clockout-timer-obj
|
||||
(run-with-idle-timer
|
||||
org-clock-auto-clockout-timer nil #'org-clock--auto-clockout-maybe)))))))
|
||||
|
||||
(defun org-clock-auto-clockout ()
|
||||
"Clock out the currently clocked in task if Emacs is idle.
|
||||
See `org-clock-auto-clockout-timer' to set the idle time span.
|
||||
@@ -1452,9 +1554,11 @@ See `org-clock-auto-clockout-timer' to set the idle time span.
|
||||
This is only effective when `org-clock-auto-clockout-insinuate'
|
||||
is present in the user configuration."
|
||||
(when (and (numberp org-clock-auto-clockout-timer)
|
||||
org-clock-current-task)
|
||||
(run-with-idle-timer
|
||||
org-clock-auto-clockout-timer nil #'org-clock-out)))
|
||||
org-clock-current-task
|
||||
(not (timerp org-clock--auto-clockout-timer-obj)))
|
||||
(setq org-clock--auto-clockout-timer-obj
|
||||
(run-with-idle-timer
|
||||
org-clock-auto-clockout-timer nil #'org-clock--auto-clockout-maybe))))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-clock-toggle-auto-clockout ()
|
||||
@@ -1562,9 +1666,9 @@ line and position cursor in that line."
|
||||
" *\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")))
|
||||
(while (re-search-forward open-clock-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (and (eq (org-element-type element) 'clock)
|
||||
(when (and (org-element-type-p element 'clock)
|
||||
(eq (org-element-property :status element) 'running))
|
||||
(beginning-of-line)
|
||||
(forward-line 0)
|
||||
(throw 'exit t))))))
|
||||
;; Look for an existing clock drawer.
|
||||
(when drawer
|
||||
@@ -1572,8 +1676,8 @@ line and position cursor in that line."
|
||||
(let ((drawer-re (concat "^[ \t]*:" (regexp-quote drawer) ":[ \t]*$")))
|
||||
(while (re-search-forward drawer-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (eq (org-element-type element) 'drawer)
|
||||
(let ((cend (org-element-property :contents-end element)))
|
||||
(when (org-element-type-p element 'drawer)
|
||||
(let ((cend (org-element-contents-end element)))
|
||||
(if (and (not org-log-states-order-reversed) cend)
|
||||
(goto-char cend)
|
||||
(forward-line))
|
||||
@@ -1586,7 +1690,7 @@ line and position cursor in that line."
|
||||
(save-excursion
|
||||
(while (re-search-forward clock-re end t)
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (eq (org-element-type element) 'clock)
|
||||
(when (org-element-type-p element 'clock)
|
||||
(setq positions (cons (line-beginning-position) positions)
|
||||
count (1+ count))))))
|
||||
(cond
|
||||
@@ -1594,19 +1698,18 @@ line and position cursor in that line."
|
||||
(org-fold-core-ignore-modifications
|
||||
;; Skip planning line and property drawer, if any.
|
||||
(org-end-of-meta-data)
|
||||
(unless (bolp) (insert-and-inherit "\n"))
|
||||
(unless (bolp) (insert-before-markers-and-inherit "\n"))
|
||||
;; Create a new drawer if necessary.
|
||||
(when (and org-clock-into-drawer
|
||||
(or (not (wholenump org-clock-into-drawer))
|
||||
(< org-clock-into-drawer 2)))
|
||||
(let ((beg (point)))
|
||||
(insert-and-inherit ":" drawer ":\n:END:\n")
|
||||
;; Make sure that point moves after drawer upon
|
||||
;; inserting it. Then, users can continue typing even
|
||||
;; if point was right where the clock is inserted.
|
||||
(insert-before-markers-and-inherit ":" drawer ":\n:END:\n")
|
||||
(org-indent-region beg (point))
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-region
|
||||
(line-end-position -1) (1- (point)) t 'drawer)
|
||||
(org-fold-region
|
||||
(line-end-position -1) (1- (point)) t 'outline))
|
||||
(org-fold-region (line-end-position -1) (1- (point)) t 'drawer)
|
||||
(forward-line -1)))))
|
||||
;; When a clock drawer needs to be created because of the
|
||||
;; number of clock items or simply if it is missing, collect
|
||||
@@ -1631,13 +1734,13 @@ line and position cursor in that line."
|
||||
"\n:END:\n")
|
||||
(let ((end (point-marker)))
|
||||
(goto-char beg)
|
||||
(save-excursion (insert-and-inherit ":" drawer ":\n"))
|
||||
(save-excursion (insert-before-markers-and-inherit ":" drawer ":\n"))
|
||||
(org-fold-region (line-end-position) (1- end) t 'outline)
|
||||
(org-indent-region (point) end)
|
||||
(forward-line)
|
||||
(unless org-log-states-order-reversed
|
||||
(goto-char end)
|
||||
(beginning-of-line -1))
|
||||
(forward-line -2))
|
||||
(set-marker end nil)))))
|
||||
(org-log-states-order-reversed (goto-char (car (last positions))))
|
||||
(t (goto-char (car positions))))))))
|
||||
@@ -1650,6 +1753,11 @@ and current `frame-title-format' is equal to `org-clock-frame-title-format'."
|
||||
(equal frame-title-format org-clock-frame-title-format))
|
||||
(setq frame-title-format org-frame-title-format-backup)))
|
||||
|
||||
(defvar org-clock-out-removed-last-clock nil
|
||||
"When non-nil, the last `org-clock-out' removed the clock line.
|
||||
This can happen when `org-clock-out-remove-zero-time-clocks' is set to
|
||||
non-nil and the latest clock took 0 minutes.")
|
||||
|
||||
;;;###autoload
|
||||
(defun org-clock-out (&optional switch-to-state fail-quietly at-time)
|
||||
"Stop the currently running clock.
|
||||
@@ -1680,7 +1788,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char org-clock-marker)
|
||||
(beginning-of-line 1)
|
||||
(forward-line 0)
|
||||
(if (and (looking-at (concat "[ \t]*" org-keyword-time-regexp))
|
||||
(equal (match-string 1) org-clock-string))
|
||||
(setq ts (match-string 2))
|
||||
@@ -1689,7 +1797,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
||||
(delete-region (point) (line-end-position))
|
||||
(org-fold-core-ignore-modifications
|
||||
(insert-and-inherit "--")
|
||||
(setq te (org-insert-time-stamp (or at-time now) 'with-hm 'inactive))
|
||||
(setq te (org-insert-timestamp (or at-time now) 'with-hm 'inactive))
|
||||
(setq s (org-time-convert-to-integer
|
||||
(time-subtract
|
||||
(org-time-string-to-time te)
|
||||
@@ -1728,10 +1836,10 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
||||
(when newstate (org-todo newstate))))
|
||||
((and org-clock-out-switch-to-state
|
||||
(not (looking-at
|
||||
(concat
|
||||
org-outline-regexp "[ \t]*"
|
||||
org-clock-out-switch-to-state
|
||||
"\\>"))))
|
||||
(concat
|
||||
org-outline-regexp "[ \t]*"
|
||||
org-clock-out-switch-to-state
|
||||
"\\(?:[ \t]\\|$\\)"))))
|
||||
(org-todo org-clock-out-switch-to-state))))))
|
||||
(force-mode-line-update)
|
||||
(message (if remove
|
||||
@@ -1740,6 +1848,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
|
||||
te (org-duration-from-minutes (+ (* 60 h) m)))
|
||||
(unless (org-clocking-p)
|
||||
(setq org-clock-current-task nil))
|
||||
(setq org-clock-out-removed-last-clock remove)
|
||||
(run-hooks 'org-clock-out-hook)
|
||||
;; Add a note, but only if we didn't remove the clock line.
|
||||
(when (and org-log-note-clock-out (not remove))
|
||||
@@ -1934,20 +2043,36 @@ PROPNAME lets you set a custom text property instead of :org-clock-minutes."
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(while (re-search-backward re nil t)
|
||||
(let ((element-type
|
||||
(org-element-type
|
||||
(save-match-data
|
||||
(org-element-at-point)))))
|
||||
(let* ((element (save-match-data (org-element-at-point)))
|
||||
(element-type (org-element-type element)))
|
||||
(cond
|
||||
((and (eq element-type 'clock) (match-end 2))
|
||||
;; Two time stamps.
|
||||
(let* ((ss (match-string 2))
|
||||
(se (match-string 3))
|
||||
(ts (org-time-string-to-seconds ss))
|
||||
(te (org-time-string-to-seconds se))
|
||||
(dt (- (if tend (min te tend) te)
|
||||
(if tstart (max ts tstart) ts))))
|
||||
(when (> dt 0) (cl-incf t1 (floor dt 60)))))
|
||||
(condition-case nil
|
||||
(let* ((timestamp (org-element-property :value element))
|
||||
(ts (float-time
|
||||
(org-encode-time
|
||||
(list 0
|
||||
(org-element-property :minute-start timestamp)
|
||||
(org-element-property :hour-start timestamp)
|
||||
(org-element-property :day-start timestamp)
|
||||
(org-element-property :month-start timestamp)
|
||||
(org-element-property :year-start timestamp)
|
||||
nil -1 nil))))
|
||||
(te (float-time
|
||||
(org-encode-time
|
||||
(list 0
|
||||
(org-element-property :minute-end timestamp)
|
||||
(org-element-property :hour-end timestamp)
|
||||
(org-element-property :day-end timestamp)
|
||||
(org-element-property :month-end timestamp)
|
||||
(org-element-property :year-end timestamp)
|
||||
nil -1 nil))))
|
||||
(dt (- (if tend (min te tend) te)
|
||||
(if tstart (max ts tstart) ts))))
|
||||
(when (> dt 0) (cl-incf t1 (floor dt 60))))
|
||||
(error
|
||||
(org-display-warning (format "org-clock-sum: Ignoring invalid %s" (org-current-line-string))))))
|
||||
((match-end 4)
|
||||
;; A naked time.
|
||||
(setq t1 (+ t1 (string-to-number (match-string 5))
|
||||
@@ -2344,7 +2469,7 @@ have priority."
|
||||
d (+ d shift)))
|
||||
((or `week `thisweek)
|
||||
(let* ((ws (or wstart 1))
|
||||
(diff (+ (* -7 shift) (if (= dow 0) (- 7 ws) (- dow ws)))))
|
||||
(diff (+ (* -7 shift) (mod (+ dow 7 (- ws)) 7))))
|
||||
(setq m 0 h org-extend-today-until d (- d diff) d1 (+ 7 d))))
|
||||
((or `month `thismonth)
|
||||
(setq h org-extend-today-until m 0 d (or mstart 1)
|
||||
@@ -2495,7 +2620,7 @@ the currently selected interval size."
|
||||
(goto-char b)
|
||||
(insert ins)
|
||||
(delete-region (point) (+ (point) (- e b)))
|
||||
(beginning-of-line 1)
|
||||
(forward-line 0)
|
||||
(org-update-dblock)
|
||||
t)))))
|
||||
|
||||
@@ -2797,13 +2922,13 @@ from the dynamic block definition."
|
||||
(if timestamp (concat ts "|") "") ;timestamp, maybe
|
||||
(if tags (concat (mapconcat #'identity tgs ", ") "|") "") ;tags, maybe
|
||||
(if properties ;properties columns, maybe
|
||||
(concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
|
||||
properties
|
||||
"|")
|
||||
"|")
|
||||
(concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
|
||||
properties
|
||||
"|")
|
||||
"|")
|
||||
"")
|
||||
(if indent ;indentation
|
||||
(org-clocktable-indent-string level)
|
||||
(org-clocktable-indent-string level)
|
||||
"")
|
||||
(format-field headline)
|
||||
;; Empty fields for higher levels.
|
||||
@@ -2811,7 +2936,7 @@ from the dynamic block definition."
|
||||
(format-field (org-duration-from-minutes time))
|
||||
(make-string (max 0 (- time-columns level)) ?|)
|
||||
(if (eq formula '%)
|
||||
(format "%.1f |" (* 100 (/ time (float total-time))))
|
||||
(format "%.1f |" (* 100 (/ time (float total-time))))
|
||||
"")
|
||||
"\n")))))))
|
||||
(delete-char -1)
|
||||
@@ -2822,7 +2947,7 @@ from the dynamic block definition."
|
||||
(when (and contents (string-match "^\\([ \t]*#\\+tblfm:.*\\)" contents))
|
||||
(setq recalc t)
|
||||
(insert "\n" (match-string 1 contents))
|
||||
(beginning-of-line 0))))
|
||||
(forward-line -1))))
|
||||
;; Insert specified formula line.
|
||||
((stringp formula)
|
||||
(insert "\n#+TBLFM: " formula)
|
||||
@@ -3004,8 +3129,9 @@ PROPERTIES: The list properties specified in the `:properties' parameter
|
||||
(let* ((todo (org-get-todo-state))
|
||||
(tags-list (org-get-tags))
|
||||
(org-scanner-tags tags-list)
|
||||
(org-trust-scanner-tags t))
|
||||
(funcall matcher todo tags-list nil)))))
|
||||
(org-trust-scanner-tags t)
|
||||
(level (org-current-level)))
|
||||
(funcall matcher todo tags-list level)))))
|
||||
(goto-char (point-min))
|
||||
(setq st t)
|
||||
(while (or (and (bobp) (prog1 st (setq st nil))
|
||||
@@ -3065,7 +3191,7 @@ Otherwise, return nil."
|
||||
(let ((origin (point))) ;; `save-excursion' may not work when deleting.
|
||||
(prog1
|
||||
(save-excursion
|
||||
(beginning-of-line 1)
|
||||
(forward-line 0)
|
||||
(skip-chars-forward " \t")
|
||||
(when (looking-at org-clock-string)
|
||||
(let ((re (concat "[ \t]*" org-clock-string
|
||||
@@ -3125,7 +3251,7 @@ The details of what will be saved are regulated by the variable
|
||||
org-clock-has-been-used
|
||||
(not (file-exists-p org-clock-persist-file))))
|
||||
(with-temp-file org-clock-persist-file
|
||||
(insert (format ";; %s - %s at %s\n"
|
||||
(insert (format ";; %s - %s at %s -*- lexical-binding: t; -*-\n"
|
||||
(file-name-nondirectory org-clock-persist-file)
|
||||
(system-name)
|
||||
(format-time-string (org-time-stamp-format t))))
|
||||
@@ -3135,7 +3261,7 @@ The details of what will be saved are regulated by the variable
|
||||
(and (buffer-live-p b)
|
||||
(buffer-file-name b)
|
||||
(or (not org-clock-persist-query-save)
|
||||
(y-or-n-p (format "Save current clock (%s) "
|
||||
(y-or-n-p (format "Save current clock (%s)?"
|
||||
org-clock-heading))))))
|
||||
(insert
|
||||
(format "(setq org-clock-stored-resume-clock '(%S . %d))\n"
|
||||
@@ -3175,7 +3301,7 @@ The details of what will be saved are regulated by the variable
|
||||
(`(,(and file (pred file-exists-p)) . ,position)
|
||||
(with-current-buffer (find-file-noselect file)
|
||||
(when (or (not org-clock-persist-query-resume)
|
||||
(y-or-n-p (format "Resume clock (%s) "
|
||||
(y-or-n-p (format "Resume clock (%s)?"
|
||||
(save-excursion
|
||||
(goto-char position)
|
||||
(org-get-heading t t)))))
|
||||
|
||||
Reference in New Issue
Block a user