diff --git a/.github/workflows/panvimdoc.yml b/.github/workflows/panvimdoc.yml
new file mode 100644
index 0000000..eb8ec73
--- /dev/null
+++ b/.github/workflows/panvimdoc.yml
@@ -0,0 +1,26 @@
+# https://github.com/kdheepak/panvimdoc
+name: panvimdoc
+
+on:
+ push:
+ paths:
+ - README.md
+ - .github/workflows/panvimdoc.yml
+
+permissions:
+ contents: write
+
+jobs:
+ docs:
+ runs-on: ubuntu-latest
+ name: pandoc to vimdoc
+ steps:
+ - uses: actions/checkout@v2
+ - uses: kdheepak/panvimdoc@main
+ with:
+ vimdoc: code_runner
+ version: "NVIM v0.11.0"
+ - uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ commit_message: "docs: :memo: Auto generate docs"
+ branch: ${{ github.head_ref }}
diff --git a/.luarc.json b/.luarc.json
new file mode 100644
index 0000000..de0acc7
--- /dev/null
+++ b/.luarc.json
@@ -0,0 +1,3 @@
+{
+ "runtime.version": "LuaJIT"
+}
diff --git a/README.md b/README.md
index 0c70a04..5e5c847 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
Code_Runner
+# code_runner.nvim
-🔥 Code Runner for Neovim written in pure lua 🔥
+🏃♂️ Code Runner for Neovim written in pure lua 🌙

