diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 53bc9a3..eef36eb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,7 @@ repos: types: [python] stages: [pre-commit] verbose: true + pass_filenames: false - id: ruff_format name: ruff_format @@ -17,14 +18,7 @@ repos: types: [python] stages: [pre-commit] verbose: true - - - id: isort - name: isort - entry: bash -c "cd python_coderunner && isort ." - language: system - types: [python] - stages: [pre-commit] - verbose: true + pass_filenames: false - id: mypy name: mypy @@ -33,6 +27,7 @@ repos: types: [python] stages: [pre-commit] verbose: true + pass_filenames: false - id: pylint name: pylint @@ -41,6 +36,7 @@ repos: types: [python] stages: [pre-commit] verbose: true + pass_filenames: false - id: commitlint name: commitlint diff --git a/README.md b/README.md index bd6f19b..86d1b1e 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ TInterpolatorCommandBuilder ..|> ICommandBuilder : implements TInterpolatorCommandBuilder "1" o--> "1" IProjectInfoExtractor : aggregates TInterpolatorCommandBuilder "1" o--> "1" IFileInfoExtractor : aggregates IProjectInfoExtractor "1" o--> "1" IFileInfoExtractor : aggregates +TBaseFileInfoExtractor ..|> IFileInfoExtractor : implements class TCodeRunner { @@ -312,7 +313,6 @@ class IProjectInfoExtractor { + get_all_files_filter_by_file_type(file_types: set[str]) Iterable[str] } - class IFileInfoExtractor { <> Declares all commands that are directly connected to the file. diff --git a/autoload/coderunner.vim b/autoload/coderunner.vim index 3a1e8c7..c5ba1f4 100644 --- a/autoload/coderunner.vim +++ b/autoload/coderunner.vim @@ -63,10 +63,10 @@ def coderunner_on_exit(): sys.path.insert(0, os.path.dirname(vim.eval("s:script_folder_path"))) try: - from python_coderunner import TCodeRunner, TVimCodeRunnerBuilder + from python_coderunner import TCodeRunner, TVimCodeRunnerFactory - coderunner: TCodeRunner = TVimCodeRunnerBuilder().build() + coderunner: TCodeRunner = TVimCodeRunnerFactory().create() except Exception as error: vim.command("redraw | echohl ErrorMsg") for line in traceback.format_exc().splitlines(): diff --git a/python_coderunner/__init__.py b/python_coderunner/__init__.py index 850925b..a912b12 100644 --- a/python_coderunner/__init__.py +++ b/python_coderunner/__init__.py @@ -1,2 +1,2 @@ from .src.coderunner import TCodeRunner -from .src.coderunner_builder import TVimCodeRunnerBuilder +from .src.coderunner_builder import TVimCodeRunnerFactory diff --git a/python_coderunner/pyproject.toml b/python_coderunner/pyproject.toml index 019e2f8..8f17204 100644 --- a/python_coderunner/pyproject.toml +++ b/python_coderunner/pyproject.toml @@ -3,13 +3,12 @@ name = "vim-code-runner" authors = [ {name = "Zahar Chernenko", email = "zaharchernenko35@gmail.com"}, ] -version = "1.0.0" +version = "1.0.1" requires-python = ">=3.10" [dependency-groups] dev = [ "commitlint>=1.3.0", - "isort>=4.3.21", "mypy>=0.910", "pre-commit>=1.21.0", "pylint>=2.6.2", @@ -19,7 +18,6 @@ dev = [ "ruff>=0.12.0", ] pre-commit = [ - "isort>=4.3.21", "mypy>=0.910", "pre-commit>=1.21.0", "pylint>=2.6.2", @@ -35,9 +33,6 @@ test = [ pythonpath = ["."] # to run without python -m, otherwise there will be no src in the path testpaths = ["tests"] -[tool.isort] -profile = "black" - [tool.mypy] check_untyped_defs = true explicit_package_bases = true # without this, mypy complains about duplicate packages. @@ -52,6 +47,10 @@ disable_error_code = [ line-length = 120 [tool.ruff.format] quote-style = "double" +[tool.ruff.lint] +extend-select = ["I", "F401"] +extend-unsafe-fixes = ["F401"] +ignore = ["W292"] [tool.ruff.lint.per-file-ignores] "__init__.py" = [ "F401", # ignore unused imports @@ -91,10 +90,11 @@ argument-naming-style = "snake_case" attr-naming-style = "snake_case" class-attribute-naming-style = "any" class-const-naming-style = "UPPER_CASE" -class-rgx="^(((I|T|E|Supports)[A-Z][a-zA-Z0-9]*)|[A-Z][a-zA-Z0-9]*Error)$" +class-rgx="^(((I|T|E)[A-Z][a-zA-Z0-9]*)|([A-Z][a-zA-Z0-9]*(Error|Protocol)))$" const-naming-style= "any" function-naming-style = "snake_case" -typevar="^T[A-Z][a-zA-Z0-9]*$" +typealias-rgx="^(((I|T|E)[A-Z][a-zA-Z0-9]*)|([A-Z][a-zA-Z0-9]*(Error|Protocol)))$" +typevar-rgx="^[A-Z][a-zA-Z0-9]*Type$" variable-naming-style = "snake_case" module-naming-style = "snake_case" inlinevar-naming-style = "any" diff --git a/python_coderunner/src/coderunner_builder/__init__.py b/python_coderunner/src/coderunner_builder/__init__.py index 8f26846..b00d7ea 100644 --- a/python_coderunner/src/coderunner_builder/__init__.py +++ b/python_coderunner/src/coderunner_builder/__init__.py @@ -1,2 +1,2 @@ -from .interface import ICodeRunnerBuilder -from .vim_coderunner_builder import TVimCodeRunnerBuilder +from .interface import ICodeRunnerFactory +from .vim_coderunner_builder import TVimCodeRunnerFactory diff --git a/python_coderunner/src/coderunner_builder/interface.py b/python_coderunner/src/coderunner_builder/interface.py index 23a8b62..7003cc3 100644 --- a/python_coderunner/src/coderunner_builder/interface.py +++ b/python_coderunner/src/coderunner_builder/interface.py @@ -4,7 +4,7 @@ from ..coderunner import TCodeRunner -class ICodeRunnerBuilder(ABC): +class ICodeRunnerFactory(ABC): @abstractmethod - def build(self) -> Optional[TCodeRunner]: + def create(self) -> Optional[TCodeRunner]: raise NotImplementedError diff --git a/python_coderunner/src/coderunner_builder/vim_coderunner_builder.py b/python_coderunner/src/coderunner_builder/vim_coderunner_builder.py index 75d05f9..f74a100 100644 --- a/python_coderunner/src/coderunner_builder/vim_coderunner_builder.py +++ b/python_coderunner/src/coderunner_builder/vim_coderunner_builder.py @@ -24,11 +24,11 @@ from ..file_info_extractor import TVimFileInfoExtractor from ..message_printer import TVimMessagePrinter from ..project_info_extractor import TVimProjectInfoExtractor -from .interface import ICodeRunnerBuilder +from .interface import ICodeRunnerFactory -class TVimCodeRunnerBuilder(ICodeRunnerBuilder): - def build(self) -> Optional[TCodeRunner]: +class TVimCodeRunnerFactory(ICodeRunnerFactory): + def create(self) -> Optional[TCodeRunner]: config_manager: TVimConfigManager = TVimConfigManager(TVimConfigGetter(), TBasicConfigValidator()) message_printer: TVimMessagePrinter = TVimMessagePrinter() @@ -42,7 +42,7 @@ def build(self) -> Optional[TCodeRunner]: ) command_dispatcher_strategy_selector: TBasicCommandDispatcherStrategySelector = ( - self._build_command_dispatcher_strategy_selector( + self._create_command_dispatcher_strategy_selector( config_manager, file_info_extractor, project_info_extractor ) ) @@ -61,7 +61,7 @@ def build(self) -> Optional[TCodeRunner]: return None - def _build_command_dispatcher_strategy_selector( + def _create_command_dispatcher_strategy_selector( self, config_manager: TVimConfigManager, file_info_extractor: TVimFileInfoExtractor, @@ -71,17 +71,17 @@ def _build_command_dispatcher_strategy_selector( file_info_extractor ) file_ext_command_builders_dispatcher: TFileExtCommandBuildersDispatcher = ( - self._build_file_ext_command_builders_dispatcher( + self._create_file_ext_command_builders_dispatcher( config_manager, file_info_extractor, project_info_extractor ) ) file_type_command_builders_dispatcher: TFileTypeCommandBuildersDispatcher = ( - self._build_file_type_command_builders_dispatcher( + self._create_file_type_command_builders_dispatcher( config_manager, file_info_extractor, project_info_extractor ) ) - glob_command_builders_dispatcher: TGlobCommandBuildersDispatcher = self._build_glob_command_builders_dispatcher( - config_manager, file_info_extractor, project_info_extractor + glob_command_builders_dispatcher: TGlobCommandBuildersDispatcher = ( + self._create_glob_command_builders_dispatcher(config_manager, file_info_extractor, project_info_extractor) ) return TBasicCommandDispatcherStrategySelector( @@ -92,7 +92,7 @@ def _build_command_dispatcher_strategy_selector( config_manager=config_manager, ) - def _build_file_ext_command_builders_dispatcher( + def _create_file_ext_command_builders_dispatcher( self, config_manager: TVimConfigManager, file_info_extractor: TVimFileInfoExtractor, @@ -106,7 +106,7 @@ def _build_file_ext_command_builders_dispatcher( file_info_extractor, ) - def _build_file_type_command_builders_dispatcher( + def _create_file_type_command_builders_dispatcher( self, config_manager: TVimConfigManager, file_info_extractor: TVimFileInfoExtractor, @@ -120,7 +120,7 @@ def _build_file_type_command_builders_dispatcher( file_info_extractor, ) - def _build_glob_command_builders_dispatcher( + def _create_glob_command_builders_dispatcher( self, config_manager: TVimConfigManager, file_info_extractor: TVimFileInfoExtractor, diff --git a/python_coderunner/src/file_info_extractor/__init__.py b/python_coderunner/src/file_info_extractor/__init__.py index a2f955a..03aaf5d 100644 --- a/python_coderunner/src/file_info_extractor/__init__.py +++ b/python_coderunner/src/file_info_extractor/__init__.py @@ -1,2 +1,3 @@ +from .base import TBaseFileInfoExtractor from .interface import IFileInfoExtractor from .vim_file_info_extractor import TVimFileInfoExtractor diff --git a/python_coderunner/src/file_info_extractor/base.py b/python_coderunner/src/file_info_extractor/base.py new file mode 100644 index 0000000..10dfeea --- /dev/null +++ b/python_coderunner/src/file_info_extractor/base.py @@ -0,0 +1,48 @@ +import os +from abc import abstractmethod +from typing import Optional + +from .interface import IFileInfoExtractor + + +class TBaseFileInfoExtractor(IFileInfoExtractor): + def get_dir(self, file_path_abs: str) -> str: + dir_path: str = os.path.dirname(file_path_abs) + if dir_path and not dir_path.endswith(os.sep): + dir_path += os.sep + return dir_path + + def get_dir_without_trailing_slash(self, file_path_abs: str) -> str: + return os.path.dirname(file_path_abs).rstrip(os.sep) + + def get_drive_letter(self, file_path_abs: str) -> str: + drive, _ = os.path.splitdrive(file_path_abs) + return drive + + def get_file_ext(self, file_path_abs: str) -> str: + base: str = self.get_file_name(file_path_abs) + dot_pos: int = base.rfind(".") + return base[dot_pos : len(base)].lower() if dot_pos != -1 else "" + + def get_file_name(self, file_path_abs: str) -> str: + return os.path.basename(file_path_abs) + + def get_file_name_without_ext(self, file_path_abs: str) -> str: + base: str = self.get_file_name(file_path_abs) + dot_pos: int = base.rfind(".") + return base[:dot_pos] if dot_pos != -1 else base + + @abstractmethod + def get_file_type(self, file_path_abs: str) -> Optional[str]: + raise NotImplementedError + + def get_shebang(self, file_path_abs: str) -> Optional[str]: + if not os.path.exists(file_path_abs): + return None + + try: + with open(file_path_abs, "r", encoding="utf-8") as fin: + first_line: str = fin.readline().strip() + return first_line[2:] if first_line.startswith("#!") and not first_line.startswith("#![") else None + except (IOError, UnicodeDecodeError): + return None diff --git a/python_coderunner/src/file_info_extractor/interface.py b/python_coderunner/src/file_info_extractor/interface.py index 6b380bd..8b3c9c1 100644 --- a/python_coderunner/src/file_info_extractor/interface.py +++ b/python_coderunner/src/file_info_extractor/interface.py @@ -1,4 +1,3 @@ -import os from abc import ABC, abstractmethod from typing import Optional @@ -9,43 +8,34 @@ class IFileInfoExtractor(ABC): Accepts only file absolute path. """ + @abstractmethod def get_dir(self, file_path_abs: str) -> str: - dir_path: str = os.path.dirname(file_path_abs) - if dir_path and not dir_path.endswith(os.sep): - dir_path += os.sep - return dir_path + raise NotImplementedError + @abstractmethod def get_dir_without_trailing_slash(self, file_path_abs: str) -> str: - return os.path.dirname(file_path_abs).rstrip(os.sep) + raise NotImplementedError + @abstractmethod def get_drive_letter(self, file_path_abs: str) -> str: - drive, _ = os.path.splitdrive(file_path_abs) - return drive + raise NotImplementedError + @abstractmethod def get_file_ext(self, file_path_abs: str) -> str: - base: str = self.get_file_name(file_path_abs) - dot_pos: int = base.rfind(".") - return base[dot_pos : len(base)].lower() if dot_pos != -1 else "" + raise NotImplementedError + @abstractmethod def get_file_name(self, file_path_abs: str) -> str: - return os.path.basename(file_path_abs) + raise NotImplementedError + @abstractmethod def get_file_name_without_ext(self, file_path_abs: str) -> str: - base: str = self.get_file_name(file_path_abs) - dot_pos: int = base.rfind(".") - return base[:dot_pos] if dot_pos != -1 else base + raise NotImplementedError @abstractmethod def get_file_type(self, file_path_abs: str) -> Optional[str]: raise NotImplementedError + @abstractmethod def get_shebang(self, file_path_abs: str) -> Optional[str]: - if not os.path.exists(file_path_abs): - return None - - try: - with open(file_path_abs, "r", encoding="utf-8") as fin: - first_line: str = fin.readline().strip() - return first_line[2:] if first_line.startswith("#!") and not first_line.startswith("#![") else None - except (IOError, UnicodeDecodeError): - return None + raise NotImplementedError diff --git a/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py b/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py index 0701aed..4e6c5a2 100644 --- a/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py +++ b/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py @@ -2,10 +2,10 @@ import vim -from .interface import IFileInfoExtractor +from .base import TBaseFileInfoExtractor -class TVimFileInfoExtractor(IFileInfoExtractor): +class TVimFileInfoExtractor(TBaseFileInfoExtractor): def get_file_type(self, file_path_abs: str) -> Optional[str]: file_type: Optional[str] = vim.eval("&filetype") return None if not file_type else file_type diff --git a/python_coderunner/uv.lock b/python_coderunner/uv.lock index 597eb06..15e0f7a 100644 --- a/python_coderunner/uv.lock +++ b/python_coderunner/uv.lock @@ -408,13 +408,12 @@ wheels = [ [[package]] name = "vim-code-runner" -version = "1.0.0" +version = "1.0.1" source = { virtual = "." } [package.dev-dependencies] dev = [ { name = "commitlint" }, - { name = "isort" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pylint" }, @@ -424,7 +423,6 @@ dev = [ { name = "ruff" }, ] pre-commit = [ - { name = "isort" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pylint" }, @@ -441,7 +439,6 @@ test = [ [package.metadata.requires-dev] dev = [ { name = "commitlint", specifier = ">=1.3.0" }, - { name = "isort", specifier = ">=4.3.21" }, { name = "mypy", specifier = ">=0.910" }, { name = "pre-commit", specifier = ">=1.21.0" }, { name = "pylint", specifier = ">=2.6.2" }, @@ -451,7 +448,6 @@ dev = [ { name = "ruff", specifier = ">=0.12.0" }, ] pre-commit = [ - { name = "isort", specifier = ">=4.3.21" }, { name = "mypy", specifier = ">=0.910" }, { name = "pre-commit", specifier = ">=1.21.0" }, { name = "pylint", specifier = ">=2.6.2" },