robotcode-language-server 1.3.0.dev2__tar.gz → 1.3.0.dev4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/PKG-INFO +5 -5
  2. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/pyproject.toml +4 -4
  3. robotcode_language_server-1.3.0.dev4/src/robotcode/language_server/__version__.py +1 -0
  4. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/configuration.py +3 -0
  5. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/formatting.py +82 -34
  6. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/keywords_treeview.py +122 -8
  7. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/project_info.py +14 -19
  8. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/robocop_diagnostics.py +3 -10
  9. robotcode_language_server-1.3.0.dev4/src/robotcode/language_server/robotframework/parts/robocop_tidy_mixin.py +49 -0
  10. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/semantic_tokens.py +3 -1
  11. robotcode_language_server-1.3.0.dev2/src/robotcode/language_server/__version__.py +0 -1
  12. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/.gitignore +0 -0
  13. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/LICENSE.txt +0 -0
  14. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/README.md +0 -0
  15. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/__init__.py +0 -0
  16. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/cli.py +0 -0
  17. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/__init__.py +0 -0
  18. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/decorators.py +0 -0
  19. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/__init__.py +0 -0
  20. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/code_action.py +0 -0
  21. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/code_lens.py +0 -0
  22. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/commands.py +0 -0
  23. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/completion.py +0 -0
  24. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/declaration.py +0 -0
  25. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/definition.py +0 -0
  26. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/diagnostics.py +0 -0
  27. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/document_highlight.py +0 -0
  28. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/document_symbols.py +0 -0
  29. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/documents.py +0 -0
  30. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/folding_range.py +0 -0
  31. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/formatting.py +0 -0
  32. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/hover.py +0 -0
  33. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/implementation.py +0 -0
  34. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/inlay_hint.py +0 -0
  35. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/inline_value.py +0 -0
  36. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/linked_editing_ranges.py +0 -0
  37. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/protocol_part.py +0 -0
  38. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/references.py +0 -0
  39. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/rename.py +0 -0
  40. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/selection_range.py +0 -0
  41. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/semantic_tokens.py +0 -0
  42. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/signature_help.py +0 -0
  43. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/window.py +0 -0
  44. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/workspace.py +0 -0
  45. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/parts/workspace_symbols.py +0 -0
  46. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/protocol.py +0 -0
  47. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/common/server.py +0 -0
  48. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/hooks.py +0 -0
  49. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/py.typed +0 -0
  50. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/__init__.py +0 -0
  51. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/__init__.py +0 -0
  52. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/code_action_documentation.py +0 -0
  53. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/code_action_helper_mixin.py +0 -0
  54. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/code_action_quick_fixes.py +0 -0
  55. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/code_action_refactor.py +0 -0
  56. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/code_lens.py +0 -0
  57. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/completion.py +0 -0
  58. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/debugging_utils.py +0 -0
  59. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/diagnostics.py +0 -0
  60. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/document_highlight.py +0 -0
  61. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/document_symbols.py +0 -0
  62. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/documents_cache.py +0 -0
  63. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/folding_range.py +0 -0
  64. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/goto.py +0 -0
  65. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/hover.py +0 -0
  66. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/http_server.py +0 -0
  67. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/inlay_hint.py +0 -0
  68. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/inline_value.py +0 -0
  69. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/protocol_part.py +0 -0
  70. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/references.py +0 -0
  71. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/rename.py +0 -0
  72. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/robot_workspace.py +0 -0
  73. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/selection_range.py +0 -0
  74. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/signature_help.py +0 -0
  75. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/parts/workspace_symbols.py +0 -0
  76. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/protocol.py +0 -0
  77. {robotcode_language_server-1.3.0.dev2 → robotcode_language_server-1.3.0.dev4}/src/robotcode/language_server/robotframework/server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotcode-language-server
