forked from pyQode/pyqode.python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcalltips.py
More file actions
131 lines (117 loc) · 4.88 KB
/
calltips.py
File metadata and controls
131 lines (117 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- coding: utf-8 -*-
"""
Contains the JediCompletionProvider class implementation.
"""
import logging
from pyqode.core.api import Mode, TextHelper
from pyqode.qt import QtCore, QtWidgets
from pyqode.python.backend import workers
def _logger():
return logging.getLogger(__name__)
class CalltipsMode(Mode, QtCore.QObject):
""" Shows function calltips.
This mode shows function/method call tips in a QToolTip using
:meth:`jedi.Script.call_signatures`.
"""
tooltipDisplayRequested = QtCore.Signal(object, int)
tooltipHideRequested = QtCore.Signal()
def __init__(self):
Mode.__init__(self)
QtCore.QObject.__init__(self)
self.tooltipDisplayRequested.connect(self._display_tooltip)
self.tooltipHideRequested.connect(QtWidgets.QToolTip.hideText)
self.__requestCnt = 0
def on_state_changed(self, state):
if state:
self.editor.key_released.connect(self._on_key_released)
else:
self.editor.key_released.disconnect(self._on_key_released)
def _on_key_released(self, event):
if (event.key() == QtCore.Qt.Key_ParenLeft or
event.key() == QtCore.Qt.Key_Comma):
tc = self.editor.textCursor()
line = tc.blockNumber()
col = tc.columnNumber()
fn = self.editor.file.path
encoding = self.editor.file.encoding
source = self.editor.toPlainText()
# jedi has a bug if the statement has a closing parenthesis
# remove it!
lines = source.splitlines()
try:
l = lines[line].rstrip()
except IndexError:
# at the beginning of the last line (empty)
return
if l.endswith(")"):
lines[line] = l[:-1]
source = "\n".join(lines)
self._request_calltip(source, line, col, fn, encoding)
elif (event.key() in [
QtCore.Qt.Key_ParenRight,
QtCore.Qt.Key_Return,
QtCore.Qt.Key_Left,
QtCore.Qt.Key_Right,
QtCore.Qt.Key_Up,
QtCore.Qt.Key_Down,
QtCore.Qt.Key_End,
QtCore.Qt.Key_Home,
QtCore.Qt.Key_PageDown,
QtCore.Qt.Key_PageUp,
QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete]):
QtWidgets.QToolTip.hideText()
def _request_calltip(self, source, line, col, fn, encoding):
if self.__requestCnt == 0:
self.__requestCnt += 1
self.editor.backend.send_request(
workers.calltips,
{'code': source, 'line': line, 'column': col, 'path': None,
'encoding': encoding}, on_receive=self._on_results_available)
def _on_results_available(self, results):
self.__requestCnt -= 1
if results:
call = {"call.module.name": results[0],
"call.call_name": results[1],
"call.params": results[2],
"call.index": results[3],
"call.bracket_start": results[4]}
self.tooltipDisplayRequested.emit(call, results[5])
def _is_last_chard_end_of_word(self):
try:
tc = TextHelper(self.editor).word_under_cursor()
tc.setPosition(tc.position())
tc.movePosition(tc.StartOfLine, tc.KeepAnchor)
l = tc.selectedText()
last_char = l[len(l) - 1]
seps = self.editor.word_separators
symbols = [",", " ", "("]
return last_char in seps and last_char not in symbols
except IndexError:
return False
def _display_tooltip(self, call, col):
if not call or self._is_last_chard_end_of_word():
return
# create a formatted calltip (current index appear in bold)
calltip = "<p style='white-space:pre'>{0}.{1}(".format(
call['call.module.name'], call['call.call_name'])
for i, param in enumerate(call['call.params']):
if i < len(call['call.params']) - 1 and not param.endswith(','):
param += ", "
if param.endswith(','):
param += ' ' # pep8 calltip
if i == call['call.index']:
calltip += "<b>"
calltip += param
if i == call['call.index']:
calltip += "</b>"
calltip += ')</p>'
# set tool tip position at the start of the bracket
char_width = self.editor.fontMetrics().width('A')
w_offset = (col - call['call.bracket_start'][1]) * char_width
position = QtCore.QPoint(
self.editor.cursorRect().x() - w_offset,
self.editor.cursorRect().y() + char_width +
self.editor.panels.margin_size(0))
position = self.editor.mapToGlobal(position)
# show tooltip
QtWidgets.QToolTip.showText(position, calltip, self.editor)