Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Icons to Completions #2337

Merged
merged 10 commits into from
Apr 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ spyderlib/images/whole_words.png
spyderlib/images/win_env.png
spyderlib/images/actions/hist.png
spyderlib/images/actions/window_nofullscreen.png
spyderlib/images/editor/attribute.png
spyderlib/images/editor/filelist.png
spyderlib/images/editor/function.png
spyderlib/images/editor/method.png
spyderlib/images/editor/module.png
spyderlib/images/editor/no_match.png
spyderlib/images/editor/private1.png
spyderlib/images/editor/private2.png
spyderlib/images/editor/cell.png
Expand Down
Binary file added spyderlib/images/editor/attribute.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added spyderlib/images/editor/module.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added spyderlib/images/editor/no_match.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions spyderlib/utils/introspection/fallback_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class FallbackPlugin(IntrospectionPlugin):
name = 'fallback'

def get_completions(self, info):
"""Return a list of completion strings
"""Return a list of (completion, type) tuples

Simple completion based on python-like identifiers and whitespace
"""
Expand All @@ -54,7 +54,7 @@ def get_completions(self, info):
match = re.search('''[ "\']([\w\.\\\\/]+)\Z''', info.line)
if match:
items += _complete_path(match.groups()[0])
return list(sorted(items))
return [(i, '') for i in sorted(items)]

def get_definition(self, info):
"""
Expand Down
7 changes: 4 additions & 3 deletions spyderlib/utils/introspection/jedi_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ def load_plugin(self):
self._warmup_thread.start()

def get_completions(self, info):
"""Return a list of completion strings"""
"""Return a list of (completion, type) tuples"""
completions = self.get_jedi_object('completions', info)
completions = [(c.word, c.type) for c in completions]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove this debug_print here? Just curious, I don't know how important that is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you plan to remove or leave this debug_print? You haven't answered my question :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed now, with updated info!

debug_print(str(completions)[:100])
return [c.word for c in completions]
return completions