3
- Version: 1.3.0.dev2
3
+ Version: 1.3.0.dev4
4
4
  Summary: RobotCode Language Server for Robot Framework
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -25,10 +25,10 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
25
25
  Classifier: Topic :: Utilities
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.8
28
- Requires-Dist: robotcode-analyze==1.3.0-dev.2
29
- Requires-Dist: robotcode-jsonrpc2==1.3.0-dev.2
30
- Requires-Dist: robotcode-robot==1.3.0-dev.2
31
- Requires-Dist: robotcode==1.3.0-dev.2
28
+ Requires-Dist: robotcode-analyze==1.3.0-dev.4
29
+ Requires-Dist: robotcode-jsonrpc2==1.3.0-dev.4
30
+ Requires-Dist: robotcode-robot==1.3.0-dev.4
31
+ Requires-Dist: robotcode==1.3.0-dev.4
32
32
  Requires-Dist: robotframework>=4.1.0
33
33
  Description-Content-Type: text/markdown
34
34
 
@@ -27,10 +27,10 @@ classifiers = [
27
27
  ]
28
28
  dependencies = [
29
29
  "robotframework>=4.1.0",
30
- "robotcode-jsonrpc2==1.3.0-dev.2",
31
- "robotcode-robot==1.3.0-dev.2",
32
- "robotcode-analyze==1.3.0-dev.2",
33
- "robotcode==1.3.0-dev.2",
30
+ "robotcode-jsonrpc2==1.3.0-dev.4",
31
+ "robotcode-robot==1.3.0-dev.4",
32
+ "robotcode-analyze==1.3.0-dev.4",
33
+ "robotcode==1.3.0-dev.4",
34
34
  ]
35
35
  dynamic = ["version"]
36
36
 
@@ -0,0 +1 @@
1
+ __version__ = "1.3.0-dev.4"
@@ -33,6 +33,9 @@ class RoboCopConfig(ConfigBase):
33
33
  enabled: bool = True
34
34
  include: List[str] = field(default_factory=list)
35
35
  exclude: List[str] = field(default_factory=list)
36
+ ignore_git_dir: bool = False
37
+ ignore_file_config: bool = False
38
+ config_file: Optional[str] = None
36
39
  configurations: List[str] = field(default_factory=list)
37
40
 
38
41
 
@@ -1,6 +1,5 @@
1
1
  import io
2
2
  import os
3
- import re
4
3
  from concurrent.futures import CancelledError
5
4
  from typing import TYPE_CHECKING, Any, List, Optional, cast
6
5
 
@@ -14,26 +13,17 @@ from robotcode.core.lsp.types import (
14
13
  )
15
14
  from robotcode.core.text_document import TextDocument
16
15
  from robotcode.core.utils.logging import LoggingDescriptor
17
- from robotcode.core.utils.version import create_version_from_str
18
- from robotcode.robot.diagnostics.model_helper import ModelHelper
19
16
  from robotcode.robot.utils import get_robot_version
20
17
 
21
- from ..configuration import RoboTidyConfig
18
+ from ..configuration import RoboCopConfig, RoboTidyConfig
22
19
  from .protocol_part import RobotLanguageServerProtocolPart
20
+ from .robocop_tidy_mixin import RoboCopTidyMixin
23
21
 
24
22
  if TYPE_CHECKING:
25
23
  from ..protocol import RobotLanguageServerProtocol
26
24
 
27
25
 
28
- def robotidy_installed() -> bool:
29
- try:
30
- __import__("robotidy")
31
- except ImportError:
32
- return False
33
- return True
34
-
35
-
36
- class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
26
+ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
37
27
  _logger = LoggingDescriptor()
38
28
 
39
29
  def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
@@ -41,7 +31,7 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
41
31
 
42
32
  parent.formatting.format.add(self.format)
43
33
 
44
- if robotidy_installed():
34
+ if self.robotidy_installed or (self.robocop_installed and self.robocop_version >= (6, 0)):
45
35
  parent.formatting.format_range.add(self.format_range)
