diff --git a/README.md b/README.md index 62e706a..376ef7c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Salve v1.1.1

+

Salve v1.2.0

# Installation diff --git a/docs/source/conf.py b/docs/source/conf.py index cefc25b..80eef33 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,7 +14,7 @@ project = "Salve" copyright = "2024, Moosems" author = "Moosems" -release = "v1.1.1" +release = "v1.2.0" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/docs/source/example-usage.rst b/docs/source/example-usage.rst index d023a9d..ecbea90 100644 --- a/docs/source/example-usage.rst +++ b/docs/source/example-usage.rst @@ -37,7 +37,7 @@ Now that you have ``Salve`` installed, let's try running a simple example that p sleep(1) # If there is no response we give None instead of raising an Exception - output: Response | None = context.get_response(HIGHLIGHT) + output: Response | None = context.get_response(HIGHLIGHT) # type: ignore print(output) # Finally, if you are done with the IPC before the rest of the program, you can diff --git a/docs/source/examples/highlight_logging_example.rst b/docs/source/examples/highlight_logging_example.rst deleted file mode 100644 index 3fe764e..0000000 --- a/docs/source/examples/highlight_logging_example.rst +++ /dev/null @@ -1,43 +0,0 @@ -========================= -Highlight Logging Example -========================= - -.. code-block:: python - - from logging import INFO, Logger, basicConfig, getLogger - from time import sleep - - from salve import HIGHLIGHT, IPC, Response - - basicConfig( - level=INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" - ) - logger: Logger = getLogger("Main") - - - def main(): - context = IPC() - - context.update_file( - "test", - open(__file__, "r+").read(), - ) - - context.request( - HIGHLIGHT, file="test", language="python", text_range=(1, 30) - ) - - sleep(1) - output: Response | None = context.get_response(HIGHLIGHT) - if output is None: - logger.info("Output is None") - - logger.info(f"Output: {output}") - - context.kill_IPC() - - - if __name__ == "__main__": - main() - -See the file example file `here `_. \ No newline at end of file diff --git a/examples/example_usage.py b/examples/example_usage.py index 519d4b3..40be757 100644 --- a/examples/example_usage.py +++ b/examples/example_usage.py @@ -38,7 +38,7 @@ def main(): # Check output # context.cancel_request("autocomplete") # Uncommenting this line will cause the request to always be cancelled - output: Response | None = context.get_response(AUTOCOMPLETE) + output: Response | None = context.get_response(AUTOCOMPLETE) # type: ignore if not output: continue diff --git a/examples/gui_client.py b/examples/gui_client.py index a4e68df..185348d 100644 --- a/examples/gui_client.py +++ b/examples/gui_client.py @@ -28,7 +28,7 @@ def create_request(_) -> None: label.pack() def loop() -> None: - output: Response | None = context.get_response(AUTOCOMPLETE) + output: Response | None = context.get_response(AUTOCOMPLETE) # type: ignore data: list[str] = [""] if output is not None: data: list[str] = output["result"] # type: ignore diff --git a/examples/highlight_logging_example.py b/examples/highlight_logging_example.py deleted file mode 100644 index 93e60e7..0000000 --- a/examples/highlight_logging_example.py +++ /dev/null @@ -1,35 +0,0 @@ -from logging import INFO, Logger, basicConfig, getLogger -from time import sleep - -from salve import HIGHLIGHT, IPC, Response - -basicConfig( - level=INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" -) -logger: Logger = getLogger("Main") - - -def main(): - context = IPC() - - context.update_file( - "test", - open(__file__, "r+").read(), - ) - - context.request( - HIGHLIGHT, file="test", language="python", text_range=(1, 30) - ) - - sleep(1) - output: Response | None = context.get_response(HIGHLIGHT) - if output is None: - logger.info("Output is None") - - logger.info(f"Output: {output}") - - context.kill_IPC() - - -if __name__ == "__main__": - main() diff --git a/examples/simple_autocomplete_example.py b/examples/simple_autocomplete_example.py index 555b206..7b30f98 100644 --- a/examples/simple_autocomplete_example.py +++ b/examples/simple_autocomplete_example.py @@ -20,7 +20,7 @@ def main(): sleep(1) - output: Response | None = context.get_response(AUTOCOMPLETE) + output: Response | None = context.get_response(AUTOCOMPLETE) # type: ignore print(output) context.kill_IPC() diff --git a/examples/simple_definitions_example.py b/examples/simple_definitions_example.py index faca790..9ac2e39 100644 --- a/examples/simple_definitions_example.py +++ b/examples/simple_definitions_example.py @@ -22,7 +22,7 @@ def main(): ) sleep(1) - output: Response | None = context.get_response(DEFINITION) + output: Response | None = context.get_response(DEFINITION) # type: ignore print(output) context.kill_IPC() diff --git a/examples/simple_editorconfig_example.py b/examples/simple_editorconfig_example.py index 961cf60..76cf48c 100644 --- a/examples/simple_editorconfig_example.py +++ b/examples/simple_editorconfig_example.py @@ -9,7 +9,7 @@ def main(): context.request(EDITORCONFIG, file_path=__file__) sleep(1) - output: Response | None = context.get_response(EDITORCONFIG) + output: Response | None = context.get_response(EDITORCONFIG) # type: ignore print(output) context.kill_IPC() diff --git a/examples/simple_highlight_example.py b/examples/simple_highlight_example.py index 4993745..07a003e 100644 --- a/examples/simple_highlight_example.py +++ b/examples/simple_highlight_example.py @@ -16,7 +16,7 @@ def main(): ) sleep(1) - output: Response | None = context.get_response(HIGHLIGHT) + output: Response | None = context.get_response(HIGHLIGHT) # type: ignore print(output) context.kill_IPC() diff --git a/examples/simple_links_and_hidden_chars_example.py b/examples/simple_links_and_hidden_chars_example.py index 5bb9e13..b4925f5 100644 --- a/examples/simple_links_and_hidden_chars_example.py +++ b/examples/simple_links_and_hidden_chars_example.py @@ -14,7 +14,7 @@ def main(): context.request(LINKS_AND_CHARS, file="test", text_range=(1, 30)) sleep(1) - output: Response | None = context.get_response(LINKS_AND_CHARS) + output: Response | None = context.get_response(LINKS_AND_CHARS) # type: ignore print(output) context.kill_IPC() diff --git a/examples/simple_replacements_example.py b/examples/simple_replacements_example.py index 1c76adc..94a8399 100644 --- a/examples/simple_replacements_example.py +++ b/examples/simple_replacements_example.py @@ -19,7 +19,7 @@ def main(): ) sleep(1) - output: Response | None = context.get_response(REPLACEMENTS) + output: Response | None = context.get_response(REPLACEMENTS) # type: ignore print(output) context.kill_IPC() diff --git a/salve/ipc.py b/salve/ipc.py index df81385..4dfb56c 100644 --- a/salve/ipc.py +++ b/salve/ipc.py @@ -57,20 +57,14 @@ def request( # type: ignore definition_starters: list[tuple[str, str]] = [("", "before")], ) -> None: """Sends the main_server a request of type command with given kwargs - external API""" - self.logger.debug("Beginning request") if command not in COMMANDS: - self.logger.exception( - f"Command {command} not in builtin commands. Those are {COMMANDS}!" - ) raise Exception( f"Command {command} not in builtin commands. Those are {COMMANDS}!" ) if file not in self.files and command != EDITORCONFIG: - self.logger.exception(f"File {file} does not exist in system!") raise Exception(f"File {file} does not exist in system!") - self.logger.debug("Sending info to create_message()") request: dict = { "command": command, "expected_keywords": expected_keywords, @@ -80,6 +74,8 @@ def request( # type: ignore "file_path": file_path, "definition_starters": definition_starters, } + if file: - request.update({"file": file}) - super().request(request) + request["file"] = file + + super().request(**request) diff --git a/salve/server_functions/highlight/docstring_highlight.py b/salve/server_functions/highlight/docstring_highlight.py index 0e945fb..b5a865b 100644 --- a/salve/server_functions/highlight/docstring_highlight.py +++ b/salve/server_functions/highlight/docstring_highlight.py @@ -97,7 +97,9 @@ def proper_docstring_tokens(lexer: RegexLexer, full_text: str) -> list[Token]: continue start_pos: tuple[int, int] = (1, 0) - simple_token_type: str = get_new_token_type(str(token_type)) + simple_token_type: str | None = get_new_token_type(str(token_type)) + if not simple_token_type: + continue while match: span: tuple[int, int] = match.span() diff --git a/salve/server_functions/highlight/highlight.py b/salve/server_functions/highlight/highlight.py index a000958..32be257 100644 --- a/salve/server_functions/highlight/highlight.py +++ b/salve/server_functions/highlight/highlight.py @@ -37,7 +37,7 @@ def get_highlights( for line in split_text: og_tokens: _LexReturnTokens = list(lex(line, lexer)) for token in og_tokens: - new_type: str = get_new_token_type(str(token[0])) + new_type: str | None = get_new_token_type(str(token[0])) token_str: str = token[1] token_len: int = len(token_str) @@ -45,7 +45,7 @@ def get_highlights( # Lexer adds the newline back as its own token continue - if not token_str.strip() or new_type == "Text": + if not token_str.strip() or not new_type: # If the token is empty or is plain Text we simply skip it because that's ultimately useless info start_index = (start_index[0], start_index[1] + token_len) continue diff --git a/salve/server_functions/highlight/misc.py b/salve/server_functions/highlight/misc.py index a5f9ad3..af8a74f 100644 --- a/salve/server_functions/highlight/misc.py +++ b/salve/server_functions/highlight/misc.py @@ -2,20 +2,20 @@ from token_tools import GENERIC_TOKENS -default_tokens: list[str] = [ - "Token.Text.Whitespace", - "Token.Text", - "Token.Error", - "Token.Keyword", - "Token.Name", - "Token.Literal.String", - "Token.Literal.Number", - "Token.Literal", - "Token.Operator", - "Token.Punctuation", - "Token.Comment", - "Token.Generic", -] +default_tokens: dict[str, str | None] = { + "Token.Text.Whitespace": None, + "Token.Text": None, + "Token.Error": GENERIC_TOKENS[1], + "Token.Keyword": GENERIC_TOKENS[2], + "Token.Name": GENERIC_TOKENS[0], + "Token.Literal.String": GENERIC_TOKENS[4], + "Token.Literal.Number": GENERIC_TOKENS[5], + "Token.Literal": GENERIC_TOKENS[6], + "Token.Operator": GENERIC_TOKENS[7], + "Token.Punctuation": GENERIC_TOKENS[8], + "Token.Comment": GENERIC_TOKENS[9], + "Token.Generic": None, +} def normal_text_range( @@ -34,11 +34,10 @@ def normal_text_range( @cache -def get_new_token_type(old_token: str) -> str: +def get_new_token_type(token: str) -> str | None: """Turns pygments token types into a generic predefined Token""" - new_type: str = GENERIC_TOKENS[0] - for index, token in enumerate(default_tokens): - if old_token.startswith(token): - new_type = GENERIC_TOKENS[index] - break - return new_type + for old_token, new_token in default_tokens.items(): + if token.startswith(old_token): + return new_token + + return None diff --git a/salve/server_functions/links_and_hidden_chars.py b/salve/server_functions/links_and_hidden_chars.py index e1f609a..055652d 100644 --- a/salve/server_functions/links_and_hidden_chars.py +++ b/salve/server_functions/links_and_hidden_chars.py @@ -12,6 +12,7 @@ def get_urls(whole_text: str, text_range: tuple[int, int]) -> list[Token]: while True: if start_pos[0] > text_range[1]: break + line: str = lines[start_pos[0] - text_range[0]][start_pos[1] :] match_start: Match[str] | None = url_regex.search(line) if match_start is None: diff --git a/salve/wrappers.py b/salve/wrappers.py index dc6ccc0..c75a30f 100644 --- a/salve/wrappers.py +++ b/salve/wrappers.py @@ -60,7 +60,5 @@ def get_special_tokens_request_wrapper( ) -> list[Token]: return get_special_tokens( request["file"], # type: ignore - normal_text_range(request["file"], request["text_range"])[ # type: ignore - 1 - ], + normal_text_range(request["file"], request["text_range"])[1], # type: ignore ) diff --git a/setup.py b/setup.py index 4bb9591..392673f 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name="salve", - version="1.1.1", + version="1.2.0", description="Salve is an IPC library that can be used by code editors to easily get autocompletions, replacements, editorconfig suggestions, definitions, and syntax highlighting.", author="Moosems", author_email="moosems.j@gmail.com", diff --git a/tests/test_ipc.py b/tests/test_ipc.py index 2082b80..d2ac55d 100644 --- a/tests/test_ipc.py +++ b/tests/test_ipc.py @@ -1,5 +1,4 @@ from pathlib import Path -from sys import platform from time import sleep from salve import ( @@ -20,6 +19,7 @@ def test_IPC(): context.update_file( "test", open(Path("tests/testing_file1.py"), "r+").read() ) + context.update_file("hidden_test", "https://www.google.com (​)") context.request( AUTOCOMPLETE, @@ -49,11 +49,11 @@ def test_IPC(): (r":?.*=.*", "before"), ], ) - context.request(LINKS_AND_CHARS, file="test", text_range=(1, 18)) + context.request(LINKS_AND_CHARS, file="hidden_test", text_range=(1, 18)) sleep(1) # Check output - autocomplete_output: Response | None = context.get_response(AUTOCOMPLETE) + autocomplete_output: Response | None = context.get_response(AUTOCOMPLETE) # type: ignore if autocomplete_output is None: raise AssertionError("Autocomplete output is None") autocomplete_output["id"] = 0 @@ -61,11 +61,11 @@ def test_IPC(): "id": 0, "type": "response", "cancelled": False, - "command": AUTOCOMPLETE, - "result": ["test", "this"], + "command": "autocomplete", + "result": ["test", "this", "type"], } - replacements_output: Response | None = context.get_response(REPLACEMENTS) + replacements_output: Response | None = context.get_response(REPLACEMENTS) # type: ignore if replacements_output is None: raise AssertionError("Replacements output is None") replacements_output["id"] = 0 @@ -77,97 +77,58 @@ def test_IPC(): "result": ["this"], } - highlight_output: Response | None = context.get_response(HIGHLIGHT) + highlight_output: Response | None = context.get_response(HIGHLIGHT) # type: ignore if highlight_output is None: raise AssertionError("Highlight output is None") highlight_output["id"] = 0 - expected_output: Response = { "id": 0, "type": "response", "cancelled": False, - "command": HIGHLIGHT, + "command": "highlight", "result": [ ((1, 0), 4, "Keyword"), - ((1, 5), 4, "Name"), + ((1, 5), 4, "Identifier"), ((1, 10), 6, "Keyword"), - ((1, 17), 1, "Name"), + ((1, 17), 1, "Identifier"), ((1, 20), 12, "Comment"), - ((3, 0), 3, "Name"), - ((3, 4), 1, "Operator"), - ((3, 6), 3, "Name"), - ((3, 11), 7, "Comment"), - ((5, 0), 5, "Name"), - ((5, 5), 1, "Punctuation"), - ((5, 6), 3, "String"), - ((5, 9), 1, "Punctuation"), - ((5, 12), 16, "Comment"), - ((8, 0), 5, "Keyword"), - ((8, 6), 3, "Name"), - ((8, 9), 1, "Punctuation"), - ((8, 10), 3, "Name"), - ((8, 13), 2, "Punctuation"), - ((9, 4), 3, "String"), - ((10, 4), 4, "String"), - ((11, 4), 3, "String"), - ((13, 4), 3, "Keyword"), - ((13, 8), 8, "Name"), - ((13, 16), 1, "Punctuation"), - ((13, 17), 4, "Name"), - ((13, 21), 2, "Punctuation"), - ((14, 8), 4, "Keyword"), - ((17, 0), 3, "Name"), - ((17, 3), 2, "Punctuation"), - ((18, 0), 24, "Comment"), + ((3, 0), 3, "Identifier"), + ((3, 3), 1, "Punctuation"), + ((3, 5), 4, "Identifier"), + ((3, 10), 1, "Operator"), + ((3, 12), 3, "Identifier"), + ((4, 0), 1, "Punctuation"), + ((4, 1), 3, "Identifier"), + ((4, 5), 2, "Operator"), + ((4, 8), 4, "Identifier"), + ((4, 12), 1, "Punctuation"), + ((4, 15), 12, "Comment"), + ((6, 0), 5, "Identifier"), + ((6, 5), 2, "Punctuation"), + ((9, 0), 5, "Keyword"), + ((9, 6), 3, "Identifier"), + ((9, 9), 1, "Punctuation"), + ((9, 10), 3, "Identifier"), + ((9, 13), 2, "Punctuation"), + ((10, 4), 3, "String"), + ((11, 4), 4, "String"), + ((12, 4), 3, "String"), + ((14, 4), 3, "Keyword"), + ((14, 8), 8, "Identifier"), + ((14, 16), 1, "Punctuation"), + ((14, 17), 4, "Identifier"), + ((14, 21), 2, "Punctuation"), + ((15, 8), 4, "Keyword"), + ((18, 0), 3, "Identifier"), + ((18, 3), 2, "Punctuation"), ], } - # Deal with Windows weirdness - if platform == "win32": - expected_output = { - "id": 0, - "type": "response", - "cancelled": False, - "command": HIGHLIGHT, - "result": [ - ((1, 0), 4, "Keyword"), - ((1, 5), 4, "Name"), - ((1, 10), 6, "Keyword"), - ((1, 17), 1, "Name"), - ((1, 20), 12, "Comment"), - ((3, 0), 3, "Name"), - ((3, 4), 1, "Operator"), - ((3, 6), 3, "Name"), - ((3, 11), 7, "Comment"), - ((5, 0), 5, "Name"), - ((5, 5), 1, "Punctuation"), - ((5, 6), 5, "String"), - ((5, 11), 1, "Punctuation"), - ((5, 14), 16, "Comment"), - ((8, 0), 5, "Keyword"), - ((8, 6), 3, "Name"), - ((8, 9), 1, "Punctuation"), - ((8, 10), 3, "Name"), - ((8, 13), 2, "Punctuation"), - ((9, 4), 3, "String"), - ((10, 4), 4, "String"), - ((11, 4), 3, "String"), - ((13, 4), 3, "Keyword"), - ((13, 8), 8, "Name"), - ((13, 16), 1, "Punctuation"), - ((13, 17), 4, "Name"), - ((13, 21), 2, "Punctuation"), - ((14, 8), 4, "Keyword"), - ((17, 0), 3, "Name"), - ((17, 3), 2, "Punctuation"), - ((18, 0), 24, "Comment"), - ], - } assert highlight_output == expected_output links_and_hidden_chars_result: Response | None = context.get_response( LINKS_AND_CHARS - ) + ) # type: ignore if links_and_hidden_chars_result is None: raise AssertionError("links_and_hidden_chars_result output is None") links_and_hidden_chars_result["id"] = 0 @@ -176,16 +137,8 @@ def test_IPC(): "type": "response", "cancelled": False, "command": LINKS_AND_CHARS, - "result": [((18, 2), 22, "Link"), ((5, 7), 1, "Hidden_Char")], + "result": [((1, 0), 22, "Link"), ((1, 25), 1, "Hidden_Char")], } - if platform == "win32": - expected_output = { - "id": 0, - "type": "response", - "cancelled": False, - "command": LINKS_AND_CHARS, - "result": [((18, 2), 22, "Link")], - } assert links_and_hidden_chars_result == expected_output context.update_file( diff --git a/tests/testing_file1.py b/tests/testing_file1.py index 7da5ef0..86a9c2b 100644 --- a/tests/testing_file1.py +++ b/tests/testing_file1.py @@ -1,8 +1,9 @@ from this import s # noqa: F401 -Bar = int # alias +Bar: type = int +(xyz := test) # noqa: F821 -print("​") # No width space +print() class Foo(Bar):