Ihor Radchenko <[email protected]> writes:

> A proper completion should
> replicate how parsing MATCH string works in `org-make-tags-matcher' and
> ideally offer completion for property names, todo keywords, etc.

So I took you up on your challenge and tried to make a nice completion
function.  I failed.

I have spent too many hours on this now.  The completion code is super
confusing.

Problems:
1. What is the name for the syntax described here:
   [[info:org#Matching tags and properties]]
   - In the code there are functions called
     `org-make-tags-matcher', `org-match-sparse-tree', `org-tags-view'
   - It is referred to as a "tags string", a "string with match
     syntax", a "TAGS/TODO matcher", a "tags/property/todo match", a "tags
     search"
   - I'm going to stop searching here but just know there are probably a lot
     more inconsistent references

2. The function in question `org-tags-completion-function' is NOT a completion
   function!  It's a completion table function and should probably be named in
   a way consistent with other completion table functions.  Oh wait, they
   aren't consistent at all... ugh.  I would probably go with
   `org-tags-completion-table'.

3. People don't really seem to care about quoting when doing completion.  What
   we are doing is exactly what `completing-read-multiple' does (with
   a custom `crm-separator') but we want to retain the seperators.  So I
   started copying some code from there except they don't care about quoting!
   `crm--current-element' just does a dumb regex search for the boundary.

4. How do I search for boundaries while ignoring quoted text?  I've read a lot
   of syntax.c and I've come up with a "solution".  Basically I treat the match
   characters as open parenthesis and then ask Emacs to go back an sexp.  There
   has got to be a better way right?

#+begin_src elisp
(let ((table (make-syntax-table))
      (test-string "tag1+PROPERTY=\"+\""))
  ;; The match symbols are open parenthesis
  (mapc
   (lambda (c)
     (modify-syntax-entry c "(" table))
   '(?- ?+ ?: ?& ?, ?|))
  (with-temp-buffer
    (with-syntax-table table
      (insert test-string)
      ;; This returns exactly what I want!
      (scan-lists (point-max) -1 1) ; => 5
      ;; But it doesn't handle unpaired quotes
      (insert "\"")
      (scan-lists (point-max) -1 1) ; => 16
      )))
#+end_src


Reply via email to