Skip to content

Commit 46aacd2

Browse files
Merge pull request #2921 from HelioGuilherme66/localized_bdd
Localized bdd improvements
2 parents a4de481 + 1a4184a commit 46aacd2

File tree

14 files changed

+147
-75
lines changed

14 files changed

+147
-75
lines changed

CHANGELOG.adoc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ and this project adheres to http://semver.org/spec/v2.0.0.html[Semantic Versioni
99
== https://github.com/robotframework/RIDE[Unreleased]
1010

1111
=== Added
12-
- Added syntax colorization for the ``GROUP`` marker. Improved colorization for multiple Gherkin words, for example in the French language.
12+
- Added syntax colorization for the ``GROUP`` marker.
13+
14+
=== Changed
15+
- Improved the recognition of BDD/Gherkin prefixes when localized in autocomplete on Grid Editor.
16+
- Improved colorization for multiple Gherkin words, for example in the French language.
1317

1418
=== Fixed
1519

README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Likewise, the current version of wxPython, is 4.2.2, but RIDE is known to work w
4040

4141
`pip install -U robotframework-ride`
4242

43-
(3.8 <= python <= 3.13) Install current development version (**2.2dev6**) with:
43+
(3.8 <= python <= 3.13) Install current development version (**2.2dev7**) with:
4444

4545
`pip install -U https://github.com/robotframework/RIDE/archive/develop.zip`
4646

src/robotide/application/CHANGELOG.html

Lines changed: 37 additions & 40 deletions
Large diffs are not rendered by default.

src/robotide/application/releasenotes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ def set_content(self, html_win, content):
168168
</ul>
169169
<p><strong>New Features and Fixes Highlights</strong></p>
170170
<ul class="simple">
171+
<li>Improved the recognition of BDD/Gherkin prefixes when localized in autocomplete on Grid Editor.</li>
171172
<li>Added syntax colorization for the <em>GROUP</em> marker. Improved colorization for multiple Gherkin words, for
172173
example in the French language.</li>
173174
<li>Fixed multiple scroll bars in Grid Editor when editing Test Cases or Keywords. This caused bad navigation on cells.</li>
@@ -227,7 +228,7 @@ def set_content(self, html_win, content):
227228
<pre class="literal-block">python -m robotide.postinstall -install</pre>
228229
<p>or</p>
229230
<pre class="literal-block">ride_postinstall.py -install</pre>
230-
<p>RIDE {VERSION} was released on 14/February/2025.</p>
231+
<p>RIDE {VERSION} was released on 16/February/2025.</p>
231232
<!-- <br/>
232233
<h3>May The Fourth Be With You!</h3>
233234
<h3>Celebrate the bank holiday, 10th June, Day of Portugal, Portuguese Communities and Camões!!</h3>

src/robotide/controller/ctrlcommands.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
from ..utils import variablematcher
2727

2828

29+
BDD_ENGLISH = 'Given|When|Then|And|But'
30+
31+
def obtain_bdd_prefixes(language):
32+
from robotide.lib.compat.parsing.language import Language
33+
lang = Language.from_name(language[0] if isinstance(language, list) else language)
34+
bdd_prefixes = [f"{x}|" for x in lang.bdd_prefixes]
35+
bdd_prefixes = "".join(bdd_prefixes).strip('|')
36+
return bdd_prefixes
37+
38+
2939
class Occurrence(object):
3040

3141
def __init__(self, item, value):
@@ -279,17 +289,22 @@ class NullObserver(object):
279289

280290

281291
class RenameKeywordOccurrences(_ReversibleCommand):
282-
# TODO: Consider localization language Gherkin
283-
_gherkin_prefix = re.compile('^(Given|When|Then|And|But) ', re.IGNORECASE)
284292

285-
def __init__(self, original_name, new_name, observer, keyword_info=None):
293+
def __init__(self, original_name, new_name, observer, keyword_info=None, language='En'):
294+
self._language = language[0] if isinstance(language, list) else language
295+
if self._language.lower() not in ['en', 'english']:
296+
bdd_prefix = f"{obtain_bdd_prefixes(self._language)}|{BDD_ENGLISH}"
297+
else:
298+
bdd_prefix = BDD_ENGLISH
299+
self._gherkin_prefix = re.compile(f'^({bdd_prefix}) ', re.IGNORECASE)
286300
self._original_name, self._new_name = self._check_gherkin(new_name, original_name)
287301
self._observer = observer
288302
self._keyword_info = keyword_info
289303
self._occurrences = None
290304
# print(f"DEBUG: ctrlcommands.py RenameKeywordOccurrences INIT\n"
291-
# f"{original_name=}, {new_name=}, self._original_name={self._original_name} "
292-
# f"self._new_name={self._new_name} self._keyword_info={self._keyword_info} ")
305+
# f"{original_name=}, {new_name=}, self._original_name={self._original_name} "
306+
# f"self._new_name={self._new_name} self._keyword_info={self._keyword_info}"
307+
# f" self._gherkin_prefix={self._gherkin_prefix} ")
293308

