Giter Club home page Giter Club logo

no-neck-pain.nvim's Introduction

☕ no-neck-pain.nvim

Dead simple plugin to center the currently focused buffer to the middle of the screen.

showcase.mp4

⚡️ Features

Creates evenly sized empty buffers on each side of your focused buffer, which acts as padding for your window.

Want to see it in action? Take a look at the showcase section

📋 Installation

Package manager Snippet

wbthomason/packer.nvim

-- stable version
use {"shortcuts/no-neck-pain.nvim", tag = "*" }
-- dev version
use {"shortcuts/no-neck-pain.nvim"}

junegunn/vim-plug

-- stable version
Plug 'shortcuts/no-neck-pain.nvim', { 'tag': '*' }
-- dev version
Plug 'shortcuts/no-neck-pain.nvim'

folke/lazy.nvim

-- stable version
require("lazy").setup({{"shortcuts/no-neck-pain.nvim", version = "*"}})
-- dev version
require("lazy").setup({"shortcuts/no-neck-pain.nvim"})

🏗 v1.0.0 breaking changes

See the release description for the full list of breaking changes.

☄ Getting started

No configuration/setup steps needed! Sit back, relax and call :NoNeckPain.

⚙ Configuration

Note: Need some inspiration on customizing your experience? Take a look at the showcase

Click to unfold the full list of options with their default values

Note: The options are also available in Neovim by using:

  • :h NoNeckPain.options to see the global plugin options.
  • :h NoNeckPain.bufferOptions to see the side buffer options.
