Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ repos:
types: [python]
stages: [pre-commit]
verbose: true
pass_filenames: false

- id: ruff_format
name: ruff_format
Expand All @@ -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
Expand All @@ -33,6 +27,7 @@ repos:
types: [python]
stages: [pre-commit]
verbose: true
pass_filenames: false

- id: pylint
name: pylint
Expand All @@ -41,6 +36,7 @@ repos:
types: [python]
stages: [pre-commit]
verbose: true
pass_filenames: false

- id: commitlint
name: commitlint
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -312,7 +313,6 @@ class IProjectInfoExtractor {
+ get_all_files_filter_by_file_type(file_types: set[str]) Iterable[str]
}
class IFileInfoExtractor {
<<interface>>
Declares all commands that are directly connected to the file.
Expand Down
4 changes: 2 additions & 2 deletions autoload/coderunner.vim
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down
2 changes: 1 addition & 1 deletion python_coderunner/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .src.coderunner import TCodeRunner
from .src.coderunner_builder import TVimCodeRunnerBuilder
from .src.coderunner_builder import TVimCodeRunnerFactory
16 changes: 8 additions & 8 deletions python_coderunner/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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"
4 changes: 2 additions & 2 deletions python_coderunner/src/coderunner_builder/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .interface import ICodeRunnerBuilder
from .vim_coderunner_builder import TVimCodeRunnerBuilder
from .interface import ICodeRunnerFactory
from .vim_coderunner_builder import TVimCodeRunnerFactory
4 changes: 2 additions & 2 deletions python_coderunner/src/coderunner_builder/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
24 changes: 12 additions & 12 deletions python_coderunner/src/coderunner_builder/vim_coderunner_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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
)
)
Expand All @@ -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,
Expand All @@ -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(
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down
1 change: 1 addition & 0 deletions python_coderunner/src/file_info_extractor/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .base import TBaseFileInfoExtractor
from .interface import IFileInfoExtractor
from .vim_file_info_extractor import TVimFileInfoExtractor
48 changes: 48 additions & 0 deletions python_coderunner/src/file_info_extractor/base.py
Original file line number Diff line number Diff line change
@@ -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
38 changes: 14 additions & 24 deletions python_coderunner/src/file_info_extractor/interface.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
from abc import ABC, abstractmethod
from typing import Optional

Expand All @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 1 addition & 5 deletions python_coderunner/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.