294309
def _check_gherkin(self, new_name, original_name):
295310
was_gherkin, keyword_name = self._get_gherkin(original_name)

src/robotide/controller/macrocontrollers.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@
3333
TESTCASE_NAME_FIELD = 'Test Case Name'
3434

3535

36+
def obtain_bdd_prefixes(language):
37+
from robotide.lib.compat.parsing.language import Language
38+
lang = Language.from_name(language[0] if isinstance(language, list) else language)
39+
bdd_prefixes = lang.bdd_prefixes
40+
return list(bdd_prefixes)
41+
3642
def _empty_step():
3743
return robotapi.Step([])
3844

@@ -239,10 +245,15 @@ def create_keyword(self, name, argstr):
239245
raise ValueError(validation.error_message)
240246
return self.datafile_controller.create_keyword(name, argstr)
241247

242-
@staticmethod
243-
def _remove_bdd_prefix(name):
248+
def _remove_bdd_prefix(self, name):
249+
bdd_prefix = []
250+
language = self.language[0] if isinstance(self.language, list) else self.language
251+
if language and language.lower() not in ['en', 'english']:
252+
bdd_prefix = [f"{x.lower()} " for x in obtain_bdd_prefixes(language)]
253+
bdd_prefix += ['given ', 'when ', 'then ', 'and ', 'but ']
254+
# print(f"DEBUG: macrocontrollers.py WithStepsController _remove_bdd_prefix bdd_prefix={bdd_prefix}")
244255
matcher = name.lower()
245-
for match in ['given ', 'when ', 'then ', 'and ', 'but ']:
256+
for match in bdd_prefix:
246257
if matcher.startswith(match):
247258
return name[len(match):]
248259
return name

src/robotide/controller/stepcontrollers.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,33 @@
2222
from ..namespace.local_namespace import local_namespace
2323
from ..utils import variablematcher
2424

25+
BDD_ENGLISH = 'given|when|then|and|but'
26+
27+
def obtain_bdd_prefixes(language):
28+
from robotide.lib.compat.parsing.language import Language
29+
lang = Language.from_name(language[0] if isinstance(language, list) else language)
30+
bdd_prefixes = [f"{x}|" for x in lang.bdd_prefixes]
31+
bdd_prefixes = "".join(bdd_prefixes).strip('|')
32+
return bdd_prefixes
33+
2534

2635
class StepController(_BaseController):
2736

28-
_GIVEN_WHEN_THEN_MATCHER = re.compile(r'^(given|when|then|and|but)\s*', re.I)
2937
indent = None
3038

3139
def __init__(self, parent, step):
3240
self.continuing_kw = None
3341
self._init(parent, step)
42+
if hasattr(self.parent, 'language'):
43+
self._language = self.parent.language[0] if isinstance(self.parent.language, list) else self.parent.language
44+
else:
45+
self._language = 'en'
46+
if self._language and self._language.lower() not in ['en', 'english']:
47+
bdd_prefix = f"{obtain_bdd_prefixes(self._language)}|{BDD_ENGLISH}"
48+
else:
49+
bdd_prefix = BDD_ENGLISH
50+
self._GIVEN_WHEN_THEN_MATCHER = re.compile(fr'^({bdd_prefix})\s*', re.IGNORECASE)
51+
# print(f"DEBUG: stepcontrollers.py StepController INIT {self.parent.language}")
3452
self.step_controller_step.args = self._change_last_empty_to_empty_var(
3553
self.step_controller_step.args, self.step_controller_step.comment)
3654

src/robotide/editor/contentassist.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,20 @@
2828
from ..publish.messages import RideSettingsChanged
2929

3030

31+
def obtain_bdd_prefixes(language):
32+
from robotide.lib.compat.parsing.language import Language
33+
lang = Language.from_name(language[0] if isinstance(language, list) else language)
34+
bdd_prefixes = lang.bdd_prefixes
35+
return list(bdd_prefixes)
36+
37+
3138
_PREFERRED_POPUP_SIZE = (200, 400)
3239
_AUTO_SUGGESTION_CFG_KEY = "enable auto suggestions"
3340

3441

3542
class _ContentAssistTextCtrlBase(wx.TextCtrl):
3643