require("no-neck-pain").setup({
    -- Prints useful logs about triggered events, and reasons actions are executed.
    --- @type boolean
    debug = false,
    -- The width of the focused window that will be centered. When the terminal width is less than the `width` option, the side buffers won't be created.
    --- @type integer|"textwidth"|"colorcolumn"
    width = 100,
    -- Represents the lowest width value a side buffer should be.
    -- This option can be useful when switching window size frequently, example:
    -- in full screen screen, width is 210, you define an NNP `width` of 100, which creates each side buffer with a width of 50. If you resize your terminal to the half of the screen, each side buffer would be of width 5 and thereforce might not be useful and/or add "noise" to your workflow.
    --- @type integer
    minSideBufferWidth = 10,
    -- Disables the plugin if the last valid buffer in the list have been closed.
    --- @type boolean
    disableOnLastBuffer = false,
    -- When `true`, disabling the plugin closes every other windows except the initially focused one.
    --- @type boolean
    killAllBuffersOnDisable = false,
    -- Adds autocmd (@see `:h autocmd`) which aims at automatically enabling the plugin.
    --- @type table
    autocmds = {
        -- When `true`, enables the plugin when you start Neovim.
        -- If the main window is  a side tree (e.g. NvimTree) or a dashboard, the command is delayed until it finds a valid window.
        -- The command is cleaned once it has successfuly ran once.
        --- @type boolean
        enableOnVimEnter = false,
        -- When `true`, enables the plugin when you enter a new Tab.
        -- note: it does not trigger if you come back to an existing tab, to prevent unwanted interfer with user's decisions.
        --- @type boolean
        enableOnTabEnter = false,
        -- When `true`, reloads the plugin configuration after a colorscheme change.
        --- @type boolean
        reloadOnColorSchemeChange = false,
        -- When `true`, entering one of no-neck-pain side buffer will automatically skip it and go to the next available buffer.
        --- @type boolean
        skipEnteringNoNeckPainBuffer = false,
    },
    -- Creates mappings for you to easily interact with the exposed commands.
    --- @type table
    mappings = {
        -- When `true`, creates all the mappings that are not set to `false`.
        --- @type boolean
        enabled = false,
        -- Sets a global mapping to Neovim, which allows you to toggle the plugin.
        -- When `false`, the mapping is not created.
        --- @type string
        toggle = "<Leader>np",
        -- Sets a global mapping to Neovim, which allows you to toggle the left side buffer.
        -- When `false`, the mapping is not created.
        --- @type string
        toggleLeftSide = "<Leader>nql",
        -- Sets a global mapping to Neovim, which allows you to toggle the right side buffer.
        -- When `false`, the mapping is not created.
        --- @type string
        toggleRightSide = "<Leader>nqr",
        -- Sets a global mapping to Neovim, which allows you to increase the width (+5) of the main window.
        -- When `false`, the mapping is not created.
        --- @type string | { mapping: string, value: number }
        widthUp = "<Leader>n=",
        -- Sets a global mapping to Neovim, which allows you to decrease the width (-5) of the main window.
        -- When `false`, the mapping is not created.
        --- @type string | { mapping: string, value: number }
        widthDown = "<Leader>n-",
        -- Sets a global mapping to Neovim, which allows you to toggle the scratchPad feature.
        -- When `false`, the mapping is not created.
        --- @type string
        scratchPad = "<Leader>ns",
    },
    --- Common options that are set to both side buffers.
    --- See |NoNeckPain.bufferOptions| for option scoped to the `left` and/or `right` buffer.
    --- @type table
    buffers = {
        -- When `true`, the side buffers will be named `no-neck-pain-left` and `no-neck-pain-right` respectively.
        --- @type boolean
        setNames = false,
        -- Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
        -- note: quitting an unsaved scratchPad buffer is non-blocking, and the content is still saved.
        --- see |NoNeckPain.bufferOptionsScratchPad|
        scratchPad = NoNeckPain.bufferOptionsScratchPad,
        -- colors to apply to both side buffers, for buffer scopped options @see |NoNeckPain.bufferOptions|
        --- see |NoNeckPain.bufferOptionsColors|
        colors = NoNeckPain.bufferOptionsColors,
        -- Vim buffer-scoped options: any `vim.bo` options is accepted here.
        --- @see NoNeckPain.bufferOptionsBo `:h NoNeckPain.bufferOptionsBo`
        bo = NoNeckPain.bufferOptionsBo,
        -- Vim window-scoped options: any `vim.wo` options is accepted here.
        --- @see NoNeckPain.bufferOptionsWo `:h NoNeckPain.bufferOptionsWo`
        wo = NoNeckPain.bufferOptionsWo,
        --- Options applied to the `left` buffer, options defined here overrides the `buffers` ones.
        --- @see NoNeckPain.bufferOptions `:h NoNeckPain.bufferOptions`
        left = NoNeckPain.bufferOptions,
        --- Options applied to the `right` buffer, options defined here overrides the `buffers` ones.
        --- @see NoNeckPain.bufferOptions `:h NoNeckPain.bufferOptions`
        right = NoNeckPain.bufferOptions,
    },
    -- Supported integrations that might clash with `no-neck-pain.nvim`'s behavior.
    --- @type table
    integrations = {
        -- By default, if NvimTree is open, we will close it and reopen it when enabling the plugin,
        -- this prevents having the side buffers wrongly positioned.
        -- @link https://github.com/nvim-tree/nvim-tree.lua
        --- @type table
        NvimTree = {
            -- The position of the tree.
            --- @type "left"|"right"
            position = "left",
            -- When `true`, if the tree was opened before enabling the plugin, we will reopen it.
            --- @type boolean
            reopen = true,
        },
        -- By default, if NeoTree is open, we will close it and reopen it when enabling the plugin,
        -- this prevents having the side buffers wrongly positioned.
        -- @link https://github.com/nvim-neo-tree/neo-tree.nvim
        NeoTree = {
            -- The position of the tree.
            --- @type "left"|"right"
            position = "left",
            -- When `true`, if the tree was opened before enabling the plugin, we will reopen it.
            reopen = true,
        },
        -- @link https://github.com/mbbill/undotree
        undotree = {
            -- The position of the tree.
            --- @type "left"|"right"
            position = "left",
        },
        -- @link https://github.com/nvim-neotest/neotest
        neotest = {
            -- The position of the tree.
            --- @type "right"
            position = "right",
            -- When `true`, if the tree was opened before enabling the plugin, we will reopen it.
            reopen = true,
        },
        -- @link https://github.com/nvim-treesitter/playground
        TSPlayground = {
            -- The position of the tree.
            --- @type "right"|"left"
            position = "right",
            -- When `true`, if the tree was opened before enabling the plugin, we will reopen it.
            reopen = true,
        },
        -- @link https://github.com/rcarriga/nvim-dap-ui
        NvimDAPUI = {
            -- The position of the tree.
            --- @type "none"
            position = "none",
            -- When `true`, if the tree was opened before enabling the plugin, we will reopen it.
            reopen = true,
        },
        -- @link https://github.com/hedyhli/outline.nvim
        outline = {
            -- The position of the tree.
            --- @type "left"|"right"
            position = "right",
            -- When `true`, if the tree was opened before enabling the plugin, we will reopen it.
            reopen = true,
        },
    },
})

