Giter Site home page Giter Site logo

possession.nvim's Introduction

Lint

possession.nvim

Flexible session management for Neovim.

Features

  • Save/load Vim sessions
  • Keep track of last used session
  • Sessions stored in JSON files
  • Store arbitrary data in the session file
  • User hooks before/after save/load
  • Uses good old :mksession under the hood
  • Configurable automatic save (with CWD support)
  • Configurable automatic loading (based on CWD)
  • Out of the box telescope.nvim integration
  • Example integration with alpha-nvim
  • Save & restore nvim-dap breakpoints

Overview

This is yet another session management plugin for Neovim.

The main goal was to make session management more flexible and overall more Lua-friendly. All other session management plugins I know (e.g. auto-session, persisted.nvim, vim-obsession, vim-startify) use Vim's :mksession! directly to generate Vimscript files that are later :sourced. This works well in general, but storing user data between sessions may be problematic.

To solve this issue possession uses JSON files to easily store session metadata. Under the hood :mksession! is still used, but the resulting Vimscript is stored in the JSON file along other data.

Installation

With packer.nvim:

use {
    'jedrzejboczar/possession.nvim',
    requires = { 'nvim-lua/plenary.nvim' },
}

Or with other package managers/manually, but make sure plenary.nvim is installed.

Configuration

Detailed documentation

See doc/possession.txt.

Quick start

Call require('possession').setup { ... } somewhere in your init.lua. The default configuration is:

require('possession').setup {
    session_dir = (Path:new(vim.fn.stdpath('data')) / 'possession'):absolute(),
    silent = false,
    load_silent = true,
    debug = false,
    logfile = false,
    prompt_no_cr = false,
    autosave = {
        current = false,  -- or fun(name): boolean
        cwd = false, -- or fun(): boolean
        tmp = false,  -- or fun(): boolean
        tmp_name = 'tmp', -- or fun(): string
        on_load = true,
        on_quit = true,
    },
    autoload = false, -- or 'last' or 'auto_cwd' or 'last_cwd' or fun(): string
    commands = {
        save = 'PossessionSave',
        load = 'PossessionLoad',
        save_cwd = 'PossessionSaveCwd',
        load_cwd = 'PossessionLoadCwd',
        rename = 'PossessionRename',
        close = 'PossessionClose',
        delete = 'PossessionDelete',
        show = 'PossessionShow',
        list = 'PossessionList',
        list_cwd = 'PossessionListCwd',
        migrate = 'PossessionMigrate',
    },
    hooks = {
        before_save = function(name) return {} end,
        after_save = function(name, user_data, aborted) end,
        before_load = function(name, user_data) return user_data end,
        after_load = function(name, user_data) end,
    },
    plugins = {
        close_windows = {
            hooks = {'before_save', 'before_load'},
            preserve_layout = true,  -- or fun(win): boolean
            match = {
                floating = true,
                buftype = {},
                filetype = {},
                custom = false,  -- or fun(win): boolean
            },
        },
        delete_hidden_buffers = {
            hooks = {
                'before_load',
                vim.o.sessionoptions:match('buffer') and 'before_save',
            },
            force = false,  -- or fun(buf): boolean
        },
        nvim_tree = true,
        neo_tree = true,
        symbols_outline = true,
        outline = true,
        tabby = true,
        dap = true,
        dapui = true,
        neotest = true,
        delete_buffers = false,
        stop_lsp_clients = false,
    },
    telescope = {
        previewer = {
            enabled = true,
            previewer = 'pretty', -- or 'raw' or fun(opts): Previewer
            wrap_lines = true,
            include_empty_plugin_data = false,
            cwd_colors = {
                cwd = 'Comment',
                tab_cwd = { '#cc241d', '#b16286', '#d79921', '#689d6a', '#d65d0e', '#458588' }
            }
        },
        list = {
            default_action = 'load',
            mappings = {
                save = { n = '<c-x>', i = '<c-x>' },
                load = { n = '<c-v>', i = '<c-v>' },
                delete = { n = '<c-t>', i = '<c-t>' },
                rename = { n = '<c-r>', i = '<c-r>' },
            },
        },
    },
}

Recommendations

Migrating

To migrate existing vimscript-based sessions use the :PossessionMigrate command. It will try to generate session files in JSON format from given directory (or file). The files will be stored in session_dir so make sure to use different directories. Session name is assumed to be the filename without extension.

Commands

The defaults command names are quite long, but shorter names can be configured:

require('possession').setup {
    commands = {
        save = 'SSave',
        load = 'SLoad',
        delete = 'SDelete',
        list = 'SList',
    }
}

Session options

Under the hood this plugin uses the command :mksession which in turn uses 'sessionoptions' to "make" the session. See :help 'sessionoptions' for available options, some notable ones:

  • options - Can mess things up, use only when you know what you're doing (Neovim has sane default of not including this one)
  • buffers - While this plugin offers delete_hidden_buffers, I'd also suggest using set sessionoptions-=buffers to just exclude hidden buffers when saving session.

Telescope

require('telescope').load_extension('possession')

Then use :Telescope possession list or require('telescope').extensions.possession.list() The default action will load selected session.

Alternatively, use :Telescope possession list only_cwd=true or require('telescope').extensions.possession.list({only_cwd=true}) This will limit the displayed sessions to those related to the current working directory.

telescope

Auto-save

It is possible to automatically save the current session (or create a tmp or cwd session) when quitting Neovim or loading a different session. This behavior is disabled by default, but can be enabled using the autosave.* configuration options. Check doc/possession.txt for details.

