Giter Site home page Giter Site logo

willothy / flatten.nvim Goto Github PK

View Code? Open in Web Editor NEW
403.0 4.0 12.0 157 KB

Open files and command output from wezterm, kitty, and neovim terminals in your current neovim instance

Home Page: https://luarocks.org/modules/willothy/flatten.nvim

License: MIT License

Lua 100.00%
lua neovim neovim-plugin vim nvim terminal

flatten.nvim's Introduction

LuaRocks

flatten.nvim

Open files and command output from `:term`, Wezterm and Kitty in your current neovim instance

2023-09-21.01-25-35.mp4

Config for demo here (autodelete gitcommit on write and toggling terminal are not defaults)

NOTE
There will soon be breaking changes on main with the release of 1.0.0.
See #87 for more info.

Features

  • Open files from terminal buffers without creating a nested session
  • Allow blocking for git commits
  • Configuration
    • Callbacks/hooks for user-specific workflows
    • Open in vsplit, split, tab, current window, or alternate window
  • Pipe from terminal into a new Neovim buffer (demo)
  • Setting to force blocking from the commandline, regardless of filetype
  • Command passthrough from guest to host
  • Flatten instances from wezterm and kitty tabs/panes based on working directory

Installation1

require("lazy").setup({
  {
    "willothy/flatten.nvim",
    config = true,
    -- or pass configuration with
    -- opts = {  }
    -- Ensure that it runs first to minimize delay when opening file from terminal
    lazy = false,
    priority = 1001,
  },
  --- ...
})
:Rocks install flatten.nvim

Then, in plugins/flatten.lua:

require("flatten").setup({
  -- your config
})

Usage

Open files normally:

nvim file1 file2

Force blocking for a file:

# with a custom block handler, you can use `nvim -b file1 file2`
nvim --cmd 'let g:flatten_wait=1' file1

Open files in diff mode:

nvim -d file1 file2

Enable blocking for $VISUAL:

# with a custom block handler, you can use `export VISUAL="nvim -b"`
export VISUAL="nvim --cmd 'let g:flatten_wait=1'" # allows edit-exec <C-x><C-e>

Enable manpage formatting:

export MANPAGER="nvim +Man!"

Execute a command in the host instance, before opening files:

nvim --cmd <cmd>

Execute a command in the host instance, after opening files:

nvim +<cmd>

Configuration

Defaults

Flatten comes with the following defaults:

---Types:
--
-- Passed to callbacks that handle opening files
---@alias BufInfo { fname: string, bufnr: buffer }
--
-- The first argument is a list of BufInfo tables representing the newly opened files.
-- The third argument is a single BufInfo table, only provided when a buffer is created from stdin.
--
-- IMPORTANT: For `block_for` to work, you need to return a buffer number OR a buffer number and a window number.
--            The `winnr` return value is not required, `vim.fn.bufwinid(bufnr)` is used if it is not provided.
--            The `filetype` of this buffer will determine whether block should happen or not.
--
---@alias OpenHandler fun(files: BufInfo[], argv: string[], stdin_buf: BufInfo, guest_cwd: string):window, buffer
--
local config = {
  callbacks = {
    ---Called to determine if a nested session should wait for the host to close the file.
    ---@param argv table a list of all the arguments in the nested session
    ---@return boolean
    should_block = require("flatten").default_should_block,
    ---If this returns true, the nested session will be opened.
    ---If false, default behavior is used, and
    ---config.nest_if_no_args is respected.
    ---@type fun(host: channel):boolean
    should_nest = require("flatten").default_should_nest,
    ---Called before a nested session is opened.
    pre_open = function() end,
    ---Called after a nested session is opened.
    ---@param bufnr buffer
    ---@param winnr window
    ---@param filetype string
    ---@param is_blocking boolean
    ---@param is_diff boolean
    post_open = function(bufnr, winnr, filetype, is_blocking, is_diff) end,
    ---Called when a nested session is done waiting for the host.
    ---@param filetype string
    block_end = function(filetype) end,
  },
  -- <String, Bool> dictionary of filetypes that should be blocking
  block_for = {
    gitcommit = true,
    gitrebase = true,
  },
  -- Command passthrough
  allow_cmd_passthrough = true,
  -- Allow a nested session to open if Neovim is opened without arguments
  nest_if_no_args = false,
  -- Window options
  window = {
    -- Options:
    -- current        -> open in current window (default)
    -- alternate      -> open in alternate window (recommended)
    -- tab            -> open in new tab
    -- split          -> open in split
    -- vsplit         -> open in vsplit
    -- smart          -> smart open (avoids special buffers)
    -- OpenHandler    -> allows you to handle file opening yourself (see Types)
    --
    open = "current",
    -- Options:
    -- vsplit         -> opens files in diff vsplits
    -- split          -> opens files in diff splits
    -- tab_vsplit     -> creates a new tabpage, and opens diff vsplits
    -- tab_split      -> creates a new tabpage, and opens diff splits
    -- OpenHandler    -> allows you to handle file opening yourself (see Types)
    diff = "tab_vsplit",
    -- Affects which file gets focused when opening multiple at once
    -- Options:
    -- "first"        -> open first file of new files (default)
    -- "last"         -> open last file of new files
    focus = "first",
  },
  -- Override this function to use a different socket to connect to the host
  -- On the host side this can return nil or the socket address.
  -- On the guest side this should return the socket address
  -- or a non-zero channel id from `sockconnect`
  -- flatten.nvim will detect if the address refers to this instance of nvim, to determine if this is a host or a guest
  pipe_path = require("flatten").default_pipe_path,
  -- The `default_pipe_path` will treat the first nvim instance within a single kitty/wezterm session as the host
  -- You can configure this behaviour using the following opt-in integrations:
  one_per = {
    kitty = false, -- Flatten all instance in the current Kitty session
    wezterm = false, -- Flatten all instance in the current Wezterm session
  },
}