46
36
 
47
37
  self.space_count = 4
@@ -49,14 +39,22 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
49
39
  self.line_separator = os.linesep
50
40
  self.short_test_name_length = 18
51
41
  self.setting_and_variable_name_length = 14
42
+ self.is_robocop_notification_shown = False
52
43
 
53
- def get_config(self, document: TextDocument) -> RoboTidyConfig:
44
+ def get_tidy_config(self, document: TextDocument) -> RoboTidyConfig:
54
45
  folder = self.parent.workspace.get_workspace_folder(document.uri)
55
46
  if folder is None:
56
47
  return RoboTidyConfig()
57
48
 
58
49
  return self.parent.workspace.get_configuration(RoboTidyConfig, folder.uri)
59
50
 
51
+ def get_robocop_config(self, document: TextDocument) -> RoboCopConfig:
52
+ folder = self.parent.workspace.get_workspace_folder(document.uri)
53
+ if folder is None:
54
+ return RoboCopConfig()
55
+
56
+ return self.parent.workspace.get_configuration(RoboCopConfig, folder.uri)
57
+
60
58
  @language_id("robotframework")
61
59
  @_logger.call
62
60
  def format(
@@ -66,23 +64,33 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
66
64
  options: FormattingOptions,
67
65
  **further_options: Any,
68
66
  ) -> Optional[List[TextEdit]]:
69
- config = self.get_config(document)
67
+ if (get_robot_version() >= (5, 0)) and self.robocop_installed and self.robocop_version >= (6, 0):
68
+ if not self.is_robocop_notification_shown and self.robotidy_installed:
69
+ self.parent.window.show_message(
70
+ "`robotframework-robocop >= 6.0` is installed and will be used for formatting.\n\n"
71
+ "`robotframework-tidy` is also detected in the workspace, but its use is redundant.\n"
72
+ "Robocop fully supports all formatting tasks and provides a more comprehensive solution.\n\n"
73
+ "Note: The use of `robotframework-tidy` is deprecated and should be avoided in favor of Robocop.",
74
+ MessageType.INFO,
75
+ )
76
+ self.is_robocop_notification_shown = True
70
77
 
71
- if (config.enabled or get_robot_version() >= (5, 0)) and robotidy_installed():
72
- return self.format_robot_tidy(document, options, config=config, **further_options)
78
+ return self.format_robocop(document, options, **further_options)
79
+
80
+ tidy_config = self.get_tidy_config(document)
81
+ if (tidy_config.enabled or get_robot_version() >= (5, 0)) and self.robotidy_installed:
82
+ return self.format_robot_tidy(document, options, config=tidy_config, **further_options)
73
83
 
74
84
  if get_robot_version() < (5, 0):
75
85
  return self.format_internal(document, options, **further_options)
76
86
 
77
87
  self.parent.window.show_message(
78
- "RobotFramework formatter is not available, please install 'robotframework-tidy'.",
88
+ "RobotFramework formatter is not available, please install 'robotframework-robocop'.",
79
89
  MessageType.ERROR,
80
90
  )
81
91
 
82
92
  return None
83
93
 
84
- RE_LINEBREAKS = re.compile(r"\r\n|\r|\n")
85
-
86
94
  def format_robot_tidy(
87
95
  self,
88
96
  document: TextDocument,
@@ -91,28 +99,24 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
91
99
  config: Optional[RoboTidyConfig] = None,
92
100
  **further_options: Any,
93
101
  ) -> Optional[List[TextEdit]]:
94
- from robotidy.version import __version__
95
-
96
102
  try:
97
103
  if config is None:
98
- config = self.get_config(document)
99
-
100
- robotidy_version = create_version_from_str(__version__)
104
+ config = self.get_tidy_config(document)
101
105
 
102
106
  model = self.parent.documents_cache.get_model(document, False)
103
107
 
