How can I set the height for window split? - vim

:sp horizontally splits the current window in two.
How can I set the height of the new window?
I am imagining something like:
:sp --width=30

By preceding the :split with a number, you can set the height:
" Split a 10-line height window above:
:10split
" Or to open the new viewport below the current
:below 10split
From :help split:
:[N]sp[lit] [++opt] [+cmd] :sp :split
Split current window in two. The result is two viewports on
the same file. Make new window N high (default is to use half
the height of the current window)

Related

How do I set up a vertically split terminal for the vim-slime plugin?

For the vim-slime plugin, these are my settings:
let g:slime_target = "vimterminal"
let g:slime_paste_file = "$HOME/.slime_paste"
let g:slime_vimterminal_cmd = "sbcl --noinform --load " . #%
let g:slime_vimterminal_config = {"term_opencmd": "vert term | buffer %d", "term_finish": "close"}
What I wish to do is to have my terminal vertically split upon opening. Currently, it splits my terminal horizontally. I did some research and found out that I can manipulate these settings for slime_vimterminal_config. My idea is to run vert term and pipe that to my screen buffer, as seen above. This is still not splitting my screen vertically. Does anyone familiar with the plugin know what to do?

In Vim/NeoVim, how to draw inside text buffer without modifying content

For example, suppose I want to implement a plugin that draws a margin line at 80 colums using custom characters (suppose I want the line to made from a column of * characters).
How can that be done in Vim or Neovim?
But more generically, is there a way to draw stuff over the text buffer without affecting the text content?
For example, how can I draw an inner rectangle inside a window which I can make bright colored in order to show the active window? The effect would be that the first line visible line of what is currently a text buffer would be filled with --- characters, the right-most column of the what is currently a text buffer would be filled with |. This would be inside the window, separate from the statuslines or vertical split lines.
Etc. How to do such things?
Some plugins that currently draw over the text buffer in different ways:
https://github.com/easymotion/vim-easymotion
https://github.com/Yggdroot/indentLine
EasyMotion does not draw over the text, i don't think this is possible.
What it does is defined in following function (sourcecode):
function! EasyMotion#helper#VarReset(var, ...) "{{{
if ! exists('s:var_reset')
let s:var_reset = {}
endif
if a:0 == 0 && has_key(s:var_reset, a:var)
" Reset var to original value
" setbufvar( or bufname): '' or '%' can be used for the current buffer
call setbufvar('%', a:var, s:var_reset[a:var])
elseif a:0 == 1
" Save original value and set new var value
let new_value = a:0 == 1 ? a:1 : ''
" Store original value
let s:var_reset[a:var] = getbufvar("", a:var)
" Set new var value
call setbufvar('%', a:var, new_value)
endif
endfunction "}}}
So it saves every replaced char and restores them afterwards.
I haven't looked at indentLine but it probably does intelligent listchars, as there is never text under the indentchar.
Anyway it isn't as if I am an expert on one of the plugin or vim in general. I just write this answer because i think there are easier way to achieve what you want. You could for example highlight the border lines with a certain color, or change the background for the active split. There is also a plugin for dimming inactive splits: https://github.com/blueyed/vim-diminactive

VimL: VSPLIT with width specified as a function of total width

I want to write a vim script that opens a new window with vsplit, where the width of the new window is equal to the total number of columns minus 90.
The result would be, the current window would be 90 columns wide (to view 80 cols of code + gutter) and the new vsplit would occupy whatever part of the screen is left over.
If I understand vsplit correctly, :vsplit 90 specifies the window being created should be 90 columns. Is there a way to get the current number of columns in a window into a variable?
let cur_cols = [insert magic here]
let win_width = cur_cols - 90
execute "vsplit ". win_width
Use winwidth to find width of window. winwidth returns width as the no. of characters window can accommodate. In your case, use
let cur_cols = winwidth(0)
Here the parameter 0 refers to current widow. For more information,
:help winwidth
:help :vsplilt

Different VimResized autocmds for Shrinking and Growing

autocmd VimResized * <foo> will run the command <foo> whenever the vim application's window is resized.
Is there a way to run different commands depending on whether the resize is a shrink or a grow?
And, if so, are there any caveats for console vim?
A window is 2-dimensionnal, so the concept of shrinking or growing is quite imprecise : are you talking about the height, or about the width, or about the area?
Let's assume you're talking about the area.
A simple way to do it is to save the last size of the window, on startup and on each time the win is resized; then you just have to compare the last size and the new one, each time the win is resized:
" Defines a command to save the current dims:
command! SaveVimDims let g:last_lines=&lines | let g:last_columns=&columns
" Saves the dims on startup:
au VimEnter * SaveVimDims
" Calls the func below, each the win is resized:
au VimResized * call VimResized_Func()
function! VimResized_Func()
" Gets the area of the last dims:
let last_area = g:last_lines * g:last_columns
" Saves the new dims:
SaveVimDims
" Gets the area of the new dims:
let cur_area = g:last_lines * g:last_columns
" Compares the areas:
if cur_area < last_area
" do something when shrinking
else
" do something when growing
endif
endf
This was only tested with Gvim; I never use Vim in console. Hope it'll work as well

Resizing the vim tabline on NERDTree window resize

I am using vim (terminal/console vim NOT gui vim) with NERDTree and NERDTreeTabs.
As you may have guessed I like to use vim's tab functionality to keep track of multiple open files.
I never really liked how the tabs would start at the very "beginning" of the tabline (there would be tabs on top of the NERDTree window). I wanted to have the tabs start from the END of the NERDTree window (i.e. the right edge), resembling an IDE. So I defined my own tabline like so:
" Globals
" NERDTree width
let g:ntw = 25
set showtabline=2 " Always show tabs
function! Tabline(width)
let s = '%#String#'. repeat(' ', a:width).'|'
for i in range(tabpagenr('$'))
let tab = i + 1
let bufnr = tabpagebuflist(tab)[tabpagewinnr(tab) - 1]
let bufname = bufname(bufnr)
let s .= '%' . tab . 'T'
let s .= (tab == tabpagenr() ? '%#TabLineSel#' : '%#TabLine#')
let s .= ' '.(bufname != '' ? fnamemodify(bufname, ':t') : 'New ').' '
if getbufvar(bufnr, "&mod") " If buf is modified
let s .= '+ '
endif
endfor
let s .= '%#TabLineFill#'
return s
endfunction
set tabline=%!Tabline(g:ntw)
let g:NERDTreeWinSize = g:ntw
Basically all I am doing is inserting blank spaces into the tabline before any tabs start. The width of the blank spaces would match the width of NERDTree. Now the problem is when I resize the NERDTree window. Obviously, the tab line's extra spacing does not resize itself automatically, resulting in an ugly mismatch.
I was thinking I could find out a way to execute 'set tabline=%!Tabline(g:ntw)" where g:btw is the current width of NERDTree whenever the NERDTree window is resized. But I am unable to find out a way to do this.
As a side note, since I am using NERDTreeTabs plugin, you can assume that the NERDTree window will ALWAYS exist. You can also assume that the NERDTree window will always be on the left.
So then my questions are:
1) Is there a more elegant way of getting this done?
2) If no to 1), how could I achieve what I am trying to do? (example code please)
Thanks in advance!
Assuming that the NERD_Tree window is always at the left, occupying the full height, its window number is 1. You can then query the current width via winwidth(1) instead of hard-coding it in your g:ntw variable.

Resources