From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Wiegley Subject: Re: Re: Patch for resolving "away time" when clocked in Date: Fri, 16 Oct 2009 12:45:08 -0400 Message-ID: <131E75B1-D61D-46B6-A28A-F75F7CFE622E@gmail.com> References: <27E1810B-0447-46B3-9AF4-BA14ACECA00A@gmail.com> <877huvmirr.fsf@dynapse.com> Mime-Version: 1.0 (Apple Message framework v1075.2) Content-Type: multipart/mixed; boundary=Apple-Mail-1-378917840 Return-path: Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MypvX-0004SA-D7 for emacs-orgmode@gnu.org; Fri, 16 Oct 2009 12:45:15 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MypvW-0004Qc-Pb for emacs-orgmode@gnu.org; Fri, 16 Oct 2009 12:45:14 -0400 Received: from [199.232.76.173] (port=49059 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MypvW-0004QQ-Ar for emacs-orgmode@gnu.org; Fri, 16 Oct 2009 12:45:14 -0400 Received: from ey-out-1920.google.com ([74.125.78.150]:24953) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MypvV-0004g7-Bf for emacs-orgmode@gnu.org; Fri, 16 Oct 2009 12:45:14 -0400 Received: by ey-out-1920.google.com with SMTP id 3so2398931eyh.34 for ; Fri, 16 Oct 2009 09:45:12 -0700 (PDT) In-Reply-To: <877huvmirr.fsf@dynapse.com> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: "Gregory J. Grubbs" Cc: emacs-orgmode@gnu.org --Apple-Mail-1-378917840 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes On Oct 16, 2009, at 11:59 AM, Gregory J. Grubbs wrote: > One suggestion: I think when your code stops on a clock and prompts to > keep/subtract/cancel, it should expand the drawer (for those of us who > use drawers). I've added this to the version of the patch below. As another question: When attempting to clock into A, and org-resolve-clocks finds a dangling clock in B, and the user presses "k" or "s" (i.e., not K or S), do you expect it to clock you into A or into B when the resolution is done? Right now K will continue the clock-in to A, but k will abort the clock-in to A and clock you into B to resume that task. John --Apple-Mail-1-378917840 Content-Disposition: attachment; filename=0001-Added-clock-resolution-logic.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Added-clock-resolution-logic.patch" Content-Transfer-Encoding: quoted-printable =46rom=2046222b3cff81bd0df53fd2c91b0548d92ef57a22=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20John=20Wiegley=20=0A= Date:=20Tue,=2013=20Oct=202009=2003:38:16=20-0400=0ASubject:=20[PATCH]=20= Added=20"clock=20resolution"=20logic=0A=0AAllows=20the=20user=20to=20= find=20and=20resolve=20dangling=20clock=20entries,=20as=20well=20as=0A= notify=20them=20if=20they=20have=20been=20idle=20while=20clocked=20in.=0A= =0AThere=20are=20several=20ways=20to=20resolve=20an=20open=20clock=20= (whether=20dangling=20or=0Aidle):=0A=0A=20=20k=20-=20Keep=20X=20minutes=20= of=20the=20time,=20default=20being=20all=20of=20the=20away=20time=0A=20=20= =20=20=20=20(for=20dangling=20entries,=20the=20away=20time=20is=20= computed=20from=20the=20last=0A=20=20=20=20=20=20time=20the=20org=20file=20= was=20saved)=0A=20=20K=20-=20Keep=20X=20minutes,=20then=20immediately=20= clock=20out=0A=20=20s=20-=20Subtract=20all=20of=20the=20idle/away=20= minutes=20and=20resume=20clock=20from=20now=0A=20=20S=20-=20Subtract=20= all=20of=20the=20idle/away=20minutes,=20and=20clock=20out=0A=20=20C=20-=20= Cancel=20the=20clock=0A=0ANote=20that=20some=20of=20these=20keys=20work=20= without=20affecting=20the=20current=20clock,=0Aunless=20the=20entry=20= being=20operated=20on=20happens=20to=20be=20the=20current=20clock.=0A= This=20means=20if=20you=20clocked=20into=20a=20different=20task,=20ran=20= M-x=0Aorg-resolve-clocks=20and=20found=20a=20dangling=20entry,=20you=20= could=20resolve=20it=0Ausing=20S=20without=20interrupting=20the=20= current=20clock.=20=20If=20you=20resolved=20with=20k=0Aor=20s,=20= however,=20it=20would=20clock=20you=20out=20of=20the=20active=20clock,=20= and=20back=20into=0Athe=20one=20being=20resolved,=20since=20those=20keys=20= assume=20a=20desire=20to=20resume=20the=0Atask=20that=20was=20orphaned.=0A= ---=0A=20doc/org.texi=20=20=20=20=20=20|=20=20=2071=20+++++++++++-=0A=20= lisp/org-clock.el=20|=20=20346=20= ++++++++++++++++++++++++++++++++++++++++++++++++++++-=0A=20lisp/org.el=20= =20=20=20=20=20=20|=20=20=20=204=20+-=0A=203=20files=20changed,=20413=20= insertions(+),=208=20deletions(-)=0A=0Adiff=20--git=20a/doc/org.texi=20= b/doc/org.texi=0Aindex=20538aba8..313c6cd=20100644=0A---=20= a/doc/org.texi=0A+++=20b/doc/org.texi=0A@@=20-231,6=20+231,7=20@@=20= Dates=20and=20Times=0A=20*=20Creating=20timestamps::=20=20=20=20=20=20=20= =20=20Commands=20which=20insert=20timestamps=0A=20*=20Deadlines=20and=20= scheduling::=20=20=20=20Planning=20your=20work=0A=20*=20Clocking=20work=20= time::=20=20=20=20=20=20=20=20=20=20Tracking=20how=20long=20you=20spend=20= on=20a=20task=0A+*=20Resolving=20idle=20time::=20=20=20=20=20=20=20=20=20= =0A=20*=20Effort=20estimates::=20=20=20=20=20=20=20=20=20=20=20=20= Planning=20work=20effort=20in=20advance=0A=20*=20Relative=20timer::=20=20= =20=20=20=20=20=20=20=20=20=20=20=20Notes=20with=20a=20running=20timer=0A= =20=0A@@=20-4703,6=20+4704,7=20@@=20is=20used=20in=20a=20much=20wider=20= sense.=0A=20*=20Creating=20timestamps::=20=20=20=20=20=20=20=20=20= Commands=20which=20insert=20timestamps=0A=20*=20Deadlines=20and=20= scheduling::=20=20=20=20Planning=20your=20work=0A=20*=20Clocking=20work=20= time::=20=20=20=20=20=20=20=20=20=20Tracking=20how=20long=20you=20spend=20= on=20a=20task=0A+*=20Resolving=20idle=20time::=20=20=20=20=20=20=20=20=20= =0A=20*=20Effort=20estimates::=20=20=20=20=20=20=20=20=20=20=20=20= Planning=20work=20effort=20in=20advance=0A=20*=20Relative=20timer::=20=20= =20=20=20=20=20=20=20=20=20=20=20=20Notes=20with=20a=20running=20timer=0A= =20@end=20menu=0A@@=20-5220,7=20+5222,7=20@@=20subtree,=20with=20dates=20= shifted=20in=20each=20copy.=20=20The=20command=20@kbd{C-c=20C-x=20c}=20= was=0A=20created=20for=20this=20purpose,=20it=20is=20described=20in=20= @ref{Structure=20editing}.=0A=20=0A=20=0A-@node=20Clocking=20work=20= time,=20Effort=20estimates,=20Deadlines=20and=20scheduling,=20Dates=20= and=20Times=0A+@node=20Clocking=20work=20time,=20Resolving=20idle=20= time,=20Deadlines=20and=20scheduling,=20Dates=20and=20Times=0A=20= @section=20Clocking=20work=20time=0A=20=0A=20Org=20mode=20allows=20you=20= to=20clock=20the=20time=20you=20spend=20on=20specific=20tasks=20in=20a=0A= @@=20-5405,7=20+5407,72=20@@=20The=20@kbd{l}=20key=20may=20be=20used=20= in=20the=20timeline=20(@pxref{Timeline})=20and=20in=0A=20the=20agenda=20= (@pxref{Weekly/daily=20agenda})=20to=20show=20which=20tasks=20have=20= been=0A=20worked=20on=20or=20closed=20during=20a=20day.=0A=20=0A-@node=20= Effort=20estimates,=20Relative=20timer,=20Clocking=20work=20time,=20= Dates=20and=20Times=0A+@node=20Resolving=20idle=20time,=20Effort=20= estimates,=20Clocking=20work=20time,=20Dates=20and=20Times=0A+@section=20= Resolving=20idle=20time=0A+@cindex=20resolve=20idle=20time=0A+=0A= +@cindex=20idle,=20resolve,=20dangling=0A+If=20you=20clock=20in=20on=20a=20= work=20item,=20and=20then=20walk=20away=20from=20your=0A= +computer---perhaps=20to=20take=20a=20phone=20call---you=20often=20need=20= to=20``resolve''=20the=0A+time=20you=20were=20away=20by=20either=20= subtracting=20it=20from=20the=20current=20clock,=20or=0A+applying=20it=20= to=20another=20one.=0A+=0A+@vindex=20org-clock-idle-time=0A+By=20= customizing=20the=20variable=20@code{org-clock-idle-time}=20to=20some=20= integer,=20such=0A+as=2010=20or=2015,=20Emacs=20can=20alert=20you=20when=20= you=20get=20back=20to=20your=20computer=20after=0A+being=20idle=20for=20= that=20many=20minutes@footnote{On=20computers=20using=20Mac=20OS=20X,=0A= +idleness=20is=20based=20on=20actual=20user=20idleness,=20not=20just=20= Emacs'=20idle=20time.},=20and=0A+ask=20what=20you=20want=20to=20do=20= with=20the=20idle=20time.=20=20There=20will=20be=20a=20question=20= waiting=0A+for=20you=20when=20you=20get=20back,=20indicating=20how=20= much=20idle=20time=20has=20passed=0A+(constantly=20updated=20with=20the=20= current=20amount),=20as=20well=20as=20a=20set=20of=20choices=20to=0A= +correct=20the=20discrepancy:=0A+=0A+@table=20@kbd=0A+@item=20k=0A+To=20= keep=20some=20or=20all=20of=20the=20minutes=20and=20stay=20clocked=20in,=20= press=20@key{k}.=20=20Org=0A+will=20ask=20how=20many=20of=20the=20= minutes=20to=20keep.=20=20Press=20@key{RET}=20to=20keep=20them=20all,=0A= +effectively=20changing=20nothing,=20or=20enter=20a=20number=20to=20keep=20= that=20many=20minutes.=0A+@item=20K=0A+If=20you=20use=20the=20shift=20= key=20and=20press=20@key{K},=20it=20will=20keep=20however=20many=20= minutes=0A+you=20request=20and=20then=20immediately=20clock=20out=20of=20= that=20task.=20=20If=20you=20keep=20all=20of=0A+the=20minutes,=20this=20= is=20the=20same=20as=20just=20clocking=20out=20of=20the=20current=20= task.=0A+@item=20s=0A+To=20keep=20none=20of=20the=20minutes,=20use=20= @key{s}=20to=20subtract=20all=20the=20away=20time=20from=0A+the=20clock,=20= and=20then=20check=20back=20in=20from=20the=20moment=20you=20returned.=0A= +@item=20S=0A+To=20keep=20none=20of=20the=20minutes=20and=20just=20clock=20= out=20at=20the=20start=20of=20the=20away=20time,=0A+use=20the=20shift=20= key=20and=20press=20@key{S}.=20=20Remember=20that=20using=20shift=20will=20= always=0A+leave=20you=20clocked=20out,=20no=20matter=20which=20option=20= you=20choose.=0A+@item=20C=0A+To=20cancel=20the=20clock=20altogether,=20= use=20@key{C}.=20=20Note=20that=20if=20instead=20of=0A+cancelling=20you=20= subtract=20the=20away=20time,=20and=20the=20resulting=20clock=20amount=20= is=20less=0A+than=20a=20minute,=20the=20clock=20will=20still=20be=20= cancelled=20rather=20than=20clutter=20up=20the=0A+log=20with=20an=20= empty=20entry.=0A+@end=20table=0A+=0A+What=20if=20you=20subtracted=20= those=20away=20minutes=20from=20the=20current=20clock,=20and=20now=0A= +want=20to=20apply=20them=20to=20a=20new=20clock?=20=20Simply=20clock=20= in=20to=20any=20task=20immediately=0A+after=20the=20subtraction.=20=20= Org=20will=20notice=20that=20you=20have=20subtracted=20time=20``on=0A= +the=20books'',=20so=20to=20speak,=20and=20will=20ask=20if=20you=20want=20= to=20apply=20those=20minutes=20to=0A+the=20next=20task=20you=20clock=20= in=20on.=0A+=0A+There=20is=20one=20other=20instance=20when=20this=20= clock=20resolution=20magic=20occurs.=20=20Say=20you=0A+were=20clocked=20= in=20and=20hacking=20away,=20and=20suddenly=20your=20cat=20chased=20a=20= mouse=20who=0A+scared=20a=20hamster=20that=20crashed=20into=20your=20= UPS's=20power=20button!=20=20You=20suddenly=0A+lose=20all=20your=20= buffers,=20but=20thanks=20to=20auto-save=20you=20still=20have=20your=20= recent=20Org=0A+mode=20changes,=20including=20your=20last=20clock=20in.=0A= +=0A+If=20you=20restart=20Emacs=20and=20clock=20into=20any=20task,=20Org=20= will=20notice=20that=20you=20have=20a=0A+dangling=20clock=20which=20was=20= never=20clocked=20out=20from=20your=20last=20session.=20=20Using=20the=0A= +Org=20file's=20last=20modified=20time=20as=20the=20beginning=20of=20the=20= ``away''=20period,=20Org=0A+will=20ask=20how=20you=20want=20to=20resolve=20= that=20unaccounted-for=20time.=20=20The=20logic=20and=0A+behavior=20is=20= identical=20to=20dealing=20with=20away=20time=20due=20to=20idleness,=20= it's=20just=0A+happening=20due=20to=20a=20recovery=20event=20rather=20= than=20a=20set=20amount=20of=20idle=20time.=0A+=0A+You=20can=20also=20= check=20all=20the=20files=20visited=20by=20your=20Org=20agenda=20for=20= dangling=0A+clocks=20at=20any=20time=20using=20@kbd{M-x=20= org-resolve-clocks}.=0A+=0A+@node=20Effort=20estimates,=20Relative=20= timer,=20Resolving=20idle=20time,=20Dates=20and=20Times=0A=20@section=20= Effort=20estimates=0A=20@cindex=20effort=20estimates=0A=20=0Adiff=20= --git=20a/lisp/org-clock.el=20b/lisp/org-clock.el=0Aindex=20= 97e5552..1f424f1=20100644=0A---=20a/lisp/org-clock.el=0A+++=20= b/lisp/org-clock.el=0A@@=20-228,10=20+228,14=20@@=20to=20add=20an=20= effort=20property.")=0A=20(put=20'org-mode-line-string=20= 'risky-local-variable=20t)=0A=20=0A=20(defvar=20= org-clock-mode-line-timer=20nil)=0A+(defvar=20org-clock-idle-timer=20= nil)=0A=20(defvar=20org-clock-heading=20"")=0A=20(defvar=20= org-clock-heading-for-remember=20"")=0A=20(defvar=20org-clock-start-time=20= "")=0A=20=0A+(defvar=20org-clock-left-over-time=20nil=0A+=20=20"If=20= non-nil,=20user=20cancelled=20a=20clock;=20this=20is=20when=20leftover=20= time=20started.")=0A+=0A=20(defvar=20org-clock-effort=20""=0A=20=20=20= "Effort=20estimate=20of=20the=20currently=20clocking=20task")=0A=20=0A@@=20= -495,6=20+499,306=20@@=20Use=20alsa's=20aplay=20tool=20if=20available."=0A= =20(defvar=20org-clock-mode-line-entry=20nil=0A=20=20=20"Information=20= for=20the=20modeline=20about=20the=20running=20clock.")=0A=20=0A+(defun=20= org-find-open-clocks=20(file)=0A+=20=20"Search=20through=20the=20given=20= file=20and=20find=20all=20open=20clocks."=0A+=20=20(let=20((buf=20(or=20= (get-file-buffer=20file)=0A+=09=09=20(find-file-noselect=20file)))=0A+=09= clocks)=0A+=20=20=20=20(with-current-buffer=20buf=0A+=20=20=20=20=20=20= (save-excursion=0A+=09(goto-char=20(point-min))=0A+=09(while=20= (re-search-forward=20"CLOCK:=20\\(\\[.*?\\]\\)$"=20nil=20t)=0A+=09=20=20= (push=20(cons=20(copy-marker=20(1-=20(match-end=201))=20t)=0A+=09=09=20=20= =20=20=20=20(org-time-string-to-time=20(match-string=201)))=20clocks))))=0A= +=20=20=20=20clocks))=0A+=0A+(defsubst=20org-is-active-clock=20(clock)=0A= +=20=20"Return=20t=20if=20CLOCK=20is=20the=20currently=20active=20= clock."=0A+=20=20(and=20(org-clock-is-active)=0A+=20=20=20=20=20=20=20(=3D= =20org-clock-marker=20(car=20clock))))=0A+=0A+(defmacro=20= org-with-clock-position=20(clock=20&rest=20forms)=0A+=20=20"Evaluate=20= FORMS=20with=20CLOCK=20as=20the=20current=20active=20clock."=0A+=20=20= `(with-current-buffer=20(marker-buffer=20(car=20,clock))=0A+=20=20=20=20=20= (save-excursion=0A+=20=20=20=20=20=20=20(save-restriction=0A+=09=20= (widen)=0A+=09=20(goto-char=20(car=20,clock))=0A+=09=20= (beginning-of-line)=0A+=09=20,@forms))))=0A+=0A+(put=20= 'org-with-clock-position=20'lisp-indent-function=201)=0A+=0A+(defmacro=20= org-with-clock=20(clock=20&rest=20forms)=0A+=20=20"Evaluate=20FORMS=20= with=20CLOCK=20as=20the=20current=20active=20clock.=0A+This=20macro=20= also=20protects=20the=20current=20active=20clock=20from=20being=20= altered."=0A+=20=20`(org-with-clock-position=20,clock=0A+=20=20=20=20=20= (let=20((org-clock-start-time=20(cdr=20,clock))=0A+=09=20=20=20= (org-clock-total-time)=0A+=09=20=20=20(org-clock-history)=0A+=09=20=20=20= (org-clock-effort)=0A+=09=20=20=20(org-clock-marker=20(car=20,clock))=0A= +=09=20=20=20(org-clock-hd-marker=20(save-excursion=0A+=09=09=09=09=20=20= (outline-back-to-heading=20t)=0A+=09=09=09=09=20=20(point-marker))))=0A+=20= =20=20=20=20=20=20,@forms)))=0A+=0A+(put=20'org-with-clock=20= 'lisp-indent-function=201)=0A+=0A+(defsubst=20org-clock-clock-in=20= (clock=20&optional=20resume)=0A+=20=20"Clock=20in=20to=20the=20clock=20= located=20by=20CLOCK.=0A+If=20necessary,=20clock-out=20of=20the=20= currently=20active=20clock."=0A+=20=20(org-with-clock-position=20clock=0A= +=20=20=20=20(let=20((org-clock-in-resume=20(or=20resume=20= org-clock-in-resume)))=0A+=20=20=20=20=20=20(org-clock-in))))=0A+=0A= +(defsubst=20org-clock-clock-out=20(clock=20&optional=20fail-quietly=20= at-time)=0A+=20=20"Clock=20out=20of=20the=20clock=20located=20by=20= CLOCK."=0A+=20=20(let=20((temp=20(copy-marker=20(car=20clock)=0A+=09=09=09= =20=20=20(marker-insertion-type=20(car=20clock)))))=0A+=20=20=20=20(if=20= (org-is-active-clock=20clock)=0A+=09(org-clock-out=20fail-quietly=20= at-time)=0A+=20=20=20=20=20=20(org-with-clock=20clock=0A+=09= (org-clock-out=20fail-quietly=20at-time)))=0A+=20=20=20=20(setcar=20= clock=20temp)))=0A+=0A+(defsubst=20org-clock-clock-cancel=20(clock)=0A+=20= =20"Cancel=20the=20clock=20located=20by=20CLOCK."=0A+=20=20(let=20((temp=20= (copy-marker=20(car=20clock)=0A+=09=09=09=20=20=20(marker-insertion-type=20= (car=20clock)))))=0A+=20=20=20=20(if=20(org-is-active-clock=20clock)=0A+=09= (org-clock-cancel)=0A+=20=20=20=20=20=20(org-with-clock=20clock=0A+=09= (org-clock-cancel)))=0A+=20=20=20=20(setcar=20clock=20temp)))=0A+=0A= +(defun=20org-clock-resolve-clock=20(clock=20resolve-to=20last-valid=20= &optional=0A+=09=09=09=09=20=20=20=20=20=20close-p=20restart-p=20= fail-quietly)=0A+=20=20"Resolve=20`CLOCK'=20given=20the=20time=20= `RESOLVE-TO',=20and=20the=20present.=0A+`CLOCK'=20is=20a=20cons=20cell=20= of=20the=20form=20(MARKER=20START-TIME).=0A+This=20routine=20can=20do=20= one=20of=20many=20things:=0A+=0A+=20=20if=20`RESOLVE-TO'=20is=20nil=0A+=20= =20=20=20if=20`CLOSE-P'=20is=20non-nil,=20give=20an=20error=0A+=20=20=20=20= if=20this=20clock=20is=20the=20active=20clock,=20cancel=20it=0A+=20=20=20= =20else=20delete=20the=20clock=20line=20(as=20if=20it=20never=20= happened)=0A+=20=20=20=20if=20`RESTART-P'=20is=20non-nil,=20start=20a=20= new=20clock=0A+=0A+=20=20else=20if=20`RESOLVE-TO'=20is=20the=20symbol=20= `now'=0A+=20=20=20=20if=20`RESTART-P'=20is=20non-nil,=20give=20an=20= error=0A+=20=20=20=20if=20`CLOSE-P'=20is=20non-nil,=20clock=20out=20the=20= entry=20and=0A+=20=20=20=20=20=20=20if=20this=20clock=20is=20the=20= active=20clock,=20stop=20it=0A+=20=20=20=20else=20if=20this=20clock=20is=20= the=20active=20clock,=20do=20nothing=0A+=20=20=20=20else=20if=20there=20= is=20no=20active=20clock,=20resume=20this=20clock=0A+=20=20=20=20else=20= ask=20to=20cancel=20the=20active=20clock,=20and=20if=20so,=0A+=20=20=20=20= =20=20=20=20=20resume=20this=20clock=20after=20cancelling=20it=0A+=0A+=20= =20else=20if=20`RESOLVE-TO'=20is=20some=20date=20in=20the=20future=0A+=20= =20=20=20give=20an=20error=20about=20`RESOLVE-TO'=20being=20invalid=0A+=0A= +=20=20else=20if=20`RESOLVE-TO'=20is=20some=20date=20in=20the=20past=0A+=20= =20=20=20if=20`RESTART-P'=20is=20non-nil,=20give=20an=20error=0A+=20=20=20= =20if=20`CLOSE-P'=20is=20non-nil,=20enter=20a=20closing=20time=20and=0A+=20= =20=20=20=20=20=20if=20this=20clock=20is=20the=20active=20clock,=20stop=20= it=0A+=20=20=20=20else=20if=20this=20clock=20is=20the=20active=20clock,=20= enter=20a=0A+=20=20=20=20=20=20=20closing=20time,=20stop=20the=20current=20= clock,=20then=0A+=20=20=20=20=20=20=20start=20a=20new=20clock=20for=20= the=20same=20item=0A+=20=20=20=20else=20just=20enter=20a=20closing=20= time=20for=20this=20clock=0A+=20=20=20=20=20=20=20and=20then=20start=20a=20= new=20clock=20for=20the=20same=20item"=0A+=20=20(cond=0A+=20=20=20((null=20= resolve-to)=0A+=20=20=20=20(org-clock-clock-cancel=20clock)=0A+=20=20=20=20= (if=20restart-p=0A+=09(org-clock-clock-in=20clock)))=0A+=0A+=20=20=20= ((eq=20resolve-to=20'now)=0A+=20=20=20=20(if=20restart-p=0A+=09(error=20= "RESTART-P=20is=20not=20valid=20here"))=0A+=20=20=20=20(if=20close-p=0A+=09= (org-clock-clock-out=20clock=20fail-quietly)=0A+=20=20=20=20=20=20= (unless=20(org-is-active-clock=20clock)=0A+=09(org-clock-clock-in=20= clock=20t))))=0A+=0A+=20=20=20((not=20(time-less-p=20resolve-to=20= (current-time)))=0A+=20=20=20=20(error=20"RESOLVE-TO=20must=20refer=20to=20= a=20time=20in=20the=20past"))=0A+=0A+=20=20=20(t=0A+=20=20=20=20(if=20= restart-p=0A+=09(error=20"RESTART-P=20is=20not=20valid=20here"))=0A+=20=20= =20=20(if=20close-p=0A+=09(progn=0A+=09=20=20(org-clock-clock-out=20= clock=20fail-quietly=20resolve-to)=0A+=09=20=20(setq=20= org-clock-left-over-time=20last-valid))=0A+=20=20=20=20=20=20= (org-clock-clock-out=20clock=20fail-quietly=20resolve-to)=0A+=20=20=20=20= =20=20(org-clock-clock-in=20clock)))))=0A+=0A+(defun=20org-clock-resolve=20= (clock=20&optional=20prompt-fn=20last-valid=20fail-quietly)=0A+=20=20= "Resolve=20an=20open=20org-mode=20clock.=0A+An=20open=20clock=20was=20= found,=20with=20`dangling'=20possibly=20being=20non-nil.=0A+If=20this=20= function=20was=20invoked=20with=20a=20prefix=20argument,=20non-dangling=0A= +open=20clocks=20are=20ignored.=20=20The=20given=20clock=20requires=20= some=20sort=20of=0A+user=20intervention=20to=20resolve=20it,=20either=20= because=20a=20clock=20was=20left=0A+dangling=20or=20due=20to=20an=20idle=20= timeout.=20=20The=20clock=20resolution=20can=0A+either=20be:=0A+=0A+=20=20= (a)=20deleted,=20the=20user=20doesn't=20care=20about=20the=20clock=0A+=20= =20(b)=20restarted=20from=20the=20current=20time=20(if=20no=20other=20= clock=20is=20open)=0A+=20=20(c)=20closed,=20giving=20the=20clock=20X=20= minutes=0A+=20=20(d)=20closed=20and=20then=20restarted=0A+=20=20(e)=20= resumed,=20as=20if=20the=20user=20had=20never=20left=0A+=0A+The=20format=20= of=20clock=20is=20(CONS=20MARKER=20START-TIME),=20where=20MARKER=0A= +identifies=20the=20buffer=20and=20position=20the=20clock=20is=20open=20= at=20(and=0A+thus,=20the=20heading=20it's=20under),=20and=20START-TIME=20= is=20when=20the=20clock=0A+was=20started."=0A+=20=20(assert=20clock)=0A+=20= =20(let*=20((ch=20(progn=0A+=09=20=20=20=20=20=20=20(unless=20= org-clock-resolving-clocks-due-to-idleness=0A+=09=09=20(org-with-clock=20= clock=0A+=09=09=20=20=20(org-clock-goto))=0A+=09=09=20= (with-current-buffer=20(marker-buffer=20(car=20clock))=0A+=09=09=20=20=20= (goto-char=20(car=20clock))=0A+=09=09=20=20=20(if=20= org-clock-into-drawer=0A+=09=09=20=20=20=20=20=20=20(ignore-errors=0A+=09= =09=09=20(outline-flag-region=20(save-excursion=0A+=09=09=09=09=09=09= (outline-back-to-heading=20t)=0A+=09=09=09=09=09=09(search-forward=20= ":LOGBOOK:")=0A+=09=09=09=09=09=09(goto-char=20(match-beginning=200)))=0A= +=09=09=09=09=09=20=20=20=20=20=20(save-excursion=0A+=09=09=09=09=09=09= (outline-back-to-heading=20t)=0A+=09=09=09=09=09=09(search-forward=20= ":LOGBOOK:")=0A+=09=09=09=09=09=09(search-forward=20":END:")=0A+=09=09=09= =09=09=09(goto-char=20(match-end=200)))=0A+=09=09=09=09=09=20=20=20=20=20= =20nil)))))=0A+=09=20=20=20=20=20=20=20(let=20(char-pressed)=0A+=09=09=20= (while=20(null=20char-pressed)=0A+=09=09=20=20=20(setq=20char-pressed=0A= +=09=09=09=20(read-char=20(concat=20(funcall=20prompt-fn=20clock)=0A+=09=09= =09=09=09=20=20=20=20"=20[(kK)eep=20(sS)ubtract=20(C)ancel]?=20")=0A+=09=09= =09=09=20=20=20=20nil=2045)))=0A+=09=09=20char-pressed)))=0A+=09=20= (last-modified=20(unless=20last-valid=0A+=09=09=09=20=20= (with-current-buffer=20(marker-buffer=20(car=20clock))=0A+=09=09=09=20=20= =20=20(nth=205=20(file-attributes=20(buffer-file-name))))))=0A+=09=20= (default=20(floor=20(/=20(time-to-seconds=0A+=09=09=09=20=20=20=20=20= (time-subtract=20(current-time)=0A+=09=09=09=09=09=20=20=20=20(or=20= last-valid=0A+=09=09=09=09=09=09last-modified)))=2060)))=0A+=09=20(keep=20= (and=20(memq=20ch=20'(?k=20?K))=0A+=09=09=20=20=20=20(read-number=20= (format=20"Keep=20how=20many=20minutes=20(since=20%s)?=20"=0A+=09=09=09=09= =09=20(if=20last-valid=0A+=09=09=09=09=09=20=20=20=20=20"idle"=20"org=20= last=20saved"))=0A+=09=09=09=09=20default)))=0A+=09=20(subtractp=20(memq=20= ch=20'(?s=20?S)))=0A+=09=20(barely-started-p=20(<=20(-=20= (time-to-seconds=20(or=20last-valid=20last-modified))=0A+=09=09=09=09=20= (time-to-seconds=20(cdr=20clock)))=2045))=0A+=09=20(start-over=20(and=20= subtractp=20barely-started-p)))=0A+=20=20=20=20(if=20(or=20(null=20ch)=0A= +=09=20=20=20=20(not=20(memq=20ch=20'(?k=20?K=20?s=20?S=20?C))))=0A+=09= (message=20"")=0A+=20=20=20=20=20=20(org-clock-resolve-clock=0A+=20=20=20= =20=20=20=20clock=20(cond=0A+=09=20=20=20=20=20=20((or=20(eq=20ch=20?C)=0A= +=09=09=20=20=20;;=20If=20the=20time=20on=20the=20clock=20was=20less=20= than=20a=20minute=20before=0A+=09=09=20=20=20;;=20the=20user=20went=20= idle,=20and=20they've=20ask=20to=20subtract=20all=20the=0A+=09=09=20=20=20= ;;=20time...=0A+=09=09=20=20=20start-over)=0A+=09=20=20=20=20=20=20=20= nil)=0A+=09=20=20=20=20=20=20(subtractp=0A+=09=20=20=20=20=20=20=20(or=20= last-valid=20last-modified))=0A+=09=20=20=20=20=20=20((=3D=20keep=20= default)=0A+=09=20=20=20=20=20=20=20'now)=0A+=09=20=20=20=20=20=20(t=0A+=09= =20=20=20=20=20=20=20(time-add=20(or=20last-valid=20last-modified)=0A+=09= =09=09=20(seconds-to-time=20(*=2060=20keep)))))=0A+=20=20=20=20=20=20=20= (or=20last-valid=20last-modified)=0A+=20=20=20=20=20=20=20(memq=20ch=20= '(?K=20?S))=0A+=20=20=20=20=20=20=20(and=20start-over=20(not=20(memq=20= ch=20'(?K=20?S))))=0A+=20=20=20=20=20=20=20fail-quietly))))=0A+=0A= +(defvar=20org-clock-resolving-clocks=20nil)=0A+(defvar=20= org-clock-resolving-clocks-due-to-idleness=20nil)=0A+=0A+(defun=20= org-resolve-clocks=20(&optional=20also-non-dangling-p=0A+=09=09=09=09=20=20= =20=20=20prompt-fn=20last-valid)=0A+=20=20"Resolve=20all=20currently=20= open=20org-mode=20clocks.=0A+If=20`also-non-dangling-p'=20is=20non-nil,=20= also=20ask=20to=20resolve=0A+non-dangling=20(i.e.,=20currently=20open=20= and=20valid)=20clocks."=0A+=20=20(interactive=20"P")=0A+=20=20(unless=20= org-clock-resolving-clocks=0A+=20=20=20=20(let=20= ((org-clock-resolving-clocks=20t))=0A+=20=20=20=20=20=20(dolist=20(file=20= org-agenda-files)=0A+=09(let=20((clocks=20(org-find-open-clocks=20= file)))=0A+=09=20=20(dolist=20(clock=20clocks)=0A+=09=20=20=20=20(let=20= ((dangling=20(or=20(not=20(org-clock-is-active))=0A+=09=09=09=09(/=3D=20= (car=20clock)=20org-clock-marker))))=0A+=09=20=20=20=20=20=20(unless=20= (and=20(not=20dangling)=20(not=20also-non-dangling-p))=0A+=09=09= (org-clock-resolve=0A+=09=09=20clock=0A+=09=09=20(or=20prompt-fn=0A+=09=09= =20=20=20=20=20(function=0A+=09=09=20=20=20=20=20=20(lambda=20(clock)=0A= +=09=09=09(format=0A+=09=09=09=20"Dangling=20clock=20from=20%d=20mins=20= ago"=0A+=09=09=09=20(floor=0A+=09=09=09=20=20(/=20(-=20(time-to-seconds=20= (current-time))=0A+=09=09=09=09(time-to-seconds=0A+=09=09=09=09=20= (with-current-buffer=20(marker-buffer=20(car=20clock))=0A+=09=09=09=09=20= =20=20(nth=205=20(file-attributes=20(buffer-file-name))))))=0A+=09=09=09=20= =20=20=20=2060))))))=0A+=09=09=20last-valid)))))))))=0A+=0A+(defcustom=20= org-clock-idle-time=20nil=0A+=20=20"When=20non-nil,=20resolve=20open=20= clocks=20if=20the=20user=20is=20idle=20more=20than=20X=20minutes."=0A+=20= =20:group=20'org-clock=0A+=20=20:type=20'(choice=0A+=09=20=20(const=20= :tag=20"Never"=20nil)=0A+=09=20=20(integer=20:tag=20"After=20N=20= minutes")))=0A+=0A+(defun=20org-emacs-idle-seconds=20()=0A+=20=20"Return=20= the=20current=20Emacs=20idle=20time=20in=20seconds,=20or=20nil=20if=20= not=20idle."=0A+=20=20(let=20((idle-time=20(current-idle-time)))=0A+=20=20= =20=20(if=20idle-time=0A+=09(time-to-seconds=20idle-time)=0A+=20=20=20=20= =20=200)))=0A+=0A+(defun=20org-mac-idle-seconds=20()=0A+=20=20"Return=20= the=20current=20Mac=20idle=20time=20in=20seconds"=0A+=20=20= (string-to-number=20(shell-command-to-string=20"ioreg=20-c=20IOHIDSystem=20= |=20perl=20-ane=20'if=20(/Idle/)=20{$idle=3D(pop=20@F)/1000000000;=20= print=20$idle;=20last}'")))=0A+=0A+(defun=20org-user-idle-seconds=20()=0A= +=20=20"Return=20the=20number=20of=20seconds=20the=20user=20has=20been=20= idle=20for.=0A+This=20routine=20returns=20a=20floating=20point=20= number."=0A+=20=20(if=20(eq=20system-type=20'darwin)=0A+=20=20=20=20=20=20= (let=20((emacs-idle=20(org-emacs-idle-seconds)))=0A+=09;;=20If=20Emacs=20= has=20been=20idle=20for=20longer=20than=20the=20user's=0A+=09;;=20= `org-clock-idle-time'=20value,=20check=20whether=20the=20whole=20system=20= has=0A+=09;;=20really=20been=20idle=20for=20that=20long.=0A+=09(if=20(>=20= emacs-idle=20(*=2060=20org-clock-idle-time))=0A+=09=20=20=20=20(min=20= emacs-idle=20(org-mac-idle-seconds))=0A+=09=20=20emacs-idle))=0A+=20=20=20= =20(org-emacs-idle-seconds)))=0A+=0A+(defun=20org-resolve-clocks-if-idle=20= ()=0A+=20=20"Resolve=20all=20currently=20open=20org-mode=20clocks.=0A= +This=20is=20performed=20after=20`org-clock-idle-time'=20minutes,=20to=20= check=0A+if=20the=20user=20really=20wants=20to=20stay=20clocked=20in=20= after=20being=20idle=20for=0A+so=20long."=0A+=20=20(when=20(and=20= org-clock-idle-time=20(not=20org-clock-resolving-clocks))=0A+=20=20=20=20= (let=20((idle=20(org-user-idle-seconds))=0A+=09=20=20= (org-clock-resolving-clocks-due-to-idleness=20t))=0A+=20=20=20=20=20=20= (if=20(>=20idle=20(*=2060=20org-clock-idle-time))=0A+=09=20=20= (org-resolve-clocks=0A+=09=20=20=20t=0A+=09=20=20=20(function=0A+=09=20=20= =20=20(lambda=20(clock)=0A+=09=20=20=20=20=20=20(format=20"Clocked=20in=20= &=20idle=20for=20%d=20mins"=0A+=09=09=20=20=20=20=20=20(/=20= (org-user-idle-seconds)=2060))))=0A+=09=20=20=20(time-subtract=20= (current-time)=0A+=09=09=09=20=20(seconds-to-time=20= (org-user-idle-seconds))))))))=0A+=0A+(defvar=20org-clock-clocking-in=20= nil)=0A+=0A=20(defun=20org-clock-in=20(&optional=20select)=0A=20=20=20= "Start=20the=20clock=20on=20the=20current=20item.=0A=20If=20necessary,=20= clock-out=20of=20the=20currently=20active=20clock.=0A@@=20-505,8=20= +809,20=20@@=20the=20clocking=20selection,=20associated=20with=20the=20= letter=20`d'."=0A=20=20=20(interactive=20"P")=0A=20=20=20(setq=20= org-clock-notification-was-shown=20nil)=0A=20=20=20(catch=20'abort=0A-=20= =20=20=20(let=20((interrupting=20(marker-buffer=20org-clock-marker))=0A-=09= =20=20ts=20selected-task=20target-pos=20(msg-extra=20""))=0A+=20=20=20=20= (let=20((interrupting=20(and=20(not=20= org-clock-resolving-clocks-due-to-idleness)=0A+=09=09=09=20=20=20=20=20= (marker-buffer=20org-clock-marker)))=0A+=09=20=20ts=20selected-task=20= target-pos=20(msg-extra=20"")=0A+=09=20=20(left-over=20(and=20(not=20= org-clock-resolving-clocks)=0A+=09=09=09=20=20= org-clock-left-over-time)))=0A+=20=20=20=20=20=20(setq=20= org-clock-left-over-time=20nil)=0A+=20=20=20=20=20=20(unless=20= org-clock-clocking-in=0A+=09(let=20((org-clock-clocking-in=20t))=0A+=09=20= =20(org-resolve-clocks)=09=20=20=20=20=20=20;=20first=20check=20if=20any=20= clocks=20are=20dangling=0A+=09=20=20;;=20If=20the=20resolution=20= resulted=20in=20a=20new=20clock=20being=20started,=20then=0A+=09=20=20;;=20= abort=20this=20clock=20in.=0A+=09=20=20(if=20(and=20(not=20interrupting)=0A= +=09=09=20=20=20(marker-buffer=20org-clock-marker))=0A+=09=20=20=20=20=20= =20(throw=20'abort=20nil))))=0A=20=20=20=20=20=20=20(when=20(equal=20= select=20'(4))=0A=20=09(setq=20selected-task=20(org-clock-select-task=20= "Clock-in=20on=20task:=20"))=0A=20=09(if=20selected-task=0A@@=20-604,7=20= +920,15=20@@=20the=20clocking=20selection,=20associated=20with=20the=20= letter=20`d'."=0A=20=09=20=20=20=20=20=20(setq=20org-clock-effort=20= (org-get-effort))=0A=20=09=20=20=20=20=20=20(setq=20org-clock-total-time=20= (org-clock-sum-current-item=0A=20=09=09=09=09=09=20=20= (org-clock-get-sum-start)))=0A-=09=20=20=20=20=20=20(setq=20= org-clock-start-time=20(current-time))=0A+=09=20=20=20=20=20=20(setq=20= org-clock-start-time=0A+=09=09=20=20=20=20(or=20(and=20left-over=0A+=09=09= =09=20=20=20=20=20(y-or-n-p=0A+=09=09=09=20=20=20=20=20=20(format=0A+=09=09= =09=20=20=20=20=20=20=20"You=20stopped=20another=20clock=20%d=20mins=20= ago;=20start=20this=20one=20from=20then?=20"=0A+=09=09=09=20=20=20=20=20=20= =20(/=20(-=20(time-to-seconds=20(current-time))=0A+=09=09=09=09=20=20=20=20= =20(time-to-seconds=20left-over))=2060)))=0A+=09=09=09=20=20=20=20=20= left-over)=0A+=09=09=09(current-time)))=0A=20=09=20=20=20=20=20=20(setq=20= ts=20(org-insert-time-stamp=20org-clock-start-time=0A=20=09=09=09=09=09=20= =20=20=20=20=20'with-hm=20'inactive))))=0A=20=09=20=20=20=20(move-marker=20= org-clock-marker=20(point)=20(buffer-base-buffer))=0A@@=20-616,8=20= +940,16=20@@=20the=20clocking=20selection,=20associated=20with=20the=20= letter=20`d'."=0A=20=09=09(setq=20global-mode-string=0A=20=09=09=20=20=20= =20=20=20(append=20global-mode-string=20'(org-mode-line-string))))=0A=20=09= =20=20=20=20(org-clock-update-mode-line)=0A+=09=20=20=20=20(when=20= org-clock-mode-line-timer=0A+=09=20=20=20=20=20=20(cancel-timer=20= org-clock-mode-line-timer)=0A+=09=20=20=20=20=20=20(setq=20= org-clock-mode-line-timer=20nil))=0A=20=09=20=20=20=20(setq=20= org-clock-mode-line-timer=0A=20=09=09=20=20(run-with-timer=2060=2060=20= 'org-clock-update-mode-line))=0A+=09=20=20=20=20(when=20= org-clock-idle-timer=0A+=09=20=20=20=20=20=20(cancel-timer=20= org-clock-idle-timer)=0A+=09=20=20=20=20=20=20(setq=20= org-clock-idle-timer=20nil))=0A+=09=20=20=20=20(setq=20= org-clock-idle-timer=0A+=09=09=20=20(run-with-timer=2060=2060=20= 'org-resolve-clocks-if-idle))=0A=20=09=20=20=20=20(message=20"Clock=20= starts=20at=20%s=20-=20%s"=20ts=20msg-extra)=0A=20=09=20=20=20=20= (run-hooks=20'org-clock-in-hook)))))))=0A=20=0A@@=20-748,7=20+1080,7=20= @@=20line=20and=20position=20cursor=20in=20that=20line."=0A=20=09=20=20=20= =20(and=20(re-search-forward=20org-property-end-re=20nil=20t)=0A=20=09=09= =20(goto-char=20(match-beginning=200))))))))=0A=20=0A-(defun=20= org-clock-out=20(&optional=20fail-quietly)=0A+(defun=20org-clock-out=20= (&optional=20fail-quietly=20at-time)=0A=20=20=20"Stop=20the=20currently=20= running=20clock.=0A=20If=20there=20is=20no=20running=20clock,=20throw=20= an=20error,=20unless=20FAIL-QUIETLY=20is=20set."=0A=20=20=20= (interactive)=0A@@=20-769,7=20+1101,8=20@@=20If=20there=20is=20no=20= running=20clock,=20throw=20an=20error,=20unless=20FAIL-QUIETLY=20is=20= set."=0A=20=09=20=20(goto-char=20(match-end=200))=0A=20=09=20=20= (delete-region=20(point)=20(point-at-eol))=0A=20=09=20=20(insert=20"--")=0A= -=09=20=20(setq=20te=20(org-insert-time-stamp=20(current-time)=20= 'with-hm=20'inactive))=0A+=09=20=20(setq=20te=20(org-insert-time-stamp=20= (or=20at-time=20(current-time))=0A+=09=09=09=09=09=20=20'with-hm=20= 'inactive))=0A=20=09=20=20(setq=20s=20(-=20(org-float-time=20(apply=20= 'encode-time=20(org-parse-time-string=20te)))=0A=20=09=09=20=20=20=20=20= (org-float-time=20(apply=20'encode-time=20(org-parse-time-string=20= ts))))=0A=20=09=09h=20(floor=20(/=20s=203600))=0A@@=20-791,6=20+1124,9=20= @@=20If=20there=20is=20no=20running=20clock,=20throw=20an=20error,=20= unless=20FAIL-QUIETLY=20is=20set."=0A=20=09=20=20(when=20= org-clock-mode-line-timer=0A=20=09=20=20=20=20(cancel-timer=20= org-clock-mode-line-timer)=0A=20=09=20=20=20=20(setq=20= org-clock-mode-line-timer=20nil))=0A+=09=20=20(when=20= org-clock-idle-timer=0A+=09=20=20=20=20(cancel-timer=20= org-clock-idle-timer)=0A+=09=20=20=20=20(setq=20org-clock-idle-timer=20= nil))=0A=20=09=20=20(setq=20global-mode-string=0A=20=09=09(delq=20= 'org-mode-line-string=20global-mode-string))=0A=20=09=20=20(when=20= org-clock-out-switch-to-state=0Adiff=20--git=20a/lisp/org.el=20= b/lisp/org.el=0Aindex=20d3d886f..d895e2f=20100644=0A---=20a/lisp/org.el=0A= +++=20b/lisp/org.el=0A@@=20-3141,6=20+3141,8=20@@=20If=20TABLE-TYPE=20is=20= non-nil,=20also=20check=20for=20table.el-type=20tables."=0A=20= (declare-function=20org-clock-save-markers-for-cut-and-paste=20= "org-clock"=0A=20=09=09=20=20(beg=20end))=0A=20(declare-function=20= org-clock-update-mode-line=20"org-clock"=20())=0A+(declare-function=20= org-resolve-clocks=20"org-clock"=0A+=09=09=20=20(&optional=20= also-non-dangling-p=20prompt=20last-valid))=0A=20(defvar=20= org-clock-start-time)=0A=20(defvar=20org-clock-marker=20(make-marker)=0A=20= =20=20"Marker=20recording=20the=20last=20clock-in.")=0A@@=20-3158,7=20= +3160,7=20@@=20The=20return=20value=20is=20actually=20the=20clock=20= marker."=0A=20=09=09=20=20org-clock-goto=20org-clock-sum=20= org-clock-display=0A=20=09=09=20=20org-clock-remove-overlays=20= org-clock-report=0A=20=09=09=20=20org-clocktable-shift=20= org-dblock-write:clocktable=0A-=09=09=20=20org-get-clocktable)))=0A+=09=09= =20=20org-get-clocktable=20org-resolve-clocks)))=0A=20=0A=20(defun=20= org-clock-update-time-maybe=20()=0A=20=20=20"If=20this=20is=20a=20CLOCK=20= line,=20update=20it=20and=20return=20t.=0A--=20=0A1.6.5=0A=0A= --Apple-Mail-1-378917840 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-orgmode mailing list Remember: use `Reply All' to send replies to the list. Emacs-orgmode@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-orgmode --Apple-Mail-1-378917840--