104
- if robotidy_version >= (3, 0):
108
+ if self.robotidy_version >= (3, 0):
105
109
  from robotidy.api import get_robotidy
106
110
  from robotidy.disablers import RegisterDisablers
107
111
 
108
- if robotidy_version >= (4, 2):
112
+ if self.robotidy_version >= (4, 2):
109
113
  robot_tidy = get_robotidy(
110
114
  document.uri.to_path(),
111
115
  None,
112
116
  ignore_git_dir=config.ignore_git_dir,
113
117
  config=config.config,
114
118
  )
115
- elif robotidy_version >= (4, 1):
119
+ elif self.robotidy_version >= (4, 1):
116
120
  robot_tidy = get_robotidy(
117
121
  document.uri.to_path(),
118
122
  None,
@@ -131,14 +135,14 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
131
135
  )
132
136
  disabler_finder.visit(model)
133
137
 
134
- if robotidy_version >= (4, 11):
138
+ if self.robotidy_version >= (4, 11):
135
139
  if disabler_finder.is_disabled_in_file():
136
140
  return None
137
141
  else:
138
142
  if disabler_finder.file_disabled:
139
143
  return None
140
144
 
141
- if robotidy_version >= (4, 0):
145
+ if self.robotidy_version >= (4, 0):
142
146
  _, _, new, _ = robot_tidy.transform_until_stable(model, disabler_finder)
143
147
  else:
144
148
  _, _, new = robot_tidy.transform(model, disabler_finder.disablers)
@@ -152,7 +156,7 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
152
156
  robot_tidy.formatting_config.start_line = range.start.line + 1
153
157
  robot_tidy.formatting_config.end_line = range.end.line + 1
154
158
 
155
- if robotidy_version >= (2, 2):
159
+ if self.robotidy_version >= (2, 2):
156
160
  from robotidy.disablers import RegisterDisablers
157
161
 
