Merge branch 'maint'
[org-mode/org-tableheadings.git] / contrib / lisp / org-eldoc.el
blob046918d9efd710636879efe6ab54de54d35a6a2d
1 ;;; org-eldoc.el --- display org header and src block info using eldoc
3 ;; Copyright (c) 2014-2016 Free Software Foundation, Inc.
5 ;; Author: Łukasz Gruner <lukasz@gruner.lu>
6 ;; Maintainer: Łukasz Gruner <lukasz@gruner.lu>
7 ;; Version: 6
8 ;; Package-Requires: ((org "8"))
9 ;; URL: https://bitbucket.org/ukaszg/org-eldoc
10 ;; Created: 25/05/2014
11 ;; Keywords: eldoc, outline, breadcrumb, org, babel, minibuffer
13 ;; This file is not part of Emacs.
15 ;; GNU Emacs is free software: you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation, either version 3 of the License, or
18 ;; (at your option) any later version.
20 ;; GNU Emacs is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ;; GNU General Public License for more details.
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
28 ;;; Commentary:
30 ;;; Changelog:
32 ;; As of 01/11/14 switching license to GPL3 to allow submission to org-mode.
33 ;; 08/11/14 switch code to automatically define eldoc-documentation-function, but don't autostart eldoc-mode.
35 ;;; Code:
37 (require 'org)
38 (require 'ob-core)
39 (require 'eldoc)
41 (declare-function org-element-at-point "org-element" ())
42 (declare-function org-element-property "org-element" (property element))
43 (declare-function org-element-type "org-element" (element))
45 (defgroup org-eldoc nil "" :group 'org)
47 (defcustom org-eldoc-breadcrumb-separator "/"
48 "Breadcrumb separator."
49 :group 'org-eldoc
50 :type 'string)
52 (defcustom org-eldoc-test-buffer-name " *Org-eldoc test buffer*"
53 "Name of the buffer used while testing for mode-local variable values."
54 :group 'org-eldoc
55 :type 'string)
57 (defun org-eldoc-get-breadcrumb ()
58 "Return breadcrumb if on a headline or nil."
59 (let ((case-fold-search t) cur)
60 (save-excursion
61 (beginning-of-line)
62 (save-match-data
63 (when (looking-at org-complex-heading-regexp)
64 (setq cur (match-string 4))
65 (org-format-outline-path
66 (append (org-get-outline-path) (list cur))
67 (frame-width) "" org-eldoc-breadcrumb-separator))))))
69 (defun org-eldoc-get-src-header ()
70 "Returns lang and list of header properties if on src definition line and nil otherwise."
71 (let ((case-fold-search t) info lang hdr-args)
72 (save-excursion
73 (beginning-of-line)
74 (save-match-data
75 (when (looking-at "^[ \t]*#\\+\\(begin\\|end\\)_src")
76 (setq info (org-babel-get-src-block-info 'light)
77 lang (propertize (or (nth 0 info) "no lang") 'face 'font-lock-string-face)
78 hdr-args (nth 2 info))
79 (concat
80 lang
81 ": "
82 (mapconcat
83 (lambda (elem)
84 (when (and (cdr elem) (not (string= "" (cdr elem))))
85 (concat
86 (propertize (symbol-name (car elem)) 'face 'org-list-dt)
87 " "
88 (propertize (cdr elem) 'face 'org-verbatim)
89 " ")))
90 hdr-args " ")))))))
92 (defun org-eldoc-get-src-lang ()
93 "Return value of lang for the current block if in block body and nil otherwise."
94 (let ((element (save-match-data (org-element-at-point))))
95 (and (eq (org-element-type element) 'src-block)
96 (>= (line-beginning-position)
97 (org-element-property :post-affiliated element))
98 (<=
99 (line-end-position)
100 (org-with-wide-buffer
101 (goto-char (org-element-property :end element))
102 (skip-chars-backward " \t\n")
103 (line-end-position)))
104 (org-element-property :language element))))
106 (defvar org-eldoc-local-functions-cache (make-hash-table :size 40 :test 'equal)
107 "Cache of major-mode's eldoc-documentation-functions,
108 used by \\[org-eldoc-get-mode-local-documentation-function].")
110 (defun org-eldoc-get-mode-local-documentation-function (lang)
111 "Check if LANG-mode sets eldoc-documentation-function and return its value."
112 (let ((cached-func (gethash lang org-eldoc-local-functions-cache 'empty))
113 (mode-func (intern-soft (format "%s-mode" lang)))
114 doc-func)
115 (if (eq 'empty cached-func)
116 (when (fboundp mode-func)
117 (with-temp-buffer
118 (funcall mode-func)
119 (setq doc-func (and eldoc-documentation-function
120 (symbol-value 'eldoc-documentation-function)))
121 (puthash lang doc-func org-eldoc-local-functions-cache))
122 doc-func)
123 cached-func)))
125 (declare-function c-eldoc-print-current-symbol-info "c-eldoc" ())
126 (declare-function css-eldoc-function "css-eldoc" ())
127 (declare-function php-eldoc-function "php-eldoc" ())
128 (declare-function go-eldoc--documentation-function "go-eldoc" ())
130 (defun org-eldoc-documentation-function ()
131 "Return breadcrumbs when on a headline, args for src block header-line,
132 calls other documentation functions depending on lang when inside src body."
134 (org-eldoc-get-breadcrumb)
135 (org-eldoc-get-src-header)
136 (let ((lang (org-eldoc-get-src-lang)))
137 (cond ((or
138 (string= lang "emacs-lisp")
139 (string= lang "elisp")) (if (fboundp 'elisp-eldoc-documentation-function)
140 (elisp-eldoc-documentation-function)
141 (let (eldoc-documentation-function)
142 (eldoc-print-current-symbol-info))))
143 ((or
144 (string= lang "c") ;; http://github.com/nflath/c-eldoc
145 (string= lang "C")) (when (require 'c-eldoc nil t)
146 (c-eldoc-print-current-symbol-info)))
147 ;; https://github.com/zenozeng/css-eldoc
148 ((string= lang "css") (when (require 'css-eldoc nil t)
149 (css-eldoc-function)))
150 ;; https://github.com/zenozeng/php-eldoc
151 ((string= lang "php") (when (require 'php-eldoc nil t)
152 (php-eldoc-function)))
153 ((or
154 (string= lang "go")
155 (string= lang "golang")) (when (require 'go-eldoc nil t)
156 (go-eldoc--documentation-function)))
157 (t (let ((doc-fun (org-eldoc-get-mode-local-documentation-function lang)))
158 (when (functionp doc-fun) (funcall doc-fun))))))))
160 ;;;###autoload
161 (defun org-eldoc-load ()
162 "Set up org-eldoc documentation function."
163 (interactive)
164 (setq-local eldoc-documentation-function #'org-eldoc-documentation-function))
166 ;;;###autoload
167 (add-hook 'org-mode-hook #'org-eldoc-load)
169 (provide 'org-eldoc)
171 ;; -*- coding: utf-8-emacs; -*-
173 ;;; org-eldoc.el ends here