metakirby5 / codi.vim

:notebook_with_decorative_cover: The interactive scratchpad for hackers.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request] Open Codi fullscreen in a 50/50 vertical split with an empty buffer

SidOfc opened this issue · comments

Hi there!

I came here to request a feature for this (awesome) plugin.

Out of the box Codi will always open with a fixed width next to the current buffer. In most of my use-cases I am debugging a large-ish file and I only want to focus on a small part of it, perhaps run some sample code to grasp exactly how it works or experiment with some new code or quickly demonstrate some feature etc...

What I wanted was essentially the following:

  • Open a source file, I'll use ruby filetype for this example.
  • Found a problem / just curious, would like to run some sample code quickly
  • Open a new empty window with the filetype set to ruby (in this case)
  • Open Codi on the right hand side with a width of 50%

In this case, there are no "Actual results" I can offer. I have however, written a sample implementation of this functionality in my vimrc. It basically comes down to this:

fun! s:FullscreenScratch()
  " store filetype and bufnr of current buffer
  " for later reference
  let current_buf_ft  = &ft
  let current_buf_num = bufnr('%')
                                                                 
  " create a new empty tab and set it up
  tabe | setlocal buftype=nofile noswapfile modifiable buflisted
                                                                 
  " set filetype to that of original source file
  " e.g. ruby / python / w/e Codi supports
  let &filetype = current_buf_ft
                                                                 
  " since it is fullscreen, I'd like a 50/50 split
  let g:codi#width = winwidth(winnr()) / 2
                                                                 
  " create a buffer local mapping that overrides the
  " outer one to delete the current scratch buffer instead
  " when the buffer is destroyed, this mapping will be
  " destroyed with it and the next <Leader><Leader>
  " will spawn a new fullscreen scratch window again
  " we do not have to unmap as this mapping will be
  " automatically destroyed alongside the buffer.
  nmap <silent><buffer> <Leader><Leader> :silent! q!<Cr>
                                                                 
  " everything is setup, filetype is set
  " let Codi do the rest :)
  Codi
endfun

" create a mapping to call the fullscreen scratch wrapper
nmap <silent> <Leader><Leader> :call <SID>FullscreenScratch()<Cr>

The above function will always create a new empty tab with a buftype=nofile, set the filetype correctly, invert the LeaderLeader mapping and call Codi.

When LeaderLeader is pressed again, the current buffer will be destroyed and you will be returned where you left off.

vim-codi-demo

I tested this snippet in the following Vim versions, each one working as expected:

Vim: vim --version | head -5

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Apr 22 2018 07:29:06)
macOS version
Included patches: 1-1700
Compiled by Homebrew
Huge version without GUI.  Features included (+) or not (-):

MacVim: mvim --version | head -5

VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 14 2018 05:28:49)
macOS version
Included patches: 1-280
Compiled by travis@Traviss-Mac-1044.local
Huge version with MacVim GUI.  Features included (+) or not (-):

NeoVim: nvim --version | head -3

NVIM v0.2.2
Build type: Release
LuaJIT 2.0.5

OS + version: macOS 10.13.6

Note: One issue I see here is that g:codi#width is overwritten, we could store it but we need to keep in mind that the buffer can be closed in unexpected ways (as I'm probably doing here with: :silent! q!).

That's pretty much it, let me know if it is something worthwhile, I've already got my polyfill which works but wouldn't mind writing a proper PR for this either. I am quite busy this week but I could send a proposal somewhere next week if there is any interest.

If one of you implements it before I can, please by all means go ahead too :)

It could be behind a setting that is disabled by default, e.g:

if (!exists('g:codi#fullscreen'))
    let g:codi#fullscreen = 0
endif

This will actually free up g:codi#width for manipulation so my old note becomes irrelevant.

Hi @SidOfc, thanks for the feature request and the work you've done thus far on it! I think the notion of a fullscreen scratch is really workflow dependent, so I'm a bit hesitant to include it in the plugin. The code to configure it, as you have shown, is about a dozen lines long, so people can include it in their vimrc (like you have) on a want-to-use basis.

However, I do like the idea of percentage-based splits; maybe we can parse g:codi#width and do a percentage split if it ends in %, otherwise do an absolute split?

I also think you bring up a good point that all of Codi's configuration is global. I would be open to adding configuration via local variables, to reduce the pain of one-off invocations with special settings.

Hi @metakirby5, I completely understand that this feature is heavily workflow inspired and therefore may not be the right fit for the plugin. It could be a tip or trick in either a wiki or readme as well, I will look into adding this snippet somewhere other than this issue so that anyone can use this code.

I would also love to see percentage support for g:codi#width.

It would even reduce the required snippet code and as you can see, it really only takes one line to do, maybe 2 when combining with user input. I could also write a PR for that instead, shouldn't take too long and I think I could even do it somewhere this week.

I'm not exactly sure of a way to do one-off's for a particular invocation but that too sounds awesome!

P.S. All this basically comes after playing around with it for about half an hour and being completely sold from that moment, thank you so much for providing us all with something like Codi 👍 😻

P.P.S.

This issue can be closed if you want, whenever I have a PR for % width ready I'll send it in referencing this issue anyway :)