NoNeckPain.bufferOptions = {
    -- When `false`, the buffer won't be created.
    --- @type boolean
    enabled = true,
    --- @see NoNeckPain.bufferOptionsColors `:h NoNeckPain.bufferOptionsColors`
    colors = NoNeckPain.bufferOptionsColors,
    --- @see NoNeckPain.bufferOptionsBo `:h NoNeckPain.bufferOptionsBo`
    bo = NoNeckPain.bufferOptionsBo,
    --- @see NoNeckPain.bufferOptionsWo `:h NoNeckPain.bufferOptionsWo`
    wo = NoNeckPain.bufferOptionsWo,
    --- @see NoNeckPain.bufferOptionsScratchPad `:h NoNeckPain.bufferOptionsScratchPad`
    scratchPad = NoNeckPain.bufferOptionsScratchPad,
}

NoNeckPain.bufferOptionsWo = {
    --- @type boolean
    cursorline = false,
    --- @type boolean
    cursorcolumn = false,
    --- @type string
    colorcolumn = "0",
    --- @type boolean
    number = false,
    --- @type boolean
    relativenumber = false,
    --- @type boolean
    foldenable = false,
    --- @type boolean
    list = false,
    --- @type boolean
    wrap = true,
    --- @type boolean
    linebreak = true,
}

NoNeckPain.bufferOptionsBo = {
    --- @type string
    filetype = "no-neck-pain",
    --- @type string
    buftype = "nofile",
    --- @type string
    bufhidden = "hide",
    --- @type boolean
    buflisted = false,
    --- @type boolean
    swapfile = false,
}

--- NoNeckPain's scratchPad buffer options.
---
--- Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
--- note: quitting an unsaved scratchPad buffer is non-blocking, and the content is still saved.
---
---@type table
---Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
NoNeckPain.bufferOptionsScratchPad = {
    -- When `true`, automatically sets the following options to the side buffers:
    -- - `autowriteall`
    -- - `autoread`.
    --- @type boolean
    enabled = false,
    -- The path to the file to save the scratchPad content to and load it in the buffer.
    --- @type string?
    --- @example: `~/notes.norg`
    pathToFile = "",
}