@@ -10,7 +10,7 @@ When I was still in college it was common to try multiple programming languages,
## Requirements
-- Neovim (>= 0.8)
+- Neovim (>= 0.11)
## Install
@@ -18,7 +18,9 @@ When I was still in college it was common to try multiple programming languages,
```lua
require("lazy").setup({
- { "CRAG666/code_runner.nvim", config = true },
+ { "CRAG666/code_runner.nvim",
+ event= "VeryLazy",
+ },
}
```
@@ -54,7 +56,7 @@ Please see my config [code_runner.lua](https://github.com/CRAG666/dotfiles/blob/
## Setup
-This plugin can be configured either in lua, with the `setup` function, or with json files for interopability between this plugin and the [original code runner](https://github.com/formulahendry/vscode-code-runner) vscode plugin.
+This plugin can be configured either in lua, with the `setup` function, or with json files for interoperability between this plugin and the [original code runner](https://github.com/formulahendry/vscode-code-runner) vscode plugin.
### Minimal example
@@ -118,24 +120,22 @@ require('code_runner').setup {
All run commands allow restart. So, for example, if you use a command that does not have hot reload, you can call a command again and it will close the previous one and start again.
-- `:RunCode`: Runs based on file type, first checking if belongs to project, then if filetype mapping exists
-- `:RunCode `: Execute command from its key in current directory.
-- `:RunFile `: Run the current file (optionally you can select an opening mode).
-- `:RunProject `: Run the current project(If you are in a project otherwise you will not do anything,).
-- `:RunClose`: Close runner(Doesn't work in better_term mode, use native plugin options)
-- `:CRFiletype` - Open json with supported files(Use only if you configured with json files).
-- `:CRProjects` - Open json with list of projects(Use only if you configured with json files).
+- `:Run`: Evaluate and write the current buffer based on filetype, first checking if belongs to project, then if filetype mapping exists
+- `:Run on `: Run the current file (optionally you can select an display mode).
+- `:Run with `: Run the current file with the associate filetype/command (will run in the default display mode).
+- `:Run`: Execute range can be combined with `on` or `with`.
+- `:Run project `: Run the current project (If you are in a project, optionally you can select an display mode).
+- `:Run closeRunnerWindow`: Close runner window/viewport (Doesn't work in better_term mode, use native plugin options)
+- `:Run openProjectFiletypes` - Open json with supported files (Use only if you configured with json files).
+- `:Run openProjectList` - Open json with list of projects(Use only if you configured with json files).
Recommended mappings:
```lua
-vim.keymap.set('n', 'r', ':RunCode', { noremap = true, silent = false })
-vim.keymap.set('n', 'rf', ':RunFile', { noremap = true, silent = false })
-vim.keymap.set('n', 'rft', ':RunFile tab', { noremap = true, silent = false })
-vim.keymap.set('n', 'rp', ':RunProject', { noremap = true, silent = false })
-vim.keymap.set('n', 'rc', ':RunClose', { noremap = true, silent = false })
-vim.keymap.set('n', 'crf', ':CRFiletype', { noremap = true, silent = false })
-vim.keymap.set('n', 'crp', ':CRProjects', { noremap = true, silent = false })
+vim.keymap.set('n', 'rr', ':Run', { noremap = true, silent = false })
+vim.keymap.set('n', 'rot', ':Run on tab', { noremap = true, silent = false })
+vim.keymap.set('n', 'rp', ':Run project', { noremap = true, silent = false })
+vim.keymap.set('n', 'rc', ':Run closeRunnerWindow', { noremap = true, silent = false })
```
## Parameters
@@ -146,13 +146,15 @@ This are the the configuration option you can pass to the `setup` function. To s
Parameters:
-- `mode`: Mode in which you want to run. Are supported: "better_term", "float", "tab", "toggleterm" (type: `bool`)
-- `focus`: Focus on runner window. Only works on term and tab mode (type: `bool`)
-- `startinsert`: init in insert mode.Only works on term and tab mode (type: `bool`)
-- `term`: Configurations for the integrated terminal
+- `mode`: Display Mode in which you want to run. Supported: "term", "float", "tab","better_term", "toggleterm" (type: `string`, default: "term")
+- `focus`: Focus on runner window. Only works on "term" and "tab" display modes (type: `bool`, default: false)
+- `startinsert`: init in insert mode. Only works on "term" and "tab" display modes (type: `bool`, default: false)
+- `hot_reload`: Run automatically on buffer save, only works in "term" or similar (type: `bool`, default: true)
+- `term`: Configurations for the integrated terminal (type: `table`)
- `position`: terminal position consult `:h windows` for options (type: `string`)
- `size`: Size of the terminal window (type: `uint` | `float`)
-- `float`: Configurations for the float window
+- `float`: Configurations for the float window (type: `table`)
+
- `border`: Window border options (type: `string`)
- "none": No border (default).
- "single": A single line box.
@@ -160,7 +162,7 @@ Parameters:
- "rounded": Like "single", but with rounded corners ("╭" etc.).
- "solid": Adds padding by a single whitespace cell.
- "shadow": A drop shadow effect by blending with the background.
- - For more border options see `:h nvim_open_win()` or [NeoVim API Documentation](https://neovim.io/doc/user/api.html#nvim_open_win())
+ - For more border options see `:h nvim_open_win()` or [NeoVim API Documentation]()
- `width`: (type: `float`)
- `x`: (type: `float`)
- `y`: (type: `float`)
@@ -180,7 +182,7 @@ Parameters:
### Setup Filetypes
> **Note**
-> The commands are runned in a shell. This means that you can't run neovim commands with [this](https://github.com/CRAG666/code_runner.nvim/issues/59).
+> The commands ran in a shell. This means that you can't run neovim commands with [this](https://github.com/CRAG666/code_runner.nvim/issues/59).
#### Lua
@@ -203,7 +205,7 @@ filetype = {
},
```
-If you want to add some other language or some other command follow this structure `key = commans`.
+If you want to add some other language or some other command follow this structure `key = commands`.
#### Json
@@ -242,8 +244,8 @@ If you want to add some other language or some other command follow this structu
There are 3 main ways to configure the execution of a project (found in the example.)
-1. Use the default command defined in the filetypes file (see `:CRFiletype`or check your config). In order to do that it is necessary to define file_name.
-2. Use a different command than the one set in `CRFiletype` or your config. In this case, the file_name and command must be provided.
+1. Use the default command defined in the filetypes file (see `:Run openProjectFiletypes`or check your config). In order to do that it is necessary to define file_name.
+2. Use a different command than the one set in `Run openProjectFiletypes` or your config. In this case, the file_name and command must be provided.
3. Use a command to run the project. It is only necessary to define command (You do not need to write navigate to the root of the project, because automatically the plugin is located in the root of the project).
The key for each project is a pattern to match against the current filename of
@@ -316,7 +318,7 @@ project = {
- `name`: Project name
- `description`: Project description
- `file_name`: Filename relative to root path
-- `command`: Command to run the project. It is possible to use variables exactly the same as we would in [`CRFiletype`](#commands).
+- `command`: Command to run the project. It is possible to use variables exactly the same as we would in [`Run openProjectFiletypes`](#commands).
> **Warning**
> Avoid using all the parameters at the same time. The correct way to use them is shown in the example and described above.
@@ -447,7 +449,7 @@ local function runTsFile(fileName)
vim.cmd 'vsplit term://'
-- Run the TypeScript file and print the result
- vim.fn.termopen('ts-node ' .. fileName)
+ vim.fn.jobstart('ts-node ' .. fileName, {term=true})
-- Restore the focus to the original window
vim.fn.win_gotoid(current_win)
@@ -521,8 +523,11 @@ require("harpoon.term").sendCommand(1, require("code_runner.commands").get_filet
Your help is needed to make this plugin the best of its kind, be free to contribute, criticize (don't be soft) or contribute ideas. All PRs are welcome.
-# LICENCE
+## Similar Projects
----
+- [SnipRun](https://github.com/michaelb/sniprun)
+- [iron.nvim](https://github.com/Vigemus/iron.nvim)
+
+# LICENCE
[MIT](https://github.com/CRAG666/code_runner.nvim/blob/main/LICENSE)
diff --git a/doc/.gitkeep b/doc/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/doc/code_runner.txt b/doc/code_runner.txt
index 908e944..90dcc2e 100644
--- a/doc/code_runner.txt
+++ b/doc/code_runner.txt
@@ -1,114 +1,629 @@
-*code_runner.nvim*
+*code_runner.txt* For NVIM v0.11.0 Last change: 2025 July 22
+==============================================================================
+Table of Contents *code_runner-table-of-contents*
+
+1. code_runner.nvim |code_runner-code_runner.nvim|
+ - Introduction |code_runner-code_runner.nvim-introduction|
+ - Requirements |code_runner-code_runner.nvim-requirements|
+ - Install |code_runner-code_runner.nvim-install|
+ - Features |code_runner-code_runner.nvim-features|
+ - Setup |code_runner-code_runner.nvim-setup|
+ - Commands |code_runner-code_runner.nvim-commands|
+ - Parameters |code_runner-code_runner.nvim-parameters|
+ - Hooks |code_runner-code_runner.nvim-hooks|
+ - Integration with other plugins|code_runner-code_runner.nvim-integration-with-other-plugins|
+ - Inspirations and thanks|code_runner-code_runner.nvim-inspirations-and-thanks|
+ - Screenshots |code_runner-code_runner.nvim-screenshots|
+ - Contributing |code_runner-code_runner.nvim-contributing|
+ - Similar Projects |code_runner-code_runner.nvim-similar-projects|
+2. LICENCE |code_runner-licence|
+3. Links |code_runner-links|
==============================================================================
-INTRODUCTION *code_runner-instroduction*
+1. code_runner.nvim *code_runner-code_runner.nvim*
-The best code runner you could have,like the one in vscode but with super powers.
+🏃♂️ Code Runner for Neovim written in pure lua 🌙
-==============================================================================
-REQUIREMENTS *code_runner-requirements*
+INTRODUCTION *code_runner-code_runner.nvim-introduction*
-- Neovim >= v0.5.0
+When I was still in college it was common to try multiple programming
+languages, at that time I used vscode that with a single plugin allowed me to
+run many programming languages, I left the ballast that are electron apps and
+switched to neovim, I searched the Internet and finally i found a lot of
+plugins, but none of them i liked (maybe i didn’t search well), so i started
+adding autocmds like i don’t have a tomorrow, this worked fine but this is
+lazy (maybe it will work for you, if you only programs in one or three
+languages maximum). So I decided to make this plugin and since the migration of
+my commands was very fast, it was just copy and paste and everything worked.
+Currently I don’t test many languages anymore and work in the professional
+environment, but this plugin is still my swiss army knife.
-==============================================================================
-INTERFACE *code_runner-interface*
-
-------------------------------------------------------------------------------
-FUNCTIONS *code_runner-functions*
-
-code_runner.setup([{opts}]) *code_runner.setup()*
- Set up the code_runner.
- Please see |code_runner-settings|.
-
-:CRFiletype *:CRFiletype*
- Open json with supported files.
-:CRProjects *:CRProjects*
- Open json with list of projects.
-:RunCode {opt} *:RunCode*
- Run the current project or file, if {opt} provided, it will run the
- command that maps to that {opt} from the keys in the supported files
- json
-:RunFile {modes} *:RunFile*
- Run the current file(optionally you can select an opening {mode}: {"toggle", "float", "tab", "toggleterm", "buf"}, default: "term").
-:RunProject *:RunProject*
- Run the current project(If you are in a project otherwise you will not do anything, optionally you can select an opening {mode}: {"toggle", "float", "tab", "toggleterm", "buf"}, default: "term").
+REQUIREMENTS *code_runner-code_runner.nvim-requirements*
-==============================================================================
-SETTINGS *code_runner-settings*
+- Neovim (>= 0.11)
-You can set it with |code_runner.setup()|.
-default value: >
+INSTALL *code_runner-code_runner.nvim-install*
- {
- mode = 'term',
- -- startinsert (see ':h inserting-ex')
- startinsert = false,
- term = {
- -- Position to open the terminal, this option is ignored if mode ~= term
- position = "bot",
- -- window size, this option is ignored if tab is true
- size = 8,
+- With lazy.nvim
+
+>lua
+ require("lazy").setup({
+ { "CRAG666/code_runner.nvim",
+ event= "VeryLazy",
},
- float = {
- -- Window border (see ':h nvim_open_win')
- border = "none",
-
- -- Num from `0 - 1` for measurements
- height = 0.8,
- width = 0.8,
- x = 0.5,
- y = 0.5,
-
- -- Highlight group for floating window/border (see ':h winhl')
- border_hl = "FloatBorder",
- float_hl = "Normal",
-
- -- Transparency (see ':h winblend')
- blend = 0,
+ }
+<
+
+- With packer.nvim
+
+>lua
+ use 'CRAG666/code_runner.nvim'
+<
+
+- With paq-nvim
+
+>lua
+ require "paq"{ 'CRAG666/code_runner.nvim'; }
+<
+
+Please see my config code_runner.lua
+
+
+
+FEATURES *code_runner-code_runner.nvim-features*
+
+
+ **Note** If you want implement a new feature open an issue to know if it is
+ worth implementing it and if there are people interested.
+- Toggle runner(you need CRAG666/betterTerm.nvim , By the way, this is the mode I currently use with this plugin)
+- Reload task on the fly
+- Run code in a Float window
+- Run code in a tab
+- Run code in a split
+- Run code with toggleTerm
+- Custom hooks, for example preview in files like markdown, hot reload enabled.
+ see |code_runner-hooks|
+- Assign commands to projects without files in the root of the project
+- Run project commands in different modes for a per projects base
+
+
+SETUP *code_runner-code_runner.nvim-setup*
+
+This plugin can be configured either in lua, with the `setup` function, or with
+json files for interoperability between this plugin and the original code
+runner vscode plugin.
+
+
+MINIMAL EXAMPLE ~
+
+
+LUA
+
+>lua
+ require('code_runner').setup({
+ filetype = {
+ java = {
+ "cd $dir &&",
+ "javac $fileName &&",
+ "java $fileNameWithoutExt"
+ },
+ python = "python3 -u",
+ typescript = "deno run",
+ rust = {
+ "cd $dir &&",
+ "rustc $fileName &&",
+ "$dir/$fileNameWithoutExt"
+ },
+ c = function(...)
+ c_base = {
+ "cd $dir &&",
+ "gcc $fileName -o",
+ "/tmp/$fileNameWithoutExt",
+ }
+ local c_exec = {
+ "&& /tmp/$fileNameWithoutExt &&",
+ "rm /tmp/$fileNameWithoutExt",
+ }
+ vim.ui.input({ prompt = "Add more args:" }, function(input)
+ c_base[4] = input
+ vim.print(vim.tbl_extend("force", c_base, c_exec))
+ require("code_runner.commands").run_from_fn(vim.list_extend(c_base, c_exec))
+ end)
+ end,
},
- filetype_path = vim.fn.stdpath("data") .. "/site/pack/packer/start/code_runner.nvim/lua/code_runner/code_runner.json",
- filetype = {},
- project_path = vim.fn.stdpath("data")
- .. "/site/pack/packer/start/code_runner.nvim/lua/code_runner/project_manager.json",
- project = {},
+ })
+<
+
+
+JSON
+
+
+ **Warning** A common mistake is using relative paths instead of absolute paths
+ in. Use absolute paths in configurations or else the plugin won’t work, in
+ case you like to use short or relative paths you can use something like this
+ `vim.fn.expand('~/.config/nvim/project_manager.json')`
+
+ **Note** If you want to change were the code is displayed you need to specify
+ the `mode` <> attribute in the setup `function`
+>lua
+ -- this is a config example
+ require('code_runner').setup {
+ filetype_path = vim.fn.expand('~/.config/nvim/code_runner.json'),
+ project_path = vim.fn.expand('~/.config/nvim/project_manager.json')
}
<
-mode *code_runner-settings-mode*
- Mode in which you want to run(default: term, valid options: {"toggle", "float", "tab", "toggleterm", "buf"}),
-startinsert *code_runner-settings-startinsert*
- Init in insert mode(default: false)
+COMMANDS *code_runner-code_runner.nvim-commands*
+
-term *code_runner-settings-term*
- Configurations for the integrated terminal
+ **Note** To check what modes ore supported see |code_runner-mode-parameter|.
+All run commands allow restart. So, for example, if you use a command that does
+not have hot reload, you can call a command again and it will close the
+previous one and start again.
-filetype *code_runner-settings-filetype*
- Configuration for filetype
+- `:Run`: Evaluate and write the current buffer based on filetype, first checking if belongs to project, then if filetype mapping exists
+- `:Run on `: Run the current file (optionally you can select an display mode).
+- `:Run with `: Run the current file with the associate filetype/command (will run in the default display mode).
+- `:Run`: Execute range can be combined with `on` or `with`.
+- `:Run project `: Run the current project (If you are in a project, optionally you can select an display mode).
+- `:Run closeRunnerWindow`: Close runner window/viewport (Doesn’t work in better_term mode, use native plugin options)
+- `:Run openProjectFiletypes` - Open json with supported files (Use only if you configured with json files).
+- `:Run openProjectList` - Open json with list of projects(Use only if you configured with json files).
-project *code_runner-settings-project_context*
- Configuration for project
+Recommended mappings:
+
+>lua
+ vim.keymap.set('n', 'rr', ':Run', { noremap = true, silent = false })
+ vim.keymap.set('n', 'rot', ':Run on tab', { noremap = true, silent = false })
+ vim.keymap.set('n', 'rp', ':Run project', { noremap = true, silent = false })
+ vim.keymap.set('n', 'rc', ':Run closeRunnerWindow', { noremap = true, silent = false })
+<
-Example: >
- require'code_runner'.setup {
- mode = "tab",
- startinsert = true,
- term = {
- position = "vert",
- size = 8
+PARAMETERS *code_runner-code_runner.nvim-parameters*
+
+
+SETUP GLOBAL ~
+
+This are the the configuration option you can pass to the `setup` function. To
+see the default values see: `code_runner.nvim/lua/code_runner/options`
+.
+
+Parameters:
+
+- `mode`: Display Mode in which you want to run. Supported: "term", "float",
+ "tab","better_term", "toggleterm" (type: `string`, default: "term")
+- `focus`: Focus on runner window. Only works on "term" and "tab" display modes
+ (type: `bool`, default: false)
+- `startinsert`: init in insert mode. Only works on "term" and "tab" display
+ modes (type: `bool`, default: false)
+- `hot_reload`: Run automatically on buffer save, only works in "term" or similar
+ (type: `bool`, default: true)
+- `term`: Configurations for the integrated terminal (type: `table`)
+ - `position`: terminal position consult |windows| for options (type: `string`)
+ - `size`: Size of the terminal window (type: `uint` | `float`)
+- `float`: Configurations for the float window (type: `table`)
+ - `border`: Window border options (type: `string`)
+ - "none": No border (default).
+ - "single": A single line box.
+ - "double": A double line box.
+ - "rounded": Like "single", but with rounded corners ("╭" etc.).
+ - "solid": Adds padding by a single whitespace cell.
+ - "shadow": A drop shadow effect by blending with the background.
+ - For more border options see |nvim_open_win()| or |NeoVim API Documentation|
+ - `width`: (type: `float`)
+ - `x`: (type: `float`)
+ - `y`: (type: `float`)
+ - `border_hl`: (type: `string`)
+- `better_term`: Toggle mode replacement(Install CRAG666/betterTerm.nvim
+ )
+ - `clean`: Clean terminal before launch(type: `bool`)
+ - `number`: Use nil for dynamic number and set init(type: `uint?`)
+ - `init`: Set a start number for executions, each execution will go to a different terminal(type: `uint?`)
},
- filetype_path = "/home/myuser/.config/nvim/code_runner.json",
- project_path = "/home/myuser/.config/nvim/projects.json"
+- `before_run_filetype`: Execute before executing a file (type: `func`)
+- `filetype`: If you prefer to use lua instead of json files, you can add your
+ settings by file type here (type: `table`)
+- `filetype_path`: Absolute path to json file config (type: `absolute paths`)
+- `project`: If you prefer to use lua instead of json files, you can add your
+ settings by project here (type: `table`)
+- `project_path`: Absolute path to json file config (type: `absolute paths`)
+
+
+SETUP FILETYPES ~
+
+
+ **Note** The commands ran in a shell. This means that you can’t run neovim
+ commands with this .
+
+LUA
+
+The filetype table can take either a `string`, a `table` or a `function`.
+
+>lua
+ -- in setup function
+ filetype = {
+ java = { "cd $dir &&", "javac $fileName &&", "java $fileNameWithoutExt" },
+ python = "python3 -u",
+ typescript = "deno run",
+ rust = { "cd $dir &&",
+ "rustc $fileName &&",
+ "$dir/$fileNameWithoutExt"
+ },
+ cs = function(...)
+ local root_dir = require("lspconfig").util.root_pattern "*.csproj"(vim.loop.cwd())
+ return "cd " .. root_dir .. " && dotnet run$end"
+ end,
+ },
+<
+
+If you want to add some other language or some other command follow this
+structure `key = commands`.
+
+
+JSON
+
+
+ **Note** In Json you can only pass the commands as a string
+The equivalent for your json filetype file is:
+
+>json
+ {
+ "java": "cd $dir && javac $fileName && java $fileNameWithoutExt",
+ "python": "python3 -u",
+ "typescript": "deno run",
+ "rust": "cd $dir && rustc $fileName && $dir/$fileNameWithoutExt"
}
+<
+
+
+VARIABLES ~
+
+
+ **Note** If you don’t want to use the plugin specific variables you can use
+ vim |filename-modifiers|.
+This uses some special keyword to that means different things. This is do
+mainly for be compatible with the original vscode plugin.
+
+The available variables are the following:
+
+- `file`: path to current open file (e.g. `/home/user/current_dir/current_file.ext`
+- `fileName`: filename of current open file (e.g. `current_file.ext`)
+- `fileNameWithoutExt`: filename without extension of current file (e.g. `current_file`)
+- `dir`: path to directory of current open file (e.g. `/home/user/current_dir`)
+- `end`: finish the command (it is useful for commands that do not require final autocompletion)
+
+If you want to add some other language or some other command follow this
+structure `key: commans`.
+
+
+SETUP PROJECTS ~
+
+There are 3 main ways to configure the execution of a project (found in the
+example.)
+
+1. Use the default command defined in the filetypes file (see `:Run openProjectFiletypes`or check your config). In order to do that it is necessary to define file_name.
+2. Use a different command than the one set in `Run openProjectFiletypes` or your config. In this case, the file_name and command must be provided.
+3. Use a command to run the project. It is only necessary to define command (You do not need to write navigate to the root of the project, because automatically the plugin is located in the root of the project).
+
+The key for each project is a pattern to match against the current filename of
+the buffer. The pattern is a lua patterns
+and needs to escape magic characters like `-`, `.`, `(`, etc. with a `%`. To
+match the entire path to a directory you cannot simply append `/`. This is due
+to `vim.fs.normalize` being used. Append `/.-` instead to prevent stripping of
+`/`.
+
+Also see |code_runner-project-parameters| to set correctly your project
+commands.
+
+
+LUA
+
+>lua
+ project = {
+ ["~/python/intel_2021_1"] = {
+ name = "Intel Course 2021",
+ description = "Simple python project",
+ file_name = "POO/main.py"
+ },
+ ["~/deno/example"] = {
+ name = "ExapleDeno",
+ description = "Project with deno using other command",
+ file_name = "http/main.ts",
+ command = "deno run --allow-net"
+ },
+ ["~/cpp/example"] = {
+ name = "ExapleCpp",
+ description = "Project with make file",
+ command = "make buid && cd buid/ && ./compiled_file"
+ },
+ ["~/private/.*terraform%-prod.-/.-"] = {
+ name = "ExampleTerraform",
+ description = "All Folders in ~/private containing \"terraform-prod\"",
+ command = "terraform plan",
+ },
+ },
+<
+
+
+JSON
+
+>json
+ {
+ "~/python/intel_2021_1": {
+ "name": "Intel Course 2021",
+ "description": "Simple python project",
+ "file_name": "POO/main.py"
+ },
+ "~/deno/example": {
+ "name": "ExapleDeno",
+ "description": "Project with deno using other command",
+ "file_name": "http/main.ts",
+ "command": "deno run --allow-net"
+ },
+ "~/cpp/example": {
+ "name": "ExapleCpp",
+ "description": "Project with make file",
+ "command": "make buid && cd buid/ && ./compiled_file"
+ },
+ "~/private/.*terrafrom%-prod.-/.-": {
+ "name": "ExampleTerraform",
+ "description": "All Folders in ~/private containing \"terraform-prod\"",
+ "command": "terraform plan"
+ }
+ }
+<
+
+
+PARAMETERS
+
+- `name`: Project name
+- `description`: Project description
+- `file_name`: Filename relative to root path
+- `command`: Command to run the project. It is possible to use variables exactly the same as we would in |code_runner-`run-openprojectfiletypes`|.
+
+
+ **Warning** Avoid using all the parameters at the same time. The correct way to
+ use them is shown in the example and described above.
+
+ **Note** Don’t forget to name your projects because if you don’t do so code
+ runner will fail as it uses the name for the buffer name
+
+HOOKS *code_runner-code_runner.nvim-hooks*
+
+These elements are intended to help with those commands that require more
+complexity. For example, implement hot reload on markup documents.
+
+
+PREVIEW PDF ~
+
+This module allows us to send a command to compile to pdf as well as show the
+result every time we save the original document.
+
+
+USAGE EXAMPLE
+
+>lua
+ {
+ ...
+ filetype = {
+ -- Using pdflatex compiler
+ -- tex = function(...)
+ -- require("code_runner.hooks.preview_pdf").run {
+ -- command = "pdflatex",
+ -- args = { "-output-directory", "/tmp", "$fileName" },
+ -- preview_cmd = "/bin/zathura --fork",
+ -- overwrite_output = "/tmp",
+ -- }
+ -- end,
+ -- Using tectonic compiler
+ tex = function(...)
+ require("code_runner.hooks.ui").select {
+ Single = function()
+ local preview = require "code_runner.hooks.preview_pdf"
+ preview.run {
+ command = "tectonic",
+ args = { "$fileName", "--keep-logs", "-o", "/tmp" },
+ preview_cmd = preview_cmd,
+ overwrite_output = "/tmp",
+ }
+ end,
+ Project = function()
+ local cr_au = require "code_runner.hooks.autocmd"
+ cr_au.stop_job()
+ os.execute "tectonic -X build --keep-logs --open &> /dev/null &"
+ local fn = function()
+ os.execute "tectonic -X build --keep-logs &> /dev/null &"
+ end
+ cr_au.create_au_write(fn)
+ end,
+ }
+ end,
+ markdown = function(...)
+ local hook = require "code_runner.hooks.preview_pdf"
+ require("code_runner.hooks.ui").select {
+ Normal = function()
+ hook.run {
+ command = "pandoc",
+ args = { "$fileName", "-o", "$tmpFile", "-t pdf" },
+ preview_cmd = preview_cmd,
+ }
+ end,
+ Presentation = function()
+ hook.run {
+ command = "pandoc",
+ args = { "$fileName", "-o", "$tmpFile", "-t beamer" },
+ preview_cmd = preview_cmd,
+ }
+ end,
+ Eisvogel = function()
+ hook.run {
+ command = "bash",
+ args = { "./build.sh" },
+ preview_cmd = preview_cmd,
+ overwrite_output = ".",
+ }
+ end,
+ }
+ end,
+ ...
+ }
+<
+
+In the above example we use the hook to compile markdown and latex files to
+pdf. Not only that, but we also indicate in what order the resulting pdf file
+will be opened. In my case it is zathura but you can use a browser if it is
+more comfortable for you.
+
+It is important that you take into account that each time you save the original
+file, the pdf file will be generated.
+
+
+PARAMETERS
+
+- `command`: Command used to generate the pdf
+- `args`: Arguments of the above command
+- `preview_cmd`: Command used to open the resulting PDF
+- `overwrite_output`: If for some reason you cannot define the output of the pdf file use this option to define the directory where it will be saved, and the name of the source file is concatenated with the pdf extension
+
+
+VARS
+
+These are variables used to be substituted for values according to each
+filename.
+
+- `$fileName`: Will be replaced by the full path of the file.
+- `$tmpFile`: This variable is replaced by a dynamic name generated by lua, stored in tmp.
+
+
+TYPESCRIPT HOOKS ~
+
+This example showcases how to write a hook to run ts file, print the result in
+a new vertical windows and reload on save. Read the comments for more info.
+
+>lua
+ -- custom function to run ts file
+ -- and print result in a new vertical windows
+ local function runTsFile(fileName)
+ -- Check if the current file is a TypeScript file
+ if string.match(fileName, '%.ts$') then
+ -- Save the current window id
+ local current_win = vim.fn.win_getid()
+
+ -- Close previous terminal windows
+ vim.cmd 'silent! wincmd w | if &buftype ==# "terminal" | q | endif'
+
+ -- Open a vertical terminal
+ vim.cmd 'vsplit term://'
+
+ -- Run the TypeScript file and print the result
+ vim.fn.jobstart('ts-node ' .. fileName, {term=true})
+
+ -- Restore the focus to the original window
+ vim.fn.win_gotoid(current_win)
+ else
+ print 'Not a TypeScript file!'
+ end
+ end
+
+ -- hooks config
+ {
+ filetype = {
+ typescript = function()
+ local cr_au = require "code_runner.hooks.autocmd"
+ -- stop previous job (if has any)
+ cr_au.stop_job() -- CodeRunnerJobPosWrite
+
+ local fileName = vim.fn.expand '%:p'
+ local fn = function()
+ runTsFile(fileName)
+ end
+
+ -- run the command the first time
+ fn()
+
+ -- listen to bufwrite event after the first run time
+ cr_au.create_au_write(fn)
+ end,
+ },
+ }
+<
+
+
+INTEGRATION WITH OTHER PLUGINS*code_runner-code_runner.nvim-integration-with-other-plugins*
+
+
+API ~
+
+These functions could be useful if you intend to create plugins around
+code_runner, currently only the file type and current project commands can be
+accessed respectively
+
+>lua
+ require("code_runner.commands").get_filetype_command() -- get the current command for this filetype
+ require("code_runner.commands").get_project_command() -- get the current command for this project
+<
+
+
+HARPOON ~
+
+You can directly integrate this plugin with ThePrimeagen/harpoon
+ the way to do it is through command
+queries, harpoon allows the command to be sent to a terminal, below it is shown
+how to use harpoon term together with code_runner.nvim:
+
+>lua
+ require("harpoon.term").sendCommand(1, require("code_runner.commands").get_filetype_command() .. "\n")
+<
+
+
+INSPIRATIONS AND THANKS *code_runner-code_runner.nvim-inspirations-and-thanks*
+
+- The idea of this project comes from the vscode plugin code_runner You can even copy your configuration and pass it to this plugin, as they are the same in the way of defining commands associated with filetypes
+- jaq-nvim some ideas of how to execute commands were taken from this plugin, thank you very much.
+- FTerm.nvim Much of how this README.md is structured was blatantly stolen from this plugin, thank you very much
+- @adalessa, profile , Much of the code for the
+ pdf preview hook was taken from a plugin it has. thank you. For the Spanish
+ community he has an excellent channel on neovim, Channel
+- Thanks to all current and future collaborators, without their contributions this plugin would not be what it is today
+
+
+SCREENSHOTS *code_runner-code_runner.nvim-screenshots*
+
+
+CONTRIBUTING *code_runner-code_runner.nvim-contributing*
+
+
+ **Note** If you have any ideas to improve this project, do not hesitate to make
+ a request, if problems arise, try to solve them and publish them. Don’t be so
+ picky I did this in one afternoon
+Your help is needed to make this plugin the best of its kind, be free to
+contribute, criticize (don’t be soft) or contribute ideas. All PRs are
+welcome.
+
+
+SIMILAR PROJECTS *code_runner-code_runner.nvim-similar-projects*
+
+- SnipRun
+- iron.nvim
==============================================================================
-FAQ *code_runner-faq*
+2. LICENCE *code_runner-licence*
+
+MIT
==============================================================================
-vim:tw=78:sw=4:sts=4:ts=4:ft=help:norl:et
+3. Links *code_runner-links*
+
+1. *preview*: https://github.com/CRAG666/dotfiles/blob/main/config/nvim/lua/plugins/dev/code_runner.lua
+2. *@adalessa*:
+
+Generated by panvimdoc
+
+vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/lua/code_runner.lua b/lua/code_runner.lua
index ea99b84..ccbc556 100644
--- a/lua/code_runner.lua
+++ b/lua/code_runner.lua
@@ -1,7 +1,7 @@
local commands = require("code_runner.commands")
local o = require("code_runner.options")
-local function setup(opt)
+local function config(opt)
-- Load json config and convert to table
local load_json_as_table = require("code_runner.load_json")
@@ -29,8 +29,7 @@ local function setup(opt)
end
end
- -- set user options
- o.set(opt)
+ o.set(opt) -- set user options
-- Message if json file not exist
if vim.tbl_isempty(o.get().filetype) then
@@ -68,42 +67,66 @@ M.open_project_manager = function()
end
M.setup = function(user_options)
- setup(user_options or {})
+ config(user_options or {})
- local simple_cmds = {
- RunClose = commands.run_close,
- CRFiletype = M.open_filetype_suported,
- CRProjects = M.open_project_manager,
+ local Subcmds = {
+ on = "on",
+ with = "with",
+ project = "project",
+ close = "closeRunnerWindow",
+ openProject = "openProjectList",
+ openProjectFtSupported = "openProjectFiletypes",
}
- for cmd, func in pairs(simple_cmds) do
- vim.api.nvim_create_user_command(cmd, func, { nargs = 0 })
- end
- -- Commands with autocomplete
- local modes = vim.tbl_keys(commands.modes)
- -- Format:
- -- CoomandName = { function, option_list }
- local completion_cmds = {
- RunCode = { commands.run_code, vim.tbl_keys(o.get().filetype) },
- RunFile = { commands.run_filetype, modes },
- RunProject = { commands.run_project, modes },
- }
- for cmd, cmo in pairs(completion_cmds) do
- vim.api.nvim_create_user_command(cmd, function(opts)
- cmo[1](unpack(opts.fargs))
- end, {
- nargs = "*",
- complete = function(ArgLead, word, ...)
- -- only complete the first argument
- if #vim.split(word, "%s+") > 2 then
- return
+ vim.api.nvim_create_user_command("Run", function(opts)
+ if opts.args == "" then
+ return commands.run_current_file(nil, opts)
+ end
+
+ local args = vim.split(opts.args, "%s+")
+ local subcommand = args[1]
+ local value = args[2]
+
+ if subcommand == Subcmds.on then
+ return commands.run_current_file(value, opts)
+ elseif subcommand == Subcmds.with then
+ return commands.run_code(value, opts)
+ elseif subcommand == Subcmds.project then
+ return commands.run_project(value, opts)
+ elseif subcommand == Subcmds.close then
+ return commands.close_current_execution()
+ elseif subcommand == Subcmds.openProject then
+ return M.open_project_manager()
+ elseif subcommand == Subcmds.openProjectFtSupported then
+ return M.open_filetype_suported()
+ else
+ return vim.notify(
+ string.format("Invalid operation %s"),
+ vim.log.levels.ERROR,
+ { title = "Code Runner plugin Error" }
+ )
+ end
+ end, {
+ range = 0,
+ nargs = "?",
+ complete = function(ArgLead, CmdLine, _) -- :help :command-completion-custom
+ local cmdline_values = vim.split(CmdLine, "%s+")
+
+ if #cmdline_values > 2 and #cmdline_values < 4 then
+ local sub_cmd = cmdline_values[2]
+ if sub_cmd == Subcmds.with then
+ return completion(ArgLead, vim.tbl_keys(o.get().filetype))
+ elseif sub_cmd == Subcmds.on or sub_cmd == Subcmds.project then
+ return completion(ArgLead, vim.tbl_keys(commands.display_modes))
end
- return completion(ArgLead, cmo[2])
- end,
- })
- end
+ elseif #cmdline_values == 2 then
+ return completion(ArgLead, vim.tbl_values(Subcmds))
+ end
+ end,
+ })
+
M.run_code = commands.run_code
- M.run_filetype = commands.run_filetype
+ M.run_current_file = commands.run_current_file
M.run_project = commands.run_project
end
diff --git a/lua/code_runner/commands.lua b/lua/code_runner/commands.lua
index 5dcd5f7..d0c7e3f 100644
--- a/lua/code_runner/commands.lua
+++ b/lua/code_runner/commands.lua
@@ -1,12 +1,15 @@
local o = require("code_runner.options")
-local pattern = "crunner_"
+local cr_bufname_prefix = "crunner_"
local au_cd = require("code_runner.hooks.autocmd")
+local M = {}
+
+-- util functions {{{
-- Replace variables with full paths
----@param command string command to run the path
+---@param command (string| table | function) command to run the path
---@param path string absolute path
----@param user_argument table?
----@return string?
+---@param user_argument? table
+---@return string|nil
local function replaceVars(command, path, user_argument)
if type(command) == "function" then
local cmd = command(user_argument)
@@ -20,9 +23,8 @@ local function replaceVars(command, path, user_argument)
end
-- command is of type string
-
+ ---@cast command string
local no_sub_command = command
-
command = command:gsub("$fileNameWithoutExt", vim.fn.fnamemodify(path, ":t:r"))
command = command:gsub("$fileName", vim.fn.fnamemodify(path, ":t"))
command = command:gsub("$file", path)
@@ -38,15 +40,15 @@ end
-- Check if current buffer is in project
-- if a project return table of project
----@return table?
+---@return table|nil project
local function getProjectRootPath()
local projects = o.get().project
local file_path = vim.fn.expand("%:p")
for project_path, _ in pairs(projects) do
- path_full = vim.fs.normalize(project_path)
+ local path_full = vim.fs.normalize(project_path)
local path_start, path_end = string.find(file_path, path_full)
if path_start == 1 then
- current_project = projects[project_path]
+ local current_project = projects[project_path]
current_project["path"] = string.sub(file_path, path_start, path_end)
return current_project
end
@@ -54,15 +56,21 @@ local function getProjectRootPath()
end
--- Return a command for filetype
----@param filetype string
----@param path string?
----@param user_argument table?
+---@param filetype string|nil
+---@param path? string
+---@param user_argument? table
---@return string?
local function getCommand(filetype, path, user_argument)
local opt = o.get()
path = path or vim.fn.expand("%:p")
local command = opt.filetype[filetype]
- if command then
+ if command == nil or command == "" then
+ vim.notify(
+ string.format("Can't execute filetype/cmd: %s, check your opts/config", filetype),
+ vim.log.levels.WARN,
+ { title = "Code Runner (plugin)" }
+ )
+ else
local command_vim = replaceVars(command, path, user_argument)
return command_vim
end
@@ -70,7 +78,7 @@ end
-- Run command in project context
---@param context table
----@return string?
+---@return string|nil
local function getProjectCommand(context)
local command = nil
if context.file_name then
@@ -90,12 +98,12 @@ local function getProjectCommand(context)
end
--- Close runner
----@param bufname string?
+---@param bufname? string
local function closeRunner(bufname)
- bufname = bufname or pattern .. vim.fn.expand("%:t:r")
+ bufname = bufname or cr_bufname_prefix .. vim.fn.expand("%:t:r")
local current_buf = vim.fn.bufname("%")
- if string.find(current_buf, pattern) then
+ if string.find(current_buf, cr_bufname_prefix) then
vim.cmd("bwipeout!")
else
local bufid = vim.fn.bufnr(bufname)
@@ -108,23 +116,23 @@ end
--- Execute command and create name buffer
---@param command string
---@param bufname string
----@param prefix string?
-local function execute(command, bufname, prefix)
+---@param bufname_prefix? string
+local function execute(command, bufname, bufname_prefix)
local opt = o.get()
local fn = function()
- prefix = prefix or opt.prefix
+ bufname_prefix = bufname_prefix or opt.prefix
local set_bufname = "file " .. bufname
local current_wind_id = vim.api.nvim_get_current_win()
closeRunner(bufname)
- vim.cmd(prefix)
- vim.fn.termopen(command)
+ vim.cmd(bufname_prefix)
+ vim.fn.jobstart(command, {term=true})
vim.cmd("norm G")
vim.opt_local.relativenumber = false
vim.opt_local.number = false
vim.cmd(set_bufname)
- vim.api.nvim_buf_set_option(0, "filetype", "crunner")
- if prefix ~= "tabnew" then
+ vim.api.nvim_set_option_value("filetype", "crunner", { buf = 0 })
+ if bufname_prefix ~= "tabnew" then
vim.bo.buflisted = false
end
if opt.focus then
@@ -142,7 +150,66 @@ local function execute(command, bufname, prefix)
end
end
-btm_number = o.get().better_term.init
+--Execute the selected lines by filetype, display_mode, bufname
+---@param lines string
+---@param display_mode? CodeRunnerDisplayMode
+---@param ft? string
+---@param bufname? string
+---@return nil
+local function executeRange(lines, ft, display_mode, bufname)
+ lines = lines:gsub("'", "'\\''")
+ local current_filetype = ft or vim.bo.ft
+ local cmd = ""
+ if current_filetype == "python" then
+ cmd = string.format("python -c '%s'", lines)
+ elseif current_filetype == "typescript" or current_filetype == "javascript" then
+ cmd = string.format("bun -e '%s'", lines)
+ elseif current_filetype == "clojure" then
+ cmd = string.format("clojure -M -e '%s'", lines)
+ -- cmd = string.format("node -e '%s'", lines)
+ --NOTE: this could be better there are some similarities for the below repl languages
+ -- maybe call getCommand and inject it in string.format() of some similar idea
+ elseif current_filetype == "lua" then
+ cmd = string.format("lua -e '%s'", lines)
+ elseif current_filetype == "ruby" then
+ cmd = string.format("ruby -e '%s'", lines)
+ elseif current_filetype == "elixir" then
+ cmd = string.format("elixir -e '%s'", lines)
+ else
+ vim.notify("Sorry not supported for this filetype", vim.log.levels.INFO, { title = "Code Runner (plugin)" })
+ end
+
+ -- execute(cmd, bufname, "tabnew")
+ display_mode = display_mode or o.get().mode
+ local displayer = M.display_modes[display_mode]
+ bufname = bufname or cr_bufname_prefix .. vim.fn.expand("%:t:r")
+ displayer(cmd, bufname)
+end
+
+-- get the select line range
+---@return string|nil
+local function getTextFromRange(opts)
+ if opts and opts.range ~= 0 then
+ local mode = vim.fn.mode()
+ if mode == "v" or mode == "V" then
+ -- :h getpos()
+ local start_pos = vim.fn.getpos("'<") --> [bufnum, lnum, col, off]
+ local end_pos = vim.fn.getpos("'>") --> [bufnum, lnum, col, off]
+ if end_pos[3] == vim.v.maxcol then -- when mode is "V" the col of '> is v:maxcol
+ end_pos[3] = vim.fn.col("'>") - 1
+ end
+ return table.concat(
+ vim.api.nvim_buf_get_text(0, start_pos[2] - 1, start_pos[3] - 1, end_pos[2] - 1, end_pos[3], {}),
+ "\n"
+ )
+ elseif mode == "n" then
+ return table.concat(vim.api.nvim_buf_get_lines(0, opts.line1 - 1, opts.line2, false), "\n")
+ end
+ end
+end
+
+--External plugin
+local btm_number = o.get().better_term.init
local function betterTermM(command)
local opt = o.get().better_term
local betterTerm_ok, betterTerm = pcall(require, "betterTerm")
@@ -155,51 +222,78 @@ local function betterTermM(command)
betterTerm.send(command, btm_number, { clean = opt.clean })
end
end
+-- }}}
-local M = {}
-
--- Valid modes
-M.modes = {
+-- Valid display modes
+---@class (exact) CodeRunnerDisplayModes
+---@field term function
+---@field tab function
+---@field float function
+---@field better_term function
+---@field toggleterm function
+M.display_modes = {
term = function(command, bufname)
execute(command, bufname)
end,
tab = function(command, bufname)
execute(command, bufname, "tabnew")
end,
- float = function(command, ...)
+ float = function(command, _)
local window = require("code_runner.floats")
window.floating(command)
end,
- better_term = function(command, ...)
+ --External plugin required
+ better_term = function(command, _)
betterTermM(command)
end,
- toggleterm = function(command, ...)
+ --External plugin required
+ toggleterm = function(command, _)
local tcmd = string.format('TermExec cmd="%s"', command)
vim.cmd(tcmd)
end,
}
---- Run according to a mode
+
+--- Run according to a display mode
---@param command string
---@param bufname string
----@param mode string?
-local function runMode(command, bufname, mode)
+---@param display_mode? CodeRunnerDisplayMode
+local function getDisplayMode(command, bufname, display_mode)
local opt = o.get()
- mode = mode or opt.mode
- if mode == "" then
- mode = opt.mode
+ display_mode = display_mode or opt.mode
+ if display_mode == "" then
+ display_mode = opt.mode
+ elseif display_mode == "better_term" and vim.fn.exepath("better_term") == "" then
+ return vim.notify(
+ "external plugin required: https://github.com/CRAG666/betterTerm.nvim\nplease install it, to properly enable this display mode.",
+ vim.log.levels.WARN,
+ { title = "Code Runner (plugin) config" }
+ )
+ elseif display_mode == "toggleterm" and vim.fn.exepath("toggleterm") == "" then
+ return vim.notify(
+ "external plugin required: https://github.com/akinsho/toggleterm.nvim\nplease install it, to properly enable this display mode.",
+ vim.log.levels.WARN,
+ { title = "Code Runner (plugin) config" }
+ )
end
- bufname = pattern .. bufname
- local call_mode = M.modes[mode]
+ local call_mode = M.display_modes[display_mode]
if call_mode == nil then
- vim.notify(":( mode not found, Select valid mode", vim.log.levels.INFO, { title = "Project" })
+ vim.notify(
+ string.format(
+ "Invalid display mode: %s, set one of these valid modes: {'term', 'float', 'tab', 'better_term', 'toggleterm'}.\
+ :h code_runner_settings-mode",
+ display_mode
+ ),
+ vim.log.levels.WARN,
+ { title = "Code Runner (plugin) config:" }
+ )
return
end
+ bufname = cr_bufname_prefix .. bufname
call_mode(command, bufname)
end
-M.run_mode = runMode
-
function M.run_from_fn(cmd)
+ local command = nil
if type(cmd) == "string" then
command = cmd
elseif type(cmd) == "table" then
@@ -207,7 +301,7 @@ function M.run_from_fn(cmd)
end
local path = vim.fn.expand("%:p")
local command_vim = replaceVars(command, path)
- M.run_mode(command_vim, vim.fn.expand("%:t:r"))
+ getDisplayMode(command_vim --[[@as string]], vim.fn.expand("%:t:r"))
end
-- Get command for the current filetype
@@ -216,7 +310,7 @@ function M.get_filetype_command()
return getCommand(filetype) or ""
end
--- Get command for this current project
+-- Get command for the current project
---@return table?
function M.get_project_command()
local project_context = {}
@@ -233,13 +327,19 @@ function M.get_project_command()
end
end
--- Execute current file
----@param mode string?
-function M.run_filetype(mode)
+-- Execute current file with the specified display mode
+-- if called without argument uses the default display mode
+---@param display_mode? CodeRunnerDisplayMode
+---@param opts? table
+function M.run_current_file(display_mode, opts)
+ local code_range = getTextFromRange(opts)
+ if code_range then
+ return executeRange(code_range, nil, display_mode)
+ end
local command = M.get_filetype_command()
if command ~= "" then
- o.get().before_run_filetype()
- runMode(command, vim.fn.expand("%:t:r"), mode)
+ o.get().before_run_filetype() --write buffer
+ getDisplayMode(command, vim.fn.expand("%:t:r"), display_mode)
else
local nvim_files = {
lua = "luafile %",
@@ -251,37 +351,45 @@ function M.run_filetype(mode)
end
--- Run a project associated with the current path
----@param mode string?
----@param notify boolean?
+---@param display_mode? CodeRunnerDisplayMode
+---@param notify? boolean
---@return boolean
-function M.run_project(mode, notify)
+function M.run_project(display_mode, notify)
if notify == nil then
notify = true
end
+ if notify then
+ vim.notify(
+ ":( There is no project associated with this path",
+ vim.log.levels.INFO,
+ { title = "Code Runner plugin" }
+ )
+ end
local project = M.get_project_command()
if project then
- if not mode then
- mode = project.mode
+ if not display_mode then
+ display_mode = project.mode
end
- runMode(project.command, project.name, mode)
+ getDisplayMode(project.command, project.name, display_mode)
return true
end
- if notify then
- vim.notify(":( There is no project associated with this path", vim.log.levels.INFO, { title = "Project" })
- end
return false
end
-- Execute filetype or project
----@param filetype string?
----@param user_argument table?
+---@param filetype? string
+---@param user_argument? table
function M.run_code(filetype, user_argument)
+ local code_range = getTextFromRange(user_argument)
+ if code_range then
+ return executeRange(code_range, filetype)
+ end
if filetype ~= nil and filetype ~= "" then
-- since we have reached here, means we have our command key
local cmd_to_execute = getCommand(filetype, nil, user_argument)
if cmd_to_execute then
- o.get().before_run_filetype()
- runMode(cmd_to_execute, vim.fn.expand("%:t:r"))
+ o.get().before_run_filetype() --write buffer
+ getDisplayMode(cmd_to_execute, vim.fn.expand("%:t:r"))
return
else
-- command was a lua function with no output
@@ -289,23 +397,22 @@ function M.run_code(filetype, user_argument)
return
end
end
- -- procede here if no input arguments
+ -- procure here if no input arguments
local project = M.run_project(nil, false)
if not project then
- M.run_filetype()
+ M.run_current_file()
end
end
---- Close current execution
-function M.run_close()
+--- Close current execution window/viewport
+function M.close_current_execution()
local context = getProjectRootPath()
if context then
- closeRunner(pattern .. context.name)
+ closeRunner(cr_bufname_prefix .. context.name)
else
closeRunner()
end
- -- stop auto_cmd
- au_cd.stop_job()
+ au_cd.stop_job() -- stop auto_cmd
end
return M
diff --git a/lua/code_runner/floats.lua b/lua/code_runner/floats.lua
index a347ff8..6d20abd 100644
--- a/lua/code_runner/floats.lua
+++ b/lua/code_runner/floats.lua
@@ -4,14 +4,19 @@ local o = require("code_runner.options")
function M.floating(command)
local opt = o.get()
local buf = vim.api.nvim_create_buf(false, true)
+
vim.api.nvim_buf_set_keymap(buf, "t", "", "", { silent = true })
vim.api.nvim_buf_set_keymap(buf, "n", opt.float.close_key, "q!", { silent = true })
- vim.api.nvim_buf_set_option(buf, "filetype", "crunner")
- local win_height = math.ceil(vim.api.nvim_get_option("lines") * opt.float.height - 4)
- local win_width = math.ceil(vim.api.nvim_get_option("columns") * opt.float.width)
- local row = math.ceil((vim.api.nvim_get_option("lines") - win_height) * opt.float.y - 1)
- local col = math.ceil((vim.api.nvim_get_option("columns") - win_width) * opt.float.x)
- local opts = {
+ vim.api.nvim_set_option_value("filetype", "crunner", { buf = buf })
+
+ -- stylua: ignore start
+ local win_height = math.ceil(vim.api.nvim_get_option_value("lines", { filetype = "crunner" }) * opt.float.height - 4)
+ local win_width = math.ceil(vim.api.nvim_get_option_value("columns", { filetype = "crunner" }) * opt.float.width)
+ local row = math.ceil((vim.api.nvim_get_option_value("lines", { filetype = "crunner" }) - win_height) * opt.float.y - 1)
+ local col = math.ceil((vim.api.nvim_get_option_value("columns", { filetype = "crunner" }) - win_width) * opt.float.x)
+ -- stylua: ignore end
+
+ local config = {
style = "minimal",
relative = "editor",
border = opt.float.border,
@@ -20,16 +25,19 @@ function M.floating(command)
row = row,
col = col,
}
- local win = vim.api.nvim_open_win(buf, true, opts)
- vim.fn.termopen(command)
+ local win_id = vim.api.nvim_open_win(buf, true, config)
+
+ vim.api.nvim_set_option_value(
+ "winhl",
+ "Normal:" .. opt.float.float_hl .. ",FloatBorder:" .. opt.float.border_hl,
+ { win = win_id }
+ )
+ vim.api.nvim_set_option_value("winblend", opt.float.blend, { win = win_id })
+
+ vim.fn.jobstart(command, {term=true})
if opt.startinsert then
vim.cmd("startinsert")
end
- if opt.wincmd then
- vim.cmd("wincmd p")
- end
- vim.api.nvim_win_set_option(win, "winhl", "Normal:" .. opt.float.float_hl .. ",FloatBorder:" .. opt.float.border_hl)
- vim.api.nvim_win_set_option(win, "winblend", opt.float.blend)
end
return M
diff --git a/lua/code_runner/hooks/preview_pdf.lua b/lua/code_runner/hooks/preview_pdf.lua
index 9edc011..e2a2ca9 100644
--- a/lua/code_runner/hooks/preview_pdf.lua
+++ b/lua/code_runner/hooks/preview_pdf.lua
@@ -1,7 +1,7 @@
local Job = require("plenary.job")
local hook = require("code_runner.hooks.autocmd")
-function replaceElement(table, replacement_table)
+local function replaceElement(table, replacement_table)
for i, value in ipairs(table) do
if replacement_table[value] then
table[i] = replacement_table[value]
diff --git a/lua/code_runner/load_json.lua b/lua/code_runner/load_json.lua
index a0ce4b5..fd60b02 100644
--- a/lua/code_runner/load_json.lua
+++ b/lua/code_runner/load_json.lua
@@ -1,7 +1,7 @@
-- Load json and convert to table
---@param json_path string
---@return table | nil
-function load_as_table(json_path)
+local function load_as_table(json_path)
local contents = ""
local file = io.open(json_path, "r")
diff --git a/lua/code_runner/options.lua b/lua/code_runner/options.lua
index 034faf1..493f1a7 100644
--- a/lua/code_runner/options.lua
+++ b/lua/code_runner/options.lua
@@ -1,36 +1,27 @@
-local options = {
- -- choose default mode (valid term, tab, float, toggle)
- mode = "term",
- -- add hot reload
- hot_reload = true,
- -- Focus on runner window(only works on toggle, term and tab mode)
- focus = true,
- -- startinsert (see ':h inserting-ex')
- startinsert = false,
- insert_prefix = "",
- term = {
- -- Position to open the terminal, this option is ignored if mode ~= term
- position = "bot",
- -- window size, this option is ignored if mode == tab
- size = 12,
+---@type CodeRunnerOptions
+local default_options = {
+ mode = "term", -- default display mode
+ hot_reload = true, -- hot reload enabled/disabled
+ focus = false, -- Focus window/viewport on the buffer (only works term and tab display mode)
+ startinsert = false, -- startinsert (see ':h inserting-ex')
+ insert_prefix = "", -- this key is controlled by startinsert
+ term = { -- this configs are ignored if mode ~= "term"
+ position = "vert", -- Position to open the terminal,
+ size = 64, -- window size, if position 'bot'(bottom) 8 is a good default
},
float = {
close_key = "",
- -- Window border (see ':h nvim_open_win')
- border = "none",
+ border = "solid", -- Window border (see ':h nvim_open_win()' ; /border)
- -- Num from `0 - 1` for measurements
height = 0.8,
width = 0.8,
x = 0.5,
y = 0.5,
- -- Highlight group for floating window/border (see ':h winhl')
- border_hl = "FloatBorder",
+ border_hl = "FloatBorder", -- Highlight group for floating window/border (see ':h winhl')
float_hl = "Normal",
- -- Transparency (see ':h winblend')
- blend = 0,
+ blend = 0, -- Transparency (see ':h winblend')
},
better_term = { -- Toggle mode replacement
clean = false, -- Clean terminal before launch
@@ -84,18 +75,18 @@ local function concat(v)
end
-- set user config
----@param user_options table
+---@param user_options CodeRunnerUserOptions
M.set = function(user_options)
if user_options.startinsert then
user_options.insert_prefix = "startinsert"
end
- options = vim.tbl_deep_extend("force", options, user_options)
- options.filetype = vim.tbl_map(concat, options.filetype)
- options.prefix = string.format("%s %d new", options.term.position, options.term.size)
+ default_options = vim.tbl_deep_extend("force", default_options, user_options)
+ default_options.filetype = vim.tbl_map(concat, default_options.filetype)
+ default_options.prefix = string.format("%s %d new", default_options.term.position, default_options.term.size)
end
M.get = function()
- return options
+ return default_options
end
return M
diff --git a/types/options.lua b/types/options.lua
new file mode 100644
index 0000000..4654594
--- /dev/null
+++ b/types/options.lua
@@ -0,0 +1,69 @@
+---@meta
+
+--- Don't edit or require this file
+error("Requiring a meta file")
+
+-- Code Runner Options (Library)
+---@class CodeRunnerOptions
+---@field mode CodeRunnerDisplayMode
+---@field hot_reload boolean
+---@field focus boolean
+---@field startinsert boolean
+---@field filetype table
+---@field prefix string
+---@field term CodeRunnerOptionsTermTable
+---@field float CodeRunnerOptionsFloatTable
+
+---@type CodeRunnerDisplayMode
+---@alias CodeRunnerDisplayMode
+---|'"term"'
+---|'"float"'
+---|'"tab"'
+---|'"better_term"'
+---|'"toggleterm"'
+
+-- configuration for term display mode
+---@class CodeRunnerOptionsTermTable
+---@field position ("vert"|"bot")
+---@field size number
+
+---@class CodeRunnerOptionsFloatTable
+---@field close_key string keymap to close (default: )
+---@field height number number from `0 - 1` e.g 0.8 for measurements
+---@field width number number from `0 - 1` e.g 0.8 for measurements
+---@field x number
+---@field y number
+---@field border ("none"|"single"|"double"|"rounded"|"solid"|"shadow") | string[] string[]: length must be 8 e.g {"╔", "═" ,"╗", "║", "╝", "═", "╚", "║"}
+---@field blend number
+---@field border_hl string
+---@field float_hl string
+
+
+-- User Options (Client)
+---@class CodeRunnerUserOptions : CodeRunnerOptions
+---@field mode? CodeRunnerDisplayMode
+---@field hot_reload? boolean enabled/disabled (only works with 'term' or term like display modes)
+---@field focus? boolean Focus on runner window/viewport (only works on 'term' and 'tab' display mode)
+---@field insert_prefix? string
+---@field startinsert? boolean startinsert (see ':h inserting-ex') if focus is false has no effect unless display mode is 'float'
+---@field filetype? table ft entries, is unknown run :=vim.bo.ft
+---@field prefix? string
+---@field term? CodeRunnerUserOptionsTermTable
+---@field float? CodeRunnerUserOptionsFloatTable
+
+-- configuration for term display mode
+---@class CodeRunnerUserOptionsTermTable
+---@field position? ("vert"|"bot")
+---@field size? number
+
+-- configuration for float display mode
+---@class CodeRunnerUserOptionsFloatTable
+---@field close_key? string keymap to close (default: )
+---@field height? number
+---@field width? number
+---@field x? number
+---@field y? number
+---@field border? ("none"|"single"|"double"|"rounded"|"solid"|"shadow") | string[] string[]: length must be 8 e.g {"╔", "═" ,"╗", "║", "╝", "═", "╚", "║"}
+---@field blend? number
+---@field border_hl? string
+---@field float_hl? string