Giter Site home page Giter Site logo

mrjones2014 / smart-splits.nvim Goto Github PK

View Code? Open in Web Editor NEW
728.0 7.0 27.0 309 KB

๐Ÿง  Smart, seamless, directional navigation and resizing of Neovim + terminal multiplexer splits. Supports tmux, Wezterm, and Kitty. Think about splits in terms of "up/down/left/right".

License: MIT License

Lua 87.01% Shell 0.31% Python 4.15% Makefile 1.89% Vim Script 2.72% Nix 3.92%
nvim neovim neovim-plugin window-manager window-management split split-pane kitty mux tmux wezterm hacktoberfest

smart-splits.nvim's Introduction

๐Ÿง  smart-splits.nvim

๐Ÿง  Smarter and more intuitive split pane management that uses a mental model of left/right/up/down instead of wider/narrower/taller/shorter for resizing. Supports seamless navigation between Neovim and terminal multiplexer split panes. See Multiplexer Integrations.

demo

Table of Contents

Install

smart-splits.nvim now supports semantic versioning via git tags. See Releases for a full list of versions and their changelogs, starting from 1.0.0.

With Packer.nvim:

use('mrjones2014/smart-splits.nvim')
-- or use a specific version
use({ 'mrjones2014/smart-splits.nvim', tag = 'v1.0.0' })
-- to use Kitty multiplexer support, run the post install hook
use({ 'mrjones2014/smart-splits.nvim', run = './kitty/install-kittens.bash' })

With Lazy.nvim:

{ 'mrjones2014/smart-splits.nvim' }
-- or use a specific version, or a range of versions using lazy.nvim's version API
{ 'mrjones2014/smart-splits.nvim', version = '>=1.0.0' }
-- to use Kitty multiplexer support, run the post install hook
{ 'mrjones2014/smart-splits.nvim', build = './kitty/install-kittens.bash' }

Configuration

You can set ignored buftypes or filetypes which will be ignored when figuring out if your cursor is currently at an edge split for resizing. This is useful in order to ignore "sidebar" type buffers while resizing, such as nvim-tree.lua which tries to maintain its own width unless manually resized. Note that nothing is ignored when moving between splits, only when resizing.

Note

smart-splits.nvim does not map any keys on it's own. See Usage.

Defaults are shown below:

require('smart-splits').setup({
  -- Ignored buffer types (only while resizing)
  ignored_buftypes = {
    'nofile',
    'quickfix',
    'prompt',
  },
  -- Ignored filetypes (only while resizing)
  ignored_filetypes = { 'NvimTree' },
  -- the default number of lines/columns to resize by at a time
  default_amount = 3,
  -- Desired behavior when your cursor is at an edge and you
  -- are moving towards that same edge:
  -- 'wrap' => Wrap to opposite side
  -- 'split' => Create a new split in the desired direction
  -- 'stop' => Do nothing
  -- function => You handle the behavior yourself
  -- NOTE: If using a function, the function will be called with
  -- a context object with the following fields:
  -- {
  --    mux = {
  --      type:'tmux'|'wezterm'|'kitty'
  --      current_pane_id():number,
  --      is_in_session(): boolean
  --      current_pane_is_zoomed():boolean,
  --      -- following methods return a boolean to indicate success or failure
  --      current_pane_at_edge(direction:'left'|'right'|'up'|'down'):boolean
  --      next_pane(direction:'left'|'right'|'up'|'down'):boolean
  --      resize_pane(direction:'left'|'right'|'up'|'down'):boolean
  --      split_pane(direction:'left'|'right'|'up'|'down',size:number|nil):boolean
  --    },
  --    direction = 'left'|'right'|'up'|'down',
  --    split(), -- utility function to split current Neovim pane in the current direction
  --    wrap(), -- utility function to wrap to opposite Neovim pane
  -- }
  -- NOTE: `at_edge = 'wrap'` is not supported on Kitty terminal
  -- multiplexer, as there is no way to determine layout via the CLI
  at_edge = 'wrap',
  -- when moving cursor between splits left or right,
  -- place the cursor on the same row of the *screen*
  -- regardless of line numbers. False by default.
  -- Can be overridden via function parameter, see Usage.
  move_cursor_same_row = false,
  -- whether the cursor should follow the buffer when swapping
  -- buffers by default; it can also be controlled by passing
  -- `{ move_cursor = true }` or `{ move_cursor = false }`
  -- when calling the Lua function.
  cursor_follows_swapped_bufs = false,
  -- resize mode options
  resize_mode = {
    -- key to exit persistent resize mode
    quit_key = '<ESC>',
    -- keys to use for moving in resize mode
    -- in order of left, down, up' right
    resize_keys = { 'h', 'j', 'k', 'l' },
    -- set to true to silence the notifications
    -- when entering/exiting persistent resize mode
    silent = false,
    -- must be functions, they will be executed when
    -- entering or exiting the resize mode
    hooks = {
      on_enter = nil,
      on_leave = nil,
    },
  },
  -- ignore these autocmd events (via :h eventignore) while processing
  -- smart-splits.nvim computations, which involve visiting different
  -- buffers and windows. These events will be ignored during processing,
  -- and un-ignored on completed. This only applies to resize events,
  -- not cursor movement events.
  ignored_events = {
    'BufEnter',
    'WinEnter',
  },
  -- enable or disable a multiplexer integration;
  -- automatically determined, unless explicitly disabled or set,
  -- by checking the $TERM_PROGRAM environment variable,
  -- and the $KITTY_LISTEN_ON environment variable for Kitty
  multiplexer_integration = nil,
  -- disable multiplexer navigation if current multiplexer pane is zoomed
  -- this functionality is only supported on tmux and Wezterm due to kitty
  -- not having a way to check if a pane is zoomed
  disable_multiplexer_nav_when_zoomed = true,
  -- Supply a Kitty remote control password if needed,
  -- or you can also set vim.g.smart_splits_kitty_password
  -- see https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.remote_control_password
  kitty_password = nil,
  -- default logging level, one of: 'trace'|'debug'|'info'|'warn'|'error'|'fatal'
  log_level = 'info',
})