NoNeckPain.bufferOptionsColors = {
    -- Hexadecimal color code to override the current background color of the buffer. (e.g. #24273A)
    -- Transparent backgrounds are supported by default.
    --- @type string?
    background = nil,
    -- Brighten (positive) or darken (negative) the side buffers background color. Accepted values are [-1..1].
    --- @type integer
    blend = 0,
    -- Hexadecimal color code to override the current text color of the buffer. (e.g. #7480c2)
    --- @type string?
    text = nil,
}

🧰 Commands

Command Description
:NoNeckPain Toggles the plugin state, between enable and disable.
:NoNeckPainResize INT Updates the config width with the given INT value and resizes the no-neck-pain windows.
:NoNeckPainToggleLeftSide Toggles the left side buffer (open/close).
:NoNeckPainToggleRightSide Toggles the right side buffer (open/close).
:NoNeckPainWidthUp Increases the config width by 5 and resizes the no-neck-pain windows.
:NoNeckPainWidthDown Decreases the config width by 5 and resizes the no-neck-pain windows.

⌨ Contributing

PRs and issues are always welcome. Make sure to provide as much context as possible when opening one.

See Makefile for the available commends

You'll need to install Bob, a useful nvim version manager in order to run the test suite for every supported versions.

🗞 Wiki

You can find guides and showcase of the plugin on the Wiki

🎭 Motivations

Although there's other (amazing!) alternatives that provide a zen-distraction-free-center mode, they usually make assumptions that might alter your workflow, or at least require some configuration to suit your needs.

no-neck-pain.nvim aims at providing a seamless non-opinionated buffer centering experience, while being super customizable.

no-neck-pain.nvim's People

Contributors

alphakeks avatar berkeleytrue avatar embe221ed avatar github-actions[bot] avatar primamateria avatar shortcuts avatar tomdeneire avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

no-neck-pain.nvim's Issues

feat: do not kill side buffers in vsplit, if there's enough space

Describe the problem

Suggested here and here

killing buffers should only be done when there's not enough space on the screen, even in vsplit.

Describe the solution

  • side buffers are still present on vsplit with big windows
  • side buffers are disabled when there's not enough space to host more than 2 main windows

something like this: winwidth > ((padding * 2) + widthmain + (widthvsplit * nbvsplit))

Using plugin in nix configuration

Hi, I was trying to build this plugin with nix. During the build, the test phase in Makefile fails with error that module mini.test is missing.
I have noticed that in scripts/minimal_init.lua the runtime path is extended with deps/mini.nvim. Deps directory is now git-ignored.

I am not very familiar with Makefile principles, but in NPM before you execute test you usually need to install all dependencies. Would it be possible to add some prepare stage that would first clone the mini.nvim?

feat: easier dashboard-nvim support

We can move this snippet to an internal check in the enable method

-- do not trigger when opening dashboard (e.g. dashboard-nvim)
if vim.bo.filetype == "dashboard" then
	return
end

the goal is to reduce the snippet length to automate NNP enabling

Feat: Close side buffers if they are the last

Describe the problem

I am used to that nvim quits when I <c-w>q my current window, which is the only one opened. Now, with the side buffers opened, it hangs on them.

Describe the solution

The plugin checks if the only opened windows have the buff IDs which equal to side buffers, and if yes, it automatically closes them, which should result in closing the editor.

I can also try to help to work on the PR if I will have time.

Buffers remain open when work buffer is closed

If I open a file to edit, NNP is activated.

If I then close this file, I'm left with the empty side buffers created by NNP.

I'm not sure how hard this is, but it be great if these where the last buffers open, that they'd close themselves.

Too long returning to NNP mode

Description

I had shortcut for buffer closing map('n', ',x', ':wq<cr>'). When i open two buffers with vertical split NNP mode is disabled. Then two ways:
1 - i close buffer with :q or :wq and return to NNP mode. It's normal.
2 - i close buffer using shortcut, then nvim returns to NNP mode only after ~5s.

Content is shifted as diagnostics plugin shows a warning

Description

The content of main buffer is shifted as diagnostics plugin shows a warning.

Steps to reproduce

  1. open nvim
  2. run :set signcolumn=auto
  3. make sure you're using at least one diagnostics plugin
  4. make an error, so your diagnostics plugin shows a warning sign
  5. the content of main buffer is shifted

Expected behavior

Left empty buffer shrinks for the size of signcolumn. The content of main buffer stays still.

Environment

  • Neovim: 0.8.1
    unshifted
    shifted

feat: provide pre/post `enable` and pre/post `disable` callback methods

Describe the problem

Suggested here

Providing such methods would allow user to customize the behavior of the plugin, disable/enable other plugins, but also some easy escape hatch.

Describe the solution

  • Provide callback methods defined at the config level
    • (do nothing by default)
  • methods should provide some cool parameters like the internal state

Highlights groups not cleared

Description

Steps to reproduce

  1. Enable
  2. Close NNP side buffer with bd
  3. See new buffer created with side buffer highlight group

Expected behavior

Highlight groups are cleared when the plugin is disabled

When NoNeckPain mode toggled, running `:bdelete` also close the current window

First I'd like to thank you for writing this plugin, I've been wanting this kind of feature for so long!

Description

After running :NoNeckPain, running :bdelete will close the current window even if there are multiple other opened buffers. This means that running :bdelete will effectively close Neovim if no other windows has been created, even if other buffers are opened.

Steps to reproduce

  1. Open Neovim
  2. :e buffer1, :e buffer2
  3. :NoNeckPain
  4. :bdelete
  5. Neovim closes even if there was still another buffer opened

Expected behavior

Only buffer buffer2 should have been closed.

Environment

  • Neovim: 0.8.1

Side Buffers get disabled when switching tabs

Description

When creating new tabs, or switching between existing ones, the side buffers disappear. They can be re-enabled manually but I don't think this behavior is intended.

Steps to reproduce

  1. Open nvim
  2. run :tabnew
  3. switch back to the original tab
  4. the side buffers are gone

Note: if you close all extra tabs, they re-appear again.

Expected behavior

They should not disappear.

Environment

  • Neovim: 0.8.1

Screenshot at 18-35-17
Screenshot at 18-35-25

Allow enabling NoNeckPain per buffer

Describe the problem

Currently, running :NoNeckPain will enable it for every opened and new buffers.

Describe the solution

It would be nice to be able to choose whether to enable the NoNeckPain mode for every opened and new buffers or only for the current buffer. We could then be able to enable it on selected buffers rather than all of them by default. This would also, as a consequence, allow users to enable the plugin for specific filetypes using autocmd.

Doesn't play well with dashboard-nvim

If I open vim without a buffer selected, I should see my dashboard.

Instead I see my dashboard quickly pushed to the right and I'm left with an empty buffer. Further file openings show no NNP.

If I open vim with a file selected, it works fine.

Disables on horizontal split

Description

The plugin shows the expected behavior when running :vsplit (i.e., it exits "centered" mode until I close the second vertical split).
However, I would not expect the plugin to exit "centered" mode, when :split is being run, as that doesn't require any additional horizontal space.

Steps to reproduce

  1. Run :NoNeckPain
  2. Run :split
  3. The plugin exits "centered" mode

Expected behavior

I would expect the plugin to remain in "centered" mode until I run :vsplit.

Environment

  • Neovim: 0.8.x

mkview triggers error when exiting the plugin

Description

When exiting a file while NoNeckPain is toggled, the following error occurs:

Error executing vim.schedule lua callback: ...er/start/no-neck-pain.nvim/lua/no-neck-pain/util/win.lua:122
: Vim(mkview):E32: No file name
stack traceback:
        [C]: in function 'nvim_win_close'
        ...er/start/no-neck-pain.nvim/lua/no-neck-pain/util/win.lua:122: in function 'close'
        ...packer/start/no-neck-pain.nvim/lua/no-neck-pain/main.lua:57: in function 'close'
        ...packer/start/no-neck-pain.nvim/lua/no-neck-pain/main.lua:350: in function <
        ...packer/start/no-neck-pain.nvim/lua/no-neck-pain/main.lua:325>

Steps to reproduce

  1. Open a file
  2. Toggle NoNeckPain on (:NoNeckPain)
  3. Quit neovim

Expected behavior

The error should not appear.

Environment

  • Neovim version: 0.8.2, Release (LuaJIT 2.1.0-beta3)
  • no-neck-pain.nvim version: 0.2.3
  • Might be relevant: my neovim config can be found here

[Question] Border highlighting and hiding lua line

Ref. https://old.reddit.com/r/vimplugins/comments/zxndcz/update_noneckpainnvim_dead_simple_plugin_to/j24owce/

image

Few things here:

  1. The border at right appears correctly (is grey, takes in WinSeparator as highlight) but the left one is white, which probably infers it from Normal
  2. I just updated nvim to latest nightly and :NoNeckPain is unable to hide statusline anymore. I'm using lualine.

For 1, I'd prefer it to use WinSeparator too. For 2, I have no idea what caused this.

Jumps around when being used with nvim-tree

Description

When using this plugin with pseudo buffers like nvim-tree, the focused buffer jumps around.

Steps to reproduce

  1. Install this plugin and nvim-tree
  2. Run :NoNeckPain
  3. Run :NvimTreeToggle
  4. The focused buffer jumps around

Without nvim-tree

Screenshot 2022-12-19 at 12 10 13

With nvim-tree

Screenshot 2022-12-19 at 12 10 32

Expected behavior

I would expect the focused buffer to stay in place when the only other buffer opened is a pseudo buffer like nvim-tree and they both fit next to each other without any jumping around.

The current behavior is even weirder for me when using something like symbols-outline.

Environment

  • Neovim: 0.8.x
  • Plugin clash: nvim-tree

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.