Advanced configuration examples

Toggleterm

If you use a toggleable terminal and don't want the new buffer(s) to be opened in your current window, you can use the alternate mode instead of current to open in your last window. With this method, the terminal doesn't need to be closed and re-opened as it did with the old example config.

The only reason 'alternate' isn't the default is to avoid breaking people's configs. It may become the default at some point if that's something that people ask for (e.g., open an issue if you want that, or comment on one if it exists).

Note that when opening a file in blocking mode, such as a git commit, the terminal will be inaccessible. You can get the filetype from the bufnr or filetype arguments of the post_open callback to only close the terminal for blocking files, and the block_end callback to reopen it afterwards.

Here's my setup for toggleterm, including an autocmd to automatically close a git commit buffer on write:

local flatten = {
  "willothy/flatten.nvim",
  opts = function()
    ---@type Terminal?
    local saved_terminal

    return {
      window = {
        open = "alternate",
      },
      callbacks = {
        should_block = function(argv)
          -- Note that argv contains all the parts of the CLI command, including
          -- Neovim's path, commands, options and files.
          -- See: :help v:argv

          -- In this case, we would block if we find the `-b` flag
          -- This allows you to use `nvim -b file1` instead of
          -- `nvim --cmd 'let g:flatten_wait=1' file1`
          return vim.tbl_contains(argv, "-b")

          -- Alternatively, we can block if we find the diff-mode option
          -- return vim.tbl_contains(argv, "-d")
        end,
        pre_open = function()
          local term = require("toggleterm.terminal")
          local termid = term.get_focused_id()
          saved_terminal = term.get(termid)
        end,
        post_open = function(bufnr, winnr, ft, is_blocking)
          if is_blocking and saved_terminal then
            -- Hide the terminal while it's blocking
            saved_terminal:close()
          else
            -- If it's a normal file, just switch to its window
            vim.api.nvim_set_current_win(winnr)

            -- If we're in a different wezterm pane/tab, switch to the current one
            -- Requires willothy/wezterm.nvim
            require("wezterm").switch_pane.id(
              tonumber(os.getenv("WEZTERM_PANE"))
            )
          end

          -- If the file is a git commit, create one-shot autocmd to delete its buffer on write
          -- If you just want the toggleable terminal integration, ignore this bit
          if ft == "gitcommit" or ft == "gitrebase" then
            vim.api.nvim_create_autocmd("BufWritePost", {
              buffer = bufnr,
              once = true,
              callback = vim.schedule_wrap(function()
                vim.api.nvim_buf_delete(bufnr, {})
              end),
            })
          end
        end,
        block_end = function()
          -- After blocking ends (for a git commit, etc), reopen the terminal
          vim.schedule(function()
            if saved_terminal then
              saved_terminal:open()
              saved_terminal = nil
            end
          end)
        end,
      },
    }
  end,
}

Pipe path

Flatten now checks for kitty and wezterm by default, but this is how it works. If you use another terminal emulator or multiplexer, you can implement your pipe_path function based on this.

local pipe_path = function()
  -- If running in a terminal inside Neovim:
  if vim.env.NVIM then
    return vim.env.NVIM
  end
  -- If running in a Kitty terminal,
  -- all tabs/windows/os-windows in the same instance of kitty
  -- will open in the first neovim instance
  if vim.env.KITTY_PID then
    local addr = ("%s/%s"):format(
      vim.fn.stdpath("run"),
      "kitty.nvim-" .. vim.env.KITTY_PID
    )
    if not vim.loop.fs_stat(addr) then
      vim.fn.serverstart(addr)
    end
    return addr
  end
