Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
bc23baaa
Commit
bc23baaa
authored
Dec 07, 2008
by
Carsten Dominik
Browse files
Checking in the correct versions of the files, sorry, I hade used the files
from an experimental branch.....
parent
e5f29d66
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
280 additions
and
309 deletions
+280
-309
doc/misc/ChangeLog
doc/misc/ChangeLog
+10
-0
lisp/org/ChangeLog
lisp/org/ChangeLog
+0
-20
lisp/org/org-clock.el
lisp/org/org-clock.el
+1
-2
lisp/org/org-exp.el
lisp/org/org-exp.el
+16
-23
lisp/org/org-id.el
lisp/org/org-id.el
+58
-194
lisp/org/org-timer.el
lisp/org/org-timer.el
+181
-0
lisp/org/org.el
lisp/org/org.el
+14
-70
No files found.
doc/misc/ChangeLog
View file @
bc23baaa
2008-12-02 Carsten Dominik <carsten.dominik@gmail.com>
* org.texi (Using the mapping API): Fix bug in mapping example.
(Publishing options): Make the list of properties complete again, in
correspondence to the variable `org-export-plist-vars'.
(Property searches): Document new special values for time comparisons.
(Tag inheritance): Refine the description of tag inheritance.
(Project alist): Add info about the publishing sequence of components.
(Effort estimates): Document the new relativer timer.
2008-12-04 David Engster <dengste@eml.cc>
* gnus.texi (nnmairix): Mention mairix.el. Point out the importance
...
...
lisp/org/ChangeLog
View file @
bc23baaa
2008-12-07 Carsten Dominik <carsten.dominik@gmail.com>
* org-id.el (org-id-locations-file): Wrap file name with
`convert-standard-filename'.
(org-id-files): New variable.
(org-id-use-hash): New option.
(org-id-update-id-locations): Also search in all files current
listed in `org-id-files'. Convert the resulting alist to a hash
if the user customation says so.
(org-id-locations-save): Handle he case if `org-id-locations' is a
hash.
(org-id-locations-load): Convert the alist to a hash.
(org-id-add-location): Handle the hast case.
(kill-emacs-hook): Make sure id locations are saved when Emacs is
exited.
(org-id-hash-to-alist, org-id-alist-to-hash)
(org-id-paste-tracker): New functions.
2008-12-07 Carsten Dominik <carsten.dominik@gmail.com>
...
...
@@ -244,9 +227,6 @@
(org-remember-mode): New minor mode.
(org-remember-apply-template): Turn on `org-remember-mode'.
* org-id.el (org-id-add-location): Avoid error when no file is
given.
* org-remember.el (org-remember-apply-template): Fix the way how
the list of allowed properties is retrieved from the target file.
...
...
lisp/org/org-clock.el
View file @
bc23baaa
...
...
@@ -118,8 +118,7 @@ be visited."
(
const
:tag
"Clock and history"
t
)
(
const
:tag
"No persistence"
nil
)))
(
defcustom
org-clock-persist-file
(
convert-standard-filename
"~/.emacs.d/org-clock-save.el"
)
(
defcustom
org-clock-persist-file
"~/.emacs.d/org-clock-save.el"
"File to save clock data to"
:group
'org-clock
:type
'string
)
...
...
lisp/org/org-exp.el
View file @
bc23baaa
...
...
@@ -1465,9 +1465,6 @@ on this string to produce the exported version."
;; Handle source code snippets
(org-export-replace-src-segments)
;; Find all headings and compute the targets for them
(setq target-alist (org-export-define-heading-targets target-alist))
;; Get rid of drawers
(org-export-remove-or-extract-drawers drawers
...
...
@@ -1490,6 +1487,9 @@ on this string to produce the exported version."
;; Remove todo-keywords before exporting, if the user has requested so
(org-export-remove-headline-metadata parameters)
;; Find all headings and compute the targets for them
(setq target-alist (org-export-define-heading-targets target-alist))
;; Find targets in comments and move them out of comments,
;; but mark them as targets that should be invisible
(setq target-alist (org-export-handle-invisible-targets target-alist))
...
...
@@ -1513,6 +1513,7 @@ on this string to produce the exported version."
;; Remove comment environment and comment subtrees
(org-export-remove-comment-blocks-and-subtrees)
;; Find matches for radio targets and turn them into internal links
(org-export-mark-radio-links)
...
...
@@ -1570,22 +1571,18 @@ on this string to produce the exported version."
The new targets are added to TARGET-ALIST, which is also returned."
(goto-char (point-min))
(org-init-section-numbers)
(let ((re (concat "^" org-outline-regexp
"\\| [ \t]*:ID:[ \t]*\\([^ \t\r\n]+\\)"))
(let ((re (concat "^" org-outline-regexp))
level target)
(while (re-search-forward re nil t)
(if (match-end 1)
(push (cons (org-match-string-no-properties 1)
target) target-alist)
(setq level (org-reduced-level
(save-excursion (goto-char (point-at-bol))
(org-outline-level))))
(setq target (org-solidify-link-text
(format "sec-%s" (org-section-number level))))
(push (cons target target) target-alist)
(add-text-properties
(point-at-bol) (point-at-eol)
(list 'target target)))))
(setq level (org-reduced-level
(save-excursion (goto-char (point-at-bol))
(org-outline-level))))
(setq target (org-solidify-link-text
(format "sec-%s" (org-section-number level))))
(push (cons target target) target-alist)
(add-text-properties
(point-at-bol) (point-at-eol)
(list 'target target))))
target-alist)
(defun org-export-handle-invisible-targets (target-alist)
...
...
@@ -1614,11 +1611,9 @@ Mark them as invisible targets."
target-alist)
(defun org-export-target-internal-links (target-alist)
"Find all internal links and assign target
s
to them.
"Find all internal links and assign target to them.
If a link has a fuzzy match (i.e. not a *dedicated* target match),
let the link point to the corresponding section.
This function also handles the id links, if they have a match in
the current file."
let the link point to the corresponding section."
(goto-char (point-min))
(while (re-search-forward org-bracket-link-regexp nil t)
(org-if-unprotected
...
...
@@ -1630,8 +1625,6 @@ the current file."
(target
(cond
((cdr (assoc slink target-alist)))
((and (string-match "^id:" link)
(cdr (assoc (substring link 3) target-alist))))
((string-match org-link-types-re link) nil)
((or (file-name-absolute-p link)
(string-match "^\\." link))
...
...
lisp/org/org-id.el
View file @
bc23baaa
;;; org-id.el --- Global identifier
s
for Org-mode entries
;;; org-id.el --- Global identifier for Org-mode entries
;; Copyright (C) 2008 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
...
...
@@ -116,42 +116,17 @@ be added."
:group
'org-id
:type
'boolean
)
(
defcustom
org-id-track-globally
t
"Non-nil means, track ID's trhough files, so that links work globally.
This work by maintaining a hash table for ID's and writing this table
to disk when exiting Emacs. Because of this, it works best if you use
a single Emacs process, not many.
When nil, ID's are not tracked. Links to ID's will still work within
a buffer, but not if the entry is located in another file.
ID's can still be used if the entry with the id is in the same file as
the link."
:group
'org-id
:type
'boolean
)
(
defcustom
org-id-locations-file
(
convert-standard-filename
"~/.emacs.d/.org-id-locations"
)
"The file for remembering in which file an ID was defined.
This variable is only relevant when `org-id-track-globally' is set."
"~/.org-id-locations"
)
"The file for remembering the last ID number generated."
:group
'org-id
:type
'file
)
(
defvar
org-id-locations
nil
"List of files with ID's in those files.
Depending on `org-id-use-hash' this can also be a hash table mapping ID's
to files."
)
(
defvar
org-id-files
nil
"List of files that contain ID's."
)
"List of files with ID's in those files."
)
(
defcustom
org-id-extra-files
'org-agenda-text-search-extra-files
"Files to be searched for ID's, besides the agenda files.
When Org reparses files to remake the list of files and ID's it is tracking,
it will normally scan the agenda files, the archives related to agenda files,
any files that are listed as ID containing in the current register, and
any Org-mode files currently visited by Emacs.
You can list additional files here.
This variable is only relevant when `org-id-track-globally' is set."
"Files to be searched for ID's, besides the agenda files."
:group
'org-id
:type
'
(
choice
...
...
@@ -159,14 +134,6 @@ This variable is only relevant when `org-id-track-globally' is set."
(
repeat
:tag
"List of files"
(
file
))))
(
defcustom
org-id-search-archives
t
"Non-nil means, search also the archive files of agenda files for entries.
This is a possibility to reduce overhead, but it measn that entries moved
to the archives can no longer be found by ID.
This variable is only relevant when `org-id-track-globally' is set."
:group
'org-id
:type
'boolean
)
;;; The API functions
;;;###autoload
...
...
@@ -235,7 +202,7 @@ It returns the ID of the entry. If necessary, the ID is created."
(
defun
org-id-goto
(
id
)
"Switch to the buffer containing the entry with id ID.
Move the cursor to that entry in that buffer."
(
interactive
"sID: "
)
(
interactive
)
(
let
((
m
(
org-id-find
id
'marker
)))
(
unless
m
(
error
"Cannot find entry with ID \"%s\""
id
))
...
...
@@ -359,153 +326,77 @@ and time is the usual three-integer representation of time."
;; Storing ID locations (files)
(
defun
org-id-update-id-locations
(
&optional
files
check
)
(
defun
org-id-update-id-locations
()
"Scan relevant files for ID's.
Store the relation between files and corresponding ID's.
This will scan all agenda files, all associated archives, and all
files currently mentioned in `org-id-locations'.
When FILES is given, scan these files instead."
Store the relation between files and corresponding ID's."
(
interactive
)
(
if
(
not
org-id-track-globally
)
(
error
"Please turn on `org-id-track-globally' if you want to track id's."
)
(
let
((
files
(
or
files
(
append
;; Agenda files and all associated archives
(
org-agenda-files
t
org-id-search-archives
)
;; Explicit extra files
(
if
(
symbolp
org-id-extra-files
)
(
symbol-value
org-id-extra-files
)
org-id-extra-files
)
;; Files associated with live org-mode buffers
(
delq
nil
(
mapcar
(
lambda
(
b
)
(
with-current-buffer
b
(
and
(
org-mode-p
)
(
buffer-file-name
))))
(
buffer-list
)))
;; All files known to have id's
org-id-files
)))
org-agenda-new-buffers
file
nfiles
tfile
ids
reg
found
id
seen
(
ndup
0
))
(
setq
nfiles
(
length
files
))
(
while
(
setq
file
(
pop
files
))
(
message
"Finding ID locations (%d/%d files): %s"
(
-
nfiles
(
length
files
))
nfiles
file
)
(
setq
tfile
(
file-truename
file
))
(
when
(
and
(
file-exists-p
file
)
(
not
(
member
tfile
seen
)))
(
push
tfile
seen
)
(
setq
ids
nil
)
(
with-current-buffer
(
org-get-agenda-file-buffer
file
)
(
save-excursion
(
save-restriction
(
widen
)
(
goto-char
(
point-min
))
(
while
(
re-search-forward
"^[ \t]*:ID:[ \t]+\\(\\S-+\\)[ \t]*$"
nil
t
)
(
setq
id
(
org-match-string-no-properties
1
))
(
if
(
member
id
found
)
(
progn
(
message
"Duplicate ID \"%s\""
id
)
(
setq
ndup
(
1+
ndup
)))
(
push
id
found
)
(
push
id
ids
)))
(
push
(
cons
(
abbreviate-file-name
file
)
ids
)
reg
))))))
(
org-release-buffers
org-agenda-new-buffers
)
(
setq
org-agenda-new-buffers
nil
)
(
setq
org-id-locations
reg
)
(
setq
org-id-files
(
mapcar
'car
org-id-locations
))
(
org-id-locations-save
)
;; this function can also handle the alist form
;; now convert to a hash
(
setq
org-id-locations
(
org-id-alist-to-hash
org-id-locations
))
(
if
(
>
ndup
0
)
(
message
"WARNING: %d duplicate ID's found, check *Messages* buffer"
ndup
)
(
message
"%d unique files scanned for ID's"
(
length
org-id-files
)))
org-id-locations
)))
(
let
((
files
(
append
(
org-agenda-files
)
(
if
(
symbolp
org-id-extra-files
)
(
symbol-value
org-id-extra-files
)
org-id-extra-files
)))
org-agenda-new-buffers
file
ids
reg
found
id
)
(
while
(
setq
file
(
pop
files
))
(
setq
ids
nil
)
(
with-current-buffer
(
org-get-agenda-file-buffer
file
)
(
save-excursion
(
save-restriction
(
widen
)
(
goto-char
(
point-min
))
(
while
(
re-search-forward
"^[ \t]*:ID:[ \t]+\\(\\S-+\\)[ \t]*$"
nil
t
)
(
setq
id
(
org-match-string-no-properties
1
))
(
if
(
member
id
found
)
(
error
"Duplicate ID \"%s\""
id
))
(
push
id
found
)
(
push
id
ids
))
(
push
(
cons
file
ids
)
reg
)))))
(
org-release-buffers
org-agenda-new-buffers
)
(
setq
org-agenda-new-buffers
nil
)
(
setq
org-id-locations
reg
)
(
org-id-locations-save
)))
(
defun
org-id-locations-save
()
"Save `org-id-locations' in `org-id-locations-file'."
(
when
org-id-track-globally
(
let
((
out
(
if
(
hash-table-p
org-id-locations
)
(
org-id-hash-to-alist
org-id-locations
)
org-id-locations
)))
(
with-temp-file
org-id-locations-file
(
print
out
(
current-buffer
))))))
(
with-temp-file
org-id-locations-file
(
print
org-id-locations
(
current-buffer
))))
(
defun
org-id-locations-load
()
"Read the data from `org-id-locations-file'."
(
setq
org-id-locations
nil
)
(
when
org-id-track-globally
(
with-temp-buffer
(
condition-case
nil
(
progn
(
insert-file-contents-literally
org-id-locations-file
)
(
goto-char
(
point-min
))
(
setq
org-id-locations
(
read
(
current-buffer
))))
(
error
(
message
"Could not read org-id-values from %s. Setting it to nil."
org-id-locations-file
))))
(
setq
org-id-files
(
mapcar
'car
org-id-locations
))
(
setq
org-id-locations
(
org-id-alist-to-hash
org-id-locations
))))
(
with-temp-buffer
(
condition-case
nil
(
progn
(
insert-file-contents-literally
org-id-locations-file
)
(
goto-char
(
point-min
))
(
setq
org-id-locations
(
read
(
current-buffer
))))
(
error
(
message
"Could not read org-id-values from %s. Setting it to nil."
org-id-locations-file
)))))
(
defun
org-id-add-location
(
id
file
)
"Add the ID with location FILE to the database of ID loations."
;; Only if global tracking is on, and when the buffer has a file
(
when
(
and
org-id-track-globally
id
file
)
(
when
(
and
id
file
)
; don't error when called from a buffer with no file
(
unless
org-id-locations
(
org-id-locations-load
))
(
puthash
id
(
abbreviate-file-name
file
)
org-id-locations
)
(
add-to-list
'org-id-files
(
abbreviate-file-name
file
))))
(
add-hook
'kill-emacs-hook
'org-id-locations-save
)
(
defun
org-id-hash-to-alist
(
hash
)
"Turn an org-id hash into an alist, so that it can be written to a file."
(
let
(
res
x
)
(
maphash
(
lambda
(
k
v
)
(
if
(
setq
x
(
member
v
res
))
(
push
k
(
cdr
x
))
(
push
(
list
v
k
)
res
)))
hash
)
res
))
(
defun
org-id-alist-to-hash
(
list
)
"Turn an org-id location list into a hash table."
(
let
((
res
(
make-hash-table
:test
'equal
:size
(
apply
'+
(
mapcar
'length
list
))))
f
i
)
(
mapc
(
lambda
(
x
)
(
setq
f
(
car
x
))
(
mapc
(
lambda
(
i
)
(
puthash
i
f
res
))
(
cdr
x
)))
list
)
res
))
(
defun
org-id-paste-tracker
(
txt
&optional
buffer-or-file
)
"Update any ID's in TXT and assign BUFFER-OR-FILE to them."
(
when
org-id-track-globally
(
save-match-data
(
setq
buffer-or-file
(
or
buffer-or-file
(
current-buffer
)))
(
when
(
bufferp
buffer-or-file
)
(
setq
buffer-or-file
(
or
(
buffer-base-buffer
buffer-or-file
)
buffer-or-file
))
(
setq
buffer-or-file
(
buffer-file-name
buffer-or-file
)))
(
when
buffer-or-file
(
let
((
fname
(
abbreviate-file-name
buffer-or-file
))
(
s
0
))
(
while
(
string-match
"^[ \t]*:ID:[ \t]+\\([^ \t\n\r]+\\)"
txt
s
)
(
setq
s
(
match-end
0
))
(
org-id-add-location
(
match-string
1
txt
)
fname
)))))))
(
catch
'exit
(
let
((
locs
org-id-locations
)
list
)
(
while
(
setq
list
(
pop
locs
))
(
when
(
equal
(
file-truename
file
)
(
file-truename
(
car
list
)))
(
setcdr
list
(
cons
id
(
cdr
list
)))
(
throw
'exit
t
))))
(
push
(
list
file
id
)
org-id-locations
))
(
org-id-locations-save
)))
;; Finding entries with specified id
(
defun
org-id-find-id-file
(
id
)
"Query the id database for the file in which this ID is located."
(
unless
org-id-locations
(
org-id-locations-load
))
(
or
(
gethash
id
org-id-locations
)
;; ball back on current buffer
(
buffer-file-name
(
or
(
buffer-base-buffer
(
current-buffer
))
(
current-buffer
)))))
(
catch
'found
(
mapc
(
lambda
(
x
)
(
if
(
member
id
(
cdr
x
))
(
throw
'found
(
car
x
))))
org-id-locations
)
nil
))
(
defun
org-id-find-id-in-file
(
id
file
&optional
markerp
)
"Return the position of the entry ID in FILE.
...
...
@@ -524,35 +415,8 @@ optional argument MARKERP, return the position as a new marker."
(
move-marker
(
make-marker
)
pos
buf
)
(
cons
file
pos
))))))))
;; id link type
;; Calling the following function is hard-coded into `org-store-link',
;; so we do have to add it to `org-store-link-functions'.
(
defun
org-id-store-link
()
"Store a link to the current entry, using it's ID."
(
interactive
)
(
let*
((
link
(
org-make-link
"id:"
(
org-id-get-create
)))
(
desc
(
save-excursion
(
org-back-to-heading
t
)
(
or
(
and
(
looking-at
org-complex-heading-regexp
)
(
if
(
match-end
4
)
(
match-string
4
)
(
match-string
0
)))
link
))))
(
org-store-link-props
:link
link
:description
desc
:type
"id"
)
link
))
(
defun
org-id-open
(
id
)
"Go to the entry with id ID."
(
org-mark-ring-push
)
(
switch-to-buffer-other-window
(
current-buffer
))
(
org-id-goto
id
))
(
org-add-link-type
"id"
'org-id-open
)
(
provide
'org-id
)
;;; org-id.el ends here
;; arch-tag: e5abaca4-e16f-4b25-832a-540cfb63a712
lisp/org/org-timer.el
0 → 100644
View file @
bc23baaa
;;; org-clock.el --- The time clocking code for Org-mode
;; Copyright (C) 2008 Free Software Foundation, Inc.
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;; Version: 6.14
;;
;; This file is part of GNU Emacs.
;;
;; GNU Emacs 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 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;; This file contains the relative timer code for Org-mode
(
require
'org
)
(
defvar
org-timer-start-time
nil
"t=0 for the running timer."
)
(
defconst
org-timer-re
"\\([-+]?[0-9]+\\):\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)"
"Regular expression used to match timer stamps."
)
(
defcustom
org-timer-format
"%s "
"The format to insert the time of the timer.
This format must contain one instance of \"%s\" which will be replaced by
the value of the relative timer."
:group
'org-time
:type
'string
)
;;;###autoload
(
defun
org-timer-start
(
&optional
offset
)
"Set the starting time for the relative timer to now.
When called with prefix argument OFFSET, prompt the user for an offset time,
with the default taken from a timer stamp at point, if any.
If OFFSET is a string or an integer, it is directly taken to be the offset
without user interaction.
When called with a double prefix arg, all timer strings in the active
region will be shifted by a specific amount. You will be prompted for
the amount, with the default to make the first timer string in
the region 0:00:00."
(
interactive
"P"
)
(
if
(
equal
offset
'
(
16
))
(
call-interactively
'org-timer-change-times-in-region
)
(
let
(
delta
def
s
)
(
if
(
not
offset
)
(
setq
org-timer-start-time
(
current-time
))
(
cond
((
integerp
offset
)
(
setq
delta
offset
))
((
stringp
offset
)
(
setq
delta
(
org-timer-hms-to-secs
offset
)))
(
t
(
setq
def
(
if
(
org-in-regexp
org-timer-re
)
(
match-string
0
)
"0:00:00"
)
s
(
read-string
(
format
"Restart timer with offset [%s]: "
def
)))
(
unless
(
string-match
"\\S-"
s
)
(
setq
s
def
))
(
setq
delta
(
org-timer-hms-to-secs
(
org-timer-fix-incomplete
s
)))))
(
setq
org-timer-start-time
(
seconds-to-time
(
-
(
time-to-seconds
(
current-time
))
(
org-timer-hms-to-secs
s
)))))
(
message
"Timer start time set to %s, current value is %s"
(
format-time-string
"%T"
org-timer-start-time
)
(
org-timer-secs-to-hms
(
or
delta
0
))))))
;;;###autoload
(
defun
org-timer
(
&optional
restart
)
"Insert a H:MM:SS string from the timer into the buffer.
The first time this command is used, the timer is started. When used with
a `C-u' prefix, force restarting the timer.
When used with a double prefix arg `C-u C-u', change all the timer string
in the region by a fixed amount. This can be used to recalibrate a timer
that was not started at the correct moment."
(
interactive
"P"
)
(
if
(
equal
restart
'
(
4
))
(
org-timer-start
))
(
or
org-timer-start-time
(
org-timer-start
))
(
insert
(
format
org-timer-format
(
org-timer-secs-to-hms
(
floor
(
-
(
time-to-seconds
(
current-time
))
(
time-to-seconds
org-timer-start-time
)))))))
;;;###autoload
(
defun
org-timer-change-times-in-region
(
beg
end
delta
)
"Change all h:mm:ss time in region by a DELTA."
(
interactive
"r\nsEnter time difference like \"-1:08:26\". Default is first time to zero: "
)
(
let
((
re
"[-+]?[0-9]+:[0-9]\\{2\\}:[0-9]\\{2\\}"
)
p
)
(
unless
(
string-match
"\\S-"
delta
)
(
save-excursion
(
goto-char
beg
)
(
when
(
re-search-forward
re
end
t
)
(
setq
delta
(
match-string
0
))
(
if
(
equal
(
string-to-char
delta
)
?-
)
(
setq
delta
(
substring
delta
1
))
(
setq
delta
(
concat
"-"
delta
))))))
(
setq
delta
(
org-timer-hms-to-secs
(
org-timer-fix-incomplete
delta
)))
(
when
(
=
delta
0
)
(
error
"No change"
))
(
save-excursion
(
goto-char
end
)
(
while
(
re-search-backward
re
beg
t
)
(
setq
p
(
point
))
(
replace-match
(
save-match-data
(
org-timer-secs-to-hms
(
+
(
org-timer-hms-to-secs
(
match-string
0
))
delta
)))
t
t
)
(
goto-char
p
)))))
;;;###autoload
(
defun
org-timer-item
(
&optional
arg
)
"Insert a description-type item with the curren timer value."
(
interactive
"P"
)
(
let
((
ind
0
))
(
save-excursion
(
skip-chars-backward
" \n\t"
)
(
condition-case
nil
(
progn
(
org-beginning-of-item
)
(
setq
ind
(
org-get-indentation
)))
(
error
nil
)))
(
or
(
bolp
)
(
newline
))
(
org-indent-line-to
ind
)
(
insert
"- "
)
(
org-timer
(
if
arg
'
(
4
)))
(
insert
":: "
)))
(
defun
org-timer-fix-incomplete
(
hms
)
"If hms is a H:MM:SS string with missing hour or hour and minute, fix it."
(
if
(
string-match
"\\(?:\\([0-9]+:\\)?\\([0-9]+:\\)\\)?\\([0-9]+\\)"
hms
)
(
replace-match
(
format
"%d:%02d:%02d"
(
if
(
match-end
1
)
(
string-to-number
(
match-string
1
hms
))
0
)
(
if
(
match-end
2
)
(
string-to-number
(
match-string
2
hms
))
0
)
(
string-to-number
(
match-string
3
hms
)))
t
t
hms
)
(
error
"Canot parse HMS string \"%s\""
hms
)))
(
defun
org-timer-hms-to-secs
(
hms
)
"Convert h:mm:ss string to an integer time.
If the string starts with a minus sign, the integer will be negative."
(
if
(
not
(
string-match
"\\([-+]?[0-9]+\\):\\([0-9]\\{2\\}\\):\\([0-9]\\{2\\}\\)"
hms
))
0
(
let*
((
h
(
string-to-number
(
match-string
1
hms
)))
(
m
(
string-to-number
(
match-string
2
hms
)))
(
s
(
string-to-number
(
match-string
3
hms
)))
(
sign
(
equal
(
substring
(
match-string
1
hms
)
0
1
)
"-"
)))
(
setq
h
(
abs
h
))
(
*
(
if
sign
-1
1
)
(
+
s
(
*
60
(
+
m
(
*
60
h
))))))))
(
defun
org-timer-secs-to-hms
(
s
)
"Convert integer S into h:mm:ss.
If the integer is negative, the strig will start with \"-\"."
(
let
(
sign
m
h
)
(
setq
sign
(
if
(
<
s
0
)
"-"
""
)
s
(
abs
s
)
m
(
/
s
60
)
s
(
-
s
(