Re: Using lexical-binding

2021-03-21 Thread Greg Minshall
Kyle,

> Hmm, given that the lexical-binding change to ob-core was back in Org
> 9.0 (November 2016), it seems like dynamic scoping wasn't really being
> relied on (or, if it was, downstream code has already been adjusted).
> In my view it'd be better to stick with lexical scoping for these
> variables, with callers explicitly passing the subset of needed
> variables to the underlying function(s).

yes, that makes sense.  thanks.

cheers, Greg



Re: Using lexical-binding

2021-03-21 Thread Kyle Meyer
Greg Minshall writes:

> Kyle,
>
> thanks.  i see.  i wondered why the talk was all about agendas.
>
> since, in my (brand new, experimenting) use of
> =org-babel-map-src-blocks=, i'm calling a function, and that function is
> trying to de-reference, e.g., =beg-block=, i get an error.

Thanks for the details.

> it is (or does seem to be) the case that if the macro included all the
> valueless =defvars=, a function called from it has access to all those.
> i don't know if this would be a useful modification.

Hmm, given that the lexical-binding change to ob-core was back in Org
9.0 (November 2016), it seems like dynamic scoping wasn't really being
relied on (or, if it was, downstream code has already been adjusted).
In my view it'd be better to stick with lexical scoping for these
variables, with callers explicitly passing the subset of needed
variables to the underlying function(s).



Re: Using lexical-binding

2021-03-19 Thread Greg Minshall
Kyle,

thanks.  i see.  i wondered why the talk was all about agendas.

since, in my (brand new, experimenting) use of
=org-babel-map-src-blocks=, i'm calling a function, and that function is
trying to de-reference, e.g., =beg-block=, i get an error.

it is (or does seem to be) the case that if the macro included all the
valueless =defvars=, a function called from it has access to all those.
i don't know if this would be a useful modification.

cheers, Greg



Re: Using lexical-binding

2021-03-19 Thread Kyle Meyer
Greg Minshall writes:

> hi.  i just upgraded to
> : Org mode version 9.4.4 (9.4.4-27-gb712b9-elpa @ 
> /home/minshall/.emacs.d/elpa/org-20210315/)
>
> and, have also just started playing with
> (org-babel-map-inline-src-blocks), the documentation for which says
> 
> During evaluation of BODY the following local variables
> are set relative to the currently matched code block.
> ...
> 

Is there a specific error/misbehavior that you're seeing?

The patch in this thread switched only one file, lisp/org-agenda.el,
over to lexical binding.  org-babel-map-inline-src-blocks is in ob-core,
and that file has used lexical binding since 6cefae163 (ob-core: Use
lexical binding, 2016-06-20).

> but, iiuc, that relies on dynamic binding.  so, as =lexical-binding= is
> =t=, i don't have access to those appealing variables.

org-babel-map-inline-src-blocks is a macro, and these variables are
defined in its expansion.  Try:

  (pp-macroexpand-expression
   '(org-babel-map-src-blocks nil
  (message "%d %s %s" beg-block lang body)))



Re: Using lexical-binding

2021-03-19 Thread Greg Minshall
> but, iiuc, that relies on dynamic binding.  so, as =lexical-binding= is
> =t=, i don't have access to those appealing variables.

from reading the elisp manual, it seems that one could define those
variables to be "special variables", and, iiuc, one can achieve this by
using a =defvar= without a value, previous to the =let= where values are
assigned.  something like (for just full-block):

diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index af2c9912e..a0528bb06 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -1121,6 +1121,7 @@ end-body - point at the end of the body"
 (while (re-search-forward org-babel-src-block-regexp nil t)
   (when (org-babel-active-location-p)
 (goto-char (match-beginning 0))
+(defvar full-block)
 (let ((full-block (match-string 0))
   (beg-block (match-beginning 0))
   (end-block (match-end 0))

i could do a patch in this style, for all these variables.

cheers, Greg



Re: Using lexical-binding

2021-03-19 Thread Greg Minshall
hi.  i just upgraded to
: Org mode version 9.4.4 (9.4.4-27-gb712b9-elpa @ 
/home/minshall/.emacs.d/elpa/org-20210315/)

and, have also just started playing with
(org-babel-map-inline-src-blocks), the documentation for which says

During evaluation of BODY the following local variables
are set relative to the currently matched code block.
...

but, iiuc, that relies on dynamic binding.  so, as =lexical-binding= is
=t=, i don't have access to those appealing variables.

am i missing something?  or, is this a place where the "API" is no
longer compatible?  should those variables somehow be passed as a
parameter (alist?) to =,@body=?  or, (let ((lexical-binding nil)) ...)?
(if that would work.)

cheers, Greg



Re: Using lexical-binding

2021-03-10 Thread Stefan Monnier
Thanks.

So now, I'm just waiting for that code to make its way to Emacs's
`master` branch (which I guess first means to make its way to an Org
release, so I had better find something else to do in the mean time).


Stefan




Re: Using lexical-binding

2021-03-09 Thread Kyle Meyer
Stefan Monnier writes:

> Any chance you could put this in the `Package-Requires:`?

Sure, added (5263eff5a).

> Note that all the uses I introduced of `with-suppressed-warnings` only
> wrap a very small amount of code, so you could also replace them with
> `with-no-warnings` (added back in Emacs-22).

Good point.  I've switched to using with-suppressed-warnings and applied
the patch to master (129c33ddd).

Thanks again.



Re: Using lexical-binding

2021-03-09 Thread Stefan Monnier
Hi Kyle,

>> Subject: [PATCH] * lisp/org-agenda.el: Use lexical-binding
> [...]
>> +(pcase type
>> +  ('agenda
>> +   (org-agenda-list current-prefix-arg))
>
> Unfortunately Org's minimum Emacs version is still Emacs 24.3.

Sorry 'bout that.  I keep forgetting about this detail of `pcase` past.
Any chance you could put this in the `Package-Requires:`?

>> +  (let* ((gprops (nth 1 series))
>> + (gvars (mapcar #'car gprops))
>> + (gvals (mapcar (lambda (binding) (eval (cadr binding) t)) gprops)))
>> +(cl-progv gvars gvals (org-agenda-prepare name))
>> +;; We need to reset agenda markers here, because when constructing a
>> +;; block agenda, the individual blocks do not do that.
>> +(org-agenda-reset-markers)
>> +(with-suppressed-warnings ((lexical match))
>
> ... I believe with-suppressed-warnings isn't available until Emacs 27.1,
> right?

Ooh, right, and that is not just a little detail, I very much know
about that.  I don't have any excuse for this one (it's just
a careless copy).

> Any objections to me squashing the below changes into your patch?

Of course not.

> +(if (fboundp 'with-suppressed-warnings)  ; Introduced in Emacs 27.1.
> +(defalias 'org-with-suppressed-warnings 'with-suppressed-warnings)
> +  (defmacro org-with-suppressed-warnings (_warnings  body)
> +(declare (debug (sexp  body)) (indent 1))
> +`(progn ,@body)))

Note that all the uses I introduced of `with-suppressed-warnings` only
wrap a very small amount of code, so you could also replace them with
`with-no-warnings` (added back in Emacs-22).


Stefan




Re: Using lexical-binding

2021-03-08 Thread Kyle Meyer
Looking at this one more time before applying, I noticed a couple of
backward compatibility issues.

Stefan Monnier writes:

> Subject: [PATCH] * lisp/org-agenda.el: Use lexical-binding
[...]
> + (pcase type
> +   ('agenda
> +(org-agenda-list current-prefix-arg))

Unfortunately Org's minimum Emacs version is still Emacs 24.3.  I'd like
to drop Emacs 24 support soon, but that hasn't been discussed or
announced.

And...

> +  (let* ((gprops (nth 1 series))
> + (gvars (mapcar #'car gprops))
> + (gvals (mapcar (lambda (binding) (eval (cadr binding) t)) gprops)))
> +(cl-progv gvars gvals (org-agenda-prepare name))
> +;; We need to reset agenda markers here, because when constructing a
> +;; block agenda, the individual blocks do not do that.
> +(org-agenda-reset-markers)
> +(with-suppressed-warnings ((lexical match))

... I believe with-suppressed-warnings isn't available until Emacs 27.1,
right?

Any objections to me squashing the below changes into your patch?

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 001ca4b1b..d08cab061 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -2938,30 +2938,30 @@ (defun org-agenda ( arg keys restriction)
  (mapcar #'car lprops)
  (mapcar (lambda (binding) (eval (cadr binding) t)) lprops)
(pcase type
- ('agenda
+ (`agenda
   (org-agenda-list current-prefix-arg))
- ('agenda*
+ (`agenda*
   (org-agenda-list current-prefix-arg nil nil t))
- ('alltodo
+ (`alltodo
   (org-todo-list current-prefix-arg))
- ('search
+ (`search
   (org-search-view current-prefix-arg org-match nil))
- ('stuck
+ (`stuck
   (org-agenda-list-stuck-projects current-prefix-arg))
- ('tags
+ (`tags
   (org-tags-view current-prefix-arg org-match))
- ('tags-todo
+ (`tags-todo
   (org-tags-view '(4) org-match))
- ('todo
+ (`todo
   (org-todo-list org-match))
- ('tags-tree
+ (`tags-tree
   (org-check-for-org-mode)
   (org-match-sparse-tree current-prefix-arg org-match))
- ('todo-tree
+ (`todo-tree
   (org-check-for-org-mode)
   (org-occur (concat "^" org-outline-regexp "[ \t]*"
  (regexp-quote org-match) "\\>")))
- ('occur-tree
+ (`occur-tree
   (org-check-for-org-mode)
   (org-occur org-match))
  ((pred functionp)
@@ -3263,7 +3263,7 @@ (defun org-agenda-run-series (name series)
 ;; We need to reset agenda markers here, because when constructing a
 ;; block agenda, the individual blocks do not do that.
 (org-agenda-reset-markers)
-(with-suppressed-warnings ((lexical match))
+(org-with-suppressed-warnings ((lexical match))
   (defvar match))  ;Used via the `eval' below.
 (let* ((org-agenda-multi t)
   ;; FIXME: Redo should contain lists of (FUNS . ARGS) rather
@@ -3285,21 +3285,21 @@ (defun org-agenda-run-series (name series)
   (lvals (mapcar (lambda (binding) (eval (cadr binding) t)) 
lprops)))
   (cl-progv (append gvars lvars) (append gvals lvals)
(pcase type
- ('agenda
+ (`agenda
   (call-interactively 'org-agenda-list))
- ('agenda*
+ (`agenda*
   (funcall 'org-agenda-list nil nil t))
- ('alltodo
+ (`alltodo
   (call-interactively 'org-todo-list))
- ('search
+ (`search
   (org-search-view current-prefix-arg match nil))
- ('stuck
+ (`stuck
   (call-interactively 'org-agenda-list-stuck-projects))
- ('tags
+ (`tags
   (org-tags-view current-prefix-arg match))
- ('tags-todo
+ (`tags-todo
   (org-tags-view '(4) match))
- ('todo
+ (`todo
   (org-todo-list match))
  ((pred fboundp)
   (funcall type match))
@@ -5363,7 +5363,7 @@ (defun org-diary ( args)
 The function expects the lisp variables `entry' and `date' to be provided
 by the caller, because this is how the calendar works.  Don't use this
 function from a program - use `org-agenda-get-day-entries' instead."
-  (with-suppressed-warnings ((lexical date entry)) (defvar date) (defvar 
entry))
+  (org-with-suppressed-warnings ((lexical date entry)) (defvar date) (defvar 
entry))
   (when (> (- (float-time)
  

Re: Using lexical-binding

2021-03-06 Thread Stefan Monnier
>> Should I send a rebased patch for inclusion
> Yes, please.

Here it is,


Stefan
>From ba61c9660fc09321f9dfe5f746705f5d1202c474 Mon Sep 17 00:00:00 2001
From: Stefan Monnier 
Date: Tue, 23 Feb 2021 15:47:29 -0500
Subject: [PATCH] * lisp/org-agenda.el: Use lexical-binding
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Removed the global (defvar date) and (defvar entry) so as not to
  conflict with function arguments of that name.  Instead I added such
  `defvar`s in the body of each of the functions where it
  seemed needed.
- I added some FIXMEs for some issues I found along the way.
- Added an `org-dlet` macro, just like I had done for `calendar-dlet`,
  but I also use `defvar` "manually" at some places, when splitting an
  existing `let` into a mix of `let`s and `dlet`s seemed too much trouble.
- Removed uses of `org-let and `org-let2` not only because I consider
  them offensive to my sense of aesthetics but also because they're
  basically incompatible with lexical scoping.
  I replaced them with uses of `cl-progv` which are a bit more verbose.
  Maybe we should define some `org-progv` macro on top of `cl-progv` to
  make the code less verbose, but I didn't do that because I like the
  fact that the current code makes uses of `eval` a bit more obvious
  (since these behave differently with lexical scoping than with
  lexical binding, it seemed worthwhile).
- Removed the use of `eval` in `org-store-agenda-views` which was only
  placed there in order to use a macro before it's defined (it would
  have been simpler/cleaner to just move that functions *after* the
  macro, but with the new code the problem doesn't occur any more anyway).
- Replaced a few `(lambda...) with actual closures.

Detailed changes follow:

(date, entry): Don't declare as being globally dynbound.
(org-agenda-format-date-aligned): Remove unused var `weekyear`.
(org-agenda-mode): `run-mode-hooks` is always available nowadays.
(org-agenda-undo): Remove unused var `last-undo-buffer`.
(org-agenda): Rename arg to `keys` and then dyn-bind it as `org-keys`.
Remove unused vars `buf` and `key`.
(org-agenda): Use `pcase` and `cl-progv` instead of `org-let`.
(org-let, org-let2): Mark as obsolete.
(org-agenda-run-series): Use `cl-progv` instead of `org-let` and `org-let2`.
(org-agenda-run-series): New function.
(org--batch-agenda): New function extracted from `org-batch-agenda`.
(org-batch-agenda): Use it.
(org--batch-agenda-csv): New function extracted from `org-batch-agenda-csv`.
(org-batch-agenda-csv): Use it.
(org--batch-store-agenda-views): New function, extracted from
`org-batch-store-agenda-views`.
(org-store-agenda-views, org-batch-store-agenda-views): Use it.
(org--batch-store-agenda-views): Use `cl-progv` instead of
`org-eval-in-environment`.
(org-agenda-write): Use `cl-progv` instead of `org-let`.
Use `with-current-buffer`.
(org-agenda-filter-any): Use `cl-some` instead of `eval`.
(org-agenda-list): Remove unused var `e`.
(org-search-view): η-reduce.
(crm-separator): Declare var.
(org-agenda-skip-if): Remove unused var `beg`.
(org-agenda-list-stuck-projects): Use a closure rather than `(lambda..).
(diary-modify-entry-list-string-function, diary-file-name-prefix)
(diary-display-function): Declare vars.
(org-diary): Declare `date` and `entry` as dynbound.
(org-agenda-get-day-entries): Use `org-dlet`.
(org-agenda-get-timestamps, org-agenda-get-progress)
(org-agenda-get-deadlines, org-agenda-get-scheduled, org-agenda-get-blocks):
Declare `date` as dynbound.
(org-agenda-get-sexps, org-class): Declare `date` and `entry` as dynbound.
(org-agenda-format-item): Declare the vars mentioned in
`org-compile-prefix-format` as dyn-bound.
Also binding `extra`, suggested by Kyle Meyer .
(org-compile-prefix-format): Remove unused var `e`.
Use `member` rather than or+equal.
(org-set-sorting-strategy): Minor simplification.
(org-entries-lessp): Use `org-dlet`.
(org-agenda-redo): Declare var `org-agenda-tag-filter-while-redo`.
(org-agenda-redo): Use `cl-progv` rather than `org-let`.
(org-agenda-filter): Remove unused var `rpl-fn`.
Use `org-pushnew-to-end` to replace `add-to-list` on lexical var.
(org-agenda-filter-by-tag): Remove unused var `n`.
(org-agenda-filter-apply): Use `org-dlet`.
(org-agenda-compute-starting-span): Remove unused var `dg`.
(org-agenda-forward-block): Remove unused var `pos`.
(org-archive-from-agenda): Declare var.
(org-agenda-refile): Remove unused var `pos`.
(org-agenda-headline-snapshot-before-repeat): Declare var.
(org-agenda-todo): Remove redundant use of `bound-and-true-p`.
(org-agenda-add-note): Remove unused var `hdmarker` and unused `arg`.
(org-agenda-change-all-lines): Remove unused var `pl`.
(org-agenda-priority): Remove unused var `marker`.
(org-agenda-set-effort): Remove unused var `newhead`.
(org-agenda-schedule): Remove unused var `type`.
(org-agenda-clock-cancel): Remove unused `arg`.
(org-agenda-execute-calendar-command): Use `org-dlet`.

Re: Using lexical-binding

2021-03-06 Thread Kyle Meyer
Stefan Monnier writes:

> Should I send a rebased patch for inclusion

Yes, please.

> or do you want to give more time for people to try it out?

My guess is that we won't hear much more without bringing the changes
into master, and I'm in favor of doing so given that Marco and I have
both used it for a good amount of time without finding issues.  (Thanks,
Marco, for trying it out.)

Thank you.



Re: Using lexical-binding

2021-03-06 Thread Stefan Monnier
Should I send a rebased patch for inclusion or do you want to give more
time for people to try it out?


Stefan




Re: Using lexical-binding

2021-03-04 Thread Marco Wahl
> Kyle Meyer writes:
>> Stefan Monnier writes:
>>
>>> Since I'm not using it, I can't really test the result in any meaningful
>>> way.  Furthermore, just like `calendar.el`, it relies on dynamic scoping
>>> and `eval` in all kinds of ways, so it's very difficult to be sure the
>>> result is "sufficiently similar" to the old behavior not to break some
>>> funky use somewhere out there.
>>
>> I probably don't use many fancy agenda features, but I do work regularly
>> from it.  Running with these changes throughout today, I didn't notice
>> any issues.  Within the next few days, I'll try to test some non-default
>> settings and more obscure features that I don't use as part of my normal
>> workflow, and see if I can find any problems.
>
> I've continued to run with these changes and still haven't noticed any
> problems.  I've also tested various features (sticky agendas, block
> agendas, option setting from custom commands) and didn't spot anything.
>
>> I'll also push the current changes to scratch/sm/agenda-lexical with the
>> hope that others will test and report back.
>
> Has anyone else tried this out?

I'm using that branch for several days now without any problem.  LGTM!

I did nothing special for the test though.  At least I use column mode,
Org habits and interaction with calendar.


Thanks!
-- 
Marco



Re: Using lexical-binding

2021-03-03 Thread Kyle Meyer
Kyle Meyer writes:

> Stefan Monnier writes:
>
>> Since I'm not using it, I can't really test the result in any meaningful
>> way.  Furthermore, just like `calendar.el`, it relies on dynamic scoping
>> and `eval` in all kinds of ways, so it's very difficult to be sure the
>> result is "sufficiently similar" to the old behavior not to break some
>> funky use somewhere out there.
>
> I probably don't use many fancy agenda features, but I do work regularly
> from it.  Running with these changes throughout today, I didn't notice
> any issues.  Within the next few days, I'll try to test some non-default
> settings and more obscure features that I don't use as part of my normal
> workflow, and see if I can find any problems.

I've continued to run with these changes and still haven't noticed any
problems.  I've also tested various features (sticky agendas, block
agendas, option setting from custom commands) and didn't spot anything.

> I'll also push the current changes to scratch/sm/agenda-lexical with the
> hope that others will test and report back.

Has anyone else tried this out?



Re: Using lexical-binding

2021-02-24 Thread Kyle Meyer
Stefan Monnier writes:

>> It looks like add-to-diary-list became an obsolete alias for
>> diary-add-to-list in Emacs 23.1 and was removed in Emacs 25.1,
>> specifically 3f65970414 (Remove calendar code obsolete since at least
>> version 23.1, 2014-10-05).
>
> Ah, thanks for tracking it down, so I guess we can drop this altogether.
> And we can also drop the `condition-case` in `org-diary-default-entry`
> because that change in calling convention is even older than the change
> of name from `add-to-diary-list` to `diary-add-to-list`.

Yes, sounds good.  Done in Org's 0b117f72a.



Re: Using lexical-binding

2021-02-24 Thread Kyle Meyer
Stefan Monnier writes:

> Since I'm not using it, I can't really test the result in any meaningful
> way.  Furthermore, just like `calendar.el`, it relies on dynamic scoping
> and `eval` in all kinds of ways, so it's very difficult to be sure the
> result is "sufficiently similar" to the old behavior not to break some
> funky use somewhere out there.

I probably don't use many fancy agenda features, but I do work regularly
from it.  Running with these changes throughout today, I didn't notice
any issues.  Within the next few days, I'll try to test some non-default
settings and more obscure features that I don't use as part of my normal
workflow, and see if I can find any problems.

I'll also push the current changes to scratch/sm/agenda-lexical with the
hope that others will test and report back.



Re: Using lexical-binding

2021-02-23 Thread Stefan Monnier
> With a quick test of a few main commands, burps in one of four.

Excellent, and thanks for the subsequent patch (I don't think I'd have
come up with the move of `extra` on my own).

>> - I believe I have quashed all the compiler warnings (some had nothing
>>   to do with lexical scoping),
>
> Hmm, I wonder why I'm not seeing the ones unrelated to the lexical
> scoping change.

I don't think there were many of them.  As for why there were some:

1- the change away from `org-let` and friends causes some code to become
   visible to the compiler (it was hidden behind the "eval wall" until
   then).

2- I have some extra warnings in my local Emacs.

>>   except for a reference to the function `add-to-diary-list` which I
>>   can't find anywhere (is it some old function that has disappeared,
>>   maybe?).
>
> It looks like add-to-diary-list became an obsolete alias for
> diary-add-to-list in Emacs 23.1 and was removed in Emacs 25.1,
> specifically 3f65970414 (Remove calendar code obsolete since at least
> version 23.1, 2014-10-05).

Ah, thanks for tracking it down, so I guess we can drop this altogether.
And we can also drop the `condition-case` in `org-diary-default-entry`
because that change in calling convention is even older than the change
of name from `add-to-diary-list` to `diary-add-to-list`.


Stefan




Re: Using lexical-binding

2021-02-23 Thread Samuel Wales
just a thanks to maintainers of emacs and org including those of you
fixing this and those who wrote the tests.  i had no idea org wasn't
fully lexical yet.  i look forward to whatever good that brings.


On 2/23/21, Kyle Meyer  wrote:
> Kyle Meyer writes:
>
>> Stefan Monnier writes:
> [...]
>>   ;; (org-agenda-list); fails: void-variable date
>>
>> There are also some `make test' failures:
>>
>>   7 unexpected results:
>>  FAILED  test-org-agenda/diary-inclusion
>>  FAILED  test-org-agenda/empty
>>  FAILED  test-org-agenda/one-line
>>  FAILED  test-org-agenda/scheduled-non-todo
>>  FAILED  test-org-agenda/set-priority
>>  FAILED  test-org-agenda/sticky-agenda-name
>>  FAILED  test-org-agenda/sticky-agenda-name-after-reload
>>
>>> or "pretends everything is fine but doesn't do the right thing any
>>> more", or (even better) actual feedback about the code itself and the
>>> approach(es) I chose to use.
>>
>> While I'm not sure I can provide any useful feedback about approaches,
>> I'll see if I can tweak your patch to resolve the org-agenda-list
>> failure or any of the above test failures.
>
> With the changes below on top of your patch, the simple org-agenda-list
> call from above works and the test failures are gone.
>
> diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
> index 16ec70c77..81409d6ac 100644
> --- a/lisp/org-agenda.el
> +++ b/lisp/org-agenda.el
> @@ -5448,27 +5448,29 @@ (defun org-agenda-get-day-entries (file date 
> args)
> (setf args (cons :deadline* (delq :deadline* args)
>   ;; Collect list of headlines.  Return them flattened.
>   (let ((case-fold-search nil) results deadlines)
> -   (dolist (arg args (apply #'nconc (nreverse results)))
> - (pcase arg
> -   ((and :todo (guard (org-agenda-today-p date)))
> -(push (org-agenda-get-todos) results))
> -   (:timestamp
> -(push (org-agenda-get-blocks) results)
> -(push (org-agenda-get-timestamps deadlines) results))
> -   (:sexp
> -(push (org-agenda-get-sexps) results))
> -   (:scheduled
> -(push (org-agenda-get-scheduled deadlines) results))
> -   (:scheduled*
> -(push (org-agenda-get-scheduled deadlines t) results))
> -   (:closed
> -(push (org-agenda-get-progress) results))
> -   (:deadline
> -(setf deadlines (org-agenda-get-deadlines))
> -(push deadlines results))
> -   (:deadline*
> -(setf deadlines (org-agenda-get-deadlines t))
> -(push deadlines results)))
> +  (org-dlet
> +  ((date date))
> + (dolist (arg args (apply #'nconc (nreverse results)))
> +   (pcase arg
> + ((and :todo (guard (org-agenda-today-p date)))
> +  (push (org-agenda-get-todos) results))
> + (:timestamp
> +  (push (org-agenda-get-blocks) results)
> +  (push (org-agenda-get-timestamps deadlines) results))
> + (:sexp
> +  (push (org-agenda-get-sexps) results))
> + (:scheduled
> +  (push (org-agenda-get-scheduled deadlines) results))
> + (:scheduled*
> +  (push (org-agenda-get-scheduled deadlines t) results))
> + (:closed
> +  (push (org-agenda-get-progress) results))
> + (:deadline
> +  (setf deadlines (org-agenda-get-deadlines))
> +  (push deadlines results))
> + (:deadline*
> +  (setf deadlines (org-agenda-get-deadlines t))
> +  (push deadlines results
>
>  (defsubst org-em (x y list)
>"Is X or Y a member of LIST?"
> @@ -6710,6 +6712,7 @@ (defun org-agenda-format-item (extra txt 
> level category tags dotime
> (get-text-property 1 'effort txt)))
>(tag (if tags (nth (1- (length tags)) tags) ""))
>(time-grid-trailing-characters (nth 2 org-agenda-time-grid))
> +  (extra (or (and (not habitp) extra) ""))
>time
>(ts (when dotime (concat
>  (if (stringp dotime) dotime "")
> @@ -6793,7 +6796,6 @@ (defun org-agenda-format-item (extra txt 
> level category tags dotime
>(concat time-grid-trailing-characters "
> ")
>  time-grid-trailing-characters)))
>(t ""))
> -   extra (or (and (not habitp) extra) "")
> category (if (symbolp category) (symbol-name category) category)
> level (or level ""))
>   (if (string-match org-link-bracket-re category)
>
>


-- 
The Kafka Pandemic

Please learn what misopathy is.

Re: Using lexical-binding

2021-02-23 Thread Kyle Meyer
Kyle Meyer writes:

> Stefan Monnier writes:
[...]
>   ;; (org-agenda-list); fails: void-variable date
>
> There are also some `make test' failures:
>
>   7 unexpected results:
>  FAILED  test-org-agenda/diary-inclusion
>  FAILED  test-org-agenda/empty
>  FAILED  test-org-agenda/one-line
>  FAILED  test-org-agenda/scheduled-non-todo
>  FAILED  test-org-agenda/set-priority
>  FAILED  test-org-agenda/sticky-agenda-name
>  FAILED  test-org-agenda/sticky-agenda-name-after-reload
>
>> or "pretends everything is fine but doesn't do the right thing any
>> more", or (even better) actual feedback about the code itself and the
>> approach(es) I chose to use.
>
> While I'm not sure I can provide any useful feedback about approaches,
> I'll see if I can tweak your patch to resolve the org-agenda-list
> failure or any of the above test failures.

With the changes below on top of your patch, the simple org-agenda-list
call from above works and the test failures are gone.

diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index 16ec70c77..81409d6ac 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -5448,27 +5448,29 @@ (defun org-agenda-get-day-entries (file date  args)
  (setf args (cons :deadline* (delq :deadline* args)
;; Collect list of headlines.  Return them flattened.
(let ((case-fold-search nil) results deadlines)
- (dolist (arg args (apply #'nconc (nreverse results)))
-   (pcase arg
- ((and :todo (guard (org-agenda-today-p date)))
-  (push (org-agenda-get-todos) results))
- (:timestamp
-  (push (org-agenda-get-blocks) results)
-  (push (org-agenda-get-timestamps deadlines) results))
- (:sexp
-  (push (org-agenda-get-sexps) results))
- (:scheduled
-  (push (org-agenda-get-scheduled deadlines) results))
- (:scheduled*
-  (push (org-agenda-get-scheduled deadlines t) results))
- (:closed
-  (push (org-agenda-get-progress) results))
- (:deadline
-  (setf deadlines (org-agenda-get-deadlines))
-  (push deadlines results))
- (:deadline*
-  (setf deadlines (org-agenda-get-deadlines t))
-  (push deadlines results)))
+  (org-dlet
+  ((date date))
+   (dolist (arg args (apply #'nconc (nreverse results)))
+ (pcase arg
+   ((and :todo (guard (org-agenda-today-p date)))
+(push (org-agenda-get-todos) results))
+   (:timestamp
+(push (org-agenda-get-blocks) results)
+(push (org-agenda-get-timestamps deadlines) results))
+   (:sexp
+(push (org-agenda-get-sexps) results))
+   (:scheduled
+(push (org-agenda-get-scheduled deadlines) results))
+   (:scheduled*
+(push (org-agenda-get-scheduled deadlines t) results))
+   (:closed
+(push (org-agenda-get-progress) results))
+   (:deadline
+(setf deadlines (org-agenda-get-deadlines))
+(push deadlines results))
+   (:deadline*
+(setf deadlines (org-agenda-get-deadlines t))
+(push deadlines results
 
 (defsubst org-em (x y list)
   "Is X or Y a member of LIST?"
@@ -6710,6 +6712,7 @@ (defun org-agenda-format-item (extra txt  level 
category tags dotime
  (get-text-property 1 'effort txt)))
 (tag (if tags (nth (1- (length tags)) tags) ""))
 (time-grid-trailing-characters (nth 2 org-agenda-time-grid))
+(extra (or (and (not habitp) extra) ""))
 time
 (ts (when dotime (concat
   (if (stringp dotime) dotime "")
@@ -6793,7 +6796,6 @@ (defun org-agenda-format-item (extra txt  level 
category tags dotime
   (concat time-grid-trailing-characters " ")
 time-grid-trailing-characters)))
 (t ""))
- extra (or (and (not habitp) extra) "")
  category (if (symbolp category) (symbol-name category) category)
  level (or level ""))
(if (string-match org-link-bracket-re category)



Re: Using lexical-binding

2021-02-23 Thread Kyle Meyer
Stefan Monnier writes:

> As part of the on-going work to use lexical-binding in all the files
> bundled with Emacs, I took a stab at converting org-agenda.el to
> lexical-binding.

Thank you.

> [...]
> Anyway, here's my first cut (the patch is made against the head of
> Org's `master` rather than Emacs's `master`, since I suspect that could
> make things easier for you).  The commit message is basically empty
> because it's not intended to be installed yet.  I'm instead hoping for
> some feedback, such as "tried it, works" or "burps all over the place",

With a quick test of a few main commands, burps in one of four.
Contents /tmp/scratch.org:

--8<---cut here---start->8---
* TODO a  :t:
SCHEDULED: <2021-02-23 Tue>
foo
* DONE b
* TODO c
DEADLINE: <2021-02-23 Tue>
--8<---cut here---end--->8---

Running with emacs 27.1 and -Q:

  (require 'org-agenda)
  (setq org-agenda-files '("/tmp/scratch.org"))
  (global-set-key (kbd "C-c a") #'org-agenda)

  ;; Commands:

  ;; (org-todo-list)  ; works
  ;; (org-search-view nil "foo")  ; works
  ;; (org-tags-view nil "+t") ; works
  ;; (org-agenda-list); fails: void-variable date

There are also some `make test' failures:

  7 unexpected results:
 FAILED  test-org-agenda/diary-inclusion
 FAILED  test-org-agenda/empty
 FAILED  test-org-agenda/one-line
 FAILED  test-org-agenda/scheduled-non-todo
 FAILED  test-org-agenda/set-priority
 FAILED  test-org-agenda/sticky-agenda-name
 FAILED  test-org-agenda/sticky-agenda-name-after-reload

> or "pretends everything is fine but doesn't do the right thing any
> more", or (even better) actual feedback about the code itself and the
> approach(es) I chose to use.

While I'm not sure I can provide any useful feedback about approaches,
I'll see if I can tweak your patch to resolve the org-agenda-list
failure or any of the above test failures.

> - I believe I have quashed all the compiler warnings (some had nothing
>   to do with lexical scoping),

Hmm, I wonder why I'm not seeing the ones unrelated to the lexical
scoping change.  `make compile' and `make single' are quiet for me on
Org's current master (d21d200bc) with Emacs 27.  If I use an Emacs built
from a recent Emacs commit (6172454ff3), I see a couple of "docstring
wider than 80 characters" warnings (will fix), but nothing in
org-agenda.el.

>   except for a reference to the function `add-to-diary-list` which I
>   can't find anywhere (is it some old function that has disappeared,
>   maybe?).

It looks like add-to-diary-list became an obsolete alias for
diary-add-to-list in Emacs 23.1 and was removed in Emacs 25.1,
specifically 3f65970414 (Remove calendar code obsolete since at least
version 23.1, 2014-10-05).



Using lexical-binding

2021-02-23 Thread Stefan Monnier
As part of the on-going work to use lexical-binding in all the files
bundled with Emacs, I took a stab at converting org-agenda.el to
lexical-binding.

Since I'm not using it, I can't really test the result in any meaningful
way.  Furthermore, just like `calendar.el`, it relies on dynamic scoping
and `eval` in all kinds of ways, so it's very difficult to be sure the
result is "sufficiently similar" to the old behavior not to break some
funky use somewhere out there.

Anyway, here's my first cut (the patch is made against the head of
Org's `master` rather than Emacs's `master`, since I suspect that could
make things easier for you).  The commit message is basically empty
because it's not intended to be installed yet.  I'm instead hoping for
some feedback, such as "tried it, works" or "burps all over the place",
or "pretends everything is fine but doesn't do the right thing any
more", or (even better) actual feedback about the code itself and the
approach(es) I chose to use.


Stefan


- Removed the global (defvar date) and (defvar entry) so as not to
  conflict with function arguments of that name.  Instead I added such
  `defvar`s in the body of each of the functions where it seemed needed.
- I believe I have quashed all the compiler warnings (some had nothing
  to do with lexical scoping), except for a reference to the function
  `add-to-diary-list` which I can't find anywhere (is it some old
  function that has disappeared, maybe?).
- Added an `org-dlet` macro, just like I had done for `calendar-dlet`,
  but I also use `defvar` "manually" at some places, when splitting an
  existing `let` into a mix of `let`s and `dlet`s seemed too much trouble.
- Removed uses of `org-let and `prg-let2` not only because I consider
  them offensive to my sense of aesthetics but also because they're
  basically incompatible with lexical scoping.
  I replaced them with uses of `cl-progv` which are a bit more verbose.
  Maybe we should define some `org-progv` macro on top of `cl-progv` to
  make the code less verbose, but I didn't do that because I like the
  fact that the current code makes uses of `eval` a bit more obvious
  (since these behave differently with lexical scoping than with
  lexical binding, it seemed worthwhile).
- Removed the use of `eval` in `org-store-agenda-views` which was only
  placed there in order to use a macro before it's defined (it would
  have been simpler/cleaner to just move that functions *after* the
  macro, but with the new code the problem doesn't occur any more
  anyway).
- Replaced a few `(lambda...) with actual closures.

>From d34f993044ee817f7ee18342bcc686285329bea5 Mon Sep 17 00:00:00 2001
From: Stefan Monnier 
Date: Tue, 23 Feb 2021 15:47:29 -0500
Subject: [PATCH] * org-agenda.el: First attempt at using `lexical-binding`

---
 .gitignore |   6 +
 doc/Makefile   |  14 +-
 lisp/org-agenda.el | 827 +
 lisp/org-macs.el   |  41 ++-
 4 files changed, 502 insertions(+), 386 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1a72cc20b0..4bb81c359b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,6 +49,12 @@ local*.mk
 mk/x11idle
 ChangeLog
 
+# Files generated during `make packages/org` in a clone of `elpa.git`.
+
+/org-pkg.el
+/org-autoloads.el
+/lisp/org-autoloads.el
+
 # texi2pdf --tidy
 
 doc/*.t2d
diff --git a/doc/Makefile b/doc/Makefile
index 96fda14454..dc6882927e 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -28,9 +28,9 @@ guide::		orgguide.texi org-version.inc
 endif
 
 org.texi orgguide.texi:	org-manual.org org-guide.org
-	$(BATCH) \
-	  --eval '(add-to-list '"'"'load-path "../lisp")' \
-	  --eval '(load "../mk/org-fixup.el")' \
+	$(BATCH)   \
+	  --eval '(add-to-list `load-path "../lisp")' \
+	  --eval '(load "../mk/org-fixup.el")' 	  \
 	  --eval '(org-make-manuals)'
 
 org-version.inc:	org.texi
@@ -88,8 +88,8 @@ ifneq ($(SERVERMK),)
 endif
 
 %_letter.tex:	%.tex
-	$(BATCH) \
-	  --eval '(add-to-list '"'"'load-path "../lisp")' \
-	  --eval '(load "org-compat.el")' \
-	  --eval '(load "../mk/org-fixup.el")' \
+	$(BATCH)   \
+	  --eval '(add-to-list `load-path "../lisp")' \
+	  --eval '(load "org-compat.el")' 	  \
+	  --eval '(load "../mk/org-fixup.el")' 	  \
 	  --eval '(org-make-letterformat "$(= iso-week 52))
-			  (1- year))
-			 ((and (= month 12) (<= iso-week 1))
-			  (1+ year))
-			 (t year)))
+	 ;; (weekyear (cond ((and (= month 1) (>= iso-week 52))
+	 ;;	  (1- year))
+	 ;;	 ((and (= month 12) (<= iso-week 1))
+	 ;;	  (1+ year))
+	 ;;	 (t year)))
 	 (weekstring (if (= day-of-week 1)
 			 (format " W%02d" iso-week)
 		   "")))
@@ -2269,7 +2271,7 @@ The following commands are available:
 	 (setq-local org-agenda-this-buffer-is-sti