Hooks

The hook table allows you to define callbacks for the on_enter and on_leave events of the resize mode.

Examples

Integration with bufresize.nvim:

require('smart-splits').setup({
  resize_mode = {
    hooks = {
      on_leave = require('bufresize').register,
    },
  },
})

Custom messages when using resize mode:

require('smart-splits').setup({
  resize_mode = {
    silent = true,
    hooks = {
      on_enter = function()
        vim.notify('Entering resize mode')
      end,
      on_leave = function()
        vim.notify('Exiting resize mode, bye')
      end,
    },
  },
})

Usage

Key Mappings

If you are a legendary.nvim (>= v2.10.0) user, you can quickly easily and easily create with the legendary.nvim extension for smart-splits.nvim. See more option in the extension documentation in legendary.nvim.

require('legendary').setup({
  extensions = {
    -- to use default settings:
    smart_splits = {},
    -- default settings shown below:
    smart_splits = {
      directions = { 'h', 'j', 'k', 'l' },
      mods = {
        -- for moving cursor between windows
        move = '<C>',
        -- for resizing windows
        resize = '<M>',
        -- for swapping window buffers
        swap = false, -- false disables creating a binding
      },
    },
    -- or, customize the mappings
    smart_splits = {
      mods = {
        -- any of the mods can also be a table of the following form
        swap = {
          -- this will create the mapping like
          -- <leader><C-h>
          -- <leader><C-j>
          -- <leader><C-k>
          -- <leader><C-l>
          mod = '<C>',
          prefix = '<leader>',
        },
      },
    },
  },
})

Otherwise, here are some recommended mappings.