158
162
  disabler_finder = RegisterDisablers(
@@ -186,6 +190,50 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
186
190
  self.parent.window.show_message(f"Executing `robotidy` failed: {e}", MessageType.ERROR)
187
191
  return None
188
192
 
193
+ def format_robocop(
194
+ self,
195
+ document: TextDocument,
196
+ options: FormattingOptions,
197
+ range: Optional[Range] = None,
198
+ **further_options: Any,
199
+ ) -> Optional[List[TextEdit]]:
200
+ from robocop.config import ConfigManager
201
+ from robocop.formatter.runner import RobocopFormatter
202
+
203
+ robocop_config = self.get_robocop_config(document)
204
+
205
+ config_manager = ConfigManager(
206
+ [document.uri.to_path()],
207
+ config=robocop_config.config_file,
208
+ ignore_git_dir=robocop_config.ignore_git_dir,
209
+ ignore_file_config=robocop_config.ignore_file_config,
210
+ )
211
+
212
+ config = config_manager.get_config_for_source_file(document.uri.to_path())
213
+
214
+ if range is not None:
215
+ config.formatter.start_line = range.start.line + 1
216
+ config.formatter.end_line = range.end.line + 1
217
+
218
+ runner = RobocopFormatter(config_manager)
219
+ runner.config = config
220
+
221
+ model = self.parent.documents_cache.get_model(document, False)
222
+ _, _, new, _ = runner.format_until_stable(model)
223
+
224
+ if new.text == document.text():
225
+ return None
226
+
227
+ return [
228
+ TextEdit(
229
+ range=Range(
230
+ start=Position(line=0, character=0),
231
+ end=Position(line=len(document.get_lines()), character=0),
232
+ ),
233
+ new_text=new.text,
234
+ )
235
+ ]
236
+
189
237
  def format_internal(
190
238
  self,
191
239
  document: TextDocument,
@@ -233,8 +281,8 @@ class RobotFormattingProtocolPart(RobotLanguageServerProtocolPart, ModelHelper):
233
281
  options: FormattingOptions,
234
282
  **further_options: Any,
235
283
  ) -> Optional[List[TextEdit]]:
236
- config = self.get_config(document)
237
- if config.enabled and robotidy_installed():
284
+ config = self.get_tidy_config(document)
285
+ if (config.enabled and self.robotidy_installed) or (self.robocop_installed and self.robocop_version >= (6, 0)):
238
286
  return self.format_robot_tidy(document, options, range=range, config=config, **further_options)
239
287
 
240
288
  return None
@@ -2,6 +2,7 @@ from dataclasses import dataclass
2
2
  from typing import TYPE_CHECKING, Any, List, Optional
3
3
 
4
4
  from robotcode.core.lsp.types import TextDocumentIdentifier
5
+ from robotcode.core.uri import Uri
5
6
  from robotcode.core.utils.dataclasses import CamelSnakeMixin
6
7
  from robotcode.core.utils.logging import LoggingDescriptor
7
8
  from robotcode.jsonrpc2.protocol import rpc_method
@@ -16,6 +17,26 @@ if TYPE_CHECKING:
16
17
  @dataclass(repr=False)
17
18
  class GetDocumentImportsParams(CamelSnakeMixin):
18
19
  text_document: TextDocumentIdentifier
20
+ no_documentation: Optional[bool] = None
21
+
22
+
23
+ @dataclass(repr=False)
24
+ class GetDocumentKeywordsParams(CamelSnakeMixin):
25
+ text_document: TextDocumentIdentifier
26
+ no_documentation: Optional[bool] = None
27
+
28
+
29
+ @dataclass(repr=False)
30
+ class GetLibraryDocumentationParams(CamelSnakeMixin):
31
+ workspace_folder_uri: str
32
+ library_name: str
33
+
34
+
35
+ @dataclass(repr=False)
36
+ class GetKeywordDocumentationParams(CamelSnakeMixin):
37
+ workspace_folder_uri: str
38
+ library_name: str
39
+ keyword_name: str
19
40
 
20
41
 
21
42
  @dataclass(repr=False)
@@ -26,6 +47,14 @@ class Keyword(CamelSnakeMixin):
26
47
  documentation: Optional[str] = None
27
48
 
28
49
 
50
+ @dataclass(repr=False)
51
+ class LibraryDocumentation(CamelSnakeMixin):
52
+ name: str
53
+ documentation: Optional[str] = None
54
+ keywords: Optional[List[Keyword]] = None
55
+ initializers: Optional[List[Keyword]] = None
56
+
57
+
29
58
  @dataclass(repr=False)
30
59
  class DocumentImport(CamelSnakeMixin):
31
60
  name: str
@@ -54,6 +83,7 @@ class RobotKeywordsTreeViewPart(RobotLanguageServerProtocolPart, ModelHelper):
54
83
  def _get_document_imports(
55
84
  self,
56
85
  text_document: TextDocumentIdentifier,
86
+ no_documentation: Optional[bool] = None,
57
87
  *args: Any,
58
88
  **kwargs: Any,
59
89
  ) -> Optional[List[DocumentImport]]:
@@ -72,16 +102,18 @@ class RobotKeywordsTreeViewPart(RobotLanguageServerProtocolPart, ModelHelper):
72
102
  alias=v.alias,
73
103
  id=str(hash(v)),
74
104
  type="library",
75
- documentation=v.library_doc.to_markdown(add_signature=False),
105
+ documentation=v.library_doc.to_markdown(add_signature=False) if not no_documentation else None,
76
106
  keywords=[
77
107
  Keyword(
78
108
  l.name,
79
109
  str(hash(l)),
80
110
  l.parameter_signature(),
81
- l.to_markdown(add_signature=False),
111
+ l.to_markdown(add_signature=False) if not no_documentation else None,
82
112
  )
83
113
  for l in v.library_doc.keywords.values()
84
- ],
114
+ ]
115
+ if not no_documentation
116
+ else None,
85
117
  )
