diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2a9bd57..931503b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,6 +29,10 @@ jobs: documentation: runs-on: ubuntu-latest name: documentation + permissions: + # This gives the default GITHUB_TOKEN write permission to commit and push the + # added or changed files to the reposito + contents: write steps: - uses: actions/checkout@v4 with: @@ -38,13 +42,27 @@ jobs: uses: rhysd/action-setup-vim@v1 with: neovim: true - version: v0.11.0 + version: stable - name: generate documentation - run: make documentation-ci + uses: kdheepak/panvimdoc@main + with: + vimdoc: copy-python-path + pandoc: README.md + version: Neovim >= 0.8.0 + demojify: true + + - name: generate tags + run: | + nvim --headless -c 'helptags doc' -c 'quit' - - name: check docs diff - run: exit $(git status --porcelain doc | wc -l | tr -d " ") + - name: push changes + uses: stefanzweifel/git-auto-commit-action@v6 + with: + commit_message: "docs(vimdoc): auto-generate vimdocs" + commit_user_name: "github-actions[bot]" + commit_user_email: "github-actions[bot]@users.noreply.github.com" + commit_author: "github-actions[bot] " tests: needs: @@ -54,7 +72,7 @@ jobs: timeout-minutes: 1 strategy: matrix: - neovim_version: ['v0.9.5', 'v0.10.1', 'v0.11.0'] + neovim_version: ["v0.8.0", "v0.9.5", "v0.10.4", "v0.11.0"] steps: - uses: actions/checkout@v4 diff --git a/.luarc.json b/.luarc.json index f7cbd2c..ac2bc39 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,5 +1,3 @@ { - "diagnostics.globals": [ - "MiniTest" - ] -} \ No newline at end of file + "diagnostics.globals": ["MiniTest", "vim"] +} diff --git a/Makefile b/Makefile index e06a23a..b12f05d 100644 --- a/Makefile +++ b/Makefile @@ -18,18 +18,12 @@ deps: # installs deps before running tests, useful for the CI. test-ci: deps test -# generates the documentation. -documentation: - nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "lua require('mini.doc').generate()" -c "qa!" - -# installs deps before running the documentation generation, useful for the CI. -documentation-ci: deps documentation - # performs a lint check and fixes issue if possible, following the config in `.editorconfig`. lint: stylua . -g '*.lua' -g '!deps/' -g '!nightly/' luacheck plugin/ lua/ +# LuaLS is more capable than luacheck (e.g. catch type errors) luals-ci: rm -rf .ci/lua-ls/log lua-language-server --configpath .luarc.json --logpath .ci/lua-ls/log --check . diff --git a/README.md b/README.md index 97e2335..0b37494 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Neovim plugin to copy the reference path of a Python symbol. # Installation -Requires Neovim >=0.7.0. +Requires Neovim >=0.8.0. With [folke/lazy.nvim](https://github.com/folke/lazy.nvim): diff --git a/doc/copy-python-path.txt b/doc/copy-python-path.txt index e69de29..e589e9f 100644 --- a/doc/copy-python-path.txt +++ b/doc/copy-python-path.txt @@ -0,0 +1,217 @@ +*copy-python-path.txt* For Neovim >= 0.8.0 Last change: 2025 July 01 + +============================================================================== +Table of Contents *copy-python-path-table-of-contents* + +1. copy-python-path.nvim |copy-python-path-copy-python-path.nvim| +2. Features |copy-python-path-features| +3. Installation |copy-python-path-installation| +4. Gettingstarted |copy-python-path-gettingstarted| + - Path format examples|copy-python-path-gettingstarted-path-format-examples| + - Custom keymappings |copy-python-path-gettingstarted-custom-keymappings| +5. Command |copy-python-path-command| +6. API |copy-python-path-api| + - get_path_under_cursor |copy-python-path-api-get_path_under_cursor| +7. Similar Work |copy-python-path-similar-work| + +============================================================================== +1. copy-python-path.nvim *copy-python-path-copy-python-path.nvim* + +Neovim plugin to copy the reference path of a Python symbol. + + + + +============================================================================== +2. Features *copy-python-path-features* + +- Supports copying different path formats (see |copy-python-path-examples|): + - Dotted path (e.g. `some.module.func_1`) + - Import path (e.g. `from some.module import func_1`) +- Supports various Python symbol definitions (see |copy-python-path-getting-started|) +- Simple Python project root detection +- Allow copy to user-specified register +- No LSP setup required + + +============================================================================== +3. Installation *copy-python-path-installation* + +Requires Neovim >=0.8.0. + +With folke/lazy.nvim + +>lua + -- Stable version + { 'AnsonH/copy-python-path.nvim', version = '*' } +< + +Withwbthomason/packer.nvim + +>lua + -- Stable version + use {"AnsonH/copy-python-path.nvim", tag = "*" } +< + + +============================================================================== +4. Gettingstarted *copy-python-path-gettingstarted* + +Open a Python file and place the cursor on the following supported symbols: + +- Function definitions (e.g. `def func_1()`, `async def func_2()`) +- Class definitions (e.g. `class MyClass:`) +- Class methods and inner classes +- Module-level variable definitions +- Imported symbols (e.g. `import numpy as np`, `from some.module import func_1`) + +Then, run the command `:CopyPythonPath ` to copy to clipboard: + +- `:CopyPythonPath dotted` - Copies the dotted path (e.g. `some.module.func_1`) +- `:CopyPythonPath import` - Copies the import path (e.g. `from some.module import func_1`) + + +PATH FORMAT EXAMPLES *copy-python-path-gettingstarted-path-format-examples* + +Let’s say we have a file called `app.py` + +>py + """ app.py """ + import numpy as np + from user.models import User + + # (1) 👇 + def func_1(): + pass + + # (2) 👇 + async def func_2(): + pass + + # (3) 👇 + class MyClass: + # (4) 👇 + class Meta: + pass + + # (5) 👇 + def method_1(self): + # (6) 👇 + User() + # (7) 👇 + return np.array([]) + + # (8) 👇 + MODULE_VAR = 'foo' +< + + ---------------------------------------------------------------------------------- + CursorLocation :CopyPythonPath dotted :CopyPythonPath import + ------------------------- ------------------------ ------------------------------- + (1) Function definition app.func_1 from app import func_1 + + (2) Async function app.func_2 from app import func_2 + definition + + (3) Class definition app.MyClass from app import MyClass + + (4) Inner class app.MyClass.Meta from app import MyClass¹ + + (5) Class method app.MyClass.method_1 from app import MyClass¹ + + (6) Imported symbol user.models.User from user.models import User² + + (7) Imported symbol with numpy import numpy + alias + + (8) Module-level variable app.MODULE_VAR from app import MODULE_VAR + + Elsewhere in the file app from app import + ---------------------------------------------------------------------------------- +Notes: + +1. Inner classes and class methods cannot be directly imported, so it only imports the outer class. +2. When the symbol is imported, it copies the original path of where it was imported from. + + +CUSTOM KEYMAPPINGS *copy-python-path-gettingstarted-custom-keymappings* + +This plugin does NOT set up any keymappings by default. You can define custom +keymappings in your Neovim config, for example: + +>lua + vim.api.nvim_set_keymap('n', 'yd', ':CopyPythonPath dotted', { noremap = true, silent = true }) + vim.api.nvim_set_keymap('n', 'yi', ':CopyPythonPath import', { noremap = true, silent = true }) +< + + +============================================================================== +5. Command *copy-python-path-command* + +> + :CopyPythonPath [] +< + +Copies the reference path of the Python symbol under the cursor. + + -------------------------------------------------------------------------- + Argument Description Accepted Values Default Value + ---------- ----------------------------- ------------------- ------------- + format The path format to copy dotted, import N.A. + (required) + + register (optional) The register to Any valid register + (clipboard) + copy to name + -------------------------------------------------------------------------- + +============================================================================== +6. API *copy-python-path-api* + +The plugin API is available via: + +>lua + local copy_python_path = require('copy-python-path') +< + + +GET_PATH_UNDER_CURSOR *copy-python-path-api-get_path_under_cursor* + +Gets the Python path of the symbol underneath the cursor. + +>lua + --- Gets the Python path of the symbol underneath the cursor. + ---@param format string The Python path format. Accepted values are: + --- - `"dotted"`: Dotted path (e.g. `user.models.User`) + --- - `"import"`: Import statement (e.g. `from user.models import User`) + ---@return string path + copy_python_path.get_path_under_cursor(format) +< + +Example: Copy the shell command for running a Django test: + +>lua + -- e.g. `./manage.py test some.module.func_1` + vim.api.nvim_create_user_command("CopyDjangoTestCommand", function(opts) + local copy_python_path = require("copy-python-path") + + local path = copy_python_path.get_path_under_cursor("dotted") + local command = "./manage.py test " .. path + + vim.fn.setreg("+", command) + end, {}) +< + + +============================================================================== +7. Similar Work *copy-python-path-similar-work* + +- kawamataryo/copy-python-path - VS Code plugin that inspired this project +- ranelpadon/python-copy-reference.vim - Vim Script plugin with similar functionality + +Special thanks to neovim-plugin-boilerplate + for the plugin +boilerplate code. + +Generated by panvimdoc + +vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/doc/tags b/doc/tags new file mode 100644 index 0000000..d0faf8f --- /dev/null +++ b/doc/tags @@ -0,0 +1,12 @@ +copy-python-path-api copy-python-path.txt /*copy-python-path-api* +copy-python-path-api-get_path_under_cursor copy-python-path.txt /*copy-python-path-api-get_path_under_cursor* +copy-python-path-command copy-python-path.txt /*copy-python-path-command* +copy-python-path-copy-python-path.nvim copy-python-path.txt /*copy-python-path-copy-python-path.nvim* +copy-python-path-features copy-python-path.txt /*copy-python-path-features* +copy-python-path-gettingstarted copy-python-path.txt /*copy-python-path-gettingstarted* +copy-python-path-gettingstarted-custom-keymappings copy-python-path.txt /*copy-python-path-gettingstarted-custom-keymappings* +copy-python-path-gettingstarted-path-format-examples copy-python-path.txt /*copy-python-path-gettingstarted-path-format-examples* +copy-python-path-installation copy-python-path.txt /*copy-python-path-installation* +copy-python-path-similar-work copy-python-path.txt /*copy-python-path-similar-work* +copy-python-path-table-of-contents copy-python-path.txt /*copy-python-path-table-of-contents* +copy-python-path.txt copy-python-path.txt /*copy-python-path.txt* diff --git a/tests/test_command.lua b/tests/test_command.lua index bf18814..e413a91 100644 --- a/tests/test_command.lua +++ b/tests/test_command.lua @@ -96,6 +96,11 @@ T[":CopyPythonPath"]["import"]["nested Python file"] = function() end T[":CopyPythonPath"]["copies to clipboard if no register is provided"] = function() + -- CI env may not have clipboard, so skipping it + if child.fn.has("clipboard") == 0 then + return + end + child.api.nvim_command(EDIT_ROOT_FILE_COMMAND) child.api.nvim_win_set_cursor(0, { 5, 5 })