From 2c251c8a6171ae5697230890d0be92d582a35760 Mon Sep 17 00:00:00 2001 From: Lukas Reineke Date: Fri, 26 Nov 2021 16:45:50 +0900 Subject: [PATCH] Version 1.0.0 --- .github/FUNDING.yml | 1 + .github/workflows/pr_check.yml | 22 +++++++ LICENSE.md | 21 +++++++ README.md | 53 +++++++++++++++++ doc/virt-column.txt | 104 +++++++++++++++++++++++++++++++++ lua/virt-column/init.lua | 81 +++++++++++++++++++++++++ stylua.toml | 4 ++ 7 files changed, 286 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .github/workflows/pr_check.yml create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 doc/virt-column.txt create mode 100644 lua/virt-column/init.lua create mode 100644 stylua.toml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..0307e85 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [lukas-reineke] diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml new file mode 100644 index 0000000..d820cb5 --- /dev/null +++ b/.github/workflows/pr_check.yml @@ -0,0 +1,22 @@ +name: Pull request check + +on: + pull_request: + +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: JohnnyMorganz/stylua-action@1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + args: --check . + + block-fixup: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Block Fixup Commit Merge + uses: 13rac1/block-fixup-merge-action@v2.0.0 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..f38dc29 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +The MIT Licence + +Copyright (c) 2021 Lukas Reineke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f591c2a --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# virt-column.nvim + +Display a character as the colorcolumn. + +Screenshot + +## Install + +Use your favourite plugin manager to install. + +#### Example with Packer + +[wbthomason/packer.nvim](https://github.com/wbthomason/packer.nvim) + +```lua +-- init.lua +require("packer").startup( + function() + use "lukas-reineke/virt-column.nvim" + end +) +``` + +#### Example with Plug + +[junegunn/vim-plug](https://github.com/junegunn/vim-plug) + +```vim +" init.vim +call plug#begin('~/.vim/plugged') +Plug 'lukas-reineke/virt-column.nvim' +call plug#end() +``` + +## Setup + +To configure virt-column.nvim you need to run the setup function. + +```lua +require("virt-column").setup() +``` + +Please see `:help virt-column.txt`for more details and all possible values. + +You probably want to clear the old `ColorColumn` highlight if you use this. + +```vim +highlight clear ColorColumn +``` + +## Thanks + +Thank you @francium for the idea. diff --git a/doc/virt-column.txt b/doc/virt-column.txt new file mode 100644 index 0000000..37523da --- /dev/null +++ b/doc/virt-column.txt @@ -0,0 +1,104 @@ +*virt-column.txt* Display a character as the colorcolumn + + +Author: Lukas Reineke +Version: 1.0.0 + +============================================================================== +CONTENTS *virt-column.nvim* + + 1. Setup |virt-column-setup| + 2. Highlights |virt_column-highlights| + 3. Options |virt-column-options| + 4. Commands |virt-column-commands| + 5. Changelog |virt-column-changelog| + 6. License |virt-column-license| + +============================================================================== + 1. SETUP *virt-column-setup* + + Call the setup function + > + require("virt-column").setup() + +============================================================================== + 2. HIGHLIGHTS *virt-column-highlights* + +------------------------------------------------------------------------------ +VirtColumn *hl-VirtColumn* + + Highlight of virtual column character. + + Default: linked to Whitespace ~ + + Example: > + + highlight VirtColumn guifg=#00FF00 + +============================================================================== + 2. OPTIONS *virt-column-options* + + Options can be passed as a table to the setup function + > + require("virt-column").setup { char = "║" } + + +------------------------------------------------------------------------------ +char *virt-column-char* + + The char that will be displayed as the |colorcolumn| + + Default: ┃ ~ + +============================================================================== + 3. COMMANDS *virt-column-commands* + +------------------------------------------------------------------------------ +:VirtColumnRefresh *VirtColumnRefresh* + + Refreshes the virtual column + Run this with |autocmd| when the file changes. + + By default it is run for: + 1. |FileChangedShellPost| * + 2. |TextChanged| * + 3. |TextChangedI| * + 4. |CompleteChanged| * + 5. |BufWinEnter| * + 6. |WinScrolled| * + 7. |OptionSet| colorcolumn + +============================================================================== + 4. CHANGELOG *virt-column-changelog* + +1.0.0 + * First release + +============================================================================== + 5. LICENSE *virt-column-license* + +The MIT Licence +http://www.opensource.org/licenses/mit-license.php + +Copyright (c) 2021 Lukas Reineke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +============================================================================== +vim:tw=78:ts=8:ft=help:norl diff --git a/lua/virt-column/init.lua b/lua/virt-column/init.lua new file mode 100644 index 0000000..8920888 --- /dev/null +++ b/lua/virt-column/init.lua @@ -0,0 +1,81 @@ +local ffi = require "ffi" + +ffi.cdef "int curwin_col_off(void);" + +local M = { + config = { + char = "┃", + }, +} + +M.clear_buf = function(bufnr) + if M.namespace then + vim.api.nvim_buf_clear_namespace(bufnr, M.namespace, 0, -1) + end +end + +M.setup = function(config) + M.config = vim.tbl_deep_extend("force", M.config, config or {}) + M.namespace = vim.api.nvim_create_namespace "virt-column" + + vim.cmd [[command! VirtColumnRefresh lua require("virt-column").refresh()]] + vim.cmd [[highlight link VirtColumn Whitespace]] + + vim.cmd [[ + augroup VirtColumnAutogroup + autocmd! + autocmd FileChangedShellPost,TextChanged,TextChangedI,CompleteChanged,BufWinEnter,WinScrolled * VirtColumnRefresh + autocmd OptionSet colorcolumn VirtColumnRefresh + augroup END + ]] +end + +M.refresh = function() + local bufnr = 0 + local win_start = vim.fn.line "w0" + local win_end = vim.fn.line "w$" + local offset = math.max(win_start - 11, 0) + local range = math.min(win_end + 11, vim.api.nvim_buf_line_count(bufnr)) + local lines = vim.api.nvim_buf_get_lines(bufnr, offset, range, false) + local width = vim.api.nvim_win_get_width(0) - ffi.C.curwin_col_off() + local textwidth = vim.opt.textwidth:get() + local colorcolumn = vim.opt.colorcolumn:get() + + for i, c in ipairs(colorcolumn) do + if vim.startswith(c, "+") then + colorcolumn[i] = textwidth + tonumber(c:sub(2)) + elseif vim.startswith(c, "-") then + colorcolumn[i] = textwidth - tonumber(c:sub(2)) + else + colorcolumn[i] = tonumber(c) + end + end + + table.sort(colorcolumn, function(a, b) + return a > b + end) + + M.clear_buf() + + for i = 1, #lines, 1 do + local current_offset = 0 + local virt_text = {} + for _, column in ipairs(colorcolumn) do + local line = lines[i]:gsub("\t", string.rep(" ", vim.opt.tabstop:get())) + if width > column and vim.api.nvim_strwidth(line) < column then + table.insert(virt_text, 1, { string.rep(" ", width - column - current_offset) }) + table.insert(virt_text, 1, { M.config.char, "VirtColumn" }) + current_offset = width - column + 1 + end + end + if #virt_text > 0 then + vim.api.nvim_buf_set_extmark(bufnr, M.namespace, i - 1 + offset, 0, { + virt_text = virt_text, + virt_text_pos = "right_align", + hl_mode = "combine", + }) + end + end +end + +return M diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..fa346d0 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,4 @@ +line_endings = "Unix" +indent_type = "Spaces" +indent_width = 4 +no_call_parentheses = true