end

About

The name is inspired by the flatten function in Rust (and maybe other languages?), which flattens nested types (Option<Option<T>> -> Option<T>, etc).

The plugin itself is inspired by nvim-unception, which accomplishes the same goal but functions a bit differently and doesn't allow as much configuration.

Footnotes

  1. Lazy loading this plugin is not recommended - flatten should always be loaded as early as possible. Starting the host is essentially overhead-free other than the setup() function as it leverages the RPC server started on init by Neovim, and loading plugins before this in a guest session will only result in poor performance. โ†ฉ

flatten.nvim's People

Contributors

alex-tdrn avatar bekaboo avatar catgoose avatar davidmh avatar github-actions[bot] avatar indianboy42 avatar jedrzejboczar avatar kjuq avatar loqusion avatar nyngwang avatar sassanh avatar stevearc-stripe avatar utilyre avatar willothy 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

flatten.nvim's Issues

Combining with `gf`

Is your feature request related to a problem? Please describe.
As i'm using neovim terminal quite extensively, i do often use gf command to jump from an error message directly to the filepath. Would be cool to have this integrated too in flatten. Thank you for the plugin too !

Describe the solution you'd like
Using gf on something like linter output that has a filepath will reuse existing buffer

Describe alternatives you've considered
nil

Additional context
Linter example
image

Strange behavior when using git rebase in toggleterm with flatten.nvim

Describe the bug
When using git rebase -i HEAD^^ in toggleterm with flatten.nvim installed, after closing the reword buffer, :TogglTerm will make the terminal buffer occupy both windows instead of just the the bottom window.

Minimal config

local tmp = vim.env.TMPDIR
  or vim.env.TEMPDIR
  or vim.env.TMP
  or vim.env.TEMP
  or '/tmp'
local data = tmp .. '/' .. (vim.env.NVIM_APPNAME or 'nvim')
local packages_root = data .. '/site'
local cloned_root = packages_root .. '/pack/packages/start'

local flatten_cloned_path = cloned_root .. '/flatten.nvim'
local flatten_url = 'https://github.com/willothy/flatten.nvim.git'

local toggleterm_cloned_path = cloned_root .. '/toggleterm.nvim'
local toggleterm_url = 'https://github.com/akinsho/toggleterm.nvim.git'

vim.fn.mkdir(cloned_root, 'p')
vim.opt.pp:prepend(packages_root)
vim.opt.rtp:prepend(packages_root)

if not vim.loop.fs_stat(flatten_cloned_path) then
  vim.fn.system({ 'git', 'clone', flatten_url, flatten_cloned_path })
end

if not vim.loop.fs_stat(toggleterm_cloned_path) then
  vim.fn.system({ 'git', 'clone', toggleterm_url, toggleterm_cloned_path })
end

local toggleterm = require('toggleterm')
local flatten = require('flatten')

toggleterm.setup()
flatten.setup({
  window = {
    open = 'alternate',
  },
  callbacks = {
    should_block = function(argv)
      return vim.tbl_contains(argv, '-b')
    end,
    post_open = function(bufnr, winnr, ft, is_blocking)
      if not is_blocking then
        vim.api.nvim_set_current_win(winnr)
      end

      if ft == 'gitcommit' or ft == 'gitrebase' then
        vim.api.nvim_create_autocmd('BufWritePost', {
          buffer = bufnr,
          once = true,
          callback = function()
            vim.defer_fn(function()
              vim.api.nvim_buf_delete(bufnr, {})
            end, 50)
          end,
        })
      end
    end,
  },
  block_for = {
    gitcommit = true,
    gitrebase = true,
  },
})

To Reproduce
Steps to reproduce the behavior:

  1. Save the config above as minimal.lua
  2. cd to a random git repo with at least two commits
  3. nvim --clean -u minimal.lua
  4. :ToggleTerm
  5. Inside toggleterm, execute command git rebase -i HEAD^^
  6. The git interactive buffer is shown, change the first word in the second line to reword
  7. :w
  8. The git rewording buffer is shown, reword the commit and :w
  9. An empty buffer is shown
  10. :ToggleTerm --> the terminal occupies the both windows (bug)

Expected behavior
In step 10, the terminal should just be opened in the lower window not both

Screenshots

simplescreenrecorder-2023-06-28_11.07.12.mp4

Desktop (please complete the following information):

  • OS Linux xps-13-7390 6.3.9-arch1-1
  • Neovim Version NVIM v0.10.0-dev-585+g2e055e49a3

Additional context
Add any other context about the problem here.

How to use it with akinsho/toggleterm.nvim

