├── README.md └── rplugin └── python3 └── denite ├── kind └── session.py └── source └── session.py /README.md: -------------------------------------------------------------------------------- 1 | # denite-session 2 | 3 | Browse and open sessions with this Denite source. 4 | 5 | ## Features 6 | 7 | - Load, delete, and save sessions 8 | - Custom global path for sessions 9 | 10 | ## Installation 11 | 12 | Use your favorite plugin manager, mine is [dein.vim]. 13 | 14 | ### Requirements 15 | 16 | - Vim or Neovim 17 | - [denite.nvim] 18 | - Python 3.4 or later 19 | 20 | ## Usage 21 | 22 | ```viml 23 | :Denite session 24 | ``` 25 | 26 | ### Configuration 27 | 28 | The default path for sessions can be set with `g:session_directory` 29 | 30 | Or, you can set the path option via Denite: 31 | 32 | ```viml 33 | call denite#custom#var('session', 'path', '~/.vim-sessions') 34 | ``` 35 | 36 | ## Credits & Contribution 37 | 38 | - [chemzqm/denite-extra](https://github.com/chemzqm/denite-extra) 39 | 40 | This plugin is maintained by Rafael Bodill. 41 | 42 | Pull requests are welcome. 43 | 44 | [denite.nvim]: https://github.com/Shougo/denite.nvim 45 | [dein.vim]: https://github.com/Shougo/dein.vim 46 | -------------------------------------------------------------------------------- /rplugin/python3/denite/kind/session.py: -------------------------------------------------------------------------------- 1 | # ============================================================================ 2 | # FILE: session.py 3 | # AUTHOR: Rafael Bodill 4 | # License: MIT license 5 | # ============================================================================ 6 | 7 | import os 8 | 9 | from .openable import Kind as Openable 10 | 11 | class Kind(Openable): 12 | 13 | def __init__(self, vim): 14 | super().__init__(vim) 15 | 16 | self.name = 'session' 17 | self.default_action = 'open' 18 | 19 | def action_open(self, context): 20 | """ Loads first selected session after wiping out all buffers """ 21 | target = context['targets'][0] 22 | path = target['action__path'] 23 | 24 | current = self.vim.eval('v:this_session') 25 | if current and 'SessionLoad' not in self.vim.vars: 26 | self.vim.command('mksession! {}'.format(current)) 27 | 28 | self.vim.command('noautocmd silent! %bwipeout!') 29 | self.vim.command('silent! source {}'.format(path)) 30 | 31 | def action_preview(self, context): 32 | """ Opens a session anonymously """ 33 | self.action_open(context) 34 | self.vim.command("let v:this_session = ''") 35 | 36 | def action_delete(self, context): 37 | """ Delete selected session(s) """ 38 | for target in context['targets']: 39 | file_path = target['action__path'] 40 | if len(file_path) < 2 or not os.path.isfile(file_path): 41 | continue 42 | 43 | msg = 'Delete session `{}` ? '.format(os.path.basename(file_path)) 44 | if self.vim.call('input', msg) not in ['y', 'yes']: 45 | continue 46 | 47 | self.vim.call('delete', target['action__path']) 48 | if self.vim.eval('v:this_session') == file_path: 49 | self.vim.command("let v:this_session = ''") 50 | 51 | def action_save(self, context): 52 | """ Overwrite the first selected session """ 53 | target = context['targets'][0] 54 | file_path = target['action__path'] 55 | self.vim.command("mksession! {}".format(file_path)) 56 | self.vim.command("let v:this_session = '{}'".format(file_path)) 57 | -------------------------------------------------------------------------------- /rplugin/python3/denite/source/session.py: -------------------------------------------------------------------------------- 1 | # ============================================================================ 2 | # FILE: session.py 3 | # AUTHOR: Rafael Bodill 4 | # License: MIT license 5 | # ============================================================================ 6 | 7 | import os 8 | import time 9 | 10 | from denite.util import globruntime 11 | from .base import Base 12 | 13 | 14 | class Source(Base): 15 | """ Vim session loader source for Denite.nvim """ 16 | 17 | def __init__(self, vim): 18 | super().__init__(vim) 19 | 20 | self.name = 'session' 21 | self.kind = 'session' 22 | self.vars = { 23 | 'path': vim.vars.get('session_directory', '~/.cache/vim/session'), 24 | 'pattern': '*' 25 | } 26 | 27 | def on_init(self, context): 28 | if not self.vars.get('path'): 29 | raise AttributeError('Invalid session directory, please configure') 30 | 31 | def highlight(self): 32 | self.vim.command( 33 | 'highlight default link {} Special'.format(self.syntax_name)) 34 | self.vim.command( 35 | 'highlight default link deniteSessionTime Comment') 36 | 37 | def define_syntax(self): 38 | super().define_syntax() 39 | self.vim.command( 40 | 'syntax match deniteSessionTime /(.\{-})/ ' 41 | 'containedin=' + self.syntax_name) 42 | 43 | def gather_candidates(self, context): 44 | candidates = [] 45 | now = time.time() 46 | path = os.path.expanduser(self.vars['path']) 47 | 48 | for path in globruntime(path, self.vars['pattern']): 49 | mtime = os.stat(path).st_mtime 50 | name = os.path.splitext(os.path.basename(path))[0] 51 | candidates.append({ 52 | 'word': '%s (%s)' % (name, self._time_ago(now, mtime)), 53 | 'action__path': path, 54 | 'source_mtime': mtime, 55 | }) 56 | 57 | return sorted( 58 | candidates, 59 | key=lambda x: x['source_mtime'], 60 | reverse=True) 61 | 62 | def _time_ago(self, now, seconds): 63 | """ Return relative difference of two timestamps """ 64 | diff = now - seconds 65 | if diff <= 0: 66 | return 'just now' 67 | if diff < 60: 68 | return str(int(diff)) + ' seconds ago' 69 | if diff / 60 < 60: 70 | return str(int(diff/60)) + ' minutes ago' 71 | if diff / 3.6e+3 < 24: 72 | return str(int(diff/3.6e+3)) + ' hours ago' 73 | if diff / 8.64e+4 < 24: 74 | return str(int(diff/8.64e+4)) + ' days ago' 75 | if diff / 6.048e+5 < 4.34812: 76 | return str(int(diff/6.048e+5)) + ' weeks ago' 77 | if diff / 2.63e+6 < 12: 78 | return str(int(diff/2.63e+6)) + ' months ago' 79 | 80 | return str(int(diff/3.156e+7)) + 'years ago' 81 | --------------------------------------------------------------------------------