Skip to content

Commit

Permalink
Add help pop-up on Text Editor with Ctrl-M, for content at cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
HelioGuilherme66 committed Sep 18, 2023
1 parent 0c11f78 commit 800b50a
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to http://semver.org/spec/v2.0.0.html[Semantic Versioni

=== Added

- Added content help pop-up on Text Editor by pressing ``Ctrl-M`` for text at cursor position
- Added Exclude option in context nenu for Test files, previously was only possible for Test Suites folders
- Added exclusion of monitoring filesystem changes for files and directories excluded in Preferences
- Added variables creation shortcuts (``Ctrl-1,2,5``) to fields Arguments in Grid Editor
Expand Down
2 changes: 2 additions & 0 deletions src/robotide/application/CHANGELOG.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Changelog</title><link rel="stylesheet" type="text/css" href="docbook-xsl.css" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /></head><body><div xml:lang="en" class="article" lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id1337"></a>Changelog</h2></div></div><hr /></div><p>All notable changes to this project will be documented in this file.</p><p>The format is based on <a class="ulink" href="http://keepachangelog.com/en/1.0.0/" target="_top">Keep a Changelog</a>
and this project adheres to <a class="ulink" href="http://semver.org/spec/v2.0.0.html" target="_top">Semantic Versioning</a>.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="_ulink_url_https_github_com_robotframework_ride_unreleased_ulink"></a>1. <a class="ulink" href="https://github.com/robotframework/RIDE" target="_top">Unreleased</a></h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_added"></a>1.1. Added</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Added content help pop-up on Text Editor by pressing ``Ctrl-M`` for text at cursor position
</li><li class="listitem">
Added Exclude option in context nenu for Test files, previously was only possible for Test Suites folders
</li><li class="listitem">
Added exclusion of monitoring filesystem changes for files and directories excluded in Preferences
Expand Down
3 changes: 2 additions & 1 deletion src/robotide/application/releasenotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ def set_content(self, html_win, content):
</ul>
<p><strong>New Features and Fixes Highlights</strong></p>
<ul class="simple">
<li>Added content help pop-up on Text Editor by pressing <b>Ctrl-M</b> for text at cursor position</li>
<li>Added Exclude option in context nenu for Test files, previously was only possible for Test Suites folders</li>
<li>Added exclusion of monitoring filesystem changes for files and directories excluded in Preferences</li>
<li>Fixed exception when finding GREY color for excluded files and directories in Project Tree</li>
Expand Down Expand Up @@ -236,6 +237,6 @@ def set_content(self, html_win, content):
<pre class="literal-block">
python -m robotide.postinstall -install
</pre>
<p>RIDE {VERSION} was released on 10/Sep/2023.</p>
<p>RIDE {VERSION} was released on 18/Sep/2023.</p>
</div>
"""
4 changes: 4 additions & 0 deletions src/robotide/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ def bind_keys_to_evt_menu(target, actions):
<tr>
<td>Ctrl-Space or Alt-Space</td>
<td>Suggestions and auto completion</td>
</tr>
<tr>
<td>CtrlCmd-M</td>
<td>Help for content at cursor</td>
</tr>
<tr>
<td>CtrlCmd-T</td>
Expand Down
94 changes: 76 additions & 18 deletions src/robotide/editor/texteditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import wx
from wx import stc, Colour
from wx.adv import HyperlinkCtrl, EVT_HYPERLINK

from .popupwindow import HtmlPopupWindow
from .. import robotapi
from ..context import IS_WINDOWS, IS_MAC
from ..controller.ctrlcommands import SetDataFile, INDENTED_START
Expand Down Expand Up @@ -57,7 +57,7 @@ def __init__(self, application):
@property
def _editor(self):
if self._editor_component is None:
self._editor_component = SourceEditor(self.notebook,
self._editor_component = SourceEditor(self, self.notebook,
self.title,
DataValidationHandler(self))
self._refresh_timer = wx.Timer(self._editor_component)
Expand Down Expand Up @@ -383,7 +383,7 @@ def _txt_data(self, data):

class SourceEditor(wx.Panel):

def __init__(self, parent, title, data_validator):
def __init__(self, plugin, parent, title, data_validator):
wx.Panel.__init__(self, parent)
self.dlg = RIDEDialog()
self.SetBackgroundColour(Colour(self.dlg.color_background))
Expand All @@ -392,6 +392,7 @@ def __init__(self, parent, title, data_validator):
self._data_validator = data_validator
self._data_validator.set_editor(self)
self.source_editor_parent = parent
self.plugin = plugin
self._title = title
self.tab_size = self.source_editor_parent.app.settings.get(TXT_NUM_SPACES, 4)
self.reformat = self.source_editor_parent.app.settings.get('reformat', False)
Expand Down Expand Up @@ -937,6 +938,8 @@ def on_key_down(self, event):
self.delete_cell(event)
else:
self.delete_row(event)
elif keycode == ord('M') and event.ControlDown():
self.source_editor.show_kw_doc()
else:
event.Skip()
"""
Expand Down Expand Up @@ -1484,7 +1487,11 @@ class RobotDataEditor(stc.StyledTextCtrl):
def __init__(self, parent, readonly=False):
stc.StyledTextCtrl.__init__(self, parent)
self.parent = parent
self._plugin = parent.plugin
self._settings = parent.source_editor_parent.app.settings
self._information_popup = None
self.old_position = None
self.old_select = []
self.readonly = readonly
self.SetMarginType(self.margin, stc.STC_MARGIN_NUMBER)
self.SetLexer(stc.STC_LEX_CONTAINER)
Expand All @@ -1503,21 +1510,38 @@ def __init__(self, parent, readonly=False):
self.RegisterImage(2, wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16, 16)))
self.RegisterImage(3, wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16, 16)))

