alphapapa / org-ql

A searching tool for Org-mode, including custom query languages, commands, saved searches and agenda-like views, etc.
GNU General Public License v3.0
1.42k stars 110 forks source link

Support Ivy and/or completing-read #63

Open tumashu opened 4 years ago

tumashu commented 4 years ago

For example:

  (defun ivy-org-ql-agenda-files ()
    (interactive)
    (let ((files (org-agenda-files)))
      (ivy-read
       "Query: "
       #'(lambda (input)
           (let ((query (org-ql--plain-query input)))
             (when query
               (ignore-errors
                 (org-ql-select files query
                   :action (lambda ()
                             (propertize (org-get-heading t)
                                         'marker (copy-marker (point)))))))))
       :dynamic-collection t
       :action #'ivy-org-ql-agenda-goto)))

  (defun ivy-org-ql-agenda-goto (headline)
    (interactive)
    (let ((marker (get-text-property 0 'marker headline)))
      (when (markerp marker)
        (switch-to-buffer (marker-buffer marker))
        (goto-char marker)
        (org-show-entry))))
alphapapa commented 4 years ago

I think so. I'll see what I can do.

tumashu commented 4 years ago

Thanks very much, this is my new example, maybe useful

(use-package org-ql
  :after org
  :config

  ;; (define-key org-mode-map (kbd "C-c j") 'eh-org-query)
  ;; (define-key org-mode-map (kbd "C-c i") 'eh-org-query-picklink)

  (defun eh-org-query ()
    (interactive)
    (ivy-read "Org query: " #'eh-org-query-collect
              :dynamic-collection t
              :initial-input (eh-org-query-string)
              :action #'eh-org-query-goto))

  (defun eh-org-query-picklink ()
    (interactive)
    (ivy-read "Org query: " #'eh-org-query-collect
              :dynamic-collection t
              :initial-input (eh-org-query-string)
              :action #'eh-org-query-insert-link))

  (defun eh-org-query-string ()
    (when mark-active
      (buffer-substring-no-properties
       (region-beginning) (region-end))))

  (defvar eh-org-query-collect-timer nil)
  (defun eh-org-query-collect (input)
    (when eh-org-query-collect-timer
      (cancel-timer eh-org-query-collect-timer))
    (if (< (length input) 4)
        (list "" (format "%d chars more" (- 4 (length input))))
      (setq eh-org-query-collect-timer
            (run-with-timer
             0.25 nil
             `(lambda ()
                (let ((files (org-agenda-files))
                      (query (org-ql--plain-query  ,input)))
                  (when query
                    (ignore-errors
                      (setq ivy--all-candidates
                            (or
                             (org-ql-select files query
                               :action (lambda ()
                                         (propertize (org-get-heading t)
                                                     'marker (copy-marker (point)))))
                             '("" "Search no results!")))
                      (setq ivy--old-cands ivy--all-candidates)
                      (ivy--exhibit)))))))
      nil))

  (defun eh-org-query-goto (headline)
    (interactive)
    (let ((marker (get-text-property 0 'marker headline)))
      (when (markerp marker)
        (switch-to-buffer (marker-buffer marker))
        (goto-char marker)
        (org-show-entry))))

  (defun eh-org-query-insert-link (headline &optional link-type breadcrumbs)
    (interactive)
    (let ((marker (get-text-property 0 'marker headline))
          store-link)
      (when (markerp marker)
        (org-with-point-at marker
          (let* ((id (org-id-get (point) t))
                 (attach-dir (org-attach-dir t))
                 (breadcrumbs
                  (when breadcrumbs
                    (let ((s (org-format-outline-path
                              (org-get-outline-path)
                              (1- (frame-width))
                              nil org-picklink-breadcrumbs-separator)))
                      (if (eq "" s) "" (concat s org-picklink-breadcrumbs-separator)))))
                 (item (concat (or breadcrumbs "") (org-entry-get (point) "ITEM")))
                 (link
                  (cl-case link-type
                    (attach (list :link attach-dir :description (concat item "(ATTACH)") :type "file"))
                    (t (list :link (concat "id:" id) :description item :type "id")))))
            (setq store-link link)))
        (org-insert-link nil (plist-get store-link :link) (plist-get store-link :description))
        (cond ((org-in-item-p)
               (call-interactively #'org-insert-item))
              (t (insert " ")))))))
alphapapa commented 4 years ago

Thanks. For now I'm waiting on that upstream issue to be addressed.

alphapapa commented 4 years ago

@tumashu If you're interested in working on that upstream issue, it might help it get fixed more quickly. I don't know if the Ivy maintainers are interested in it. I'd prefer to have it fixed before adding this to org-ql. :)

tumashu commented 4 years ago

@alphapapa Today I try to fix ivy's problem, but i have found that it is a hard job,

COLLECTION is either a list of strings, a function, an alist, or
a hash table, supplied for ‘minibuffer-completion-table’.

when I read doc, I think it may be not a bug :-) is is our misuse

alphapapa commented 4 years ago

Oleh pushed a fix for the bug, so I'll see about adding Ivy support. It probably won't be for a while, as I have other priorities now. Thanks.

GTrunSec commented 4 years ago

+1 on this. the helm has been archived. also, the ivy search frame that can be easily searched in CJK input.

alphapapa commented 4 years ago

Helm's principal author has archived his copy of the Helm repo. Helm, the software, is just as usable today as it was the day before he archived his repo. It's not going anywhere.

alphapapa commented 3 years ago

Rather than adding support for Ivy specifically, it might be better to make a command using the completing-read API that could work with various completion frontends.