Is your feature request related to a problem? Please describe.
I want to use it with toggleterm instead of inbuilt neovim terminal

Describe the solution you'd like
Some integration of this plugin and the toggleterm plugin

Add condition config for use with lazy

Discussed in #27

Originally posted by herrvonvoid March 25, 2023
... this way of setting the plugin up with lazy.nvim is not very convenient because then flatten.nvim appears as plugin to clean in the lazy ui and has to be reinstalled every time I clean some other plugins. How about putting the check in lazy.nvim's global condition (defaults.cond) instead? ...

`invalid escape sequence near ''\.'` on Windows

Describe the bug
While using flatten.nvim on Windows with the example configuration for toggleterm shown on the README, it returns the following error:

Error detected while processing BufEnter Autocommands for "*":
Error executing lua callback: Vim:Error invoking 'nvim_exec_lua' on channel 3:
Error loading lua: [string "<nvim>"]:3: invalid escape sequence near ''\.'
stack traceback:
        [C]: in function 'rpcrequest'
        .../Local/nvim-data/lazy/flatten.nvim/lua/flatten/guest.lua:19: in function 'send_files'
        .../Local/nvim-data/lazy/flatten.nvim/lua/flatten/guest.lua:56: in function <.../Local/nvim-data/lazy/flatten.nvim/lua/flatten/guest.lua:51>

To Reproduce
Steps to reproduce the behavior:

  1. Use the following config:
opts = {
		callbacks = {
				pre_open = function()
						-- Close toggleterm when an external open request is received
						require("toggleterm").toggle(0)
				end,
				post_open = function(bufnr, winnr, ft)
						if ft == "gitcommit" then
								-- If the file is a git commit, create one-shot autocmd to delete it on write
								-- If you just want the toggleable terminal integration, ignore this bit and only use the
								-- code in the else block
								vim.api.nvim_create_autocmd(
										"BufWritePost",
										{
												buffer = bufnr,
												once = true,
												callback = function()
														-- This is a bit of a hack, but if you run bufdelete immediately 
														-- the shell can occasionally freeze
														vim.defer_fn(
																function()
																		vim.api.nvim_buf_delete(bufnr, {})
																end,
																50
														)
												end
										}
								)
						else
								-- If it's a normal file, then reopen the terminal, then switch back to the newly opened window
								-- This gives the appearance of the window opening independently of the terminal
								require("toggleterm").toggle(0)
								vim.api.nvim_set_current_win(winnr)
						end
				end,
				block_end = function()
						-- After blocking ends (for a git commit, etc), reopen the terminal
						require("toggleterm").toggle(0)
				end
		}
}
  1. Try to open a file with nvim inside toggleterm

Desktop:

  • Windows 10 Home 21H2
  • NVIM v0.9.0-dev-1219+g773febc46

Allow to configure where to open files

Hi, thanks for this plugin! I just tried it with your settings for toggle-term and it works perfect.

There is one thing I would appreciate. Currently, a file is opened in a new tab. As I never work with tabs, it would be wonderful if there is an option allowing you to open a file in the current window.

Provide options for when Wezterm/kitty windows should nest

Describe the bug

Currently, I'm pinning commit = "d92c93959e9ac52a00002d6fd64c2d2ca5dd7192", since one of the changes afterwards includes a regression that will close a neovim instance when trying to open nvim in another tab of a terminal that already has a running nvim instance. It would be necessary to open another terminal and run it to not have it closed.
A fix would be superb - here and then there always comes up a use-case for terminal tabs :).

System

  • Linux, deb based
  • Neovim Nightly
  • Tested with kitty and wezterm tabs.

Should avoid opening files in windows containing special buffers (`&buftype != ''`)

Is your feature request related to a problem? Please describe.
It seems that currently flatten.nvim will open files in users' previous windows no matter what buffer is originally associated in that window. This can be an issue when users have two terminal windows opening side by side and try to open a file inside one of the terminals since the file opened will be displayed in the window for another terminal.

Describe the solution you'd like
Find the first window that is not associate with a special buffer (vim.bo.bt == '') and open the file in that window.

Describe alternatives you've considered
N/A

Additional context

There are some screenshots that explain the issue:

  1. Two terminals opened side by side:
    image

  2. Opening files from the terminal on the right (with the window on the left as the previous window accessed):

    image

  3. File opened on the left window, taking the place of the first terminal, which is not expected:

    image

Diff support

Support the -d, -O, and -o arguments being sent from guest to host

Option to return to the terminal after closing a file

Is your feature request related to a problem? Please describe.
I really like the 'alternate' option, but when I use it I end up accidentally closing the whole window when I'm done with the file.