86
118
  )
87
119
  for _k, v in namespace.get_resources().items():
@@ -91,21 +123,29 @@ class RobotKeywordsTreeViewPart(RobotLanguageServerProtocolPart, ModelHelper):
91
123
  alias=None,
92
124
  id=str(hash(v)),
93
125
  type="resource",
94
- documentation=v.library_doc.to_markdown(add_signature=False),
126
+ documentation=v.library_doc.to_markdown(add_signature=False) if not no_documentation else None,
95
127
  keywords=[
96
- Keyword(l.name, str(hash(l)), l.parameter_signature(), l.to_markdown(add_signature=False))
128
+ Keyword(
129
+ l.name,
130
+ str(hash(l)),
131
+ l.parameter_signature(),
132
+ l.to_markdown(add_signature=False) if not no_documentation else None,
133
+ )
97
134
  for l in v.library_doc.keywords.values()
98
- ],
135
+ ]
136
+ if not no_documentation
137
+ else None,
99
138
  )
100
139
  )
101
140
 
102
141
  return result
103
142
 
104
- @rpc_method(name="robot/keywordsview/getDocumentKeywords", param_type=GetDocumentImportsParams, threaded=True)
143
+ @rpc_method(name="robot/keywordsview/getDocumentKeywords", param_type=GetDocumentKeywordsParams, threaded=True)
105
144
  @_logger.call
106
145
  def _get_document_keywords(
107
146
  self,
108
147
  text_document: TextDocumentIdentifier,
148
+ no_documentation: Optional[bool] = None,
109
149
  *args: Any,
110
150
  **kwargs: Any,
111
151
  ) -> Optional[List[Keyword]]:
@@ -116,7 +156,12 @@ class RobotKeywordsTreeViewPart(RobotLanguageServerProtocolPart, ModelHelper):
116
156
  namespace = self.parent.documents_cache.get_namespace(document)
117
157
 
118
158
  return [
119
- Keyword(l.name, str(hash(l)), l.parameter_signature(), l.to_markdown(add_signature=False))
159
+ Keyword(
160
+ l.name,
161
+ str(hash(l)),
162
+ l.parameter_signature(),
163
+ l.to_markdown(add_signature=False) if not no_documentation else None,
164
+ )
120
165
  for l in namespace.get_library_doc().keywords.values()
121
166
  ]
122
167
 
@@ -165,3 +210,72 @@ class RobotKeywordsTreeViewPart(RobotLanguageServerProtocolPart, ModelHelper):
165
210
  )
166
211
 
167
212
  return None
