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