-- recommended mappings
-- resizing splits
-- these keymaps will also accept a range,
-- for example `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
-- moving between splits
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
vim.keymap.set('n', '<C-\\>', require('smart-splits').move_cursor_previous)
-- swapping buffers between windows
vim.keymap.set('n', '<leader><leader>h', require('smart-splits').swap_buf_left)
vim.keymap.set('n', '<leader><leader>j', require('smart-splits').swap_buf_down)
vim.keymap.set('n', '<leader><leader>k', require('smart-splits').swap_buf_up)
vim.keymap.set('n', '<leader><leader>l', require('smart-splits').swap_buf_right)

Lua API

-- resizing splits
-- amount defaults to 3 if not specified
-- use absolute values, no + or -
-- the functions also check for a range,
-- so for example if you bind `<A-h>` to `resize_left`,
-- then `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
require('smart-splits').resize_up(amount)
require('smart-splits').resize_down(amount)
require('smart-splits').resize_left(amount)
require('smart-splits').resize_right(amount)
-- moving between splits
-- You can override config.at_edge and
-- config.move_cursor_same_row via opts
-- See Configuration.
require('smart-splits').move_cursor_up({ same_row = boolean, at_edge = 'wrap' | 'split' | 'stop' })
require('smart-splits').move_cursor_down()
require('smart-splits').move_cursor_left()
require('smart-splits').move_cursor_right()
require('smart-splits').move_cursor_previous()
-- Swapping buffers directionally with the window to the specified direction
require('smart-splits').swap_buf_up()
require('smart-splits').swap_buf_down()
require('smart-splits').swap_buf_left()
require('smart-splits').swap_buf_right()
-- the buffer swap functions can also take an `opts` table to override the
-- default behavior of whether or not the cursor follows the buffer
require('smart-splits').swap_buf_right({ move_cursor = true })
-- persistent resize mode
-- temporarily remap your configured resize keys to
-- smart resize left, down, up, and right, respectively,
-- press <ESC> to stop resize mode (unless you've set a different key in config)
-- resize keys also accept a range, e.e. pressing `5j` will resize down 5 times the default_amount
require('smart-splits').start_resize_mode()

Multiplexer Integrations

smart-splits.nvim can also enable seamless navigation between Neovim splits and tmux, wezterm, or kitty panes. You will need to set up keymaps in your tmux, wezterm, or kitty configs to match the Neovim keymaps.

Tmux

Add the following snippet to your ~/.tmux.conf/~/.config/tmux/tmux.conf file (customizing the keys and resize amount if desired):

# '@pane-is-vim' is a pane-local option that is set by the plugin on load,
# and unset when Neovim exits or suspends; note that this means you'll probably
# not want to lazy-load smart-splits.nvim, as the variable won't be set until
# the plugin is loaded

# Smart pane switching with awareness of Neovim splits.
bind-key -n C-h if -F "#{@pane-is-vim}" 'send-keys C-h'  'select-pane -L'
bind-key -n C-j if -F "#{@pane-is-vim}" 'send-keys C-j'  'select-pane -D'
bind-key -n C-k if -F "#{@pane-is-vim}" 'send-keys C-k'  'select-pane -U'
bind-key -n C-l if -F "#{@pane-is-vim}" 'send-keys C-l'  'select-pane -R'

# Alternatively, if you want to disable wrapping when moving in non-neovim panes, use these bindings
# bind-key -n C-h if -F '#{@pane-is-vim}' { send-keys C-h } { if -F '#{pane_at_left}'   '' 'select-pane -L' }
# bind-key -n C-j if -F '#{@pane-is-vim}' { send-keys C-j } { if -F '#{pane_at_bottom}' '' 'select-pane -D' }
# bind-key -n C-k if -F '#{@pane-is-vim}' { send-keys C-k } { if -F '#{pane_at_top}'    '' 'select-pane -U' }
# bind-key -n C-l if -F '#{@pane-is-vim}' { send-keys C-l } { if -F '#{pane_at_right}'  '' 'select-pane -R' }

# Smart pane resizing with awareness of Neovim splits.
bind-key -n M-h if -F "#{@pane-is-vim}" 'send-keys M-h' 'resize-pane -L 3'
bind-key -n M-j if -F "#{@pane-is-vim}" 'send-keys M-j' 'resize-pane -D 3'
bind-key -n M-k if -F "#{@pane-is-vim}" 'send-keys M-k' 'resize-pane -U 3'
bind-key -n M-l if -F "#{@pane-is-vim}" 'send-keys M-l' 'resize-pane -R 3'

tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if -F \"#{@pane-is-vim}\" 'send-keys C-\\'  'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if -F \"#{@pane-is-vim}\" 'send-keys C-\\\\'  'select-pane -l'"

bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l

Wezterm

Note

It is recommended not to lazy load smart-splits.nvim if using the Wezterm integration. If you need to lazy load, you need to use a different is_vim() implementation below. The plugin is small, and smart about not loading modules unnecessarily, so it should have minimal impact on your startup time. It adds about 0.07ms on my setup.

Note

Pane resizing currently requires a nightly build of Wezterm. Check the output of wezterm cli adjust-pane-size --help to see if your build supports it; if not, you can check how to obtain a nightly build by following the instructions here.

First, ensure that the wezterm CLI is on your $PATH, as the CLI is used by the integration.

Then, if you're on Wezterm nightly, you can use Wezterm's experimental plugin loader:

local wezterm = require('wezterm')
local smart_splits = wezterm.plugin.require('https://github.com/mrjones2014/smart-splits.nvim')
local config = wezterm.config_builder()
-- you can put the rest of your Wezterm config here
smart_splits.apply_to_config(config, {
  -- the default config is here, if you'd like to use the default keys,
  -- you can omit this configuration table parameter and just use
  -- smart_splits.apply_to_config(config)

  -- directional keys to use in order of: left, down, up, right
  direction_keys = { 'h', 'j', 'k', 'l' },
  -- modifier keys to combine with direction_keys
  modifiers = {
    move = 'CTRL', -- modifier to use for pane movement, e.g. CTRL+h to move left
    resize = 'META', -- modifier to use for pane resize, e.g. META+h to resize to the left
  },
})

Otherwise, add the following snippet to your ~/.config/wezterm/wezterm.lua:

local w = require('wezterm')

-- if you are *NOT* lazy-loading smart-splits.nvim (recommended)
local function is_vim(pane)
  -- this is set by the plugin, and unset on ExitPre in Neovim
  return pane:get_user_vars().IS_NVIM == 'true'
end

-- if you *ARE* lazy-loading smart-splits.nvim (not recommended)
-- you have to use this instead, but note that this will not work
-- in all cases (e.g. over an SSH connection). Also note that
-- `pane:get_foreground_process_name()` can have high and highly variable
-- latency, so the other implementation of `is_vim()` will be more
-- performant as well.
local function is_vim(pane)
  -- This gsub is equivalent to POSIX basename(3)
  -- Given "/foo/bar" returns "bar"
  -- Given "c:\\foo\\bar" returns "bar"
  local process_name = string.gsub(pane:get_foreground_process_name(), '(.*[/\\])(.*)', '%2')
  return process_name == 'nvim' or process_name == 'vim'
end

local direction_keys = {
  h = 'Left',
  j = 'Down',
  k = 'Up',
  l = 'Right',
}

local function split_nav(resize_or_move, key)
  return {
    key = key,
    mods = resize_or_move == 'resize' and 'META' or 'CTRL',
    action = w.action_callback(function(win, pane)
      if is_vim(pane) then
        -- pass the keys through to vim/nvim
        win:perform_action({
          SendKey = { key = key, mods = resize_or_move == 'resize' and 'META' or 'CTRL' },
        }, pane)
      else
        if resize_or_move == 'resize' then
          win:perform_action({ AdjustPaneSize = { direction_keys[key], 3 } }, pane)
        else
          win:perform_action({ ActivatePaneDirection = direction_keys[key] }, pane)
        end
      end
    end),
  }
end

return {
  keys = {
    -- move between split panes
    split_nav('move', 'h'),
    split_nav('move', 'j'),
    split_nav('move', 'k'),
    split_nav('move', 'l'),
    -- resize panes
    split_nav('resize', 'h'),
    split_nav('resize', 'j'),
    split_nav('resize', 'k'),
    split_nav('resize', 'l'),
  },
}

Kitty

Note

The config.at_edge = 'wrap' option is not supoprted in Kitty terminal multiplexer due to inability to determine pane layout from CLI.

By default the plugin sets a kitty user-var IS_NVIM when it loads. You can take advantage of this together with kittys conditional mappings feature to use the same keybind for both kitty and neovim.

Add the following snippet to ~/.config/kitty/kitty.conf, adjusting the keymaps and resize amount as desired.


map ctrl+j neighboring_window down
map ctrl+k neighboring_window up
map ctrl+h neighboring_window left
map ctrl+l neighboring_window right

# Unset the mapping to pass the keys to neovim
map --when-focus-on var:IS_NVIM ctrl+j
map --when-focus-on var:IS_NVIM ctrl+k
map --when-focus-on var:IS_NVIM ctrl+h
map --when-focus-on var:IS_NVIM ctrl+l

# the 3 here is the resize amount, adjust as needed
map alt+j kitten relative_resize down  3
map alt+k kitten relative_resize up    3
map alt+h kitten relative_resize left  3
map alt+l kitten relative_resize right 3

map --when-focus-on var:IS_NVIM alt+j
map --when-focus-on var:IS_NVIM alt+k
map --when-focus-on var:IS_NVIM alt+h
map --when-focus-on var:IS_NVIM alt+l

Then, you must allow Kitty to listen for remote commands on a socket. You can do this either by running Kitty with the following command:

# For linux only:
kitty -o allow_remote_control=yes --single-instance --listen-on unix:@mykitty

# Other unix systems:
kitty -o allow_remote_control=yes --single-instance --listen-on unix:/tmp/mykitty

Or, by adding the following to ~/.config/kitty/kitty.conf:

# For linux only:
allow_remote_control yes
listen_on unix:@mykitty

# Other unix systems:
allow_remote_control yes
listen_on unix:/tmp/mykitty
Credits

Thanks @knubie for inspiration for the Kitty implementation from vim-kitty-navigator.

Thanks to @chancez for the relative resize Python kitten.

Multiplexer Lua API

You can directly access the multiplexer API for scripting purposes as well. To get a handle to the current multiplexer backend, you can do:

local mux = require('smart-splits.mux').get()

This returns the currently enabled multiplexer backend, or nil if none is currently in use. The API offers the following methods:

local mux = require('smart-splits.mux').get()
-- mux matches the following type annotations
---@class SmartSplitsMultiplexer
---@field current_pane_id fun():number|nil
---@field current_pane_at_edge fun(direction:'left'|'right'|'up'|'down'):boolean
---@field is_in_session fun():boolean
---@field current_pane_is_zoomed fun():boolean
---@field next_pane fun(direction:'left'|'right'|'up'|'down'):boolean
---@field resize_pane fun(direction:'left'|'right'|'up'|'down', amount:number):boolean
---@field split_pane fun(direction:'left'|'right'|'up'|'down',size:number|nil):boolean
---@field type 'tmux'|'wezterm'|'kitty'

smart-splits.nvim's People

Contributors

alesandar avatar freddiehaddad avatar ghostbuster91 avatar hsheikhali1 avatar jebaum avatar l2ashdz avatar loqusion avatar lucobellic avatar matthewsia98 avatar mr-hypocrite avatar mrjones2014 avatar oddnugget avatar pwnalone avatar rmarquis avatar roginfarrer avatar sarmong avatar thenbe avatar towry avatar vimpostor avatar zeapoz 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  avatar  avatar

smart-splits.nvim's Issues

listen to key repeats after leader

In the way I use tmux, I press the prefix key then use the arrow keys for any direction and it will listen for repeated key presses for resizing panes.
I believe there's a 500ms timeout by default.
The resize behavior is identical to what this plugin hopes to achieve, so it's logically consistent with what I'm used to.
I would just love the ability to press the leader key and have it listen for a resize command for 500ms and repeat.
Currently I have this plugin mapped to ctrl+arrowkeys, which also works great, and am happy to settle for if this feature turns out to nonsensical.

example tmux.conf

# resizing with arrow keys because they're hardly used
unbind Left
bind -r Left resize-pane -L 5
unbind Right
bind -r Right resize-pane -R 5
unbind Down
bind -r Down resize-pane -D 5
unbind Up
bind -r Up resize-pane -U 5

Resize commands are triggering BufEnter event

Issue

I notice if we have some buffer with a BufEnter autocommand, like

au BufEnter term://* startinsert

When we use any resize command the BufEnter is triggered.

As far as I could investigate it seems to be caused by wincmd h|j|k|l| on lua/smart-splits/api.lua.
I tried to solve it preppending a noautocmd on the beginning of wincmd, but for somereason it not works on this line lua/smart-splits/api.lua#L53 (a neovim bug maybe).

To reproduce

" mini.init.vim
noautocmd e aaa
noautocmd vs bbb

call plug#begin()
  Plug 'mrjones2014/smart-splits.nvim'
call plug#end()

map <space> :lua require('smart-splits').resize_left()<CR>

lua << EOF
require('smart-splits').setup({})
EOF
$ nvim -u mini.init.vim

When space is pressed in normal mode a message with aaa and bbb is displayed.

Additional info

" PlugSnapshot
silent! let g:plugs['smart-splits.nvim'].commit = 'c8d80d90f3c783ac0ea21f256c74d541a7b66a72'

" nvim --version
NVIM v0.8.0-1210-gd367ed9b2
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-10 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNVIM_TS_HAS_SET_MATCH_LIMIT -DNVIM_TS_HAS_SET_ALLOCATOR -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fno-common -fdiagnostics-color=always -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -I/home/runner/work/neovim/neovim/build/cmake.config -I/home/runner/work/neovim/neovim/src -I/home/runner/work/neovim/neovim/.deps/usr/include -I/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include
Compiled by runner@fv-az457-787

Change splits `orientation`?

Discussed in #100

Originally posted by omaru-ok April 30, 2023
change orientation like , split -> vsplit , on key-strokes
vice-versa ,

any keybinds?! or any implementation in plugin

Provide an option to disable print() in resize-mode.lua?

Without any special overriding of vim.notify(), [1][2] just appear to be two duplicate lines when cmdheight > 1.

I wonder if it's ok to remove the print() calls? Or if this was intentional, can we have an option to suppress it? Thank you.

[1]

print(msg)
vim.notify(msg, vim.log.levels.INFO)

[2]
print(msg)
vim.notify(msg, vim.log.levels.INFO)

Smart-splits.nvim + Wezterm (performance issue)

Solution

Make sure you are using Wezterm with this commit included: wez/wezterm@96f1585

Discussed in #52

Originally posted by masoniis April 4, 2023
Does anyone else use Wezterm as their terminal emulator alongside this plugin? I noticed that on Wezterm there is a noticeable delay (maybe 500-1000ms) when performing a circular window navigation (and this doesn't appear when I switch to macOS default terminal).

I'm not sure if this is a fixable problem, or if it's just a result of the slowness of Wezterm itself when paired with the circular navigation.

[Bug]: Moving between multiplexer windows with separate nvim instances

Similar Issues

  • Before filing, I have searched for similar issues.

Neovim Version

NVIM v0.9.0-dev
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3

Expected Behavior

If I open a multiplexer like TMUX and create two panes, with a separate neovim instance in each pane, the I expect the directional movement commands require('smart-splits).move_cursor_{left, up} to move across the panes. However, only the "right" and "down" directions work.

Actual Behavior

The"left" and "up" smart movement commands do not move across the two panes.

Minimal Configuration to Reproduce

local root = vim.fn.fnamemodify('./.repro', ':p')

-- set stdpaths to use .repro
for _, name in ipairs({ 'config', 'data', 'state', 'cache' }) do
  vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    '--single-branch',
    'https://github.com/folke/lazy.nvim.git',
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  -- do not remove the colorscheme! it makes testing nicer
  'folke/tokyonight.nvim',
  'mrjones2014/smart-splits.nvim',
  -- add any other pugins here
}

require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

require('smart-splits').setup({
  wrap_at_edge = false
})

-- recommended mappings
-- resizing splits
-- these keymaps will also accept a range,
-- for example `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
-- moving between splits
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
-- swapping buffers between windows
vim.keymap.set('n', '<leader><leader>h', require('smart-splits').swap_buf_left)
vim.keymap.set('n', '<leader><leader>j', require('smart-splits').swap_buf_down)
vim.keymap.set('n', '<leader><leader>k', require('smart-splits').swap_buf_up)
vim.keymap.set('n', '<leader><leader>l', require('smart-splits').swap_buf_right)

-- add anything else here
vim.opt.termguicolors = true
-- do not remove the colorscheme! it makes testing nicer
vim.cmd([[colorscheme tokyonight]])

Additional Details and/or Screenshots

Here is a screen recording of the issue (pay attention to bottom right)

smart-splits.mp4

Reopen #26 (custom mappings)

Thanks for adding the feature, but unfortunately it does not work for me, I assume it does not like meta keys like the <arrows>.
image

[Feature]: Custom `at_edge` behaviour (user-defined function)

Similar Issues

  • Before filing, I have searched for similar issues.

Description

I just had a (weird?) idea to open nvim-tree automatically when I try to move left from the leftmost window, similar for the other edges. It might be cool to allow the user to pass a function as the at_edge parameter and call it with some information like which edge we hit. The function should return wrap, split or any other future behaviour, or 'none'/nil for which smart-splits wouldn't do anything (but from inside at_edge I would call NvimTreeOpen and focus it)

ignored_filetypes and ignored_buftypes not working

I can't seem to get the ignored_filetypes or ignored_buftypes options working No matter what I set it doesn't change the edge detection to ignore the set filetypes. This includes when I don't modify the setup and the default does nofile/quickfix/prompt. If I have the quickfix open and resize a window that isn't the quickfix it will resize it instead of keeping it as a constant size.

[FEATURE]: Swap windows directionally

Is your feature request related to a problem? Please describe.

Run :vsp then you want to swap the buffers directionally

Describe the solution you'd like

A function to swap the buffer with the buffer from the window next to it

Describe alternatives you've considered
Other plugins

Additional context

E5113: Error while calling lua chunk...attempt to call field 'nvim_add_user_command' (a nil value)

I get this error when I open a file:

ๅค„็† /Users/agou-ops/.vim/plugged/smart-splits.nvim/plugin/smart-splits.lua ๆ—ถๅ‘็”Ÿ้”™่ฏฏ:
E5113: Error while calling lua chunk: ...s/.vim/plugged/smart-splits.nvim/plugin/smart-splits.lua:13: attempt to call field 'nvim_add_user_command' (a nil value)
stack traceback:
        ...s/.vim/plugged/smart-splits.nvim/plugin/smart-splits.lua:13: in main chunk
  • nvim version: 0.6.1
  • MacOS 12.3
  • package manager: vim-plug
  • latest plugin

And my config is default:
image

[Bug]: Ignored filetypes doesn't work(at least on neo-tree)

Similar Issues

  • Before filing, I have searched for similar issues.

Neovim Version

NVIM v0.10.0-dev-24+g3c724fe1f
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: /usr/bin/gcc-10 -O2 -g -Og -g -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wvla -Wdouble-promotion -Wmissing-noreturn -Wmissing-format-attribute -Wmissing-prototypes -fno-common -Wno-unused-result -Wimplicit-fallthrough -fdiagnostics-color=always -fstack-protector-strong -DUNIT_TESTING -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -I/home/runner/work/neovim/neovim/.deps/usr/include/luajit-2.1 -I/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include -I/home/runner/work/neovim/neovim/build/src/nvim/auto -I/home/runner/work/neovim/neovim/build/include -I/home/runner/work/neovim/neovim/build/cmake.config -I/home/runner/work/neovim/neovim/src -I/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include -I/home/runner/work/neovim/neovim/.deps/usr/include

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/share/nvim"

Run :checkhealth for more info

Multiplexer Integration

Kitty

Multiplexer Version

kitty 0.27.1 created by Kovid Goyal

Steps to Reproduce

  1. Add neo-tree as an ignored filetype(or nofile as a buftype cause that's what it uses)

  2. Open a folder(neotree on the left, empty buffer on the right
    image

  3. Try to resize either splits

Expected Behavior

No resizing happens as it neotree is the only other buffer, which should be ignored

Actual Behavior

Neotree's split gets resized

Minimal Configuration to Reproduce

Uhhhhhhhhhhhhhhh

Additional Details and/or Screenshots

By running the check for ignored filetype/buftype from the code seems to return true, so it is likely the ignore mechanism's fault and not the check's

[Bug]: Limitations with Kitty navigation over SSH

Similar Issues

  • Before filing, I have searched for similar issues.

Neovim Version

n/a doesn't matter what version

Multiplexer Integration

Wezterm and Kitty both affected

Steps to Reproduce

  1. Create split
  2. SSH into a remote server and run nvim from the remote server in the split

Expected Behavior

You can use the keymaps to navigate between Neovim split panes.

Actual Behavior

You can't because the pane does not report the remote foreground process name, so the keymaps can't check if nvim is running in the pane.

Minimal Configuration to Reproduce

local root = vim.fn.fnamemodify('./.repro', ':p')

-- set stdpaths to use .repro
for _, name in ipairs({ 'config', 'data', 'state', 'cache' }) do
  vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    '--single-branch',
    'https://github.com/folke/lazy.nvim.git',
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  -- do not remove the colorscheme! it makes testing nicer
  'folke/tokyonight.nvim',
  'mrjones2014/smart-splits.nvim',
  -- add any other pugins here
}

require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

require('smart-splits').setup({
  -- add any options here
})

-- recommended mappings
-- resizing splits
-- these keymaps will also accept a range,
-- for example `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
-- moving between splits
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
-- swapping buffers between windows
vim.keymap.set('n', '<leader><leader>h', require('smart-splits').swap_buf_left)
vim.keymap.set('n', '<leader><leader>j', require('smart-splits').swap_buf_down)
vim.keymap.set('n', '<leader><leader>k', require('smart-splits').swap_buf_up)
vim.keymap.set('n', '<leader><leader>l', require('smart-splits').swap_buf_right)

-- add anything else here
vim.opt.termguicolors = true
-- do not remove the colorscheme! it makes testing nicer
vim.cmd([[colorscheme tokyonight]])

Additional Details and/or Screenshots

This appears to be a limitation in the multiplexer of Wezterm and Kitty.

Wezterm

Note
Issue has been resolved for Wezterm by #105

pane:get_foreground_process_name():

This information is only available for local panes. Multiplexer panes do not report this information. Similarly, if you are using eg: ssh to connect to a remote host, you won't be able to access the name of the remote process that is running.

Opened discussion: wez/wezterm#3648

Kitty

Opened discussion: kovidgoyal/kitty#6229

Incorrect resizing with more complicated layous

Great work on this plugin! I am testing it out to fix my split resizing woes. I just wanted to report that for somewhat complicated split layouts the resizing bindings stop working as I would expect them to. This layout is an example:

2022-03-23_10:17:31_screenshot

This is 5 splits in the following order: vertical split, horizontal split on the right, and a horizontal split on the left to make a 2x2 grid. Then finally doing a vertical split on the top left box in the grid.

After that is created if I go to the split that is highlighted in the screenshot, resize right moves the left edge to the left and resize left moves the left edge to the right. It looks like this happens any time I have nested splits of different directions.

[Bug]: Windows navigation

Similar Issues

  • Before filing, I have searched for similar issues.

Neovim Version

NVIM v0.9.0-dev-1355+gb2d10aa01

Multiplexer Integration

Wezterm

Multiplexer Version

wezterm 20230421-075330-e0a92c73

Steps to Reproduce

Same as wez/wezterm#3597

Just wanna ask have you tried this in Windows environment?, cos I wanna know if this is just really a windows-centric issue.

Expected Behavior

Should be able to navigate smoothly like tmux integration with vim using ctrl+ keymap

Actual Behavior

It is working but have a weird behavior as it using different keymap rather the specified keymap option

Minimal Configuration to Reproduce

local root = vim.fn.fnamemodify('./.repro', ':p')

-- set stdpaths to use .repro
for _, name in ipairs({ 'config', 'data', 'state', 'cache' }) do
  vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    '--single-branch',
    'https://github.com/folke/lazy.nvim.git',
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  -- do not remove the colorscheme! it makes testing nicer
  'folke/tokyonight.nvim',
  'mrjones2014/smart-splits.nvim',
  -- add any other pugins here
}

require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

require('smart-splits').setup({
  -- add any options here
})

-- recommended mappings
-- resizing splits
-- these keymaps will also accept a range,
-- for example `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
-- moving between splits
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
-- swapping buffers between windows
vim.keymap.set('n', '<leader><leader>h', require('smart-splits').swap_buf_left)
vim.keymap.set('n', '<leader><leader>j', require('smart-splits').swap_buf_down)
vim.keymap.set('n', '<leader><leader>k', require('smart-splits').swap_buf_up)
vim.keymap.set('n', '<leader><leader>l', require('smart-splits').swap_buf_right)

-- add anything else here
vim.opt.termguicolors = true
-- do not remove the colorscheme! it makes testing nicer
vim.cmd([[colorscheme tokyonight]])

Additional Details and/or Screenshots

No response

[Feature]: Smart split creation

Similar Issues

  • Before filing, I have searched for similar issues.

Description

I don't know if you consider this part of the scope of this plugin but a feature that seems to fit under the banner of smart-splits is smart split creation.

Some ideas I have are:

  • move_cursor_or_split - move the cursor in a direction or create a split in that direction if there is no window in that direction
  • split_longest_side - create a split dividing the current window along the longest side. so if its a very wide window we get a vertical split and if its a tall window then we get a horizontal split. (potentially with some cmd that is immediately run in that window)

[FEATURE]: Directional moving of windows

Is your feature request related to a problem? Please describe.
I would like to move windows directionally.
Currently swapping will keep the cursor on the current window instead of moving with the swapped buffer which is a bit unintuitive and prevents you from moving you window several positions in a row.

For example, moving the window on the left to the center :
image
This would not be possible with the current implementation of swapping (at least without moving after each swap)

Describe the solution you'd like
Either make a new method that allows directional moving of a window or allow cursor to follow current buffer while swapping.

Describe alternatives you've considered
Cry while doing a series of swap and move combinations instead of a single action.

Can't resize terminal buffers

If I try to resize a terminal buffer I get this error:

E5108: Error executing lua: .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:64: Vim(normal):Can't re-enter normal mode from terminal mode                                                                
stack traceback:                                                                                                                                                                                                     
        [C]: in function 'cmd'                                                                                                                                                                                       
        .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:64: in function 'next_window'                                                                                                                    
        .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:116: in function 'at_right_edge'                                                                                                                 
        .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:130: in function 'win_position'                                                                                                                  
        .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:158: in function 'compute_direction_horizontal'                                                                                                  
        .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:249: in function 'resize'                                                                                                                        
        .../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:320: in function <.../packer/start/smart-splits.nvim/lua/smart-splits/api.lua:316> 

[Meta]: Wezterm mux support notice

Category

Docs

Description

Hi,

Really great plugin which I was excited to try. However, for the integration with Wezterm, it only works if you are not multiplexing/ssh, as in

local function is_vim(pane)
  local process_name = basename(pane:get_foreground_process_name())
  return process_name == 'nvim' or process_name == 'vim'
end

The pane:get_foreground_process_name() has limitations (https://wezfurlong.org/wezterm/config/lua/pane/get_foreground_process_name.html?h=get_foreground_process_name):

This information is only available for local panes. Multiplexer panes do not report this information. Similarly, if you are using eg: ssh to connect to a remote host, you won't be able to access the name of the remote process that is running.

This bit of information could be added in the docs for Wezterm.

Thanks!

Request: Mappings

Allow remapping the hjkl keys in resize mode (for example - I want to use the arrow keys instead, I don't find hjkl intuitive and have remapped them to arrows everywhere else). If such a feature is available, please document it.

Regression of #16? The resize direction is unexpectedly reversed, with neo-tree open in vertical split

Looks like a regression of #16, GitHub didn't allow me to reopen that issue, so I shall repeat the issue here again for the sake of completeness.

When a tree explorer window such as neo-tree is open to the left in a vertical split to the current buffer, smart-splits does not work as expected. In fact, it has the opposite behavior. When resizing the main buffer with "Ctrl+left", it resizes to the right, making the current buffer smaller and filetree buffer larger. Similarly, the opposite behavior is noted with "<Ctrl + right>".

[BUG]: Breaking change for tmux after wezterm integration

Describe the bug
Switching from neovim to tmux pane no longer works.

Commit 3d4239b is working still

To Reproduce
Steps to reproduce the behavior:

  1. Be in neovim
  2. Try to switch to tmux pane
  3. Nothing happens

Expected behavior
Should switch from neovim to tmux pane

Version Info (please complete the following information):

  • OS: Linux

NVIM v0.8.2
Build type: Release
LuaJIT 2.1.0-beta3

Additional context
in tmux.conf :

set -g @plugin 'christoomey/vim-tmux-navigator'   

The resize direction is unexpectedly reversed with neo-tree open in a vertical split

When a tree explorer window such as neo-tree is open to the left in a vertical split to the current buffer, smart-splits does not work as expected. In fact, it has the opposite behavior. When resizing the main buffer with "Ctrl+left", it resizes to the right, making the current buffer smaller and filetree buffer larger. Similarly, the opposite behavior is noted with "<Ctrl + right>".

Big .git folder(48M) cause PackerSync failed when network is slow

It would be better to remove those big files from the previous commit.

I discover this due to my poor network speed ๐Ÿ˜‚.

Steps to reproduce

run du -h smart-splits.nvim/

  • output
4.0K	../smart-splits.nvim//plugin
 24K	../smart-splits.nvim//lua/smart-splits
 24K	../smart-splits.nvim//lua
 48M	../smart-splits.nvim//.git/objects/pack
  0B	../smart-splits.nvim//.git/objects/info
 48M	../smart-splits.nvim//.git/objects
4.0K	../smart-splits.nvim//.git/info
4.0K	../smart-splits.nvim//.git/logs/refs/heads
4.0K	../smart-splits.nvim//.git/logs/refs/remotes/origin
4.0K	../smart-splits.nvim//.git/logs/refs/remotes
8.0K	../smart-splits.nvim//.git/logs/refs
 12K	../smart-splits.nvim//.git/logs
 60K	../smart-splits.nvim//.git/hooks
4.0K	../smart-splits.nvim//.git/refs/heads
  0B	../smart-splits.nvim//.git/refs/tags
4.0K	../smart-splits.nvim//.git/refs/remotes/origin
4.0K	../smart-splits.nvim//.git/refs/remotes
8.0K	../smart-splits.nvim//.git/refs
 48M	../smart-splits.nvim//.git
 48M	../smart-splits.nvim/

[FEATURE]: Semantic Versioning

Is your feature request related to a problem? Please describe.
With the new multiplexer functionality and incredible new features being added specifically with terminal integration, it would be great to communicate through versioning if/when breaking changes occur. Plugin managers such as Lazy have the ability to track plugins based on semantic versioning to protect users from random breaking changes that would require their setup to be modified.

Describe the solution you'd like
Use GitHub releases/tags to track the version of smart-splits following the semantic versioning spec. There are also some great GitHub actions that I have seen other plugins use such as release-please-action which help automate this process and ease the added work to maintain version numbers.

Describe alternatives you've considered
The other alternative is just leaving it as it is which definitely works, but adopting semantic versioning would make it easier to communicate to users when breaking changes occur down the line such as changing default options, removing deprecated options, etc.

Additional context
AstroNvim uses (and loves! โค๏ธ) smart-splits and the way our stable releases work are we allow non-breaking updates to plugins that follow semantic versioning. If a plugin doesn't use semantic versioning then we pin the plugin to a specific known working commit for stable releases. This not only would help users that don't use AstroNvim, but it would allow AstroNvim users receive non-breaking updates without the AstroNvim devs tagging a new stable release.

Hooks in resize mode

Hi there, first of all thanks for the plugin, it's great.
Could you add hooks when entering and exiting the resize mode.

[Feature]: Allow creating mux splits from Neovim keymaps

Similar Issues

  • Before filing, I have searched for similar issues.

Description

Since we already have mux APIs for tmux, Wezterm, and Kitty, we could also use those to allow you to create Neovim keymaps which create new splits (or floating windows for tmux!).

We could have APIs like:

  • require('smart-splits').split_mux(direction)
    • Although as far as I can tell this won't work in Kitty because the mux is highly opinionated at does not allow creating arbitrary splits, can anyone confirm?
  • require('smart-splits').float_mux(opts) (opts for stuff like window size, position, etc.)
    • Will just not be implemented for Wezterm or Kitty
    • Wezterm could be implemented pending wez/wezterm#270

[FEATURE]: kitty directional resize

Great to see how the plugin has evolved! Thank you for your art!

Based on the idea of triggering kitty's resize_window <wider/narrower/taller/shorter> command depending on window layout and position, I did some research into the possibility of directional resizing with kitty.

The most promising find was based on this issue:
kovidgoyal/kitty#4684
It appeared that the issue opener had solved the request, so I took the liberty of looking into his dotfiles, where I found this little gem of a kitten:
https://github.com/chancez/dotfiles/blob/master/kitty/.config/kitty/relative_resize.py

His dots are under MIT license and I thought this could serve for extending smart-resize's kitty implementation. If it's not too much trouble, perhaps adding directional resize support could be feasible. What are your thoughts on that?

[BUG]: Error when moving to a split with a shorter buffer

Describe the bug
Say we have two splits, one with BufferA, which has 200 lines, and another with BufferB, which has 30 lines. If my cursor is on a line greater than 30, say 35 in BufferA, and I switch to the split that has BufferB using require("smart-splits").swap_buf_*(), it will switch to the second split, and try and move the cursor to line 35 of BufferB and then try to adjust line by line, which doesn't exist, which results in the following errors:

E315: ml_get: invalid lnum: 35
E315: ml_get: invalid lnum: 34
E315: ml_get: invalid lnum: 33
E315: ml_get: invalid lnum: 32
E315: ml_get: invalid lnum: 31

Expected behavior
To directly jump to the last line of the file, but I'd actually be happy if there was a configuration option to not adjust the line in the split I'm moving to so that the cursor stays where it last was

Version Info (please complete the following information):

  • OS: MacOS 13.3.1
  • Neovim version:
    NVIM v0.10.0-dev-4044+g339011f59-Homebrew
    Build type: Release
    LuaJIT 2.1.0-beta3

Minimal init.lua
The config options I use to setup smart-splits are:

      cursor_follows_swapped_bufs = true,
      ignored_filetypes = {
        "Outline",
        "Trouble",
        "help",
        "lazy",
        "neo-tree",
        "nofile",
        "propmpt",
        "quickfix",
        "toggleterm",
      },
      multiplexer_integration = "tmux",
      disable_multiplexer_nav_when_zoomed = true,

bug: SmartResizeLeft/Right echos message into command line

Calling :SmartResizeLeft or Right puts a message into the command line that means I have to press Enter on every resize, this doesn't happen for Up or Down though

image

I've silencing this via:

map <silent><A-H> :SmartResizeLeft 4<CR>
map <silent><A-J> :SmartResizeDown 2<CR>
map <silent><A-K> :SmartResizeUp 2<CR>
map <silent><A-L> :SmartResizeRight 4<CR>

but no avail

[Feature]: logging

Similar Issues

  • Before filing, I have searched for similar issues.

Description

It would be great to have some logs that I could ask users to put in bug reports. However, since all of smart-splits.nvim's functionality runs on keypresses, we will need to take special care to ensure that our logging solution is asynchronous so as not to block the main thread/freeze up the editor.

Reduce number of reloads while resizing?

I found that a lot is going on during resizing with smart-splits. Even when using a decent machine, this often produces a latency compared to regular resizing .

An example that makes it very visible is when using a statusline line like galaxyline. The statusline flashes between active and inactive mode on every resize step.

Another example is when opening two splits from different working directories and additionally a file tree that adapts to the working directory of the active buffer like nvim-tree. Using smart splits, the file tree flashes between the working directories with every resize step.

Depending on the tree plugin, and it's configuration smart-splits behavior also changes visible directories.

Working on a decent machine this won't produce peaks in system workload or something. Still, performing multiple resize steps in a row using smart splits often has a recognizable latency compared to regular resizing. But for those working on a weaker system, those become pretty recognizable lags.

Is this much processing and switching between buffers necessary for the plugins to work? If are there any ideas or plans for further development you can share, maybe the community can help with some implementations.

How to not break tmux zoom mode?

I use <F12> to toggle the zoom mode, in tmux zoom mode,
if I switch panel in vim, it will un zoom the tmux which is annoying.

Expected behavior
Ability to detect tmux zoom mode.

[Bug]: Moving between nvim splits stops working in poetry shells

Similar Issues

  • Before filing, I have searched for similar issues.

Neovim Version

NVIM v0.9.0
Build type: Release
LuaJIT 2.1.0-beta3

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/opt/homebrew/Cellar/neovim/0.9.0/share/nvim"

Multiplexer Integration

Wezterm

Multiplexer Version

wezterm 20230408-112425-69ae8472

Steps to Reproduce

Activate a poetry shell (with pynvim installed)
Open neovim
Create a neovim split
Try to move between splits using <C-{h|j|k|l}>

Expected Behavior

Moving between splits works using default keybindings

Actual Behavior

Moving between splits only works by calling :SmartCursorMove{Direction} directly

Minimal Configuration to Reproduce

local root = vim.fn.fnamemodify('./.repro', ':p')

-- set stdpaths to use .repro
for _, name in ipairs({ 'config', 'data', 'state', 'cache' }) do
  vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    '--single-branch',
    'https://github.com/folke/lazy.nvim.git',
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  -- do not remove the colorscheme! it makes testing nicer
  'folke/tokyonight.nvim',
  'mrjones2014/smart-splits.nvim',
  -- add any other pugins here
}

require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

require('smart-splits').setup({
  -- add any options here
})

-- recommended mappings
-- resizing splits
-- these keymaps will also accept a range,
-- for example `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
-- moving between splits
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
-- swapping buffers between windows
vim.keymap.set('n', '<leader><leader>h', require('smart-splits').swap_buf_left)
vim.keymap.set('n', '<leader><leader>j', require('smart-splits').swap_buf_down)
vim.keymap.set('n', '<leader><leader>k', require('smart-splits').swap_buf_up)
vim.keymap.set('n', '<leader><leader>l', require('smart-splits').swap_buf_right)

-- add anything else here
vim.opt.termguicolors = true
-- do not remove the colorscheme! it makes testing nicer
vim.cmd([[colorscheme tokyonight]])

Additional Details and/or Screenshots

No response

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.