org-ql icon indicating copy to clipboard operation
org-ql copied to clipboard

Extend with Create/Update/Delete functionality?

Open nightscape opened this issue 3 years ago • 1 comments

Hi @alphapapa,

tl;dr: Would it be feasible to add Create/Update/Delete functionality so that advanced org-mode functionality could be built on top of a "language-neutral" DSL?

This idea is probably far outside the current scope of this project, but I would love to get your input nonetheless!

I think one of the big issues with org-mode (the file format) adoption on a bigger scale is that it's so tightly bound to Emacs. I love Emacs and I'm trying to use it as much as I can, but I'm not always on a PC, and for cell phones, tablets, smart watches, ... Emacs just isn't an option (yes, there's Emacs on Termux, but it doesn't really provide a great UX). Also, Emacs is only a good option for very tech-affine people, e.g. I could never convince my wife to do our shared project planning in Emacs. Of course there are projects like beorg and orgzly and they're doing a great job at providing a partial interface for .org files, but the problem is that they basically have to reimplement every feature (clocking, back-links, agenda, ...) that exists as an Elisp org-mode extension in their respective language.

If these org-mode functionalities could be expressed in a DSL like an enhanced org-ql then one would have to port the org-ql engine once to another cross-plattform language (e.g. Rust) and every tool out there could immediately start with a high-level abstraction over org-mode and provide all the same functionality. Kind of like the Language Server Protocol idea for editors. An additional benefit (at least from my PoV) would be that extensions could move from a "Move cursor to position x, write string y at cursor, loop" to a more semantic level like "Find all TODO items with an open CLOCK and close them with the current timestamp".

Do you think an approach like this would make sense / be feasible / be correctly located in this project?

nightscape avatar Jul 05 '21 07:07 nightscape

Hi,

These are certainly interesting ideas. It would be handy to be able to run a kind of SQL-like statement to not only select items but update them. I would imagine a kind of Lispy counterpart to the query predicates, something like:

;; Find all items with deadlines more than 2 weeks overdue 
;; and make their deadlines 3 weeks later.
(org-ql-query
  :from (org-agenda-files)
  :where '(and (todo)
               (deadline :to -14))
  :update '(cl-incf (deadline) 21))

Using CL-style generalized variables, enabling macros like incf, setf, push, etc. would be nice. (Learning how to define new setters is something I'd like to do someday, but gv.el doesn't seem easy to understand, so it would take some study.) I would imagine that the org-ql-defpred macro could be extended to allow such getters/setters to be defined together with the query predicate.

For the specific example you gave:

"Find all TODO items with an open CLOCK and close them with the current timestamp".

org-ql's (clocked) predicate doesn't currently find entries with open clocks, but anyway, if you have a query that matches items you want to do something with, you can call whatever code you want as the query ACTION function. For example, this would add the tag Emacs to any entry containing the word "Emacs":

(org-ql-select (org-agenda-files)
  '(regexp "Emacs")
  :action '(org-toggle-tag "Emacs" 'on))

As for supporting other languages in the bigger picture, that does seem out of scope for this project. As well, there already exist various projects to support Org parsing and such in other languages. For example, for Clojure/JS there's https://github.com/200ok-ch/org-parser (which also has an EBNF Org grammar, which could probably be useful to other projects), and there are other projects for Python, Rust, etc.

For Elisp, there are some related projects as well, such as org-dp (obsolete/unmaintained, AFAIK), and org-ml (https://github.com/ndwarshuis/org-ml, an actively maintained project).

org-ml looks very interesting, but I have the impression that it wouldn't be very suitable for integration with org-ql. However, it might be feasible to use org-ql to find certain entries and then pass a list of them to org-ml functions to modify them.

Does any of that help answer your questions?

alphapapa avatar Jul 05 '21 21:07 alphapapa