From b68e8ad2690c356d7e62362f16f27fd1c349fa80 Mon Sep 17 00:00:00 2001 From: ZaharChernenko Date: Mon, 23 Jun 2025 21:22:40 +0300 Subject: [PATCH 1/6] changed: README.md part 1 --- LICENCE => LICENSE | 0 README.md | 70 +++++++++++----------------------------------- 2 files changed, 16 insertions(+), 54 deletions(-) rename LICENCE => LICENSE (100%) diff --git a/LICENCE b/LICENSE similarity index 100% rename from LICENCE rename to LICENSE diff --git a/README.md b/README.md index b336a54..6de6c5f 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,34 @@ -# Vim Code Runner - -- [Vim Code Runner](#vim-code-runner) - - [Overview](#overview) +# Vim Code Runner - run your code the same way as with [vs code runner](https://github.com/formulahendry/vscode-code-runner) +- [Vim Code Runner - run your code the same way as with vs code runner](#vim-code-runner---run-your-code-the-same-way-as-with-vs-code-runner) - [Requirements](#requirements) - [Installation](#installation) - [Usage](#usage) - [Configuration](#configuration) - - [Supported Languages](#supported-languages) - - [Example Usage](#example-usage) - - [Extension Guide](#extension-guide) - -## Overview - -Vim Code Runner is a plugin that provides code execution capabilities within Vim for multiple programming languages. It allows you to run code directly from your editor with customizable behavior. ## Requirements - - Vim version 8.0+ with Python3 support. Check with: ```vim :echo has('python3') "should return 1 ``` +- To use `CodeRunnerRunByGlob` python version must be above 3.13. Check with: + ```vim + :py3 import sys;print(sys.version) + ``` ## Installation - Install the Vim plugin with your favorite plugin manager, e.g. vim-plug: ```vim Plug 'ZaharChernenko/vim-code-runner' ``` ## Usage - -1. **`coderunner#Load()`** - Initializes the plugin and checks for dependencies, it can also be used to update the configuration. - -2. **`coderunner#Run()`** - Executes the current file based on its filetype. - -3. **`coderunner#Clear()`** - Cleans up any execution artifacts. - -## Configuration - -- `g:coderunner_save_file_before_run`: If 1, saves the current file before execution (default 0) -- `g:coderunner_save_all_files_before_run`: If 1, saves all open files before execution (default 0) - -## Supported Languages - -The plugin currently supports: - -- Python3 -- C++ - -The language runners are defined in the `TRunnerContext.LANG_TO_RUNNER` dictionary. - -## Example Usage - -```vim -" Map F5 to run current file -nnoremap :call coderunner#Run() - -" Map F6 to clear execution artifacts -nnoremap :call coderunner#Clear() -``` - -## Extension Guide - -To add support for new languages: - -1. Create a new runner class implementing `runners.IRunner` or `runner.ICompilingRunner` -2. Add it to `TRunnerContext.LANG_TO_RUNNER` dictionary -3. Implement any necessary cleanup in the `clear` method \ No newline at end of file +1. `CodeRunnerRunByFileExt` - tries to execute the code if the extension of the current file matches the extension from g:coderunner_by_file_ext, the extension is a dot + the last part of the file name after the last dot. +2. `CodeRunnerRunByFileType` - tries to execute the code if the current file type is defined in the g:coderunner_by_file_type, to find out what type of open file run `:echo &filetype`. +3. `CodeRunnerRunByGlob` - tries to execute the code if the full path of the current file corresponds to some glob pattern in g:coderunner_by_glob, **it is important that this function works only with vim, which has version python3.13+.** +4. `CodeRunnerRun` - tries to execute the code using the fallback strategy defined in g:coderunner_runners_order. +5. `coderunner#Load()` - the function that loads the coderunner module also updates the variables: g:coderunner_by_file_ext, g:coderunner_by_file_type g:coderunner_by_glob. +6. `coderunner#RemoveCoderunnerTempfiles()` - a function that cleans up temporary files that were created due to run with selection, it clears only those files that were created in the current vim session. + +## Configuration +- `g:coderunner_save_all_files_before_run`: If 1, saves all open files before execution, note files are saved only if a runner is found. (default 0) +- `g:coderunner_save_file_before_run`: If 1, saves the current file before execution (default 0) \ No newline at end of file From 75d33ec04c11e864b4046eebbad7917b3464d676 Mon Sep 17 00:00:00 2001 From: ZaharChernenko <124883289+ZaharChernenko@users.noreply.github.com> Date: Mon, 23 Jun 2025 21:25:18 +0300 Subject: [PATCH 2/6] changed: README.md part 2 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6de6c5f..680e148 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Vim Code Runner - run your code the same way as with [vs code runner](https://github.com/formulahendry/vscode-code-runner) +https://github.com/user-attachments/assets/63109233-1e5d-4d54-b890-30eb07dab826 - [Vim Code Runner - run your code the same way as with vs code runner](#vim-code-runner---run-your-code-the-same-way-as-with-vs-code-runner) - [Requirements](#requirements) - [Installation](#installation) @@ -31,4 +32,4 @@ Plug 'ZaharChernenko/vim-code-runner' ## Configuration - `g:coderunner_save_all_files_before_run`: If 1, saves all open files before execution, note files are saved only if a runner is found. (default 0) -- `g:coderunner_save_file_before_run`: If 1, saves the current file before execution (default 0) \ No newline at end of file +- `g:coderunner_save_file_before_run`: If 1, saves the current file before execution (default 0) From e2c919fd01e4791243a79038359d32c3606a0a3f Mon Sep 17 00:00:00 2001 From: ZaharChernenko Date: Tue, 24 Jun 2025 19:36:31 +0300 Subject: [PATCH 3/6] changed: README.md part 3 --- .gitignore | 131 ++++++++++++++++-------------------------- README.md | 65 +++++++++++++++++---- plugin/coderunner.vim | 2 +- 3 files changed, 105 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index c2720fb..1159dd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,9 @@ +# Python # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class -# C extensions -*.so - # Distribution / packaging .Python build/ @@ -27,8 +25,6 @@ share/python-wheels/ MANIFEST # PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec @@ -55,20 +51,20 @@ cover/ *.mo *.pot -# Django stuff: +# Django *.log local_settings.py db.sqlite3 db.sqlite3-journal -# Flask stuff: +# Flask instance/ .webassets-cache -# Scrapy stuff: +# Scrapy .scrapy -# Sphinx documentation +# Sphinx docs/_build/ # PyBuilder @@ -82,41 +78,15 @@ target/ profile_default/ ipython_config.py -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide +# PDM (Python package manager) .pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ -# Celery stuff +# Celery celerybeat-schedule celerybeat.pid -# SageMath parsed files +# SageMath *.sage.py # Environments @@ -128,52 +98,70 @@ ENV/ env.bak/ venv.bak/ -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation +# MkDocs /site -# mypy +# Static type checkers .mypy_cache/ .dmypy.json dmypy.json - -# Pyre type checker .pyre/ - -# pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ +# C++ # Prerequisites *.d +# Precompiled Headers +*.gch +*.pch + +# Build directories +cmake-build-debug/ +out/ +x64/ + +# Fortran +*.mod +*.smod + +# Redis +*.rdb + +# Visual Studio +*.sln +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +.vs/ + +# Visual Studio Code +.vscode/ + +# JetBrains +.idea/ + +# Spyder +.spyderproject +.spyproject + +# Rope +.ropeproject + # Compiled Object files *.slo *.lo *.o *.obj -# Precompiled Headers -*.gch -*.pch - # Compiled Dynamic libraries *.so *.dylib *.dll -# Fortran module files -*.mod -*.smod - # Compiled Static libraries *.lai *.la @@ -185,26 +173,5 @@ cython_debug/ *.out *.app -# temp -.DS_Store -.vs - -#dirs -out -x64 -cmake-build-debug - -# Redis -*.rdb - -# Visual Studio -*.sln -*.vcxproj -*.vcxproj.filters -*.vcxproj.user - -# Visual Studio Code -.vscode - -# JetBrains -.idea/ +# macOS +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 680e148..db94417 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,28 @@ https://github.com/user-attachments/assets/63109233-1e5d-4d54-b890-30eb07dab826 - [Requirements](#requirements) - [Installation](#installation) - [Usage](#usage) + - [`CodeRunnerRunByFileExt`](#coderunnerrunbyfileext) + - [`CodeRunnerRunByFileType`](#coderunnerrunbyfiletype) + - [`CodeRunnerRunByGlob`](#coderunnerrunbyglob) + - [`CodeRunnerRun`](#coderunnerrun) + - [`coderunner#Load()`](#coderunnerload) + - [`coderunner#RemoveCoderunnerTempfiles()`](#coderunnerremovecoderunnertempfiles) - [Configuration](#configuration) + - [`g:coderunner_by_file_ext`](#gcoderunner_by_file_ext) + - [`g:coderunner_by_file_type`](#gcoderunner_by_file_type) + - [`g:coderunner_by_glob`](#gcoderunner_by_glob) + - [`g:coderunner_executor`](#gcoderunner_executor) + - [`g:coderunner_save_all_files_before_run` - if 1, saves all open files before execution, note files are saved only if a runner is found, default `0`.](#gcoderunner_save_all_files_before_run---if-1-saves-all-open-files-before-execution-note-files-are-saved-only-if-a-runner-is-found-default-0) + - [`g:coderunner_save_file_before_run` - if 1, saves the current file before execution, default `0`.](#gcoderunner_save_file_before_run---if-1-saves-the-current-file-before-execution-default-0) ## Requirements - Vim version 8.0+ with Python3 support. Check with: ```vim - :echo has('python3') "should return 1 + :echo has('python3') " should return 1 ``` - To use `CodeRunnerRunByGlob` python version must be above 3.13. Check with: ```vim - :py3 import sys;print(sys.version) + :py3 import sys;print(sys.version) " should return >= 3.13 ``` ## Installation @@ -23,13 +35,46 @@ Plug 'ZaharChernenko/vim-code-runner' ``` ## Usage -1. `CodeRunnerRunByFileExt` - tries to execute the code if the extension of the current file matches the extension from g:coderunner_by_file_ext, the extension is a dot + the last part of the file name after the last dot. -2. `CodeRunnerRunByFileType` - tries to execute the code if the current file type is defined in the g:coderunner_by_file_type, to find out what type of open file run `:echo &filetype`. -3. `CodeRunnerRunByGlob` - tries to execute the code if the full path of the current file corresponds to some glob pattern in g:coderunner_by_glob, **it is important that this function works only with vim, which has version python3.13+.** -4. `CodeRunnerRun` - tries to execute the code using the fallback strategy defined in g:coderunner_runners_order. -5. `coderunner#Load()` - the function that loads the coderunner module also updates the variables: g:coderunner_by_file_ext, g:coderunner_by_file_type g:coderunner_by_glob. -6. `coderunner#RemoveCoderunnerTempfiles()` - a function that cleans up temporary files that were created due to run with selection, it clears only those files that were created in the current vim session. +### `CodeRunnerRunByFileExt` +Tries to execute the code if the extension of the current file matches the extension from [`g:coderunner_by_file_ext`](#gcoderunner_by_file_ext), the extension is a dot + the last part of the file name after the last dot. +### `CodeRunnerRunByFileType` +Tries to execute the code if the current file type is defined in the [`g:coderunner_by_file_type`](#gcoderunner_by_file_type), to find out what type of open file run `:echo &filetype`. +### `CodeRunnerRunByGlob` +Tries to execute the code if the full path of the current file corresponds to some glob pattern in [`g:coderunner_by_glob`](#gcoderunner_by_glob), **it is important that this function works only with vim, which has version python3.13+.** +### `CodeRunnerRun` +Tries to execute the code using the fallback strategy defined in g:coderunner_runners_order. +### `coderunner#Load()` +The function that loads the coderunner module also updates the variables: g:coderunner_by_file_ext, g:coderunner_by_file_type g:coderunner_by_glob. +### `coderunner#RemoveCoderunnerTempfiles()` +The function that cleans up temporary files that were created due to run with selection, it clears only those files that were created in the current vim session. ## Configuration -- `g:coderunner_save_all_files_before_run`: If 1, saves all open files before execution, note files are saved only if a runner is found. (default 0) -- `g:coderunner_save_file_before_run`: If 1, saves the current file before execution (default 0) +### `g:coderunner_by_file_ext` +Hash table with mapping of file extensions to commands, default `{}`, example: +```vim +let g:coderunner_by_file_type = { + \ '.cpp': 'bash -c "cd \"$dir\" && g++ -o cpp_output -std=c++2a *.cpp && ./cpp_output"', + \ '.py': 'bash -c "cd \"$dir\" && python3 \"$fullFileName\""', +\ } +``` +### `g:coderunner_by_file_type` +Hash table with mapping of file types to commands, default `{}`, example: +```vim +let g:coderunner_by_file_type = { + \ 'cpp': 'bash -c "cd \"$dir\" && g++ -o cpp_output -std=c++2a *.cpp && ./cpp_output"', + \ 'python': 'bash -c "cd \"$dir\" && python3 \"$fullFileName\""', +\ } +``` +To find out what type of open file run `:echo &filetype`. +### `g:coderunner_by_glob` +Hash table with mapping glob patterns into commands, given that the hash table is unordered, coderunner sorts the patterns in reverse lexicographic order, trying to find the most accurate one first, default `{}`, example: +```vim +let g:coderunner_by_glob = { + \ '**/*.cpp': 'bash -c "cd \"$dir\" && g++ -o cpp_output -std=c++2a *.cpp && ./cpp_output"', + \ '**/*.py': 'bash -c "cd \"$dir\" && python3 \"$fullFileName\""', +\ } +``` +### `g:coderunner_executor` +Any vim command that can execute a string is suitable, default `ter`, default behaviour: +### `g:coderunner_save_all_files_before_run` - if 1, saves all open files before execution, note files are saved only if a runner is found, default `0`. +### `g:coderunner_save_file_before_run` - if 1, saves the current file before execution, default `0`. diff --git a/plugin/coderunner.vim b/plugin/coderunner.vim index a5de504..95ae44e 100644 --- a/plugin/coderunner.vim +++ b/plugin/coderunner.vim @@ -12,7 +12,7 @@ if exists('g:loaded_coderunner') finish elseif !has('python3') echohl ErrorMsg - echo 'Coderunner unavailable: unable to load python3.' + echom 'Coderunner unavailable: unable to load python3.' echohl None call s:restore_cpo() finish From acf425c8553d5ee22c3f1e1f9dd0efa78326f1f2 Mon Sep 17 00:00:00 2001 From: ZaharChernenko <124883289+ZaharChernenko@users.noreply.github.com> Date: Tue, 24 Jun 2025 19:49:50 +0300 Subject: [PATCH 4/6] changed: README.md part 4 --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index db94417..d97663a 100644 --- a/README.md +++ b/README.md @@ -76,5 +76,16 @@ let g:coderunner_by_glob = { ``` ### `g:coderunner_executor` Any vim command that can execute a string is suitable, default `ter`, default behaviour: + +https://github.com/user-attachments/assets/bea987a0-7269-4dc4-ae01-590a71d9dd5f + +It is important to note that a regular terminal does not execute commands related through logical operators, for example `&`, so you need to use `bash -c` with a string. + +But for example, if you have [floaterm](https://github.com/voldikss/vim-floaterm) plugin installed, you can set the following command: +```vim +let g:coderunner_executor = "FloatermNew --autoclose=0" +``` + +https://github.com/user-attachments/assets/374e11d4-efd8-42ae-bdce-92b5df0cdb39 ### `g:coderunner_save_all_files_before_run` - if 1, saves all open files before execution, note files are saved only if a runner is found, default `0`. ### `g:coderunner_save_file_before_run` - if 1, saves the current file before execution, default `0`. From 7934cda50536bfc486fff22923200fa7e6a087f3 Mon Sep 17 00:00:00 2001 From: ZaharChernenko Date: Tue, 24 Jun 2025 20:02:25 +0300 Subject: [PATCH 5/6] changed: README.md part 5 --- README.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d97663a..d636520 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,13 @@ https://github.com/user-attachments/assets/63109233-1e5d-4d54-b890-30eb07dab826 - [`g:coderunner_by_file_type`](#gcoderunner_by_file_type) - [`g:coderunner_by_glob`](#gcoderunner_by_glob) - [`g:coderunner_executor`](#gcoderunner_executor) - - [`g:coderunner_save_all_files_before_run` - if 1, saves all open files before execution, note files are saved only if a runner is found, default `0`.](#gcoderunner_save_all_files_before_run---if-1-saves-all-open-files-before-execution-note-files-are-saved-only-if-a-runner-is-found-default-0) - - [`g:coderunner_save_file_before_run` - if 1, saves the current file before execution, default `0`.](#gcoderunner_save_file_before_run---if-1-saves-the-current-file-before-execution-default-0) + - [`g:coderunner_ignore_selection`](#gcoderunner_ignore_selection) + - [`g:coderunner_remove_coderunner_tempfiles_on_exit`](#gcoderunner_remove_coderunner_tempfiles_on_exit) + - [`g:coderunner_respect_shebang`](#gcoderunner_respect_shebang) + - [`g:coderunner_runners_order`](#gcoderunner_runners_order) + - [`g:coderunner_save_all_files_before_run`](#gcoderunner_save_all_files_before_run) + - [`g:coderunner_save_file_before_run`](#gcoderunner_save_file_before_run) + - [`g:coderunner_tempfile_prefix`](#gcoderunner_tempfile_prefix) ## Requirements - Vim version 8.0+ with Python3 support. Check with: @@ -42,7 +47,7 @@ Tries to execute the code if the current file type is defined in the [`g:coderun ### `CodeRunnerRunByGlob` Tries to execute the code if the full path of the current file corresponds to some glob pattern in [`g:coderunner_by_glob`](#gcoderunner_by_glob), **it is important that this function works only with vim, which has version python3.13+.** ### `CodeRunnerRun` -Tries to execute the code using the fallback strategy defined in g:coderunner_runners_order. +Tries to execute the code using the fallback strategy defined in [`g:coderunner_runners_order`](#gcoderunner_runners_order). ### `coderunner#Load()` The function that loads the coderunner module also updates the variables: g:coderunner_by_file_ext, g:coderunner_by_file_type g:coderunner_by_glob. ### `coderunner#RemoveCoderunnerTempfiles()` @@ -52,7 +57,7 @@ The function that cleans up temporary files that were created due to run with se ### `g:coderunner_by_file_ext` Hash table with mapping of file extensions to commands, default `{}`, example: ```vim -let g:coderunner_by_file_type = { +let g:coderunner_by_file_ext = { \ '.cpp': 'bash -c "cd \"$dir\" && g++ -o cpp_output -std=c++2a *.cpp && ./cpp_output"', \ '.py': 'bash -c "cd \"$dir\" && python3 \"$fullFileName\""', \ } @@ -87,5 +92,17 @@ let g:coderunner_executor = "FloatermNew --autoclose=0" ``` https://github.com/user-attachments/assets/374e11d4-efd8-42ae-bdce-92b5df0cdb39 -### `g:coderunner_save_all_files_before_run` - if 1, saves all open files before execution, note files are saved only if a runner is found, default `0`. -### `g:coderunner_save_file_before_run` - if 1, saves the current file before execution, default `0`. +### `g:coderunner_ignore_selection` +If 1 ranges do not work, the command is executed for the entire file, default `0`. +### `g:coderunner_remove_coderunner_tempfiles_on_exit` +If 1, then when exiting the vim, it calls the [coderunner#RemoveCoderunnerTempfiles()](#coderunnerremovecoderunnertempfiles) command, default `0`. +### `g:coderunner_respect_shebang` +if 1, the shebang command is executed, even if there are matches in the hash tables, default `1`. +### `g:coderunner_runners_order` +Defines the order of searching for matches when executing the [CodeRunnerRun](#coderunnerrun) command, default `['by_glob', 'by_file_ext', 'by_file_type']`. +### `g:coderunner_save_all_files_before_run` +If 1, saves all open files before execution, note files are saved only if a runner is found, default `0`. +### `g:coderunner_save_file_before_run` +If 1, saves the current file before execution, default `0`. +### `g:coderunner_tempfile_prefix` +The prefix with which files will be saved in the directory of the executable file when executing commands with selection. \ No newline at end of file From 92f24131deed992efff8de748ec056921e24a2e1 Mon Sep 17 00:00:00 2001 From: ZaharChernenko Date: Tue, 24 Jun 2025 22:49:11 +0300 Subject: [PATCH 6/6] changed: README.md part 6 --- README.md | 229 +++++++++++++++++++++++++++++++++++++++++- plugin/coderunner.vim | 4 +- 2 files changed, 229 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d636520..7058507 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ https://github.com/user-attachments/assets/63109233-1e5d-4d54-b890-30eb07dab826 - [`g:coderunner_save_all_files_before_run`](#gcoderunner_save_all_files_before_run) - [`g:coderunner_save_file_before_run`](#gcoderunner_save_file_before_run) - [`g:coderunner_tempfile_prefix`](#gcoderunner_tempfile_prefix) + - [Interpolated variables](#interpolated-variables) + - [For developers](#for-developers) + - [Setup environment](#setup-environment) + - [Plugin architecture](#plugin-architecture) ## Requirements - Vim version 8.0+ with Python3 support. Check with: @@ -84,7 +88,7 @@ Any vim command that can execute a string is suitable, default `ter`, default be https://github.com/user-attachments/assets/bea987a0-7269-4dc4-ae01-590a71d9dd5f -It is important to note that a regular terminal does not execute commands related through logical operators, for example `&`, so you need to use `bash -c` with a string. +It is important to note that a regular terminal does not execute commands related through logical operators, for example `&&`, so you need to use `bash -c` with a string. But for example, if you have [floaterm](https://github.com/voldikss/vim-floaterm) plugin installed, you can set the following command: ```vim @@ -105,4 +109,225 @@ If 1, saves all open files before execution, note files are saved only if a runn ### `g:coderunner_save_file_before_run` If 1, saves the current file before execution, default `0`. ### `g:coderunner_tempfile_prefix` -The prefix with which files will be saved in the directory of the executable file when executing commands with selection. \ No newline at end of file +The prefix with which files will be saved in the directory of the executable file when executing commands with selection. + +## Interpolated variables +Some string sequences starting with $ will be replaced, here is a list of them: +- $workspaceRoot - `getcwd()` +- $fullFileName +- $fileNameWithoutExt +- $fileName +- $fileExt +- $driveLetter +- $dirWithoutTrailingSlash +- $dir + +Example of the work can be viewed in the [tests](https://github.com/ZaharChernenko/vim-code-runner/blob/main/python_coderunner/tests/unit/command_builder/test_interpolator_command_builder.py). + +## For developers +### Setup environment +```shell +cd python_coderunner +uv sync +pre-commit install +``` +### Plugin architecture +```mermaid +classDiagram +TCodeRunner "1" o--> "1" IConfigManager : aggregates +TCodeRunner "1" o--> "1" ICommandsExecutor : aggregates +TCodeRunner "1" o--> "1" IMessagePrinter : aggregates +TCodeRunner "1" o--> "1" TBasicEditorServiceForCodeRunner : aggregates +TCodeRunner "1" o--> "1" TBasicCommandDispatcherStrategySelector : aggregates +IConfigManager "1" o--> "1" IConfigGetter : aggregates +IConfigManager "1" o--> "1" TBasicConfigValidator : aggregates +TBasicEditorServiceForCodeRunner "1" o--> "1" IEditor : aggregates +TBasicEditorServiceForCodeRunner "1" o--> "1" IConfigManager : aggregates +ICommandsExecutor "1" o--> "1" IConfigManager : aggregates +TBasicCommandDispatcherStrategySelector "1" o--> "1" TShebangCommandBuildersDispatcher : aggregates +TBasicCommandDispatcherStrategySelector "1" o--> "1" TGlobCommandBuildersDispatcher : aggregates +TBasicCommandDispatcherStrategySelector "1" o--> "1" TFileExtCommandBuildersDispatcher : aggregates +TBasicCommandDispatcherStrategySelector "1" o--> "1" TFileTypeCommandBuildersDispatcher : aggregates +TBasicCommandDispatcherStrategySelector "1" o--> "1" IConfigManager : aggregates +TShebangCommandBuildersDispatcher ..|> ICommandBuildersDispatcher : implements +TShebangCommandBuildersDispatcher "1" o--> "1" IFileInfoExtractor : aggregates +TGlobCommandBuildersDispatcher ..|> ICommandBuildersDispatcher : implements +TFileExtCommandBuildersDispatcher ..|> ICommandBuildersDispatcher : implements +TFileExtCommandBuildersDispatcher "1" o--> "1" IFileInfoExtractor : aggregates +TFileTypeCommandBuildersDispatcher ..|> ICommandBuildersDispatcher : implements +TFileTypeCommandBuildersDispatcher "1" o--> "1" IFileInfoExtractor : aggregates +ICommandBuildersDispatcher ..> ICommandBuilder : returns +TInterpolatorCommandBuilder ..|> ICommandBuilder : implements +TInterpolatorCommandBuilder "1" o--> "1" IProjectInfoExtractor : aggregates +TInterpolatorCommandBuilder "1" o--> "1" IFileInfoExtractor : aggregates +IProjectInfoExtractor "1" o--> "1" IFileInfoExtractor : aggregates + + +class TCodeRunner { + # config_manager: IConfigManager + # editor_service: TBasicEditorServiceForCodeRunner + # command_dispatcher_strategy_selector: TBasicCommandDispatcherStrategySelector + # commands_executor: ICommandsExecutor + # message_printer: IMessagePrinter + + run() None + + run_by_glob() None + + run_by_file_ext() None + + run_by_file_type() None + + remove_coderunner_tempfiles() None + + on_exit() None +} + + + +class IConfigManager { + <> + + get_dispatchers_order() list[str] + + get_executor() str + + get_ignore_selection() bool + + get_respect_shebang() bool + + get_save_all_files() bool + + get_save_file() bool +} + + +class IConfigGetter { + <> + + get_dispatchers_order() Any + + get_executor() Any + + get_ignore_selection() Any + + get_respect_shebang() Any + + get_save_all_files() Any + + get_save_file() Any +} + + +class TBasicConfigValidator { + + validate_bool() bool + + validate_str() str + + validate_dispatcher() Dict[str, str] + + validate_dispatchers_order() List[EDispatchersTypes] +} + + +class TBasicEditorServiceForCodeRunner { + # editor: IEditor + # config_manager: IConfigManager + // creates context which will delete file if it's temporary + + get_file_for_run() Context[str] + // runs save_file or save_all_files if the command_builder is found, + // and vars in config are True + + prepare_for_run() None + + remove_coderunner_tempfiles() None +} + + +class IEditor { + <> + + get_current_file_name() str + + get_selected_text() Optional[str] + + save_all_files() None + + save_file() None +} + + +class ICommandsExecutor { + <> + Сlass for executing a string command only. + + execute(command: str) None +} + + +class IMessagePrinter { + + info(text: str) None + + error(text: str) None +} + + +class TBasicCommandDispatcherStrategySelector { + # config_manager: IConfigManager + # shebang_dispatcher: TShebangCommandBuildersDispatcher + # file_type_dispatcher: TFileExtCommandBuildersDispatcher + # file_ext_dispatcher: TFileTypeCommandBuildersDispatcher + # file_glob_dispatcher: ICommandBuildersDispatcher + + dispatch_by_file_type(file_path_abs: str) Optional[ICommandBuilder] + + dispatch_by_file_ext(file_path_abs: str) Optional[ICommandBuilder] + + dispatch_by_glob(file_path_abs: str) Optional[ICommandBuilder] + + dispatch_by_shebang(file_path_abs: str) Optional[TShebangCommandBuilder] + + dispatch(file_path_abs: str) Optional[ICommandBuilder] +} + + +class TShebangCommandBuildersDispatcher { + # file_info_extractor: IFileInfoExtractor + + dispatch(file_path_abs: str) Optional[TShebangCommandBuilder] +} + + +class TGlobCommandBuildersDispatcher { + # file_info_extractor: IFileInfoExtractor + + dispatch(file_path_abs: str) Optional[ICommandBuilder] +} + + +class TFileExtCommandBuildersDispatcher { + # file_info_extractor: IFileInfoExtractor + + dispatch(file_path_abs: str) Optional[ICommandBuilder] +} + + +class TFileTypeCommandBuildersDispatcher { + # file_info_extractor: IFileInfoExtractor + + dispatch(file_path_abs: str) Optional[ICommandBuilder] +} + + +class ICommandBuildersDispatcher { + <> + Dispatch is optional for fallback strategy + + dispatch(file_path_abs: str) Optional[ICommandBuilder] +} + + +class TInterpolatorCommandBuilder { + # template_string: str + # file_info_extractor: IFileInfoExtractor + + TInterpolatorCommandBuilder(template_string: str, file_info_extractor: IFileInfoExtractor) + + build(file_path_abs: str) str + # interpolate(file_path_abs: str) str +} + + +class ICommandBuilder { + <> + Build requires absolute file path, because file can be temporary, like + file which was generated by run selected. + + build(file_path_abs: str) str +} + + +class IProjectInfoExtractor { + <> + # file_info_extractor: IFileInfoExtractor + + get_workspace_root() str + if the workspace is large, then it may be worth doing the operation in another thread + or asynchronous, which, however, will not give an increase in speed, but perhaps + vim will not lag at this moment + + get_all_files_filter_by_exts(exts: set[str]) Iterable[str] + + 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. + Accepts only file absolute path. + + get_dir(file_path_abs: str) str + + get_dir_without_trailing_slash(file_path_abs: str) str + + get_file_name(file_path_abs: str) str + + get_file_name_without_ext(file_path_abs: str) str + + get_file_ext(file_path_abs: str) str + + get_file_type(file_path_abs: str) Optional[str] + + get_drive_letter(file_path_abs: str) str + + get_shebang(file_path_abs: str) Optional[str] +} +``` \ No newline at end of file diff --git a/plugin/coderunner.vim b/plugin/coderunner.vim index 95ae44e..06edda2 100644 --- a/plugin/coderunner.vim +++ b/plugin/coderunner.vim @@ -32,7 +32,7 @@ let g:coderunner_save_file_before_run = get(g:, 'coderunner_save_file_before_run let g:coderunner_tempfile_prefix = get(g:, 'coderunner_tempfile_prefix', 'coderunner_tempfile_') if has('vim_starting') - augroup coderunnerStart + augroup coderunnerVimEnter autocmd! autocmd VimEnter * call coderunner#Load() augroup END @@ -40,7 +40,7 @@ else call coderunner#Load() endif -augroup coderunnerEnd +augroup coderunnerVimLeave autocmd! autocmd VimLeave * call coderunner#OnExit() augroup END