Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue with initial-input in org-ql-view--complete-buffers-files (Fix #227) #228

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 83 additions & 61 deletions org-ql-view.el
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,12 @@ When opened, the link searches the buffer it's opened from."
'("file link is in" "files currently searched")
nil t nil nil "file link is in")
("file link is in" nil)
("files currently searched" buffers-files)))
("files currently searched" (cl-typecase buffers-files
(function (funcall buffers-files))
(otherwise buffers-files)))))
(strings-or-file-buffers-p
(thing) (cl-etypecase thing
(functionp t)
(list (cl-every #'strings-or-file-buffers-p thing))
(string thing)
(buffer (or (buffer-file-name thing)
Expand Down Expand Up @@ -1032,39 +1035,48 @@ current buffer. Otherwise BUFFERS-FILES is returned unchanged."
(string (expand-file-name it))
(otherwise it))
list)))
(-->
;; TODO: Test this more exhaustively.
(pcase buffers-files
((pred listp)
(pcase (expand-files buffers-files)
((pred (seq-set-equal-p (mapcar #'expand-file-name (org-agenda-files))))
(let ((contracted-buffers-files
;; TODO: Test this more exhaustively.
(pcase buffers-files
((pred functionp) (pcase buffers-files
('org-agenda-files "org-agenda-files")
(_ buffers-files)))
((pred listp)
(pcase (expand-files buffers-files)
((pred (seq-set-equal-p (mapcar #'expand-file-name (org-agenda-files))))
"org-agenda-files")
((and (guard (file-exists-p org-directory))
(pred (seq-set-equal-p (org-ql-search-directories-files
:directories (list org-directory)))))
"org-directory")
(_ buffers-files)))
((pred (equal (current-buffer)))
"buffer")
((or 'org-agenda-files '(function org-agenda-files))
"org-agenda-files")
((and (guard (file-exists-p org-directory))
(pred (seq-set-equal-p (org-ql-search-directories-files
:directories (list org-directory)))))
"org-directory")
(_ buffers-files)))
((pred (equal (current-buffer)))
"buffer")
((or 'org-agenda-files '(function org-agenda-files))
"org-agenda-files")
((and (pred bufferp) (guard (buffer-file-name buffers-files)))
(buffer-file-name buffers-files))
((pred bufferp)
(buffer-name buffers-files))
(_ buffers-files))
;; All items needs to be strings to pick duplicates when used with the extend conterpart.
;; So making sure the buffers are convered to file names
(if (stringp it)
it
(-map
(lambda (buffer-file)
(if (bufferp buffer-file)
(--if-let (buffer-file-name buffer-file)
it
(buffer-name buffer-file))
buffer-file))
it)))))
((and (pred bufferp) (guard (buffer-file-name buffers-files)))
(buffer-file-name buffers-files))
((pred bufferp)
(buffer-name buffers-files))
(_ buffers-files))))
;; To filter duplicates with the extend counterpart of this function,
;; this needs to be a string or a list of string.
;; Hence, making sure the buffers are convered to file names or buffer names.
;; Using file-names when it's a file-buffer to avoid duplicates resulting from
;; the file-buffer and file name being entered.
(cl-typecase contracted-buffers-files
(function contracted-buffers-files)
(string contracted-buffers-files)
(list (--> contracted-buffers-files
-flatten -non-nil
(--map
(pcase-exhaustive it
((pred stringp) it)
((pred bufferp) (or (buffer-file-name it)
(buffer-name buffer-file))))
it)
-uniq))
(t (error (format "Value %s is not a string, a valid function or a list of buffer/strings" contracted-buffers-files)))))))
ahmed-shariff marked this conversation as resolved.
Show resolved Hide resolved

(defun org-ql-view--complete-buffers-files ()
"Return value for `org-ql-view-buffers-files' using completion.
Expand All @@ -1077,14 +1089,17 @@ representation `org-ql-view-buffers-files' is returned."
(initial-input (pcase contracted-org-ql-view-buffers-files
('nil nil)
('string contracted-org-ql-view-buffers-files)
((pred functionp) contracted-org-ql-view-buffers-files)
((pred listp)
(mapconcat 'identity contracted-org-ql-view-buffers-files
","))
(_ (format "%s" contracted-org-ql-view-buffers-files))))
(completion-read-result (completing-read-multiple
"Buffers/Files: "
(list 'buffer 'org-agenda-files 'org-directory 'all)
nil nil initial-input)))
(completion-read-result (if (functionp contracted-org-ql-view-buffers-files)
contracted-org-ql-view-buffers-files
(completing-read-multiple
"Buffers/Files: "
(list 'buffer 'org-agenda-files 'org-directory 'all)
nil nil initial-input))))
(if (equal completion-read-result initial-input)
org-ql-view-buffers-files
(org-ql-view--expand-buffers-files completion-read-result))))
Expand All @@ -1093,30 +1108,37 @@ representation `org-ql-view-buffers-files' is returned."
"Return BUFFERS-FILES expanded to a list of files or buffers.
The counterpart to `org-ql-view--contract-buffers-files'.
This always returns a list of string values."
(-->
(-map (lambda (buffer-file)
(pcase-exhaustive buffer-file
("all" (--select (equal (buffer-local-value 'major-mode it) 'org-mode)
(buffer-list)))
("org-agenda-files" (org-agenda-files))
("org-directory" (org-ql-search-directories-files))
((or "" "buffer")
(current-buffer))
((pred bufferp) (list buffer-file))
;; A single filename.
((pred stringp) (list buffer-file))
(_ (error (format "Value %s is not a valid buffer/file" buffer-file)))))
(-list buffers-files))
-flatten -non-nil
;; expanding all file-buffers to file names to avoid duplicate entries being formed
(-map (lambda (buffer-file)
(if (bufferp buffer-file)
(--if-let (buffer-file-name buffer-file)
it
(buffer-name buffer-file))
buffer-file))
it)
-uniq))
(let ((expanded-buffers-files
(--> buffers-files
-list -non-nil
(-map (lambda (buffer-file)
(pcase-exhaustive buffer-file
("all" (--select (equal (buffer-local-value 'major-mode it) 'org-mode)
(buffer-list)))
("org-agenda-files" (org-agenda-files))
("org-directory" (org-ql-search-directories-files))
((or "" "buffer")
(current-buffer))
((or (pred bufferp)
;; A single filename.
(pred stringp))
buffer-file)
(_ (error (format "Value %s is not a valid buffer/file" buffer-file)))))
it))))
(--> expanded-buffers-files
-flatten
;; removing `nil' again as some values have been expanded.
-non-nil
;; Expanding all buffers to file names or buffer names to remove duplicate entries.
(--map
(pcase-exhaustive it
((pred bufferp) (or (buffer-file-name it)
(buffer-name it)))
;; Any values at this point should be a buffer or string.
;; Testing for string anyways.
((pred stringp) it))
it)
-uniq)))
ahmed-shariff marked this conversation as resolved.
Show resolved Hide resolved

(defun org-ql-view--complete-super-groups ()
"Return value for `org-ql-view-super-groups' using completion."
Expand Down
47 changes: 36 additions & 11 deletions tests/test-org-ql.el
Original file line number Diff line number Diff line change
Expand Up @@ -2129,14 +2129,25 @@ with keyword arg NOW in PLIST."
(spy-on 'org-agenda-files :and-return-value temp-filenames)
(expect (org-ql-view--contract-buffers-files 'org-agenda-files) :to-equal "org-agenda-files")
(expect (org-ql-view--contract-buffers-files #'org-agenda-files) :to-equal "org-agenda-files"))
(it "arbitarary list of buffers/files"
(let ((value1 '("a.org" "b.org"))
(value2 'a))
(expect (org-ql-view--contract-buffers-files value1) :to-equal value1)
;; If the value does not result to a buffer, file, or string, throws error
(expect (org-ql-view--contract-buffers-files value2) :to-throw))))
(it "returns function"
(let ((quoted-function (lambda nil temp-filenames))
(unquoted-function '(lambda nil temp-filenames)))
(expect (org-ql-view--contract-buffers-files quoted-function) :to-equal quoted-function)
(expect (org-ql-view--contract-buffers-files unquoted-function) :to-equal unquoted-function)))
(it "with a list of strings"
(let ((list-of-strings '("a.org" "b.org")))
(expect (org-ql-view--contract-buffers-files list-of-strings) :to-equal list-of-strings)))
(describe "invalid values"
:var ((list-of-strings-and-functions '("a.org" "b.org" 'org-agenda-files))
(invalid-type 'a)
(invalid-type-list '(a)))
(it "signals error if called with value not a buffer, or string"
(expect (org-ql-view--contract-buffers-files list-of-strings-and-functions) :to-throw)
(expect (org-ql-view--contract-buffers-files invalid-type) :to-throw)
(expect (org-ql-view--contract-buffers-files invalid-type-list) :to-throw))))
(describe "handles duplicate values")
(describe "expanding org-ql-view-buffers-files"
(it "returns all buffers with `org-mode' as the major-mode"
(it "with \"all\" returns all buffers with `org-mode' as the major-mode"
(let ((buffers (list (generate-new-buffer "test.org") (generate-new-buffer "test.other"))))
(with-current-buffer (car buffers)
(org-mode))
Expand All @@ -2150,22 +2161,36 @@ with keyword arg NOW in PLIST."
(generate-new-buffer "test2")))))
(expect (org-ql-view--expand-buffers-files "org-agenda-files") :to-equal org-agenda-files)))
(it "returns values of \"org-directory\""
;; Also indirectly tests `org-ql-view--expand-buffers-files'
;; Also indirectly tests `org-ql-view--expand-buffers-files'.
(let ((org-directory temp-dir))
(expect (org-ql-view--expand-buffers-files "org-directory") :to-equal temp-filenames)))
(it "returns the current buffer"
(with-temp-buffer
ahmed-shariff marked this conversation as resolved.
Show resolved Hide resolved
(expect (org-ql-view--expand-buffers-files "buffer") :to-equal (list (buffer-name (current-buffer))))))
(it "signals error when called with a function"
(expect (org-ql-view--expand-buffers-files '((lambda nil temp-filenames))) :to-throw 'error '("Value (lambda nil temp-filenames) is not a valid buffer/file")))
(it "returns literal value(s)"
(with-temp-buffer
(expect (org-ql-view--expand-buffers-files (current-buffer)) :to-equal (list (buffer-name (current-buffer)))))
(let ((test-buffer (generate-new-buffer "test")))
(expect (org-ql-view--expand-buffers-files test-buffer) :to-equal (list (buffer-name test-buffer))))
(let ((list-of-numbers '(1 2 3))
(literal-string "random string"))
;; If the value does not result to a buffer, file, or string, throws error
;; Signal error if any of the values are not a buffer, function, or string.
(expect (org-ql-view--expand-buffers-files list-of-numbers) :to-throw)
(expect (org-ql-view--expand-buffers-files literal-string) :to-equal (list literal-string)))))
(expect (org-ql-view--expand-buffers-files literal-string) :to-equal (list literal-string))))
(it "contracts to a list without duplicates"
(let* ((list-of-strings '("a.org" "b.org"))
(duplicate-buffer-and-file (list (find-file-noselect (car temp-filenames))
(car temp-filenames)))
(org-agenda-files (list (car temp-filenames)))
(random-buffer (generate-new-buffer "new-buffer"))
(random-buffer-name (buffer-name random-buffer))
(duplicate-buffer-and-name (list random-buffer-name random-buffer))
(buffer-collection (append org-agenda-files (list random-buffer-name))))
(expect (org-ql-view--expand-buffers-files duplicate-buffer-and-file) :to-equal (list (car temp-filenames)))
(expect (org-ql-view--expand-buffers-files duplicate-buffer-and-name) :to-equal (list random-buffer-name))
(expect (org-ql-view--expand-buffers-files (list "org-agenda-files" random-buffer)) :to-equal buffer-collection))))
(describe "testing `org-ql-view--complete-buffers-files'"
(it "returns `org-agenda-files'"
(let ((org-ql-view-buffers-files temp-filenames))
Expand All @@ -2174,7 +2199,7 @@ with keyword arg NOW in PLIST."
(spy-on 'completing-read-multiple :and-return-value "org-agenda-files")
(expect (org-ql-view--complete-buffers-files) :to-equal temp-filenames)
(expect 'org-ql-view--contract-buffers-files :to-have-been-called-with temp-filenames)
;; Also testing if the initial values are set correctly
;; Also testing if the initial values are set correctly.
(expect 'completing-read-multiple :to-have-been-called-with "Buffers/Files: "
(list 'buffer 'org-agenda-files 'org-directory 'all)
nil nil "org-agenda-files")))
Expand Down