37-
def __init__(self, suggestion_source, **kw):
44+
def __init__(self, suggestion_source, language='En', **kw):
3845
super().__init__(**kw)
3946
from ..preferences import RideSettings
4047
_settings = RideSettings()
@@ -45,6 +52,7 @@ def __init__(self, suggestion_source, **kw):
4552
self.color_secondary_foreground = self.general_settings['secondary foreground']
4653
self.color_background_help = self.general_settings['background help']
4754
self.color_foreground_text = self.general_settings['foreground text']
55+
self.language = language
4856
self._popup = ContentAssistPopup(self, suggestion_source)
4957
self.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
5058
self.Bind(wx.EVT_CHAR, self.on_char)
@@ -308,9 +316,13 @@ def _populate_content_assist(self):
308316
(self.gherkin_prefix, value) = self._remove_bdd_prefix(value)
309317
return self._popup.content_assist_for(value, row=self._row)
310318

311-
@staticmethod
312-
def _remove_bdd_prefix(name):
313-
for match in ['given ', 'when ', 'then ', 'and ', 'but ']:
319+
def _remove_bdd_prefix(self, name):
320+
bdd_prefix = []
321+
if self.language.lower() not in ['en', 'english']:
322+
bdd_prefix = [f"{x.lower()} " for x in obtain_bdd_prefixes(self.language)]
323+
bdd_prefix += ['given ', 'when ', 'then ', 'and ', 'but ']
324+
# print(f"DEBUG: contentassist.py ContentAssistTextCtrlBase _remove_bdd_prefix bdd_prefix={bdd_prefix}")
325+
for match in bdd_prefix:
314326
if name.lower().startswith(match):
315327
return name[:len(match)], name[len(match):]
316328
return '', name
@@ -341,11 +353,11 @@ def dismiss(self):
341353

342354
class ExpandingContentAssistTextCtrl(_ContentAssistTextCtrlBase, ExpandoTextCtrl):
343355

344-
def __init__(self, parent, plugin, controller):
356+
def __init__(self, parent, plugin, controller, language='En'):
345357
""" According to class MRO, super().__init__ in _ContentAssistTextCtrlBase will init ExpandoTextCtrl
346358
instance """
347359

