mirror of
https://github.com/org-roam/org-roam
synced 2025-08-09 12:57:22 -05:00
Revert from emacsql-sqlite3 to emacsql-sqlite for foreign key support. This makes it slightly harder to get Org-roam up and running for Windows, but not impossible, but foreign keys makes database operations faster and keeps the code clean. Also, fix schemata for foreign keys on various tables, and add indices where joins are common (org-roam-db--table-indices).
134 lines
5.2 KiB
EmacsLisp
134 lines
5.2 KiB
EmacsLisp
;;; org-roam-completion.el --- Completion features -*- coding: utf-8; lexical-binding: t; -*-
|
|
|
|
;; Copyright © 2020 Jethro Kuan <jethrokuan95@gmail.com>
|
|
|
|
;; Author: Jethro Kuan <jethrokuan95@gmail.com>
|
|
;; URL: https://github.com/org-roam/org-roam
|
|
;; Keywords: org-mode, roam, convenience
|
|
;; Version: 2.0.0
|
|
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (org "9.4") (emacsql "3.0.0") (emacsql-sqlite "1.0.0") (magit-section "2.90.1"))
|
|
;; This file is NOT part of GNU Emacs.
|
|
|
|
;; This program is free software; you can redistribute it and/or modify
|
|
;; it under the terms of the GNU General Public License as published by
|
|
;; the Free Software Foundation; either version 3, or (at your option)
|
|
;; any later version.
|
|
;;
|
|
;; This program is distributed in the hope that it will be useful,
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;; GNU General Public License for more details.
|
|
;;
|
|
;; You should have received a copy of the GNU General Public License
|
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
;; Boston, MA 02110-1301, USA.
|
|
|
|
;;; Commentary:
|
|
;;
|
|
;; This library provides completion-at-point functions for Org-roam.
|
|
;;
|
|
;; The two main functions provided to capf are:
|
|
;;
|
|
;; `org-roam-complete-link-at-point' provides completions to nodes
|
|
;; within link brackets
|
|
;;
|
|
;; `org-roam-complete-everywhere' provides completions for nodes everywhere,
|
|
;; matching the symbol at point
|
|
;;
|
|
;;; Code:
|
|
(require 'cl-lib)
|
|
(require 'org-element)
|
|
|
|
(declare-function org-roam--get-titles "org-roam")
|
|
|
|
(defcustom org-roam-completion-ignore-case t
|
|
"Whether to ignore case in Org-roam `completion-at-point' completions."
|
|
:group 'org-roam
|
|
:type 'boolean)
|
|
|
|
(defcustom org-roam-completion-everywhere nil
|
|
"When non-nil, provide link completion matching outside of Org links."
|
|
:group 'org-roam
|
|
:type 'boolean)
|
|
|
|
(defvar org-roam-completion-functions (list #'org-roam-complete-link-at-point
|
|
#'org-roam-complete-everywhere)
|
|
"List of functions to be used with `completion-at-point' for Org-roam.")
|
|
|
|
(defun org-roam-complete-everywhere ()
|
|
"Provides completions for links for any word at point.
|
|
This is a `completion-at-point' function, and is active when
|
|
`org-roam-completion-everywhere' is non-nil."
|
|
(let ((end (point))
|
|
(start (point))
|
|
(exit-fn (lambda (&rest _) nil))
|
|
collection)
|
|
(when (and org-roam-completion-everywhere
|
|
(thing-at-point 'word)
|
|
(not (save-match-data (org-in-regexp org-link-any-re))))
|
|
(let ((bounds (bounds-of-thing-at-point 'word)))
|
|
(setq start (car bounds)
|
|
end (cdr bounds)
|
|
collection #'org-roam--get-titles
|
|
exit-fn (lambda (str _status)
|
|
(delete-char (- (length str)))
|
|
(insert "[[roam:" str "]]")))))
|
|
(when collection
|
|
(let ((prefix (buffer-substring-no-properties start end)))
|
|
(list start end
|
|
(if (functionp collection)
|
|
(completion-table-case-fold
|
|
(completion-table-dynamic
|
|
(lambda (_)
|
|
(cl-remove-if (apply-partially #'string= prefix)
|
|
(funcall collection))))
|
|
(not org-roam-completion-ignore-case))
|
|
collection)
|
|
:exit-function exit-fn)))))
|
|
|
|
(defun org-roam-complete-link-at-point ()
|
|
"Do appropriate completion for the link at point."
|
|
(let ((end (point))
|
|
(start (point))
|
|
collection link-type)
|
|
(when (org-in-regexp org-link-bracket-re 1)
|
|
(setq start (match-beginning 1)
|
|
end (match-end 1))
|
|
(let ((context (org-element-context)))
|
|
(pcase (org-element-lineage context '(link) t)
|
|
(`nil nil)
|
|
(link
|
|
(setq link-type (org-element-property :type link))
|
|
(when (member link-type '("roam" "fuzzy"))
|
|
(when (string= link-type "roam") (setq start (+ start (length "roam:"))))
|
|
(setq collection #'org-roam--get-titles))))))
|
|
(when collection
|
|
(let ((prefix (buffer-substring-no-properties start end)))
|
|
(list start end
|
|
(if (functionp collection)
|
|
(completion-table-case-fold
|
|
(completion-table-dynamic
|
|
(lambda (_)
|
|
(cl-remove-if (apply-partially #'string= prefix)
|
|
(funcall collection))))
|
|
(not org-roam-completion-ignore-case))
|
|
collection)
|
|
:exit-function
|
|
(lambda (str &rest _)
|
|
(delete-char (- 0 (length str)))
|
|
(insert (concat (unless (string= link-type "roam") "roam:")
|
|
str))
|
|
(forward-char 2)))))))
|
|
|
|
(defun org-roam--register-completion-functions ()
|
|
"."
|
|
(dolist (fn org-roam-completion-functions)
|
|
(add-hook 'completion-at-point-functions fn nil t)))
|
|
|
|
(add-hook 'org-roam-find-file-hook #'org-roam--register-completion-functions)
|
|
|
|
(provide 'org-roam-completion)
|
|
|
|
;;; org-roam-completion.el ends here
|