def show_kw_doc(self):
cursor_pos = self.GetCurrentPos()
if cursor_pos != self.old_position:
self.old_position = cursor_pos
selected = self.get_selected_or_near_text(keep_cursor_pos=True)
if self.old_select != selected:
for kw in selected:
self._show_keyword_details(kw)

def on_key_pressed(self, event):
if self.CallTipActive():
self.CallTipCancel()
if self._information_popup:
self._information_popup.hide()
key = event.GetKeyCode()
if key == 32 and event.ControlDown():
pos = self.GetCurrentPos()

# Tips
if event.ShiftDown():
self.show_kw_doc()
"""
self.CallTipSetBackground("yellow")
self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
'show some suff, maybe parameters..\n\n'
'fubar(param1, param2)')
self.CallTipShow(pos, f"lots of of text: blah, blah, blah\n\n"
"show some suff, maybe parameters..\n\n"
f"fubar(param1, param2)\n\nContext: {selected}"
)
"""
# Code completion
else:
if self._information_popup:
self._information_popup.hide()
"""
kw = list(keyword.kwlist[:])
kw.append("zzzzzz?2")
Expand Down Expand Up @@ -1588,23 +1612,36 @@ def calc_margin_width(self):
width = self.TextWidth(style, str(self.GetLineCount()))
return width + self.TextWidth(style, "1")

def get_selected_or_near_text(self):
def get_selected_or_near_text(self, keep_cursor_pos=False):
content = set()
if keep_cursor_pos:
restore_cursor_pos = self.GetInsertionPoint()
else:
restore_cursor_pos = None
# First get selected text
selected = self.GetSelectedText()
if selected:
start_pos = self.GetSelectionStart()
if selected.endswith('.'): # Special cases for libraries prefix
self.SetInsertionPoint(start_pos + len(selected))
if restore_cursor_pos:
self.SetInsertionPoint(restore_cursor_pos)
else:
self.SetInsertionPoint(start_pos + len(selected))
elif len(selected.split('.')) > 1:
parts = selected.split('.')
self.SetSelectionStart(start_pos + len(parts[0]) + 1)
self.SetSelectionEnd(start_pos + len(selected))
self.SetInsertionPoint(start_pos + len(parts[0]) + 1)
if restore_cursor_pos:
self.SetInsertionPoint(restore_cursor_pos)
else:
self.SetInsertionPoint(start_pos + len(parts[0]) + 1)
else:
self.SetSelectionStart(start_pos)
self.SetSelectionEnd(start_pos + len(selected))
self.SetInsertionPoint(start_pos + len(selected))
if restore_cursor_pos:
self.SetInsertionPoint(restore_cursor_pos)
else:
self.SetInsertionPoint(start_pos + len(selected))
content.add(selected.strip())
# Next get text on the left
text = self.GetCurLine()[0]
Expand Down Expand Up @@ -1645,16 +1682,25 @@ def get_selected_or_near_text(self):
else:
start_pos = min_pos + pos_in_line
if value.endswith('.'): # Special cases for libraries prefix
self.SetInsertionPoint(start_pos + len(value))
if restore_cursor_pos:
self.SetInsertionPoint(restore_cursor_pos)
else:
self.SetInsertionPoint(start_pos + len(value))
elif len(value.split('.')) > 1:
parts = value.split('.')
self.SetSelectionStart(start_pos + len(parts[0]) + 1)
self.SetSelectionEnd(start_pos + len(value))
self.SetInsertionPoint(start_pos + len(parts[0]) + 1)
if restore_cursor_pos:
self.SetInsertionPoint(restore_cursor_pos)
else:
parts = value.split('.')
self.SetSelectionStart(start_pos + len(parts[0]) + 1)
self.SetSelectionEnd(start_pos + len(value))
self.SetInsertionPoint(start_pos + len(parts[0]) + 1)
else:
self.SetSelectionStart(start_pos)
self.SetSelectionEnd(start_pos + len(value))
self.SetInsertionPoint(start_pos)
if restore_cursor_pos:
self.SetInsertionPoint(restore_cursor_pos)
else:
self.SetSelectionStart(start_pos)
self.SetSelectionEnd(start_pos + len(value))
self.SetInsertionPoint(start_pos)
content.add(value)
return content if content else ['']

Expand Down Expand Up @@ -1688,6 +1734,18 @@ def on_update_ui(self, evt):
else:
self.BraceHighlight(brace_at_caret, brace_opposite)

def _show_keyword_details(self, value):
details = self._plugin.get_keyword_details(value)
if details:
wpos = self.parent.source_editor_parent.GetPosition()
npos = self.parent.GetPosition()
position = self.GetCurrentPos()
position = self.PointFromPosition(position)
position = position + wpos + npos
self._information_popup = HtmlPopupWindow(self.parent, (450, 300))
self._information_popup.set_content(details, value)
self._information_popup.show_at(position)


class FromStringIOPopulator(robotapi.populators.FromFilePopulator):

Expand Down
2 changes: 1 addition & 1 deletion src/robotide/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
# limitations under the License.
#
# Automatically generated by `tasks.py`.
VERSION = 'v2.0.8dev11'
VERSION = 'v2.0.8dev12'
2 changes: 1 addition & 1 deletion utest/editor/test_texteditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def setUp(self):
ShortcutRegistry(self.frame)), settings)
self.app.project = Project(self.app.namespace, self.app.settings)
self.plugin = texteditor.TextEditorPlugin(self.app)
self.plugin._editor_component = texteditor.SourceEditor(self.app.book, self.plugin.title,
self.plugin._editor_component = texteditor.SourceEditor(self.plugin, self.app.book, self.plugin.title,
texteditor.DataValidationHandler(self.plugin))
self.plugin.enable()
self.app.project.load_datafile(datafilereader.TESTCASEFILE_WITH_EVERYTHING, MessageRecordingLoadObserver())
Expand Down
2 changes: 1 addition & 1 deletion utest/editor/test_z_editor_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def setUp(self):
self.app.project = Project(self.app.namespace, self.app.settings)

self.plugin = texteditor.TextEditorPlugin(self.app)
self.plugin._editor_component = texteditor.SourceEditor(self.app.notebook, self.plugin.title,
self.plugin._editor_component = texteditor.SourceEditor(self.plugin, self.app.notebook, self.plugin.title,
texteditor.DataValidationHandler(self.plugin))
self.frame.notebook = self.app.notebook
"""
Expand Down

0 comments on commit 800b50a

Please sign in to comment.