Skip to content

Commit

Permalink
Merge 84d05ca into d02f4da
Browse files Browse the repository at this point in the history
  • Loading branch information
galaunay committed Mar 26, 2020
2 parents d02f4da + 84d05ca commit 9e9902f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 41 deletions.
13 changes: 13 additions & 0 deletions elpy-rpc.el
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,19 @@ Returns a calltip string for the function call at point."
success error)))


(defun elpy-rpc-get-calltip-or-oneline-docstring (&optional success error)
"Call the get_calltip_or_oneline_doc API function.
Returns a calltip string or a oneline docstring for the function call at point."
(when (< (buffer-size) elpy-rpc-ignored-buffer-size)
(elpy-rpc "get_calltip_or_oneline_docstring"
(list buffer-file-name
(elpy-rpc--buffer-contents)
(- (point)
(point-min)))
success error)))


(defun elpy-rpc-get-oneline-docstring (&optional success error)
"Call the get_oneline_docstring API function.
Expand Down
62 changes: 32 additions & 30 deletions elpy.el
Original file line number Diff line number Diff line change
Expand Up @@ -3115,16 +3115,17 @@ display the current class and method instead."
(let ((flymake-error (elpy-flymake-error-at-point)))
(if flymake-error
flymake-error
;; Try getting calltip
(elpy-rpc-get-calltip
(lambda (calltip)
(elpy-rpc-get-calltip-or-oneline-docstring
(lambda (info)
(cond
((stringp calltip)
(eldoc-message calltip))
(calltip
(let ((name (cdr (assq 'name calltip)))
(index (cdr (assq 'index calltip)))
(params (cdr (assq 'params calltip))))
;; INFO is a string, just display it
((stringp info)
(eldoc-message info))
;; INFO is a calltip
((string= (cdr (assq 'kind info)) "calltip")
(let ((name (cdr (assq 'name info)))
(index (cdr (assq 'index info)))
(params (cdr (assq 'params info))))
(when index
(setf (nth index params)
(propertize (nth index params)
Expand All @@ -3137,28 +3138,29 @@ display the current class and method instead."
(if (version<= emacs-version "25")
(format "%s%s" prefix args)
(eldoc-docstring-format-sym-doc prefix args nil))))))
;; INFO is a oneline docstring
((string= (cdr (assq 'kind info)) "oneline_doc")
(let ((name (cdr (assq 'name info)))
(docs (cdr (assq 'doc info))))
(let ((prefix (propertize (format "%s: " name)
'face
'font-lock-function-name-face)))
(eldoc-message
(if (version<= emacs-version "25")
(format "%s%s" prefix docs)
(let ((eldoc-echo-area-use-multiline-p nil))
(eldoc-docstring-format-sym-doc prefix docs nil)))))))
;; INFO is nil, maybe display the current function
(t
;; Try getting oneline docstring
(elpy-rpc-get-oneline-docstring
(lambda (doc)
(cond
(doc
(let ((name (cdr (assq 'name doc)))
(doc (cdr (assq 'doc doc))))
(let ((prefix (propertize (format "%s: " name)
'face
'font-lock-function-name-face)))
(eldoc-message
(if (version<= emacs-version "25")
(format "%s%s" prefix doc)
(let ((eldoc-echo-area-use-multiline-p nil))
(eldoc-docstring-format-sym-doc prefix doc nil)))))))
;; Give the current definition
(elpy-eldoc-show-current-function
(let ((current-defun (python-info-current-defun)))
(when current-defun
(eldoc-message
(format "In: %s()" current-defun))))))))))))
(if elpy-eldoc-show-current-function
(let ((current-defun (python-info-current-defun)))
(when current-defun
(eldoc-message
(concat "In: "
(propertize
(format "%s()" current-defun)
'face 'font-lock-function-name-face)))))
(eldoc-message ""))))))
;; Return the last message until we're done
eldoc-last-message)))

Expand Down
34 changes: 34 additions & 0 deletions elpy/jedibackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,47 @@ def rpc_get_calltip(self, filename, source, offset):
"index": call.index,
"params": params}

def rpc_get_calltip_or_oneline_docstring(self, filename, source, offset):
"""
Return the current function calltip or its oneline docstring.
Meant to be used with eldoc.
"""
# Try to get a oneline docstring then
docs = self.rpc_get_oneline_docstring(filename=filename,
source=source,
offset=offset)
if docs is not None:
if docs['doc'] != "No documentation":
docs['kind'] = 'oneline_doc'
return docs
# Try to get a calltip
calltip = self.rpc_get_calltip(filename=filename, source=source,
offset=offset)
if calltip is not None:
calltip['kind'] = 'calltip'
return calltip
# Ok, no calltip, just display the function name
if docs is not None:
docs['kind'] = 'oneline_doc'
return docs
# Giving up...
return None

def rpc_get_oneline_docstring(self, filename, source, offset):
"""Return a oneline docstring for the symbol at offset"""
line, column = pos_to_linecol(source, offset)
definitions = run_with_debug(jedi, 'goto_definitions',
source=source, line=line, column=column,
path=filename, encoding='utf-8',
environment=self.environment)
# avoid unintersting stuff
try:
if definitions[0].name in ["str", "int", "float", "bool", "tuple",
"list", "dict"]:
return None
except:
pass
assignments = run_with_debug(jedi, 'goto_assignments',
source=source, line=line, column=column,
path=filename, encoding='utf-8',
Expand Down
8 changes: 8 additions & 0 deletions elpy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ def rpc_get_oneline_docstring(self, filename, source, offset):
return self._call_backend("rpc_get_oneline_docstring", None, filename,
get_source(source), offset)

def rpc_get_calltip_or_oneline_docstring(self, filename, source, offset):
"""Get a calltip or a oneline docstring for the symbol at the offset.
"""
return self._call_backend("rpc_get_calltip_or_oneline_docstring",
None, filename,
get_source(source), offset)

def rpc_get_completions(self, filename, source, offset):
"""Get a list of completion candidates for the symbol at offset.
Expand Down
22 changes: 11 additions & 11 deletions test/elpy-eldoc-documentation-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
;; Calltip available: display that
(ert-deftest elpy-eldoc-documentation-should-show-string-calltip ()
(elpy-testcase ()
(mletf* ((elpy-rpc-get-calltip
(mletf* ((elpy-rpc-get-calltip-or-oneline-docstring
(callback)
(funcall callback "Queue.cancel_join_thread()"))
(calltip nil)
Expand All @@ -21,10 +21,11 @@

(ert-deftest elpy-eldoc-documentation-should-show-object-calltip ()
(elpy-testcase ()
(mletf* ((elpy-rpc-get-calltip
(mletf* ((elpy-rpc-get-calltip-or-oneline-docstring
(callback)
(funcall callback '((name . "cancel_join_thread")
(index . 0)
(kind . "calltip")
(params "foo" "bar"))))
(calltip nil)
(eldoc-message (tip) (setq calltip tip)))
Expand All @@ -40,10 +41,11 @@

(ert-deftest elpy-eldoc-documentation-should-not-fail-for-index-nil ()
(elpy-testcase ()
(mletf* ((elpy-rpc-get-calltip
(mletf* ((elpy-rpc-get-calltip-or-oneline-docstring
(callback)
(funcall callback '((name . "cancel_join_thread")
(index . nil)
(kind . "calltip")
(params . nil))))
(calltip nil)
;; without UI, the minibuffer width is only 9,
Expand All @@ -59,12 +61,10 @@
;; No calltip: display function oneline docstring
(ert-deftest elpy-eldoc-documentation-should-show-object-onelinedoc ()
(elpy-testcase ()
(mletf* ((elpy-rpc-get-calltip
(callback)
(funcall callback nil))
(elpy-rpc-get-oneline-docstring
(mletf* ((elpy-rpc-get-calltip-or-oneline-docstring
(callback)
(funcall callback '((name . "cancel_join_thread()")
(kind . "oneline_doc")
(doc . "This function does things."))))
(doc nil)
(window-width (buff) 100000000)
Expand All @@ -84,8 +84,8 @@
;; No calltip and docstring: display current edited function
(ert-deftest elpy-eldoc-documentation-should-use-current-defun-if-nothing-else ()
(elpy-testcase ()
(mletf* ((elpy-rpc-get-calltip (callback) (funcall callback nil))
(elpy-rpc-get-oneline-docstring (callback) (funcall callback nil))
(mletf* ((elpy-rpc-get-calltip-or-oneline-docstring (callback)
(funcall callback nil))
(calltip nil)
(eldoc-message (tip) (setq calltip tip))
(python-info-current-defun () "FooClass.method"))
Expand All @@ -97,8 +97,8 @@
;; No calltip, docstring or current function: display nothing
(ert-deftest elpy-eldoc-documentation-should-return-nil-without-defun ()
(elpy-testcase ()
(mletf* ((elpy-rpc-get-calltip (callback) (funcall callback nil))
(elpy-rpc-get-oneline-docstring (callback) (funcall callback nil))
(mletf* ((elpy-rpc-get-calltip-or-oneline-docstring (callback)
(funcall callback nil))
(calltip nil)
(eldoc-message (tip) (setq calltip tip))
(python-info-current-defun () nil))
Expand Down

0 comments on commit 9e9902f

Please sign in to comment.