213
+
214
+ @rpc_method(
215
+ name="robot/keywordsview/getLibraryDocumentation", param_type=GetLibraryDocumentationParams, threaded=True
216
+ )
217
+ @_logger.call
218
+ def _get_library_documentation(
219
+ self,
220
+ workspace_folder_uri: str,
221
+ library_name: str,
222
+ *args: Any,
223
+ **kwargs: Any,
224
+ ) -> Optional[LibraryDocumentation]:
225
+ imports_manager = self.parent.documents_cache.get_imports_manager_for_uri(Uri(workspace_folder_uri))
226
+
227
+ libdoc = imports_manager.get_libdoc_for_library_import(library_name, (), ".")
228
+ if libdoc.errors:
229
+ raise ValueError(f"Errors while loading library documentation: {libdoc.errors}")
230
+
231
+ return LibraryDocumentation(
232
+ name=libdoc.name,
233
+ documentation=libdoc.to_markdown(),
234
+ keywords=[
235
+ Keyword(
236
+ l.name,
237
+ str(hash(l)),
238
+ l.parameter_signature(),
239
+ l.to_markdown(),
240
+ )
241
+ for l in libdoc.keywords.values()
242
+ ],
243
+ initializers=[
244
+ Keyword(
245
+ s.name,
246
+ str(hash(s)),
247
+ s.parameter_signature(),
248
+ s.to_markdown(),
249
+ )
250
+ for s in libdoc.inits.values()
251
+ ],
252
+ )
253
+
254
+ @rpc_method(
255
+ name="robot/keywordsview/getKeywordDocumentation", param_type=GetKeywordDocumentationParams, threaded=True
256
+ )
257
+ @_logger.call
258
+ def _get_keyword_documentation(
259
+ self,
260
+ workspace_folder_uri: str,
261
+ library_name: str,
262
+ keyword_name: str,
263
+ *args: Any,
264
+ **kwargs: Any,
265
+ ) -> Optional[Keyword]:
266
+ imports_manager = self.parent.documents_cache.get_imports_manager_for_uri(Uri(workspace_folder_uri))
267
+
268
+ libdoc = imports_manager.get_libdoc_for_library_import(library_name, (), ".")
269
+ if libdoc.errors:
270
+ raise ValueError(f"Errors while loading library documentation: {libdoc.errors}")
271
+
272
+ kw = libdoc.keywords.get(keyword_name, None)
273
+ if kw is None:
274
+ raise ValueError(f"Keyword '{keyword_name}' not found in library '{library_name}'.")
275
+
276
+ return Keyword(
277
+ name=kw.name,
278
+ id=str(hash(kw)),
279
+ signature=kw.parameter_signature(),
280
+ documentation=kw.to_markdown(),
281
+ )
@@ -1,3 +1,4 @@
1
+ import sys
1
2
  from dataclasses import dataclass
2
3
  from typing import TYPE_CHECKING, Any, Optional
3
4
 
@@ -7,9 +8,9 @@ from robotcode.core.utils.dataclasses import CamelSnakeMixin
7
8
  from robotcode.core.utils.logging import LoggingDescriptor
8
9
  from robotcode.jsonrpc2.protocol import rpc_method
9
10
 
10
- from .formatting import robotidy_installed
11
+ from ...__version__ import __version__ as robotcode_version
11
12
  from .protocol_part import RobotLanguageServerProtocolPart
12
- from .robocop_diagnostics import robocop_installed
13
+ from .robocop_tidy_mixin import RoboCopTidyMixin
13
14
 
14
15
  if TYPE_CHECKING:
15
16
  from ..protocol import RobotLanguageServerProtocol
@@ -20,9 +21,12 @@ class ProjectInfo(CamelSnakeMixin):
20
21
  robot_version_string: str
21
22
  robocop_version_string: Optional[str]
22
23
  tidy_version_string: Optional[str] = None
24
+ python_version_string: Optional[str] = None
25
+ python_executable: Optional[str] = None
26
+ robot_code_version_string: Optional[str] = None
23
27
 
24
28
 
25
- class ProjectInfoPart(RobotLanguageServerProtocolPart):
29
+ class ProjectInfoPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
26
30
  _logger = LoggingDescriptor()
27
31
 
28
32
  def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
@@ -36,27 +40,18 @@ class ProjectInfoPart(RobotLanguageServerProtocolPart):
36
40
  **kwargs: Any,
37
41
  ) -> ProjectInfo:
38
42
  robocop_version_string = None
39
- if robocop_installed():
40
- try:
41
- from robocop.version import __version__
42
-
43
- robocop_version_string = __version__
44
- except ImportError:
45
- try:
46
- from robocop import __version__
47
-
48
- robocop_version_string = __version__
49
- except ImportError:
50
- pass
43
+ if self.robocop_installed:
44
+ robocop_version_string = self.robocop_version_str
51
45
 
52
46
  tidy_version_string = None
53
- if robotidy_installed():
54
- from robotidy.version import __version__
55
-
56
- tidy_version_string = __version__
47
+ if self.robotidy_installed:
48
+ tidy_version_string = self.robotidy_version_str
57
49
 
