Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
On Mon, 24 May 2021 at 13:34, Bhavin Gandhi wrote: Yes, I have attached an updated patch. Looks good to me. Thank you! We are indeed aligned. The only additional thing I discovered was the reason `org-refile--get-location' works despite having double slashes. That was new for me. Great! Thanks for clearing that up too. Best, Gustavo.
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
On Sun, 23 May 2021 at 23:53, Timothy wrote: > > Hi Bhavin! Great to see you on the mailing list :) > > Thank you so much for looking at the bugs, investigating one, /and/ > working out a fix. That's absolutely fantastic of you! Thank you for a welcoming message! :) On Mon, 24 May 2021 at 00:28, Gustavo Barros wrote: > > The patch looks good to me, and corresponds to my analysis of the > problem and suggested fix. I have only one minor nitpick: you could go > with a simple `let' there, instead of a `let*', since we only have one > let-bound variable there anyway. Yes, I have attached an updated patch. > > [...] it has other details as well. > > As far as I could see, we are very much aligned on the problem and fix. > But perhaps I'm missing something, could you elaborate on that? We are indeed aligned. The only additional thing I discovered was the reason `org-refile--get-location' works despite having double slashes. That was new for me. Just experimenting with Woof! X-Woof-Patch: confirmed From e069c35ff6011a7f9efe372e675a0bc43ba1fa80 Mon Sep 17 00:00:00 2001 From: Bhavin Gandhi Date: Sun, 23 May 2021 23:07:13 +0530 Subject: [PATCH] org-refile: Fix double slashes in the refile targets * org-refile.el (org-refile-get-location): When we generate the `tbl' variable, we add extra slash depending on the value of `org-refile-use-outline-path'. This patch updates some locations which add another extra slash assuming the target did not have it. `org-refile--get-location' does lookup for entries with and without slash, so it was not causing any issues before. It works as it is now as well. Thanks to Gustavo Barros for a very detailed bug report. TINYCHANGE --- lisp/org-refile.el | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lisp/org-refile.el b/lisp/org-refile.el index bffad0a81..678759e10 100644 --- a/lisp/org-refile.el +++ b/lisp/org-refile.el @@ -649,20 +649,18 @@ this function appends the default value from (setq old-hist org-refile-history) (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history - (or cdef (concat (car org-refile-history) extra + (or cdef (car org-refile-history (if (setq pa (org-refile--get-location answ tbl)) - (let* ((last-refile-loc (car org-refile-history)) - (last-refile-loc-path (concat last-refile-loc extra))) + (let ((last-refile-loc (car org-refile-history))) (org-refile-check-position pa) (when (or (not org-refile-history) (not (eq old-hist org-refile-history)) - (not (equal (car pa) last-refile-loc-path))) + (not (equal (car pa) last-refile-loc))) (setq org-refile-history (cons (car pa) (if (assoc last-refile-loc tbl) org-refile-history (cdr org-refile-history - (when (or (equal last-refile-loc-path (nth 1 org-refile-history)) - (equal last-refile-loc (nth 1 org-refile-history))) + (when (equal last-refile-loc (nth 1 org-refile-history)) (pop org-refile-history))) pa) (if (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ) -- 2.31.1
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hi Bhavin, On Sun, 23 May 2021 at 15:05, Bhavin Gandhi wrote: Finally after spending a couple of hours, I was able to understand the code of org-refile-get-location \o/. The detailed bug report helped me to understand the issue. I'm attaching a patch here which should fix the problem, it has other details as well. I have tested a few basic scenarios as mentioned in the report. Thank you very much for working on this patch. I couldn't offer it myself (out of my legal bounds) and had gone as far as I was allowed to here, so I'm happy you took it from there. The patch looks good to me, and corresponds to my analysis of the problem and suggested fix. I have only one minor nitpick: you could go with a simple `let' there, instead of a `let*', since we only have one let-bound variable there anyway. About: [...] it has other details as well. As far as I could see, we are very much aligned on the problem and fix. But perhaps I'm missing something, could you elaborate on that? Thanks again. Best, Gustavo.
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hi Bhavin! Great to see you on the mailing list :) Thank you so much for looking at the bugs, investigating one, /and/ working out a fix. That's absolutely fantastic of you! For cumulative contributions under 15 (non-trivial) lines from a contributor (such as yourself) we can accept (i.e. merge without FSF papers) the changes and with a "TINYCHANGE" line at the end of the commit message --- but I see you've noticed this and have a nicely formatted commit message, brilliant! Thanks again, and I hope to see you around, Timothy. p.s. For merging hopefully someone like Nicolas or Bastien will be able to take a look at the commit. It looks good to me though :) Bhavin Gandhi writes: > Finally after spending a couple of hours, I was able to understand the code > of org-refile-get-location \o/. The detailed bug report helped me to > understand the issue. I'm attaching a patch here which should fix the > problem, it has other details as well. I have tested a few basic scenarios > as mentioned in the report. > > OTOH, I haven't signed the FSF Copyright assignment yet, should I do it > before this gets merged or it can be done later?
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Finally after spending a couple of hours, I was able to understand the code of org-refile-get-location \o/. The detailed bug report helped me to understand the issue. I'm attaching a patch here which should fix the problem, it has other details as well. I have tested a few basic scenarios as mentioned in the report. OTOH, I haven't signed the FSF Copyright assignment yet, should I do it before this gets merged or it can be done later? From 234316ed49023362d116d884ba7f2859e5f04c1b Mon Sep 17 00:00:00 2001 From: Bhavin Gandhi Date: Sun, 23 May 2021 23:07:13 +0530 Subject: [PATCH] org-refile: Fix double slashes in the refile targets * org-refile.el (org-refile-get-location): When we generate the `tbl' variable, we add extra slash depending on the value of `org-refile-use-outline-path'. This patch updates some locations which add another extra slash assuming the target did not have it. `org-refile--get-location' does lookup for entries with and without slash, so it was not causing any issues before. It works as it is now as well. Thanks to Gustavo Barros for a very detailed bug report. TINYCHANGE --- lisp/org-refile.el | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lisp/org-refile.el b/lisp/org-refile.el index bffad0a81..c4ac1c108 100644 --- a/lisp/org-refile.el +++ b/lisp/org-refile.el @@ -649,20 +649,18 @@ this function appends the default value from (setq old-hist org-refile-history) (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history - (or cdef (concat (car org-refile-history) extra + (or cdef (car org-refile-history (if (setq pa (org-refile--get-location answ tbl)) - (let* ((last-refile-loc (car org-refile-history)) - (last-refile-loc-path (concat last-refile-loc extra))) + (let* ((last-refile-loc (car org-refile-history))) (org-refile-check-position pa) (when (or (not org-refile-history) (not (eq old-hist org-refile-history)) - (not (equal (car pa) last-refile-loc-path))) + (not (equal (car pa) last-refile-loc))) (setq org-refile-history (cons (car pa) (if (assoc last-refile-loc tbl) org-refile-history (cdr org-refile-history - (when (or (equal last-refile-loc-path (nth 1 org-refile-history)) - (equal last-refile-loc (nth 1 org-refile-history))) + (when (equal last-refile-loc (nth 1 org-refile-history)) (pop org-refile-history))) pa) (if (string-match "\\`\\(.*\\)/\\([^/]+\\)\\'" answ) -- 2.31.1
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hello Bastien I'm new to Org mode codebase as well as Elisp. Is this something I can pick up, I was not sure that's why I thought of asking here on the list. -- Regards, Bhavin Gandhi (bhavin192) | https://geeksocket.in
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hi Gustavo, Gustavo Barros writes: > some time ago, I've reported an issue regarding duplicity of the default > candidate in `org-refile' > (https://orgmode.org/list/87lftw1k2n@gmail.com/). The problem was > that, when using `org-refile-use-outline-path' an "extra" slash was > appended at the end of every path, but candidates were stored in > `org-refile-history' without that extra slash. Bastien took care of > that and indeed changed things so as to pass the elements to > `org-refile-history' with the trailing slash as appropriate. > > At the time, I reported a difference of behavior between > `completing-read-default' and `ivy-completing-read' after the mentioned > commit by Bastien. But the issue did not appear for Bastien, which does > not use Ivy, and I also was not able to diagnose the problem properly. > I felt I didn't have enough to offer as to insist, so I resorted to an > old hack of mine. But the new release this week (thank you very much!, > btw) has bitten me again on this, so I went back to some digging, and > hopefully I can do a better job this time in diagnosing the problem and > suggesting a fix. Bump this thread so that it appears on updates.orgmode.org. Thanks, -- Bastien
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hi All, I'd like to kindly bump this report. It is an issue which has been around for some time. The report provides a clear reproduction recipe, which stardiviner was able to reproduce, and still affects current "org-plus-contrib-20210208". The report also provides a hopefully convincing code analysis of the affected function `org-refile-get-location' and a suggested fix (I just don't send a patch, because I can't provide CA). Best regards, Gustavo. On Mon, 21 Sep 2020 at 15:34, Gustavo Barros wrote: Hi All, some time ago, I've reported an issue regarding duplicity of the default candidate in `org-refile' (https://orgmode.org/list/87lftw1k2n@gmail.com/). The problem was that, when using `org-refile-use-outline-path' an "extra" slash was appended at the end of every path, but candidates were stored in `org-refile-history' without that extra slash. Bastien took care of that and indeed changed things so as to pass the elements to `org-refile-history' with the trailing slash as appropriate. At the time, I reported a difference of behavior between `completing-read-default' and `ivy-completing-read' after the mentioned commit by Bastien. But the issue did not appear for Bastien, which does not use Ivy, and I also was not able to diagnose the problem properly. I felt I didn't have enough to offer as to insist, so I resorted to an old hack of mine. But the new release this week (thank you very much!, btw) has bitten me again on this, so I went back to some digging, and hopefully I can do a better job this time in diagnosing the problem and suggesting a fix. An ECM to reproduce the issue as it currently stands is: - Start 'emacs -Q' - Do an initial setup: #+begin_src emacs-lisp (add-to-list 'load-path "~/.emacs.d/elpa/org-plus-contrib-20200921") (add-to-list 'load-path "~/.emacs.d/elpa/ivy-20200826.955") ;; Those are the latest Org weekly build (Org 9.4) and the current up to date ;; Ivy at Melpa (setq org-refile-targets '(("~/org/test.org" :maxlevel . 2))) (setq org-refile-use-outline-path 'file) (setq org-outline-path-complete-in-steps nil) (require 'ivy) (ivy-mode) ;; Bear with me, the problem is not with Ivy, I'll demonstrate that. #+end_src - Open file "~/org/test.org", with contents: #+begin_src org ,* Top heading 1 ,* Top heading 2 ,** Entry 1 ,** Entry 2 #+end_src - Go to heading "Entry 1", refile it to "Top heading 1" - Go to heading "Entry 2", and call `org-refile' - Observe the available candidates, and notice "test.org/Top heading 1/" is there twice, once as the default candidate, with a *double* trailing slash, and also on the paths list, with a single trailing slash. I've tried to pin down what is going on here and my understanding is that Bastien's fix on that previous thread did indeed correct the problem of the missing trailing slash in `org-refile-history' and this indeed corresponds correctly to the state of the completion "collection" (the let bound `tbl' variable in `org-refile-get-location'), as it should. But there remained a couple of instances in `org-refile-get-location' which added the trailing slash considering `org-refile-history' didn't have them, so that when this is done, we get a double trailing slash. The two instances are: 1) when the completion function is actually called: #+begin_src emacs-lisp (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history (or cdef (concat (car org-refile-history) extra #+end_src 2) And three lines bellow, on the let binding: #+begin_src emacs-lisp (let* ((last-refile-loc (car org-refile-history)) (last-refile-loc-path (concat last-refile-loc extra))) ...) #+end_src In both instances, we are getting the `car' of `org-refile-history' which now already has `extra' (that is, the trailing slash) and adding it again. My suggested fix is to remove these `extra's in duplicity, they are remnants of when `org-refile-history' didn't have them already. That is: #+begin_src emacs-lisp (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history (or cdef (car org-refile-history #+end_src And: #+begin_src emacs-lisp (let* ((last-refile-loc (car org-refile-history)) (last-refile-loc-path last-refile-loc)) ...) #+end_src Of course, the second opens some opportunity to simplify the code that follows considering `last-refile-loc-path' and `last-refile-loc' are now identical. Why I think this is the problem and the correct way to fix it: 1) If you add inspection points at the appropriate locations for the sexps =(concat (car org-refile-history) extra)= and =(concat last-refile-loc extra)= you will find the double trailing slash there, and it shouldn't be there. 2) The visual manifestation of this double trailing slash in the default candidate
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hi stardiviner, On Wed, 23 Sep 2020 at 11:17, stardiviner wrote: I have same issue when using Ivy. But can't reproduce this by disabled ivy-mode. And only happened when I refiled once, then the target will has two slash like this: #+begin_example Tasks/kk// (file.org) Tasks/hello/ (file.org) #+end_example Thank you for checking this and for confirming you also observe this behavior with Ivy. Regarding when ivy-mode is off, as I argued in the original report, the problem is indeed *not visible* when using `completing-read-default', the double trailing slash is nevertheless there if you inspect the value being passed as default value to the completing-read-function. The tests included with ivy-mode turned off were meant to emphasize things are expected to work with the suggested fix also in this case, in other words, that this is not "just a fix for ivy-mode", which is not the problem here. Best, Gustavo.
Re: Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
I have same issue when using Ivy. But can't reproduce this by disabled ivy-mode. And only happened when I refiled once, then the target will has two slash like this: #+begin_example Tasks/kk// (file.org) Tasks/hello/ (file.org) #+end_example Gustavo Barros writes: > Hi All, > > some time ago, I've reported an issue regarding duplicity of the default > candidate in `org-refile' > (https://orgmode.org/list/87lftw1k2n@gmail.com/). The problem was > that, when using `org-refile-use-outline-path' an "extra" slash was > appended at the end of every path, but candidates were stored in > `org-refile-history' without that extra slash. Bastien took care of > that and indeed changed things so as to pass the elements to > `org-refile-history' with the trailing slash as appropriate. > > At the time, I reported a difference of behavior between > `completing-read-default' and `ivy-completing-read' after the mentioned > commit by Bastien. But the issue did not appear for Bastien, which does > not use Ivy, and I also was not able to diagnose the problem properly. > I felt I didn't have enough to offer as to insist, so I resorted to an > old hack of mine. But the new release this week (thank you very much!, > btw) has bitten me again on this, so I went back to some digging, and > hopefully I can do a better job this time in diagnosing the problem and > suggesting a fix. > > > An ECM to reproduce the issue as it currently stands is: > > - Start 'emacs -Q' > > - Do an initial setup: > #+begin_src emacs-lisp > (add-to-list 'load-path "~/.emacs.d/elpa/org-plus-contrib-20200921") > (add-to-list 'load-path "~/.emacs.d/elpa/ivy-20200826.955") > ;; Those are the latest Org weekly build (Org 9.4) and the current up > to date > ;; Ivy at Melpa > (setq org-refile-targets '(("~/org/test.org" :maxlevel . 2))) > (setq org-refile-use-outline-path 'file) > (setq org-outline-path-complete-in-steps nil) > (require 'ivy) > (ivy-mode) > ;; Bear with me, the problem is not with Ivy, I'll demonstrate that. > #+end_src > > - Open file "~/org/test.org", with contents: > #+begin_src org > ,* Top heading 1 > ,* Top heading 2 > ,** Entry 1 > ,** Entry 2 > #+end_src > > - Go to heading "Entry 1", refile it to "Top heading 1" > > - Go to heading "Entry 2", and call `org-refile' > > - Observe the available candidates, and notice "test.org/Top heading 1/" > is there twice, once as the default candidate, with a *double* > trailing slash, and also on the paths list, with a single trailing > slash. > > > I've tried to pin down what is going on here and my understanding is > that Bastien's fix on that previous thread did indeed correct the > problem of the missing trailing slash in `org-refile-history' and this > indeed corresponds correctly to the state of the completion "collection" > (the let bound `tbl' variable in `org-refile-get-location'), as it > should. But there remained a couple of instances in > `org-refile-get-location' which added the trailing slash considering > `org-refile-history' didn't have them, so that when this is done, we get > a double trailing slash. > > The two instances are: 1) when the completion function is actually > called: > > #+begin_src emacs-lisp > (setq answ (funcall cfunc prompt tbl nil (not new-nodes) > nil 'org-refile-history > (or cdef (concat (car org-refile-history) > extra > #+end_src > > 2) And three lines bellow, on the let binding: > > #+begin_src emacs-lisp > (let* ((last-refile-loc (car org-refile-history)) >(last-refile-loc-path (concat last-refile-loc extra))) > ...) > #+end_src > > In both instances, we are getting the `car' of `org-refile-history' > which now already has `extra' (that is, the trailing slash) and adding > it again. > > My suggested fix is to remove these `extra's in duplicity, they are > remnants of when `org-refile-history' didn't have them already. That > is: > > #+begin_src emacs-lisp > (setq answ (funcall cfunc prompt tbl nil (not new-nodes) > nil 'org-refile-history > (or cdef (car org-refile-history > #+end_src > > And: > > #+begin_src emacs-lisp > (let* ((last-refile-loc (car org-refile-history)) >(last-refile-loc-path last-refile-loc)) > ...) > #+end_src > > Of course, the second opens some opportunity to simplify the code that > follows considering `last-refile-loc-path' and `last-refile-loc' are now > identical. > > > Why I think this is the problem and the correct way to fix it: > > 1) If you add inspection points at the appropriate locations for the > sexps =(concat (car org-refile-history) extra)= and =(concat > last-refile-loc extra)= you will find the double trailing slash there, > and it shouldn't be there. > > 2) The visual manifestation of this double trailing slash in the default > candidate with `ivy-mode' is there
Bug: Double trailing slash for default candidate in org-refile-get-target [9.4 (9.4-7-g3eccc5-elpaplus @ /home/gustavo/.emacs.d/elpa/org-plus-contrib-20200921/)]
Hi All, some time ago, I've reported an issue regarding duplicity of the default candidate in `org-refile' (https://orgmode.org/list/87lftw1k2n@gmail.com/). The problem was that, when using `org-refile-use-outline-path' an "extra" slash was appended at the end of every path, but candidates were stored in `org-refile-history' without that extra slash. Bastien took care of that and indeed changed things so as to pass the elements to `org-refile-history' with the trailing slash as appropriate. At the time, I reported a difference of behavior between `completing-read-default' and `ivy-completing-read' after the mentioned commit by Bastien. But the issue did not appear for Bastien, which does not use Ivy, and I also was not able to diagnose the problem properly. I felt I didn't have enough to offer as to insist, so I resorted to an old hack of mine. But the new release this week (thank you very much!, btw) has bitten me again on this, so I went back to some digging, and hopefully I can do a better job this time in diagnosing the problem and suggesting a fix. An ECM to reproduce the issue as it currently stands is: - Start 'emacs -Q' - Do an initial setup: #+begin_src emacs-lisp (add-to-list 'load-path "~/.emacs.d/elpa/org-plus-contrib-20200921") (add-to-list 'load-path "~/.emacs.d/elpa/ivy-20200826.955") ;; Those are the latest Org weekly build (Org 9.4) and the current up to date ;; Ivy at Melpa (setq org-refile-targets '(("~/org/test.org" :maxlevel . 2))) (setq org-refile-use-outline-path 'file) (setq org-outline-path-complete-in-steps nil) (require 'ivy) (ivy-mode) ;; Bear with me, the problem is not with Ivy, I'll demonstrate that. #+end_src - Open file "~/org/test.org", with contents: #+begin_src org ,* Top heading 1 ,* Top heading 2 ,** Entry 1 ,** Entry 2 #+end_src - Go to heading "Entry 1", refile it to "Top heading 1" - Go to heading "Entry 2", and call `org-refile' - Observe the available candidates, and notice "test.org/Top heading 1/" is there twice, once as the default candidate, with a *double* trailing slash, and also on the paths list, with a single trailing slash. I've tried to pin down what is going on here and my understanding is that Bastien's fix on that previous thread did indeed correct the problem of the missing trailing slash in `org-refile-history' and this indeed corresponds correctly to the state of the completion "collection" (the let bound `tbl' variable in `org-refile-get-location'), as it should. But there remained a couple of instances in `org-refile-get-location' which added the trailing slash considering `org-refile-history' didn't have them, so that when this is done, we get a double trailing slash. The two instances are: 1) when the completion function is actually called: #+begin_src emacs-lisp (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history (or cdef (concat (car org-refile-history) extra #+end_src 2) And three lines bellow, on the let binding: #+begin_src emacs-lisp (let* ((last-refile-loc (car org-refile-history)) (last-refile-loc-path (concat last-refile-loc extra))) ...) #+end_src In both instances, we are getting the `car' of `org-refile-history' which now already has `extra' (that is, the trailing slash) and adding it again. My suggested fix is to remove these `extra's in duplicity, they are remnants of when `org-refile-history' didn't have them already. That is: #+begin_src emacs-lisp (setq answ (funcall cfunc prompt tbl nil (not new-nodes) nil 'org-refile-history (or cdef (car org-refile-history #+end_src And: #+begin_src emacs-lisp (let* ((last-refile-loc (car org-refile-history)) (last-refile-loc-path last-refile-loc)) ...) #+end_src Of course, the second opens some opportunity to simplify the code that follows considering `last-refile-loc-path' and `last-refile-loc' are now identical. Why I think this is the problem and the correct way to fix it: 1) If you add inspection points at the appropriate locations for the sexps =(concat (car org-refile-history) extra)= and =(concat last-refile-loc extra)= you will find the double trailing slash there, and it shouldn't be there. 2) The visual manifestation of this double trailing slash in the default candidate with `ivy-mode' is there therefore independently of `ivy-mode`. Indeed, `ivy-mode' basically sets `completing-read-function' to `ivy-completing-read', which in turn calls its main API function `ivy-read'. `ivy-completing-read' just passes along the `def' argument without manipulating it. As far as I can see, `ivy-read' also does not change it before calling `read-from-minibuffer'. Why `completing-read-default' does not show this second trailing slash of the `def' argument it received is another matter. But it's there... 3) I've tested this