def get_info(self, info):
"""
Expand Down Expand Up @@ -267,7 +268,7 @@ def preload(self):
source_code = "import n"
completions = p.get_completions(CodeInfo('completions', source_code,
len(source_code)))
assert 'numpy' in completions
assert ('numpy', 'module') in completions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have an icon for modules?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not. We have an "M" icon for method, but if we used that it would be the same one as the one used in the outline explorer. I could make an "M" with a different color and use it for module.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be confuse. What about using a (P) icon for package?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I just saw that you added a new (M) for modules.

@goanpeca, what do you think about it? Should we leave it or use a (P) one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because module != package, and P could also be property.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, no problem then. Let's leave your new (M) :-)


source_code = "import matplotlib.pyplot as plt; plt.imsave"
path, line_nr = p.get_definition(CodeInfo('definition', source_code,
Expand Down
8 changes: 5 additions & 3 deletions spyderlib/utils/introspection/plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,8 @@ def _handle_completions_response(self, comp_list, info, prev_info):
return

if info.full_obj and len(info.full_obj) > len(info.obj):
new_list = [c for c in comp_list if c.startswith(info.full_obj)]
new_list = [(c, t) for (c, t) in comp_list
if c.startswith(info.full_obj)]
if new_list:
pos = info.editor.get_position('cursor')
new_pos = pos + len(info.full_obj) - len(info.obj)
Expand All @@ -429,8 +430,9 @@ def _handle_completions_response(self, comp_list, info, prev_info):
if '.' in completion_text:
completion_text = completion_text.split('.')[-1]

comp_list = [c.split('.')[-1] for c in comp_list]
comp_list = [c for c in comp_list if c.startswith(completion_text)]
comp_list = [(c.split('.')[-1], t) for (c, t) in comp_list]
comp_list = [(c, t) for (c, t) in comp_list
if c.startswith(completion_text)]

info.editor.show_completion_list(comp_list, completion_text,
prev_info.automatic)
Expand Down
9 changes: 5 additions & 4 deletions spyderlib/utils/introspection/rope_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ def load_plugin(self):
self.create_rope_project(root_path=get_conf_path())

def get_completions(self, info):
"""Get a list of completions using Rope"""
"""Get a list of (completion, type) tuples using Rope"""
if self.project is None:
return
return []
filename = info.filename
source_code = info.source_code
offset = info.position
Expand All @@ -93,10 +93,11 @@ def get_completions(self, info):
proposals = rope.contrib.codeassist.sorted_proposals(proposals)
if DEBUG_EDITOR:
log_dt(LOG_FILENAME, "code_assist/sorted_proposals", t0)
return [proposal.name for proposal in proposals]
return [(proposal.name, proposal.type) for proposal in proposals]
except Exception as _error: #analysis:ignore
if DEBUG_EDITOR:
log_last_error(LOG_FILENAME, "get_completion_list")
return []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this addition here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make sure we always return a list (I wasn't sure what else might break if I didn't).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, no problem. Just curious :-)


def get_info(self, info):
"""Get a formatted calltip and docstring from Rope"""
Expand Down Expand Up @@ -284,7 +285,7 @@ def close_rope_project(self):
source_code = "import numpy; n"
completions = p.get_completions(CodeInfo('completions', source_code,
len(source_code), __file__))
assert 'numpy' in completions
assert ('numpy', 'module') in completions

source_code = "import matplotlib.pyplot as plt; plt.imsave"
path, line_nr = p.get_definition(CodeInfo('definition', source_code,
Expand Down
34 changes: 26 additions & 8 deletions spyderlib/widgets/sourcecode/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
QTextEdit, QTextCharFormat, QToolTip,
QListWidget, QPlainTextEdit, QPalette,
QMainWindow, QTextOption, QMouseEvent,
QTextFormat, QClipboard, QAbstractItemView)
QTextFormat, QClipboard, QAbstractItemView,
QListWidgetItem)
from spyderlib.qt.QtCore import Signal, Slot, Qt, QEventLoop, QEvent, QPoint
from spyderlib.qt.compat import to_qvariant
from spyderlib.utils.qthelpers import get_icon


# Local imports
Expand Down Expand Up @@ -61,15 +63,28 @@ def setup_appearance(self, size, font):
self.setFont(font)

def show_list(self, completion_list, automatic=True):
types = [c[1] for c in completion_list]
completion_list = [c[0] for c in completion_list]
if len(completion_list) == 1 and not automatic:
self.textedit.insert_completion(completion_list[0])
return

self.completion_list = completion_list
self.clear()
self.addItems(completion_list)

icons_map = {'instance': 'attribute.png',
'statement': 'attribute.png',
'method': 'method.png',
'function': 'function.png',
'class': 'class.png',
'module': 'module.png'}

for (c, t) in zip(completion_list, types):
icon = icons_map.get(t, 'no_match.png')
self.addItem(QListWidgetItem(get_icon(icon), c))

self.setCurrentRow(0)

QApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
self.show()
self.setFocus()
Expand Down Expand Up @@ -882,15 +897,18 @@ def hide_completion_widget(self):
def show_completion_list(self, completions, completion_text="",
automatic=True):
"""Display the possible completions"""
if len(completions) == 0 or completions == [completion_text]:
c = completions
if len(c) == 0 or (len(c) == 1 and c[0][0] == completion_text):
return
self.completion_text = completion_text
# Sorting completion list (entries starting with underscore are
# put at the end of the list):
underscore = set([comp for comp in completions
underscore = set([(comp, t) for (comp, t) in completions
if comp.startswith('_')])
completions = sorted(set(completions)-underscore, key=str_lower)+\
sorted(underscore, key=str_lower)

completions = sorted(set(completions) - underscore,
key=lambda x: str_lower(x[0]))
completions += sorted(underscore, key=lambda x: str_lower(x[0]))
self.show_completion_widget(completions, automatic=automatic)

def select_completion_list(self):
Expand Down