Example:

  1. Open a terminal
  2. Run 'vi README.md'
  3. Read it, then hit ':q'
  4. The window is gone, instead of returning me to the terminal

Describe the solution you'd like
I'd like the option to return to the terminal after closing something that I opened with flatten.

Describe alternatives you've considered
I've played with callbacks. It seems that if I could trigger a ':bp' at the right point it would be perfect, but I wasn't able to figure out the right way to do that.

Additional context
For now I've just switched to using 'vsplit' instead of 'alternate' which works in my workflow, but isn't nearly as elegant.

Using neovim within flatten.nvim to edit long commands?

Context

Using neovim to edit a command in the normal shell

You can set neovim as the VISUAL environment variable so that pressing <C-x><C-e> opens it in neovim for editting:

It's a "bash" thing that's common in other shells as well. In the bash man-page, it's explained like this:

Invoke an editor on the current command line, and execute the result as shell commands. Bash attempts to invoke $VISUAL, $EDITOR, and emacs as the editor, in that order.

It looks something like this:

Using neovim to edit a command in the embedded neovim terminal shell

If you use neovim-remote you can detect when your shell is running within neovim and set VISUAL to be nvr -cc tabedit --remote-wait +'set bufhidden=wipe'. That way, instead of launching a nested neovim instance it will use the existing neovim instance to edit the command in a separate tab, inserting it on "save"

I got this from "Modern Vim" Tip 22 Using an Existing nvim Instance as the Preferred Editor, although it's a common practice

Question

If you try this with the default config and VISUAL=nvim, saving the edited command exits neovim completely:

So I was wondering whether it would be possible to have the same neovim-remote behavior with flatten.nvim i.e. opening the long command in a separate buffer for editing and recover it on save (:wq)

Perhaps one approach would be to mess with the VISUAL env var as well, or remapping the <C-x><C-e> keypress?

Customizable host address detection

Is your feature request related to a problem? Please describe.
I don't use :terminal I prefer to use kitty splits/tabs with my own plugin for sending text/running commands. I'd still like to be able to open files in the singular neovim instance. The thing is because its not actually a nested terminal I don't get the $NVIM variable in the other splits, there is a way using kitty @ ls to find all the other kitty windows and find which one has nvim running. I just need to tell flatten.nvim that

Describe the solution you'd like
Add a configuration option that allows the user to pass a callback that determines the pipe address that guest nvims should use to communicate with the host. The default implementation would just return vim.env.NVIM but users could use kitty (or wezterm, or tmux or whatever else) to find and return the correct servername/pipe address