348-
_ContentAssistTextCtrlBase.__init__(self, SuggestionSource(plugin, controller),
360+
_ContentAssistTextCtrlBase.__init__(self, SuggestionSource(plugin, controller), language=language,
349361
parent=parent, size=wx.DefaultSize,
350362
style=wx.WANTS_CHARS | wx.TE_NOHIDESEL)
351363
self.SetBackgroundColour(context.POPUP_BACKGROUND)
@@ -356,8 +368,8 @@ def __init__(self, parent, plugin, controller):
356368

357369
class ContentAssistTextCtrl(_ContentAssistTextCtrlBase):
358370

359-
def __init__(self, parent, suggestion_source, size=wx.DefaultSize):
360-
super().__init__(suggestion_source, parent=parent,
371+
def __init__(self, parent, suggestion_source, language='En', size=wx.DefaultSize):
372+
super().__init__(suggestion_source, language=language, parent=parent,
361373
size=size, style=wx.WANTS_CHARS | wx.TE_NOHIDESEL)
362374
self.SetBackgroundColour(Colour(self.color_background_help))
363375
# self.SetOwnBackgroundColour(Colour(self.color_background_help))
@@ -367,8 +379,8 @@ def __init__(self, parent, suggestion_source, size=wx.DefaultSize):
367379

368380
class ContentAssistTextEditor(_ContentAssistTextCtrlBase):
369381

370-
def __init__(self, parent, suggestion_source, pos, size=wx.DefaultSize):
371-
super().__init__(suggestion_source,
382+
def __init__(self, parent, suggestion_source, pos, language='En', size=wx.DefaultSize):
383+
super().__init__(suggestion_source, language=language,
372384
parent=parent, id=-1, value="", pos=pos, size=size,
373385
style=wx.WANTS_CHARS | wx.BORDER_NONE | wx.WS_EX_TRANSIENT | wx.TE_PROCESS_ENTER |
374386
wx.TE_NOHIDESEL)

src/robotide/editor/kweditor.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import builtins
1717
import json
1818
from json.decoder import JSONDecodeError
19+
from multiprocessing import shared_memory
1920

2021
import wx
2122
from wx import grid
@@ -74,7 +75,6 @@ def decorated_function(self, *args):
7475

7576
return decorated_function
7677

77-
7878
class KeywordEditor(GridEditor, Plugin):
7979
_no_cell = (-1, -1)
8080
_popup_menu_shown = False
@@ -163,6 +163,17 @@ def __init__(self, parent, controller, tree):
163163
self._cell_selected = False
164164
self._colorizer = Colorizer(self, controller)
165165
self._controller = controller
166+
try:
167+
set_lang = shared_memory.ShareableList(name="language")
168+
self._language = [set_lang[0]]
169+
# print(f"DEBUG: settings.py SettingEditor __init__ SHAREDMEM language={self._language}")
170+
except AttributeError:
171+
try:
172+
self._language = self._controller.language
173+
# print(f"DEBUG: settings.py SettingEditor __init__ CONTROLLER language={self._language}")
174+
except AttributeError:
175+
self._language = ['en']
176+
self._language = self._language[0] if isinstance(self._language, list) else self._language
166177
self._configure_grid()
167178
self._updating_namespace = False
168179
self._controller.datafile_controller.register_for_namespace_updates(
@@ -247,7 +258,7 @@ def _set_cells(self):
247258

248259
def _configure_grid(self):
249260
self._set_cells()
250-
self.SetDefaultEditor(ContentAssistCellEditor(self._plugin, self._controller))
261+
self.SetDefaultEditor(ContentAssistCellEditor(self._plugin, self._controller, self._language))
251262
self._set_fonts()
252263
wx.CallAfter(self.SetGridCursor, (0, 0)) # To make cells colorized as soon we select keywords or tests
253264
wx.CallAfter(self.highlight, '')
@@ -1150,7 +1161,7 @@ def on_rename_keyword(self, event):
11501161
new_name = wx.GetTextFromUser(_('New name'), _(REN_KW), default_value=old_name)
11511162
if new_name:
11521163
self._execute(RenameKeywordOccurrences(
1153-
old_name, new_name, RenameProgressObserver(self.GetParent())))
1164+
old_name, new_name, RenameProgressObserver(self.GetParent()), language=self._language))
11541165

11551166
# Add one new Dialog to edit pretty json String TODO: use better editor with more functions
11561167
def on_json_editor(self, event=None):
@@ -1205,7 +1216,7 @@ def is_json(json_str):
12051216

12061217
class ContentAssistCellEditor(GridCellEditor):
12071218

1208-
def __init__(self, plugin, controller):
1219+
def __init__(self, plugin, controller, language='En'):
12091220
self.settings = plugin.global_settings['Grid']
12101221
self.general_settings = plugin.global_settings['General']
12111222
self.filter_newlines = self.settings.get("filter newlines", True)
@@ -1214,6 +1225,7 @@ def __init__(self, plugin, controller):
12141225
GridCellEditor.__init__(self)
12151226
self._plugin = plugin
12161227
self._controller = controller
1228+
self._language = language
12171229
self._grid = None
12181230
self._original_value = None
12191231
self._value = None
@@ -1244,7 +1256,7 @@ def execute_sharp_uncomment(self):
12441256
self._tc.execute_sharp_uncomment()
12451257

12461258
def Create(self, parent, idd, evthandler):
1247-
self._tc = ExpandingContentAssistTextCtrl(parent, self._plugin, self._controller)
1259+
self._tc = ExpandingContentAssistTextCtrl(parent, self._plugin, self._controller, self._language)
12481260
self.SetControl(self._tc)
12491261
if evthandler:
12501262
self._tc.PushEventHandler(evthandler)
@@ -1316,7 +1328,7 @@ def StartingKey(self, event):
13161328
self._tc.SetInsertionPointEnd()
13171329

13181330
def Clone(self):
1319-
return ContentAssistCellEditor(self._plugin, self._controller)
1331+
return ContentAssistCellEditor(self._plugin, self._controller, self._language)
13201332

13211333

13221334
class ChooseUsageSearchStringDialog(wx.Dialog):

src/robotide/lib/compat/parsing/languages.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,8 @@ class Fr(Language):
559559
template_setting = 'Modèle'
560560
timeout_setting = "Délai d'attente"
561561
arguments_setting = 'Arguments'
562-
given_prefixes = ['Soit', 'Sachant', 'Sachant que', "Sachant qu'", 'Étant donné', 'Étant donné que', "Etant donné qu'"]
562+
given_prefixes = ['Soit', 'Sachant', 'Sachant que', "Sachant qu'", 'Étant donné', 'Étant donné que',
563+
"Etant donné qu'"]
563564
when_prefixes = ['Quand', 'Lorsque', "Lorsqu'"]
564565
then_prefixes = ['Alors', 'Donc']
565566
and_prefixes = ['Et', 'Et que', "Et qu'"]

0 commit comments

Comments
 (0)