58
50
  return ProjectInfo(
59
51
  robot_version_string=get_version(),
60
52
  robocop_version_string=robocop_version_string,
61
53
  tidy_version_string=tidy_version_string,
54
+ python_version_string=sys.version,
55
+ python_executable=sys.executable,
56
+ robot_code_version_string=robotcode_version,
62
57
  )
@@ -17,20 +17,13 @@ from robotcode.core.workspace import WorkspaceFolder
17
17
  from ...common.parts.diagnostics import DiagnosticsCollectType, DiagnosticsResult
18
18
  from ..configuration import RoboCopConfig
19
19
  from .protocol_part import RobotLanguageServerProtocolPart
20
+ from .robocop_tidy_mixin import RoboCopTidyMixin
20
21
 
21
22
  if TYPE_CHECKING:
22
23
  from ..protocol import RobotLanguageServerProtocol
23
24
 
24
25
 
25
- def robocop_installed() -> bool:
26
- try:
27
- __import__("robocop")
28
- except ImportError:
29
- return False
30
- return True
31
-
32
-
33
- class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart):
26
+ class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
34
27
  _logger = LoggingDescriptor()
35
28
 
36
29
  def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
@@ -38,7 +31,7 @@ class RobotRoboCopDiagnosticsProtocolPart(RobotLanguageServerProtocolPart):
38
31
 
39
32
  self.source_name = "robocop"
40
33
 
41
- if robocop_installed():
34
+ if self.robocop_installed and self.robocop_version < (6, 0):
42
35
  parent.diagnostics.collect.add(self.collect_diagnostics)
43
36
 
44
37
  def get_config(self, document: TextDocument) -> Optional[RoboCopConfig]:
@@ -0,0 +1,49 @@
1
+ import functools
2
+
3
+ from robotcode.core.utils.version import Version, create_version_from_str
4
+
5
+
6
+ class RoboCopTidyMixin:
7
+ """
8
+ Mixin class for handling Robocop tidy operations.
9
+ """
10
+
11
+ @functools.cached_property
12
+ def robotidy_installed(self) -> bool:
13
+ try:
14
+ __import__("robotidy")
15
+ except ImportError:
16
+ return False
17
+ return True
18
+
19
+ @functools.cached_property
20
+ def robotidy_version(self) -> Version:
21
+ from robotidy.version import __version__
22
+
23
+ return create_version_from_str(__version__)
24
+
25
+ @functools.cached_property
26
+ def robotidy_version_str(self) -> str:
27
+ from robotidy.version import __version__
28
+
29
+ return str(__version__)
30
+
31
+ @functools.cached_property
32
+ def robocop_installed(self) -> bool:
33
+ try:
34
+ __import__("robocop")
35
+ except ImportError:
36
+ return False
37
+ return True
38
+
39
+ @functools.cached_property
40
+ def robocop_version(self) -> Version:
41
+ from robocop import __version__
42
+
43
+ return create_version_from_str(__version__)
44
+
45
+ @functools.cached_property
46
+ def robocop_version_str(self) -> str:
47
+ from robocop import __version__
48
+
49
+ return str(__version__)
@@ -471,7 +471,9 @@ class RobotSemanticTokenProtocolPart(RobotLanguageServerProtocolPart):
471
471
  sem_mod.add(RobotSemTokenModifiers.BUILTIN)
472
472
 
473
473
  if kw_doc is not None and kw_doc.is_embedded and kw_doc.matcher.embedded_arguments:
474
- if get_robot_version() >= (6, 0):
474
+ if get_robot_version() >= (7, 3):
475
+ m = kw_doc.matcher.embedded_arguments.name.fullmatch(kw)
476
+ elif get_robot_version() >= (6, 0):
475
477
  m = kw_doc.matcher.embedded_arguments.match(kw)
476
478
  else:
477
479
  m = kw_doc.matcher.embedded_arguments.name.match(kw)
@@ -1 +0,0 @@
1
- __version__ = "1.3.0-dev.2"