Describe alternatives you've considered
The alternatives are something in the shell that sets $NVIM, this is possible but parsing json in shell scrip is annoying. Or figuring out somehow that the host nvim injects environment variables into all other windows (I don't think this is possible in an elegant way)

Manpage Format is Incorrect

Describe the bug
I set my default manpager to neovim by adding this to my .bashrc or .zshrc: export MANPAGER='nvim +Man!'

When opening a man page through a neovim terminal buffer with flatten.nvim loaded, the man page expectedly loads in the current neovim instance, but the format is messed up (see the screenshots below).

To Reproduce
Steps to reproduce the behavior:

  1. Add export MANPAGER='nvim +Man!' to shell config
  2. Open a terminal buffer in neovim
  3. man ls
  4. See error

Screenshots

man ls from the shell

image


man ls from neovim terminal

image

Desktop (please complete the following information):

  • macOS Monterey 12.5 (M1 Macbook Air)
  • NVIM v0.9.0-dev-1326+g7c8c15507

Additional Context
After looking around, the simple issue is that the Man! command isn't being run after flatten opens the man page in the current neovim instance. Could allowing nvim +<cmd> work with flatten?

Conflicts with other embedded nvim instances

Describe the bug
A clear and concise description of what the bug is.

I'm trying to use plugins such as one-small-step-for-vimkind which spawn an embedded Neovim instance, seemingly conflicting with this plugin. I've filed an issue under that plugin already, and the plugin author suggested asking you for solution to this problem. More context can be found under this issue.

To Reproduce
Steps to reproduce the behavior:

  1. Run :lua require'osv'.launch{port=8086}
  2. Error occurs

Expected behavior
A clear and concise description of what you expected to happen.

OSV launches and does not return the following error:

E5108: Error executing lua Vim:Error invoking 'nvim_exec_lua' on channel 3:
ch 3 was closed by the client
stack traceback:
        [C]: in function 'rpcrequest'
        ...re/nvim/lazy/one-small-step-for-vimkind/lua/osv/init.lua:134: in function 'launch'
        [string ":lua"]:1: in main chunk

Screenshots
If applicable, add screenshots and/or videos to help explain your problem.

Desktop (please complete the following information):

  • OS: Mac OS Ventura 13.2.1 (M1 Max)
  • Neovim Version: 0.8.3

Additional context
Add any other context about the problem here.

[Bug] File opened in another nvim instance

Describe the bug
File is opened in another nvim instance when I tried to open a file in a normal terminal (not nvim builtin-terminal) using nvim <filename>.

Mininal config

simplescreenrecorder-2023-07-28_00.46.32.mp4
local tmp = vim.env.TMPDIR
  or vim.env.TEMPDIR
  or vim.env.TMP
  or vim.env.TEMP
  or '/tmp'
local data = tmp .. '/' .. (vim.env.NVIM_APPNAME or 'nvim')
local packages_root = data .. '/site'
local cloned_root = packages_root .. '/pack/packages/start'
local cloned_path = cloned_root .. '/dropbar.nvim'
local url = 'https://github.com/willothy/flatten.nvim'

vim.fn.mkdir(cloned_root, 'p')
vim.opt.pp:prepend(packages_root)
vim.opt.rtp:prepend(packages_root)

if not vim.loop.fs_stat(cloned_path) then
  vim.fn.system({ 'git', 'clone', url, cloned_path })
end

require('flatten').setup()

To Reproduce
Steps to reproduce the behavior:

  1. Save the minimal config above as minimal.lua
  2. nvim --clean -u minimal.lua in one terminal
  3. In another terminal, run nvim --clean -u minimal.lua <filename>
  4. The file is opened in the first nvim instance instead of the second one.

Expected behavior
File is opened in the second nvim instance

Screenshots

Desktop (please complete the following information):

  • OS linux 6.4.4-arch1-1
  • Neovim Version: NVIM v0.10.0-dev-623+g92760a7f42

Additional context
Can confirm that the bug is introduced after commit d92c93959e9ac52a00002d6fd64c2d2ca5dd7192.

Breaking changes on main (flatten.nvim 1.0.0)

This is a tracking issue for breaking changes on main. I am releasing it an advance of any breaking changes to give fair warning, since I want using this plugin to be as seamless and unobtrusive to use as possible.

TLDR
No breaking changes yet. There will be some with 1.0.0, and then flatten will be stable.

I will soon be releasing version 1.0.0 of flatten.nvim, which will include some new features (#86), fully typed API/config docs for LSP (also #86), and a restructure of the core and guest code (wip) to allow for sending commands, files, and data separately.

This version will include some breaking changes to the configuration and callback signatures, but it will also be the last version of flatten.nvim to ever have breaking changes unless required by some change in upstream Neovim. I feel that flatten.nvim is largely feature-complete at this point, and therefore with 1.0.0 I am committing to full stability and semantic versioning. While features may be added, the API will not be subject to change once released. This is what precipitated the change to tables for callback arguments in #86 - we need to be able to add params as needed without huge arglists or breaking the API.

Any breakages required by changes in upstream Neovim will be accompanied by a major version bump for flatten.nvim, though I don't think that is likely to happen.

Unreleased (#86):

  • Moved pipe_path to callbacks, require it to be a function.
  • Changed pre_open, post_open, and block_end callbacks to take single tables instead of several args.
  • Renamed one_per to integrations.
  • TBD (considering but not implemented):
    • Rename callbacks to hooks?
    • Remove allow_command_passthrough option, add flag to explicitly disable command passthrough instead.
    • Possibly drop support for nvim 0.8? 0.9 is out everywhere and I would like to remove deprecated code.

Errors if swapfiles are enabled

Describe the bug
Trying to open a file with nvim <filename> within a neovim terminal results in a warning in the original instance of neovim and an error in the child.

To Reproduce
Steps to reproduce the behavior:

  1. Configure the plugin, following the directions, and ensure that swapfiles are enabled. The init.lua I'm using is included below.
  2. :split
  3. :term
  4. touch foo.txt
  5. nvim foo.txt

Expected behavior
No errors or warnings

Desktop (please complete the following information):

  • OS: macOS Ventura 13.2.1 (22D68)
  • Neovim version:
NVIM v0.8.3
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by [email protected]


Features: +acl +iconv +tui

Additional context
Test init.lua:

vim.opt.swapfile = true

-- Bootstrap the package manager (lazy.nvim)
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
	vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath, })
end
vim.opt.rtp:prepend(lazypath)

-- Load the plugin
require('lazy').setup { {'willothy/flatten.nvim', config = true }, }

Warning in the main neovim window:

Found a swap file by the name "~/.local/state/nvim/swap//%Users%m%foo.go.swp"
          owned by: m   dated: Sat Mar 18 08:01:54 2023
         file name: ~m/foo.go
          modified: no
         user name: m   host name: zaphod.local
        process ID: 52556 (STILL RUNNING)
While opening file "/Users/m/foo.go"
             dated: Thu Mar 16 11:17:35 2023

(1) Another program may be editing the same file.  If this is the case,
    be careful not to end up with two different instances of the same
    file when making changes.  Quit, or continue with caution.
(2) An edit session for this file crashed.
    If this is the case, use ":recover" or "vim -r /Users/m/foo.go"
    to recover the changes (see ":help recovery").
    If you did this already, delete the swap file "/Users/m/.local/state/nvim/swap//%Users%m%foo.go.swp"
    to avoid this message.

Swap file "~/.local/state/nvim/swap//%Users%m%foo.go.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: 

Error in the child neovim window (after switching buffer back to the terminal):

Error detected while processing BufEnter Autocommands for "*":                                                                                                                                                    
Error executing lua callback: Vim:Error invoking 'nvim_exec_lua' on channel 3:                                                                                                                                    
Error executing lua: ....local/share/nvim/lazy/flatten.nvim/lua/flatten/core.lua:123: Vim(edit):E325: ATTENTION                                                                                                   
stack traceback:                                                                                                                                                                                                  
        [C]: in function 'cmd'                                                                                                                                                                                    
        ....local/share/nvim/lazy/flatten.nvim/lua/flatten/core.lua:123: in function <....local/share/nvim/lazy/flatten.nvim/lua/flatten/core.lua:44>                                                             
stack traceback:                                                                                                                                                                                                  
        [C]: in function 'rpcrequest'                                                                                                                                                                             
        ...local/share/nvim/lazy/flatten.nvim/lua/flatten/guest.lua:19: in function 'send_files'                                                                                                                  
        ...local/share/nvim/lazy/flatten.nvim/lua/flatten/guest.lua:56: in function <...local/share/nvim/lazy/flatten.nvim/lua/flatten/guest.lua:51>   

post_open shall provide bufnr and winnr for newly opened file

Describe the bug
If we want to do something in the call back that moves the focus to different tab, it is not possible to shift the focus back to newly opened tab.

To Reproduce
Steps to reproduce the behavior:

config

-- Setup toggle terminal

local ftzsh = fterm:new({
    ft = 'fterm_zsh',
    cmd = "zsh",
    dimensions = {
        height = 0.9,
        width = 0.9
    }
})

function M.__fterm_zsh()
    ftzsh:toggle()
end

-- Hide the terminal before jumping to new tab so that it opens in current tab next time.

{
    callbacks = {
        post_open = function(_, winnr, _, _)
            require("fterm").__fterm_zsh()  <-------- this moves the focus to current window where floating terminal is currently open
            vim.api.nvim_set_current_win(winnr)    <---------- need winnr of newly opened file here
        end
    },
    window = {
        open = "tab"
    }
}

With toggle terminal (fterm)

Open a file

Expected behavior
Focus should be on newly opened file

Screenshots
n/a

Desktop (please complete the following information):

  • Linux (Arch, Ubuntu)
  • 0.9

Additional context
It helps users to provide both current and new win/buf numbers to customize based on the use case. Let me know if you need more information or context.

Option to have wezterm only flatten if in the same pane

Would it be possible to have instances in wezterm only flatten if the neovim instance is in the same pane?

I really like the flatten feature for when I am using splits, but when I am using tabs it's quite confusing. It took me a while to realise that it was the flatten feature that made my neovim instances instantly close becasue I had one open in a different tab ๐Ÿ˜… I could of course disable wezterm flattening, but it would be neat to have it for just splits, when the neovim instance is visible, and it is obvious what is happening.

Errors out when calling `setup` without any parameters

Describe the bug
The title.

To Reproduce
Steps to reproduce the behavior:

  1. Put require("flatten").setup() in your config.

Expected behavior
It should just use the default config.

Additional context
Although using something like the opts table or config = true in lazy.nvim is recommended, I think it's better not to throw when there's no config table provided in setup.

NOTE: I'm just gonna open a PR to fix.

When there is space in the filename the filename passed to neovim is escaped

Describe the bug
Run nvim "a b c" in nvim terminal, a a\ b\ c file is opened instead. Out of the nvim the correct a b c is opened.

To Reproduce
Steps to reproduce the behavior:

  1. Open the terminal in nvim
  2. Run nvim "a b c"

Expected behavior
The correct file name is passed to nvim.

Screenshots
If applicable, add screenshots and/or videos to help explain your problem.

Minimal Init
Please provide a minimal init to quickly reproduce the issue.

Desktop (please complete the following information):

  • OS NixOS
  • Terminal emulator / nvim GUI
  • Neovim Version 0.9.1

Additional context
Add any other context about the problem here.

Commits on August 10 Don't respect the window --> open setting

Describe the bug
I open a terminal in neovim and open a random file, in my case ~/haha.md. My setting says to open it in the current window/tab but a new tab is opened instead.

To Reproduce
Install flatten with Lazy.nvim as you normally would. Open a neovim terminal and enter nvim [some file]

Expected behavior
File should open in the same tab/window.

Desktop (please complete the following information):

  • OS: Arch Linux
  • Terminal emulator / nvim GUI: Kitty
  • Neovim Version: 0.9.1

Additional context
The problem is solved by going to commits from previous days; 07e9496191653587336b4c8f8cab02e5c34c7c44 works as expected

How to avoid swap file warning E325?

Discussed in #82

Originally posted by eddyecho November 16, 2023
If I already have a file open in an existing buffer and then try to open the file again in terminal mode with simple nvim file, how do i avoid an E325? I am coming from neovim remote which handled this out of box so I'm wondering if I am missing something here?

I'd like to find a fix for this before releasing 1.0.0, if possible.

Bug with plugins that automatically change cwd

Describe the bug
Currently the arguments are sent as is, along with guest_cwd, assuming guest_cwd/argv will give the correct absolute path. However if the user has a plugin/autocmd that automatically changes the cwd base on, for example .git or whatever, then this assumption is broken

To Reproduce
This is the autocd code I use, which is set before lazy.setup{} even
https://pastebin.com/7uq31x2a

  1. cd some_dir with a .git
  2. cd sub_dir && nvim some_file
  3. host nvim tries to open some_dir/some_file

Expected behavior
some_dir/sub_dir/some_file should be opened instead

Screenshots
If applicable, add screenshots and/or videos to help explain your problem.

Desktop (please complete the following information):

  • OS - Pop!_OS 22.04 LTS
  • Neovim Version - v0.10.0-dev-541+g96b94f8d7

Additional context
One solution is of course to make sure these autocd plugins do not load and activate too early, but then ideally the documentation of this plugin would reflect this requirement.

The more robust solution is to properly fully resolve filepaths (absolute) on the guest side, perhaps we should use the names from the buffers that are automatically opened by neovim?

`nvim --cmd 'let g:flatten_wait=1' file1` does not work, neither does `-b`

Describe the bug
None of the blocking options work

To Reproduce
Steps to reproduce the behavior:

  1. use either of the 2 blocking commands

Expected behavior
To allow nested instances

Screenshots
NA

Minimal Init

{
    "willothy/flatten.nvim",
    opts = function()
      ---@type Terminal?
      local saved_terminal

      return {
        window = {
          open = "alternate",
        },
        callbacks = {
          should_block = function(argv)
            -- Note that argv contains all the parts of the CLI command, including
            -- Neovim's path, commands, options and files.
            -- See: :help v:argv

            -- In this case, we would block if we find the `-b` flag
            -- This allows you to use `nvim -b file1` instead of
            -- `nvim --cmd 'let g:flatten_wait=1' file1`
            return vim.tbl_contains(argv, "-b")

            -- Alternatively, we can block if we find the diff-mode option
            -- return vim.tbl_contains(argv, "-d")
          end,
          pre_open = function()
            local term = require("toggleterm.terminal")
            local termid = term.get_focused_id()
            saved_terminal = term.get(termid)
          end,
          post_open = function(bufnr, winnr, ft, is_blocking)
            if is_blocking and saved_terminal then
              -- Hide the terminal while it's blocking
              saved_terminal:close()
            else
              -- If it's a normal file, just switch to its window
              vim.api.nvim_set_current_win(winnr)
            end

            -- If the file is a git commit, create one-shot autocmd to delete its buffer on write
            -- If you just want the toggleable terminal integration, ignore this bit
            if ft == "gitcommit" or ft == "gitrebase" then
              vim.api.nvim_create_autocmd("BufWritePost", {
                buffer = bufnr,
                once = true,
                callback = vim.schedule_wrap(function()
                  vim.api.nvim_buf_delete(bufnr, {})
                end),
              })
            end
          end,
          block_end = function()
            -- After blocking ends (for a git commit, etc), reopen the terminal
            vim.schedule(function()
              if saved_terminal then
                saved_terminal:open()
                saved_terminal = nil
              end
            end)
          end,
        },
      }
    end,
  },

Desktop (please complete the following information):

  • OS Void linux
  • Foot
  • NVIM v0.10.0

Additional context
I'm using toggle term

Support quickfix mode

Hi, thanks for this plugin! It works perfect.

There is one thing I would appreciate. Currently, open files in quickfix mode from terminal buffers will create a nested session.
It would be wonderful if a quickfix or location list is created in this usage.

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.