Overwriting CWD session

When autosave.cwd is set to true, there are situations were the cwd session might be saved when it is not wanted, e.g. when file arguments are passed to Neovim, and when a session is closed via :PossessionClose (see #72 for details). To prevent overwriting the cwd session in these cases, you can use the following setting:

autosave = {
    cwd = function()
          return not require('possession.session').exists(require('possession.paths').cwd_session_name())
    end
}

Auto-load

Sessions can be auto-loaded by setting the autoload.* config options. Check doc/possession.txt for details.

Statusline

To display the current session name in statusline/winbar/etc. you can define the following function:

local function session_name()
    return require('possession.session').get_session_name() or ''
end

and use it in your statusline setup. For a lualine example see #14 (comment).

Startup screen

Currently there is no out-of-the-box integration with any startup screen, PRs welcome. For an example configuration see #22 (comment). Some general guidelines are described below.

The require('possession.query') module provides helper functions for querying available sessions. It can be helpful when generating a startup screen. Take a look at the helper function workspaces_with_shortcuts which implements all the burden of splitting sessions into workspaces based on root directories specified by the user and will generate shortcuts for each group. The resulting table can be used when generating a startup screen.

When using alpha-nvim there is an additional helper function that generates a layout group that can be included in the startup screen. Example usage:

local query = require('possession.query')
local workspaces = {
    {
        'Workspace A',  -- title
        'a',            -- shortcuts prefix
        {
            '/root/directory/a',
            '/other/root/directory/',
        },
    }, {
        'Workspace B',
        'b',
        '/root/directory/b',
    }
}
-- e.g. https://github.com/goolord/alpha-nvim/blob/8a1477d8b99a931530f3cfb70f6805b759bebbf7/lua/alpha/themes/startify.lua#L28
local create_button = function(shortcut, text, keymap)
    -- ...
end

local get_layout = function()
    return query.alpha_workspace_layout(workspaces, create_button, {
        others_name = 'Sessions Without Workspace',
    })
end

-- use with the rest of sections for alpha.nvim, with throttling to avoid reading files on each redraw
local utils = require('possession.utils')
local sections = {
    -- ...
    sessions = {
        type = 'group',
        val = utils.throttle(get_layout, 5000),
    },
    -- ...
}

alpha

possession.nvim's People

Contributors

awerebea avatar axeldetlofsson avatar bogdan-the-great avatar igorlfs avatar jedrzejboczar avatar josh-nz avatar mawkler avatar ofirgall avatar raafatturki avatar wasden avatar yutkat 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

possession.nvim's Issues

Error in save/load sessions

Again, the close everything except the open buffer is happening, tried the solution shown in previous threads but it's not workig, running on Arch Linux with the nvim 0.7.2

Error when invoking PossessionShow function

The commit d4a071e causes this issue when calling function PossessionShow

Error executing Lua callback: vim/shared.lua:0: s: expected string, got table
stack traceback:
	[C]: in function 'error'
	vim/shared.lua: in function 'validate'
	vim/shared.lua: in function 'endswith'
	...share/nvim/lazy/possession.nvim/lua/possession/paths.lua:11: in function 'session'
	...re/nvim/lazy/possession.nvim/lua/possession/commands.lua:127: in function 'show'
	...local/share/nvim/lazy/possession.nvim/lua/possession.lua:33: in function <...local/share/nvim/lazy/possession.nvim/lua/possession.lua:32>

Downgrading plugin to bfef005 commit fixes this for now.

Terminals are not killed because they have "unsaved changes"

If there is a neovim terminal in a hidden buffer, possession will fail to save the session with the following message:

Cannot delete buffer with unsaved changes: "term://[...]"

Perhaps terminals should simply be force-killed if they are hidden and the option is set?

Make restoring folds more robust

Hello!

'sessionoptiions', by default, includes 'folds'. However, currently, restoring a session that contains folds might be unreliable. If a file (containing folds) from a session is modified outside said session, when restoring it, if any of the folding ranges is no longer valid, possession throws the following error:

Error executing lua: ...are/nvim/lazy/possession.nvim/lua/possession/session.lua:248: ...are/nvim/lazy/possession.nvim/lua/possession/session.lua:247: nvim_exec2(): Vim(fold):E16: Invalid range: XX,YYfold

(where XX and YY are the start and end for the range)

I understand this might an issue with neovim itself (perhaps the function call shouldn't even fail?), but if anything can be done on possession's side, that would be great! When using :mksession and nvim -S Session.vim, the session is mostly restored, albeit the given invalid range is actually invalid (and closed).

However, possession gives up on trying to restore the other buffers, which is really annoying. I often use tabs and I get this behavior:

image

As you can see, the first tab is fine, but every other tab contains an empty buffer.

If this should be handled upstream, let me know!

Bug when saving/loading session.

It closes all the buffers except the one in focus. Even after disabling all the plugin config

plugins = {
        -- close_windows = {
        --     hooks = { 'before_load', 'before_save' },
        --     preserve_layout = true, -- or fun(win): boolean
        --     match = {
        --         floating = true,
        --         buftype = {},
        --         filetype = {
        --             'gitcommit',
        --             'alpha',
        --             'dashboard',
        --             'neo-tree',
        --             'Outline',
        --             'Tagbar',
        --             'Mundo',
        --             'MundoDiff',
        --             'toggleterm',
        --             'undotree',
        --             'qf',
        --         },
        --         custom = false, -- or fun(win): boolean
        --     },
        -- },
        -- delete_hidden_buffers = false,
        -- delete_hidden_buffers = {
        --     hooks = {
        --         -- 'before_load',
        --         -- 'before_save',
        --         vim.o.sessionoptions:match('buffer') and 'before_save',
        --     },
        --     force = false, -- or fun(buf): boolean
        -- },
        -- nvim_tree = false,
        -- tabby = false,
        -- delete_buffers = true,
    },

My session option

vim.opt.sessionoptions = 'blank,buffers,curdir,folds,help,tabpages,globals,winsize,winpos,terminal'

It still closes all the buffers one by one. What I mean is if I have 12 buffers open, it will not close them all in a single save/restore command.

With every load/restore it will close 1 buffer. So after some use most of my buffers will be closed except the one in focus.

Autosave is not working

First of all, thank you for the plugin.
I am trying to autosave the currently loaded session. For example, I have saved a session with buffer a and b. If I open another buffer, then the session doesn't save the buffer. I always have to manually run the save command.

Here is the config:

    use {
        "jedrzejboczar/possession.nvim",
        requires = { "nvim-lua/plenary.nvim" },
        config = function()
            require("possession").setup {
                autosave = {
                    current = true,
                },
                plugins = { delete_hidden_buffers = false },
            }
        end,
    }

Neovim version: NVIM v0.10.0-dev-533+g7e301ed5b
I have also tested that on a stable version. Same problem.
Config repo: https://github.com/thatanjan/neovim-config

Thanks in advance

[Enhancement] add git branches support

This is best sessions plugin I have found (better then Persistence/Persisted or auto-session)
Cleanest and best configuration, custom session names (all other plugins just save session per working dir, no multiple sessions for single dir allowed)

One thing that may be lacking is command to auto name session after current git branch. Of course I can name session manually, but it would be nice to have this automated - maybe some option added to PossessionSave command
It could be even better if configuration option exist to auto load session on branch change

This is just idea, thanks for great plugin

Close session without exiting Neovim

Sometimes I want to switch projects (sessions) during the same Neovim instance. It could be a convenient feature to allow the user to close the current session without exiting Neovim.

bug: auto load cwd with auto save will save blank session first

Relates to #55

If configured with autosave.cwd = true and autoload.cwd = true, when starting Neovim M.load in session.lua will try to autosave. It looks like this should be skipped but for whatever reason, autosave_skip() is returning true for me.

This has the follow behaviour:

  1. The cwd json file is parsed first, so session data is in memory.
  2. The cwd session is loaded, triggering autosave
  3. autosave saves the blank Neovim buffers into the cwd session file
  4. session is loaded from data in memory.

While this works, if you have other autosave settings turned off (or Neovim crashes etc), then there is a chance the session will be lost.

Ideally, we skip saving when autoloading from cwd. It looks like this was the intent, and autosave_skip() has a bug. I don't know the nuance of Neovim that the skip function is trying to achieve, but results from my tests are below:

Screen Shot 2024-06-11 at 18 56 29
local function autosave_skip()
    -- Skip scratch buffer e.g. startscreen
    local unscratch_buffers = vim.tbl_filter(function(buf)
        return 'nofile' ~= vim.bo[buf].buftype
    end, vim.api.nvim_list_bufs())
    -- unscratch_buffers is true
    -- next(unscratch_buffers) is true
    -- so return evaluates to false
    return not unscratch_buffers or not next(unscratch_buffers)
end

Unable disable `delete_hidden_buffers` setting

I have looked into #18, and set delete_hidden_buffers to false and delete_buffers to true. But the behaviour still persists regardless.
My config:

local possess_status_ok, possession = pcall(require, "possession")
if not possess_status_ok then
    vim.notify("Unable to require possession")
    return
end

possession.setup {
    autosave = {
        current = true
    },
    commands = {
        save = 'SSave',
        load = 'SLoad',
        delete = 'SDelete',
        list = 'SList',
        close = 'SClose',
        show = 'SShow',
        migrate = 'SMigrate',
    },
    delete_hidden_buffers = false, -- Remove the deletion of hidden buffers without windows
    delete_buffers = true, -- Delete all buffers before loading another session
}

-- Telescope integrations
local tele_status_ok, telescope = pcall(require, "telescope")
if not tele_status_ok then
    vim.notify("Unable to require telescope for possession plugin")
    return
end

telescope.load_extension('possession')

Tabby tab names not loading

tabby 2.3.0 9e53776
possession bc22959

They don't load, no errors.
I forced tabby as a dependency for possession (with lazy.vim) to make sure you get what you require (to read and update tabs).
I can see they were written in the Session file:

...
plugin_data = {
    close_windows = {},
    dap = {
        breakpoints = {}
    },
    nvim_tree = {
        tabs = {}
    },
    symbols_outline = {},
    tabby = {
        tab_names = {
            ["1"] = "Bars",
            ["2"] = "Keyboard"
        }
    }
}
...

No fold found Error

When restoring session, the below error happens time to time. Not always.

E5108: Error executing lua ...ck/packer/opt/possession.nvim/lua/possession/session.lua:176: Vim(normal):E490: No fold found
stack traceback:
	[C]: in function 'nvim_exec'
	...ck/packer/opt/possession.nvim/lua/possession/session.lua:176: in function 'fn'
	...possession.nvim/lua/telescope/_extensions/possession.lua:77: in function 'run_replace_or_original'
	...k/packer/opt/telescope.nvim/lua/telescope/actions/mt.lua:65: in function 'key_func'
	...ack/packer/opt/telescope.nvim/lua/telescope/mappings.lua:341: in function 'execute_keymap'
	[string ":lua"]:1: in main chunk

My session options

vim.opt.sessionoptions =
	{ 'buffers', 'curdir', 'folds', 'help', 'tabpages', 'globals', 'winsize', 'winpos', 'terminal' }

Correct LSP behaviour when changing sessions?

I've investigated the errors I'm seeing when I change sessions via :PossessionLoad as per #61 (comment).

I have tried a minimal config repoduction with just my lsp config and Possession and I can still trigger the issue, even with 0.11-nightly. The key to triggering this is to have delete_buffers = true in the Possession config. More on this later.

One issue occurs in Neovim Lua file nvim/share/nvim/runtime/lua/vim/lsp.lua in the reset_defaults function. It tries to call vim.keymap.del on the K mapping. Even though it has done a check for this keymap existing right before it deletes it, the del function errors saying it cannot find it. I still had K mapped to this function manually (from before 0.10 natively supported it). Removing this manual mapping seems to solve this issue, but there are others. I wonder if the real source of this issue is not my manual mapping, but some form of race condition, as outlined below with the other issues I'm seeing.

There are a few other issues that can occur. While the keymap issue seems to occur every time you load a session and there is already an existing session loaded, these other issues only start to occur after loading different sessions a few times. All the errors complain about an invalid buffer id.

I don't have a very detailed knowledge of how the LSP client in Neovim works, but it looks like on starting, the client registers an exit callback which is what will eventually call the K map reset and other things. It looks like to me that this might happen async, as when I log the buffers being deleted by Possession during a load, it looks like the internal Neovim code is trying to access a buffer that no longer exists. Quite why or how it's getting a reference to a non-existing buffer is beyond me, except if it was async and this is a race condition.

Screen Shot 2024-06-15 at 16 05 50

The last line in utils.lua delete_all_buffers (which is what is called during :PossessionLoad when the delete_buffers = true config is set), is vim.lsp.stop_client(lsp_get_clients()) and this seems to be the source of the above mentioned issues. Removing this line makes my issues go away.

This might ultimately be some bug in Neovim (it's still present in 0.11 nightly if it is), but I'm wondering what we should be doing with the LSP clients across session loads.

Here is a basic outline of existing non-session behaviour:

  • Load blank Neovim
  • Open Lua file - Lua LSP attaches to this buffer
  • Open Python file - Python LSP attaches to this buffer
  • :LspInfo shows 1 active (Python) client attached to this buffer, and 1 active (Lua) client not attached to this buffer
  • Switch to the Lua buffer
  • :LspInfo shows the same info as above but obviously the clients are swapped.
  • Delete Lua buffer
  • :LspInfo shows that the Lua client is still active even though no Lua files are open anymore.
  • Delete Python buffer
  • :LspInfo shows that the Python (and Lua) clients are still active even though no Lua or Python files are open anymore

This suggests to me that the LSP clients remain until explicitly stopped by the user, or Neovim exists. This gives us context on how to proceed when switching between sessions within the same Neovim instance.

Given the LSP client behaviour defined above, perhaps we just remove vim.lsp.stop_client(lsp_get_clients()) and do nothing. I've had a look at several other session plugins and none of them do anything with LSP clients when loading sessions. This doesn't mean they are correct of course.

There is a question of cleaning up the LSP workspaces and how this works when buffers are deleted. Maybe Neovim takes care of it for us, but it also looks like we can something like:

                if vim.lsp.buf_is_attached(buffer, client.id) then
                    vim.lsp.buf_detach_client(buffer, client.id)
                end

which might be worthwhile, but I'm unsure what it exactly does and whether it is needed. I would hope that :bd takes care of whatever is needed automatically.

I haven't been able to find much else around what the correct thing to do is, when loading sessions and LSP clients. There is however this in the LSP FAQ:

Q: How to force-reload LSP?
A: Stop all clients, then reload the buffer.
:lua vim.lsp.stop_client(vim.lsp.get_clients())
:edit

Which makes me wonder, if instead of calling vim.lsp.stop_client(lsp_get_clients()) after deleting buffers, we call the above after loading a new session (except the autoload session, since there will be no LSP clients running at this point, and we don't want to interrupt any that are starting up and make them restart).

Auto-restore based on CWD

It loads sessions from other directories and it is very annoying. I created a keybind that loads the session aswell. This should use the sessions corresponding to the directory and not one big session file (I think that is what it does)

require('possession').setup {
	commands = {
		save = 'SSave',
		load = 'SLoad',
		delete = 'SDelete',
		list = 'SList',
	},
	autosave = {
		current = true,
		tmp = true,
		on_load = true,
		on_quit = true,
	},
}

"Unknown keys passed to possession.setup" appears on startup

After recent update the following error appears on startup:

Unknown keys passed to possession.setup:
  plugins.close_windows.match.filetype.1

This is my setup:

possession.setup({
    silent = true,
    autosave = {
        current = true
    },
    plugins = {
        delete_hidden_buffers = {
            hooks = {
            }
        },
        delete_buffers = true,
        close_windows = {
            hooks = { 'before_save', 'before_load' },
            preserve_layout = false,
            match = {
                floating = true,
                buftype = {},
                filetype = { 'aerial' }
            }
        },
    }
})

It seems like this was introduced by commit c65d25a . Not sure why this is considered "unknown option" as this is documented option which seems to continue to work.

`:PossessionSave` closes all non-visible buffers

:PossessionSave closes any buffer that's not in a window. To reproduce, use the following config:

Click to expand
-- Ignore default config and plugins
vim.opt.runtimepath:remove(vim.fn.expand('~/.config/nvim'))
vim.opt.packpath:remove(vim.fn.expand('~/.local/share/nvim/site'))

-- Append test directory
local test_dir = vim.fn.expand('~/code-other/nvim-test-config')
vim.opt.runtimepath:append(vim.fn.expand(test_dir))
vim.opt.packpath:append(vim.fn.expand(test_dir))

-- Install packer
local install_path = test_dir .. '/pack/packer/start/packer.nvim'
local install_plugins = false

if vim.fn.empty(vim.fn.glob(install_path)) > 0 then
  vim.cmd('!git clone https://github.com/wbthomason/packer.nvim ' .. install_path)
  vim.cmd('packadd packer.nvim')
  install_plugins = true
end

local packer = require('packer')

packer.init({
  package_root = test_dir .. '/pack',
  compile_path = test_dir .. '/plugin/packer_compiled.lua'
})

packer.startup(function()
  function Use(module)
    use(require(string.format('configs.%s', module)))
  end

  -- Packer can manage itself
  packer.use 'wbthomason/packer.nvim'


  use { 'jedrzejboczar/possession.nvim',
    requires = { 'nvim-lua/plenary.nvim' },
    config = function()
      require('possession').setup()
    end
  }

  if install_plugins then
    packer.sync()
  else
    -- load plugins at your earliest convenience
    vim.defer_fn(function()
      vim.cmd('doautocmd User LoadPlugins')
    end, 1)
  end
end)
And then run this:
> nvim -u path/to/file/above.lua foo bar baz -c ':buffers' -c ':PossessionSave test' -c ':buffers'

Here's the output of the first :buffers:

  1 %a   "foo"                          line 0
  2      "bar"                          line 0
  3      "baz"                          line 0

And here's the output of the second :buffers:

  1 %a   "foo"                          line 1

You get the same behaviour if you run :PossessionSave manually from inside Neovim.

Feature request: `:PossessionRename`

I think it would be neat if we had a :PossessionRename command that changes the name of a session.

The user would type :PossessionRename <session name> and a vim.ui.input prompt would pop asking for the new name.

After selecting in Telescope not returned to normal mode

Whenever I open a session using Telescope possession list the state isn't returned back into normal mode. This can be quite annoying because the file that it opens isn't necessary the one I want to edit right away. Is there a setting to force it back into normal mode right after opening? Opening using the commands driectly doesn't experience this issue.

[Question] Custom plugins? (extensions?)

I'd like to add my own plugin that uses the hooks and adds its own plugin_data to the session.

For example if you wanted to give open tabs custom names, and store them in the session JSON file.

I've looked through the code and I can't see any way to add to the plugins array?

A better name for this might be 'extensions', similar to telescope.

Problem with tmux-resurrect

tmux-resurrect is an amazing tmux plugin that allows your tmux sessions to be persistent after reboot. It has an amazing feature that allows you to also load your vim/nvim sessions afterwards as especified here restore-vim-sessions. Now the issue is when I restore my tmux session it attempts to automatically load all nvim sessions but for some reasons it can't. The feature requires that the corresponding session.vim are present in order to be able to load them. Hope anyone can reproduce the issue, thanks in advance. Sorry for opening the other issue ๐Ÿ™. Amazing nvim plugin btw.

E492: Not an editor command: require("telescope").extensions.possession.list()

I have been running this plugin for about a week.

I build nvim everyday from master and I am facing this error when I try to trigger the command to load the list of sessions:


E492: Not an editor command: require("telescope").extensions.possession.list()
E5108: Error executing lua: ....local/share/nvim/lazy/plenary.nvim/lua/plenary/path.lua:749: EISDIR: illegal operation on a directory
stack traceback:
	[C]: in function 'assert'
	....local/share/nvim/lazy/plenary.nvim/lua/plenary/path.lua:749: in function 'read'
	...are/nvim/lazy/possession.nvim/lua/possession/session.lua:380: in function 'list'
	...share/nvim/lazy/possession.nvim/lua/possession/query.lua:11: in function 'as_list'
	...e/nvim/lazy/possession.nvim/lua/possession/telescope.lua:82: in function 'get_finder'
	...e/nvim/lazy/possession.nvim/lua/possession/telescope.lua:112: in function 'list'
	/home/tds/.config/nvim/lua/plugins.lua:95: in function </home/tds/.config/nvim/lua/plugins.lua:94>

I think maybe require("telescope").extensions.possession.list() changed on a recent update?

Relevant context:

version: NVIM v0.11.0-dev-226+g721551210
package manager: lazy.nvim
configuration:

	-- Session manager
	{
		"jedrzejboczar/possession.nvim",
		event = "BufReadPre",
		cmd = { "PossessionLoad", "PossessionList" },
		keys = {
			{
				"<leader>Sl",
				function()
					require("telescope").extensions.possession.list()
				end,
				desc = "List Sessions",
			},
			{
				"<leader>Ss",
				function()
					-- Get the current working directory
					local cwd = vim.fn.getcwd()
					-- Extract the root directory from the CWD
					local root_dir = cwd:match("([^/]+)$")
					-- Get user input for the session name
					local input = vim.fn.input("Enter the session name: ")
					-- Check if the user provided an input
					if input ~= "" then
						-- Concatenate root directory with user input as the session name
						local session_name = root_dir .. "." .. input
						-- Save the session with the new name
						require("possession.session").save(session_name)
					else
						print("No input provided.")
					end
				end,
				desc = "Save Session",
			},
		},
		opts = {
			telescope = {
				list = {
					default_action = "load",
					mappings = {
						delete = { n = "d", i = "<c-d>" },
						rename = { n = "r", i = "<c-r>" },
					},
				},
			},
		},
	},
...
require("telescope").load_extension("possession")
...

[Feature] Add mappings to telescope extension

Hey, thank you for your plugin.

I really like the telescope extension. It would be really nice to add a key for deleting and renaming a listed item.

As far as I understand the code it only loads the current selected item by .

Terminal command to load session.

Hello. I used to use obsession for my sessions management. But it is slightly slow...
May I use possession the same way as obsession?
I normally do :Obsession in session which I want to track and than i do nvim -S if I want restore session for current dir and just nvim if I doesn't.
How can I do it with possession?

Thoughts on new features

I've been looking for a sesssion manager that does what I want but haven't yet found an ideal one. This project is appealing because of the use of JSON and so the possibility to save additional data, but it's lacking some features I would like. The purpose of this issue is to outline features I'd like to (try) and add, and see if they are a good fit or would be accepted, before I start too much work on them.

  1. I'd like it to automatically restore the last used session based on the CWD, not the last used session. It seems others also would like this, #45, and #55 might help towards this, but I think it has some current issues I'll discuss over there. I think for this to be a feature, there needs to be consideration of what to do with the existing behaviour of loading the last session, which some might wish to retain. Edit: this feature looks almost ready from #55, great stuff.

I actually think that this is the bare minimum to make this more useful to me. There are some further enhancements that might be nice:

  1. The current auto save tmp is limited to a single session. It might be useful to have this per CWD. Edit: looks to be implemented by #55

  2. Related to 2, I think I'd prefer the auto session save to not happen every CWD, but only in certain folders (notably those with a .git folder present). [Current workaround: manually save a session on start up, and then the auto cwd load from 1. above (when implemented) will always restore it]. Edit: This looks to be doable via the fun(): boolean option to cwd autosave. Nice!

  3. Some integration with git branch names might be nice, but I'm not currently using Neovim enough in this context to have strong opinions on how exactly this should work.

Some other more minor issues I've noticed that I'd like to look at:

  • tmp session file will overwrite each other if 2 vim instances are running. I'm not actually sure what to do about this issue at present. A tmp file per CWD might be enough to avoid most issues here.

  • __last__ symlink will point to invalid file if session is removed via telescope. I think there is a better way to ascertain the last session than by using symlinks (idea stolen from nvim.possession), which removes some complexity. A similar method can probably used to help implement 1.

  • when trying to save session, if no session is open, prompt for name instead of displaying error if no name is initially provided.

I can make separate issues for the minor issues as I work on them, if desired.

Compatibility with nvim terminal

It looks like PossessionSave is not compatible with nvim terminals.
This happen when I want to save a session containing multiple terminals.

image

Deprecated treesitter function

The vim.treesitter.parse_query is deprecated in neovim 0.9 and will be removed in 0.10.
Possible solution:

diff --git a/lua/possession/display.lua b/lua/possession/display.lua
index 7a3412b..b669762 100644
--- a/lua/possession/display.lua
+++ b/lua/possession/display.lua
@@ -9,7 +9,13 @@ local utils = require('possession.utils')
 -- the`vimscript` variable.
 local function patch_treesitter_injections(buf)
     local parser = vim.treesitter.get_parser(buf, 'lua')
-    local new_query = vim.treesitter.parse_query(
+    local parse_query
+    if vim.treesitter.query.parse then
+        parse_query = vim.treesitter.query.parse
+    else
+        parse_query = vim.treesitter.parse_query
+    end
+    local new_query = parse_query(
         'lua',
         [[
         (assignment_statement

How do I create a session?

Hi! I'm trying this plugin out but got stuck immediately. I want to save the current session, but running :PossessionSave prints the error "No session is currently open". Is that the intended behaviour? Since I don't yet have any sessions I can't open one.

This is my config:

use {
  'jedrzejboczar/possession.nvim',
  requires = { 'nvim-lua/plenary.nvim' },
  config = function()
    require('possession').setup()
  end
}

Issue with telescope configuration/Option to turn off the telescope previewer

It would be nice to have that option, to make it look more like the project.nvim. I tried to make it, but it seems that my new option previewer (and any telescope option) isn't "connected" to my configuration lua file, but its default variables work. Here's what I did (all in ~/.local/share/nvim/lazy/possession/lua/):

possesion/config.lua
...
list = {
    previewer = true,
    default_action = 'load',
...
possesion/telescope.lua
... -- added previewer field in list
---@field sort? boolean|possession.QuerySortKey sort the initial sessions list, `true` means 'mtime'
---@field previewer? boolean enable or disable preview

---@param opts possession.TelescopeListOpts
function M.list(opts)
    opts = vim.tbl_extend('force', {
        default_action = 'load',
        sessions = nil,
        sort = 'mtime',
        previewer = true,
    }, opts or {})
...
-- in same function in: pickers.new(opts, { ...
    sorter = conf.generic_sorter(opts),
    previewer = opts.previewer and session_previewer() or false,
    attach_mappings = function(prompt_buf, map)
...
~/.config/nvim/lua/plugins/sessions.lua
...
    telescope = {
        list = {
            previewer = false,
            default_action = 'delete',
        }
    }
...

This always displays previewer (even if I specified otherwise) and default_action doesn't work either. So maybe I do something wrong or as I said before telescope configuration isn't accessible from plugin's configuration (by mistake I also pasted telescope's configuration (previewer = false etc.) in telescope's extensions configuration and they also don't work there).

Automatic session save/restore

As noted in #2, it would be nice to have this kind of functionality built-in.

Currently one could use the provided API to do this in their config: list avaliable sessions and compare sessions[X].cwd to current working directory to select the session we want.

Adding this feature to the plugin would require some configuration options like:

  • should be enabled by a config option (disabled by default)
  • do we want to match CWD exactly, or if opening Vim in /dir/a/b session with cwd /dir/a should be used?
  • or should we actually load the previously open session and not care about cwd whatsoever?
  • when to auto-save the session?
  • config option for enabling this could be a boolean or a user function that returns a boolean - this can offload some more logic to users

Loading Session Keeps Current Buffers

If I have some buffers that I have been editing and I load a session those buffers initial buyers I was editing remain in the new session.
I would expect the loaded session buffers to be the only ones ?
If you need any more details please let me know.

Cheers

Can't load temperary session

                    require("possession").setup({
                        autosave = {
                            current = false, -- or fun(name): boolean
                            tmp = true, -- or fun(): boolean
                            tmp_name = "tmp",
                            on_load = true,
                            on_quit = true,
                        },
                    })

After auto saving a temporary session, I can't run PossessionLoad tmp to restore session.

Buffers are closed after PossessionLoad or PossessionSave

this has been driving me up the wall for the past 30 mins, why does my lua buffer close after a session save and why doesn't it show when I load said session. I've tried configuring it so it closes nothing and still got the same result.

https://asciinema.org/a/CeVVGybVHbj0Z1JXvoZ2JWCKE

minimal config on NVIM v0.7.0-dev+1275-g00effff56

return require('packer').startup(function()
        use 'wbthomason/packer.nvim'

        use {
                'jedrzejboczar/possession.nvim',
                requires = { 'nvim-lua/plenary.nvim' },
                config = function() require('possession').setup{
                        silent = false,
                        load_silent = false,
                        debug = true,
                        plugins = {
                                close_windows = false,
                                delete_hidden_buffers = false,
                                nvim_tree = false,
                                tabby = false,
                        },
                } end
        }
end)

Lualine session name doesn't accurately reflect session

With autosave set to cwd, any time a named session is not open, the Lualine session name should show the cwd name. Currently this is only the case when this cwd session exists and is loaded from disk.

An example of this issue.

  1. Ensure autosave is set to cwd and Lualine session is enabled.
  2. Save a session foo.
  3. Lualine session shows foo.
  4. Close session foo.

Expected: Lualine session should show cwd
Actual: Lualine session shows nothing.

The concept of an "active" session isn't something that Neo/Vim has. You can save and load a session, and that's it. With the addition of autosaving sessions enabled via Possession, there is an implicit "active" session that exists even if there is no session file on disk at this moment in time. There WILL be a session file in the future (eg, when the user quits), but the session is still "active".

Not showing this active session name in the Lualine status bar provides users incorrect information about what will happen when they quit. In the above example, it looks like no session is active yet when they quit, the cwd session will be over/written.

This will almost certainly apply to the tmp session also.

:PossessionSave only saves session after root directory

Perhaps I'm not understanding exactly, but I would expect :PossessionSave to save a session with the name of the current directory, not the root directory.

Screen Shot 2022-04-03 at 22 33 24

Currently, this is the only session file it will create.

When I dismiss the message, I get the following error:

Screen Shot 2022-04-03 at 22 36 17

Edit: After actually looking at the commands, I realize this requires an argument. However, when saving the session, all open buffers are closed. Very weird.

I was hoping this would be essentially a drop-in replacement for auto-sessions which basically just manages the sessions for me. I don't want to have to type commands or use Telescope to load a session every time. If in the future, Possession will just work out of the box like auto-session I'll be happy to have another look!

No longer works with nvim-tree

It seems like since recent update Possession no longer works with nvim-tree: errors appear when loading or saving session (probably broken in 1656010).

E5108: Error executing lua ...art/possession.nvim/lua/possession/plugins/nvim_tree.lua:21: module 'nvim-tree.api' not found:                                                                                                                  
        no field package.preload['nvim-tree.api']
        no file './nvim-tree/api.lua'
        no file '/usr/share/luajit-2.1.0-beta3/nvim-tree/api.lua'
        no file '/usr/local/share/lua/5.1/nvim-tree/api.lua'
        no file '/usr/local/share/lua/5.1/nvim-tree/api/init.lua'
        no file '/usr/share/lua/5.1/nvim-tree/api.lua'
        no file '/usr/share/lua/5.1/nvim-tree/api/init.lua'
        no file '/home/.../.cache/nvim/packer_hererocks/2.1.0-beta3/share/lua/5.1/nvim-tree/api.lua'
        no file '/home/.../.cache/nvim/packer_hererocks/2.1.0-beta3/share/lua/5.1/nvim-tree/api/init.lua'
        no file '/home/.../.cache/nvim/packer_hererocks/2.1.0-beta3/lib/luarocks/rocks-5.1/nvim-tree/api.lua'
        no file '/home/.../.cache/nvim/packer_hererocks/2.1.0-beta3/lib/luarocks/rocks-5.1/nvim-tree/api/init.lua'
        no file './nvim-tree/api.so'
        no file '/usr/local/lib/lua/5.1/nvim-tree/api.so'
        no file '/usr/lib/lua/5.1/nvim-tree/api.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
        no file '/home/.../.cache/nvim/packer_hererocks/2.1.0-beta3/lib/lua/5.1/nvim-tree/api.so'
        no file './nvim-tree.so'
        no file '/usr/local/lib/lua/5.1/nvim-tree.so'
        no file '/usr/lib/lua/5.1/nvim-tree.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
        no file '/home/.../.cache/nvim/packer_hererocks/2.1.0-beta3/lib/lua/5.1/nvim-tree.so'
stack traceback:
        [C]: in function 'require'
        ...art/possession.nvim/lua/possession/plugins/nvim_tree.lua:21: in function 'open_tree'
        ...art/possession.nvim/lua/possession/plugins/nvim_tree.lua:67: in function <...art/possession.nvim/lua/possession/plugins/nvim_tree.lua:61>
        ...er/start/possession.nvim/lua/possession/plugins/init.lua:60: in function 'call_plugin'
        ...er/start/possession.nvim/lua/possession/plugins/init.lua:83: in function 'after_save'
        .../packer/start/possession.nvim/lua/possession/session.lua:104: in function 'commit'
        .../packer/start/possession.nvim/lua/possession/session.lua:117: in function 'save'
        ...packer/start/possession.nvim/lua/possession/commands.lua:61: in function 'save'
        [string ":lua"]:1: in main chunk

Invalid window id on saving

Hi,

I check if Possession can be useful for me.

Probably (maybe not only) we need nvim_win_is_valid inside loop in https://github.com/jedrzejboczar/possession.nvim/blob/master/lua/possession/plugins/close_windows.lua#L38

I tried to see how saving behaves when DBUI is open with the query result and Noice is enabled and got

 ๏™™  Error  02:22:23 msg_show.lua_error   PossessionSave! dim E5108: Error executing lua ...possession.nvim/lua/possession/plugins/close_windows.lua:7: Invalid window id: 1476
stack traceback:
	[C]: in function 'nvim_win_get_config'
	...possession.nvim/lua/possession/plugins/close_windows.lua:7: in function 'is_floating'
	...possession.nvim/lua/possession/plugins/close_windows.lua:39: in function 'fn'
	...rged/opt/possession.nvim/lua/possession/plugins/init.lua:110: in function <...rged/opt/possession.nvim/lua/possession/plugins/init.lua:109>
	...rged/opt/possession.nvim/lua/possession/plugins/init.lua:59: in function 'call_plugin'
	...rged/opt/possession.nvim/lua/possession/plugins/init.lua:67: in function 'before_save'
	.../unmerged/opt/possession.nvim/lua/possession/session.lua:68: in function 'save'
	...unmerged/opt/possession.nvim/lua/possession/commands.lua:61: in function 'save'
	[string ":lua"]:1: in main chunk

Config:

require('possession').setup {
  plugins = {
    nvim_tree = false,
    delete_hidden_buffers = false,
  },
}

Can you reproduce this bug?

I set close_windows = false, while it occurs for me.

Bug: Sessions can be lost if there is a Possession error during load

If for some reason Possession cannot load a session during Neovim start, and autosave.cwd or autosave.tmp is configured, when exiting Neovim, these files will be overwritten, potentially losing session data.

I don't think this is so much of a problem for tmp since the name implies it is temporary. But I not sure that the cwd session should be overwritten.

I wonder if it might be worthwhile to set a global flag on error, and if this is set, do not autosave.

I'm not sure how common this scenario will be. I ran across it during development of #63 in part due to bugs. The situation where I think this could be most likely is with a custom autoload function returning something invalid. This however gets complicated because the user could manually start a cwd session, in which case autosave should probably be enabled again?

Maybe it is satisfactory enough to just document the current risk.

cwd session can get overwritten

This is essentially a variant of #67.

I have autoload set to cwd, autosave.cwd = true, and autosave.on_quit = true. This works great for the typical use case for me: I load nvim, open some buffers, quit, come back, and the session is restored for that cwd.

We implemented the feature that when a file is passed to nvim, it prevents autoload. This is good, but autosave then saves this single file on quit, overwriting my cwd autosave session. While #67 was more an issue due to dev bugs, this is a real world issue and really annoying.

Probably want to have more of a think how to handle this. I'm sure it's going to affect others.

Repro:

  1. Have the three config values set as above
  2. Open nvim, no args.
  3. Open some buffers.
  4. Quit -> buffers should autosave.
  5. Open nvim, no args -> buffers should autoload. (This and next step are just for verification)
  6. Quit.
  7. Open nvim with a file argument.
  8. Quit.
  9. Open nvim.

Actual: the file argument file is restored as the autoloaded session.
Expected: the original buffers from step 3.

I would expect that if autoload is disabled, then autosave is also disabled (with caveats, see below).

Some quick notes on things to consider:
User might not have not autoload enabled
User might opt in to a session, so autosave might need to be enabled at some point even if it was disabled due to a file arg being passed to nvim.

Show session name in lualine?

Is there a way to show the current session name in a lualine section?

It seems like I would need to create a custom lualine component that returns the Possession session name as a string. It seems like I could get the session name from this function, but I'm not sure how to do that exactly. Any help would be appreciated! Thanks for a great plugin!

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.