From: "Christopher M. Miles" <numbchild@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: help-gnu-emacs@gnu.org
Subject: Re: [QUESTION] I have problem on my org-contacts capf function source code
Date: Mon, 15 Nov 2021 17:05:40 +0800 [thread overview]
Message-ID: <PAXPR08MB664092113BD1AFB73CD1C1C5A3989@PAXPR08MB6640.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <jwvh7ce49z5.fsf-monnier+emacs@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 8016 bytes --]
Here is my changed source code:
#+begin_src emacs-lisp
(defun org-contacts-org-complete--annotation-function (candidate)
"Return org-contacts tags of contact candidate."
;; TODO
"Tags: ")
(defun org-contacts-org-complete--doc-function (candidate)
"Return org-contacts content of contact candidate."
(let ((name (plist-get candidate :name))
(file (plist-get candidate :file))
(position (plist-get candidate :position)))
(company-doc-buffer
;; get org-contact headline and property drawer.
(with-current-buffer (find-file-noselect file)
(goto-char position)
(when (derived-mode-p 'org-mode)
;; `org-edit-src-code' is not a real narrowing command.
;; Remove this first conditional if you don't want it.
(cond ((ignore-errors (org-edit-src-code))
(delete-other-windows))
((org-at-block-p)
(org-narrow-to-block))
(t (org-narrow-to-subtree)))
(buffer-substring (point-min) (point-max)))))))
(defun org-contacts-org-complete--location-function (candidate)
"Return org-contacts location of contact candidate."
(let ((name (plist-get candidate :name))
(file (plist-get candidate :file))
(position (plist-get candidate :position)))
(with-current-buffer (find-file-noselect file)
(goto-char position)
(cons (current-buffer) position))))
(defun org-contacts-org-complete-function ()
"Function used in `completion-at-point-functions' in `org-mode' to complete @name."
(when-let* ((bounds (bounds-of-thing-at-point 'symbol))
(begin (car bounds))
(end (cdr bounds))
(symbol (buffer-substring-no-properties begin end))
(@-prefix-p (string-prefix-p "@" symbol))
(prefix (substring-no-properties symbol 1 nil))
)
(list begin
end
;; (all-completions
;; nil
;; (mapcar
;; (lambda (contact) (plist-get contact :name))
;; (org-contacts--all-contacts))
;; 'stringp)
;; FIXME
(completion-table-dynamic
(lambda (input)
(mapcar
(lambda (contact) (plist-get contact :name))
(org-contacts--all-contacts))))
;; :exclusive 'no
;; :annotation-function #'org-contacts-org-complete--annotation-function
;; :company-docsig #'identity ; metadata
;; :company-doc-buffer #'org-contacts-org-complete--doc-function ; doc popup
;; :company-location #'org-contacts-org-complete--location-function
)))
(add-hook 'completion-at-point-functions 'org-contacts-org-complete-function nil 'local)
#+end_src
When I evaluated upper code, and test by typing in "@Chri", I have not seen org-contacts related
complete popup candidates. So I describe it not working. I also try to edebug on the source code.
Have not found error stacktrace. Don't know where is the problem. If you have time, can you try my
code and take a testing debug? Thanks a lot.
Stefan Monnier via Users list for the GNU Emacs text editor <help-gnu-emacs@gnu.org> writes:
>> I try to write a capf function for org-contacts to auto complete
>> contact names after "@". Here is my code, but it still does not
>> work.
>
> Some description of what you mean by "doesn't work" would be helpful.
>
>> #+begin_src emacs-lisp
>> (defun org-contacts-org-complete-function ()
>> "Function used in `completion-at-point-functions' in `org-mode' to complete @name."
>> (when-let* ((@-prefix-p (string-prefix-p "@" (thing-at-point 'symbol)))
>> (symbol (thing-at-point 'symbol))
>> (prefix (substring-no-properties symbol 1 nil))
>> (bounds (bounds-of-thing-at-point 'symbol))
>> (begin (car bounds))
>> (end (cdr bounds)))
>
> You ask thingatpt to compute the same information 3 times. Not only
> it's inefficient, but if for some reason it doesn't return the same info
> all three times your code will be broken. So better start with
> `bounds-of-thing-at-point` and then use `buffer-substring` to extract
> `symbol` from it, and then use that in the `string-prefix-p` test.
Advice taken.
>
>> (list begin
>> end
>> (all-completions
>> prefix
>> (mapcar
>> (lambda (contact) (plist-get contact :name))
>> (org-contacts--all-contacts))
>> 'stringp)
>
> Don't use `prefix` here.
> Provide the a general completion table which can be used with other
> prefixes as well: the CAPF function should only choose which kind of
> completion to perform and which part of the buffer.
>
So, does that mean the "prefix" should be nil?
>> ;; (completion-table-dynamic
>> ;; (lambda (input)
>> ;; (mapcar
>> ;; (lambda (contact) (plist-get contact :name))
>> ;; (org-contacts--all-contacts))))
>
> That would be better, yes.
Don't know whether my code is right.
>
>> :exclusive 'no
>
> Is this *really* necessary? This functionality is fundamentally very
> hard to implement, so it comes with a lot of warts and restrictions.
> Only use it if it's really really indispensable.
I read the ~:exclusive 'no~ docstring of ~completion-at-point-functions~ which means auto pass to next
completion backend if this completion backend failed. I think it should be used here.
>
>> :annotation-function ; tags
>> ;; TODO
>> (lambda (candidate)
>> "Tags: ")
>> :company-docsig #'identity ; metadata
>> :company-doc-buffer ; doc popup
>> (lambda (candidate)
>> (let ((name (plist-get candidate :name))
>> (file (plist-get candidate :file))
>> (position (plist-get candidate :position)))
>> (company-doc-buffer
>> ;; get org-contact headline and property drawer.
>> (with-current-buffer (find-file-noselect file)
>> (goto-char position)
>> (when (derived-mode-p 'org-mode)
>> ;; `org-edit-src-code' is not a real narrowing command.
>> ;; Remove this first conditional if you don't want it.
>> (cond ((ignore-errors (org-edit-src-code))
>> (delete-other-windows))
>> ((org-at-block-p)
>> (org-narrow-to-block))
>> (t (org-narrow-to-subtree)))
>> (buffer-substring (point-min) (point-max)))))))
>> :company-location (lambda (candidate)
>> (let ((name (plist-get candidate :name))
>> (file (plist-get candidate :file))
>> (position (plist-get candidate :position)))
>> (with-current-buffer (find-file-noselect file)
>> (goto-char position)
>> (cons (current-buffer) position)))))))
>
> I recommend you move those functions outside of the CAFP function
> instead, give them a name and refer to them by name here. Will make the
> code easier to read, will help indentation-depth, and can also
> help debugging.
>
I moved those lambda functions to single functions now. Thanks for your suggestions.
--
[ stardiviner ]
I try to make every word tell the meaning that I want to express.
Blog: https://stardiviner.github.io/
IRC(freenode): stardiviner, Matrix: stardiviner
GPG: F09F650D7D674819892591401B5DF1C95AE89AC3
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2021-11-15 9:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-14 9:59 [QUESTION] I have problem on my org-contacts capf function source code Christopher M. Miles
2021-11-14 23:10 ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-11-15 9:05 ` Christopher M. Miles [this message]
2021-11-15 13:50 ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-11-15 15:43 ` Christopher M. Miles
2021-11-15 21:30 ` Stefan Monnier
2021-11-18 6:56 ` [SOLVED] " Christopher M. Miles
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=PAXPR08MB664092113BD1AFB73CD1C1C5A3989@PAXPR08MB6640.eurprd08.prod.outlook.com \
--to=numbchild@gmail.com \
--cc=help-gnu-emacs@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.