7 changed files with 842 additions and 4 deletions
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2019 voldikss |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,127 @@ |
|||||||
|
# vim-floaterm |
||||||
|
|
||||||
|
[](https://travis-ci.org/voldikss/vim-floaterm) |
||||||
|
|
||||||
|
Use neovim terminal in the floating window. |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
## Installation |
||||||
|
|
||||||
|
- vim-plug |
||||||
|
|
||||||
|
```vim |
||||||
|
Plug 'voldikss/vim-floaterm' |
||||||
|
``` |
||||||
|
|
||||||
|
- dein.nvim |
||||||
|
|
||||||
|
```vim |
||||||
|
call dein#add('voldikss/vim-floaterm') |
||||||
|
``` |
||||||
|
|
||||||
|
## Keymaps |
||||||
|
|
||||||
|
This plugin doesn't supply any default mappings. |
||||||
|
|
||||||
|
```vim |
||||||
|
""" Example configuration |
||||||
|
let g:floaterm_keymap_new = '<F7>' |
||||||
|
let g:floaterm_keymap_prev = '<F8>' |
||||||
|
let g:floaterm_keymap_next = '<F9>' |
||||||
|
let g:floaterm_keymap_toggle = '<F10>' |
||||||
|
``` |
||||||
|
|
||||||
|
## Features |
||||||
|
|
||||||
|
- Toggle terminal window quickly |
||||||
|
- Multiple terminal instances |
||||||
|
- Customizable floating terminal style |
||||||
|
- Switch/Preview floating terminal buffer using [vim-clap](https://github.com/liuchengxu/vim-clap)(try `:Clap floaterm`) |
||||||
|
|
||||||
|
## Configurations |
||||||
|
|
||||||
|
#### **`g:floaterm_type`** |
||||||
|
|
||||||
|
- Available: `'floating'`(neovim only), `'normal'`(vim8 and neovim) |
||||||
|
|
||||||
|
- Default: `'floating'` |
||||||
|
|
||||||
|
#### **`g:floaterm_width`** |
||||||
|
|
||||||
|
- Type: `int` (number of columns) or `float` (between 0 and 1). If `float`, the width is relative to `&columns`. |
||||||
|
- Default: `0.6` |
||||||
|
|
||||||
|
#### **`g:floaterm_height`** |
||||||
|
|
||||||
|
- Type: `int` (number of lines) or `float` (between 0 and 1). If `float`, the height is relative to `&lines`. |
||||||
|
- Default: `0.6` |
||||||
|
|
||||||
|
#### `g:floaterm_winblend` |
||||||
|
|
||||||
|
- Description: The opacity of the floating terminal |
||||||
|
|
||||||
|
- Default: `0` |
||||||
|
|
||||||
|
#### **`g:floaterm_position`** |
||||||
|
|
||||||
|
- Available: `'center'`, `'topleft'`, `'topright'`, `'bottomleft'`, `'bottomright'`, `'auto'(at the cursor place)` |
||||||
|
|
||||||
|
- Default: `'center'` |
||||||
|
|
||||||
|
#### **`g:floaterm_background`** |
||||||
|
|
||||||
|
- Type: string(e.g. `'#000000'`, `'black'`) |
||||||
|
|
||||||
|
- Default: background color of normal floating window |
||||||
|
|
||||||
|
#### **`g:floaterm_borderchars`** |
||||||
|
|
||||||
|
- Default: `['─', '│', '─', '│', '┌', '┐', '┘', '└']` |
||||||
|
|
||||||
|
#### **`g:floaterm_border_color`** |
||||||
|
|
||||||
|
- Type: string(e.g. `'#FFFFFF'`, `'blue'`) |
||||||
|
|
||||||
|
- Default: foreground color of normal floating window |
||||||
|
|
||||||
|
## Commands |
||||||
|
|
||||||
|
- `:FloatermNew` |
||||||
|
|
||||||
|
- `:FloatermToggle` |
||||||
|
|
||||||
|
- `:FloatermPrev` |
||||||
|
|
||||||
|
- `:FloatermNext` |
||||||
|
|
||||||
|
## Q & A |
||||||
|
|
||||||
|
- #### This plugin leaves an empty buffer on startify window |
||||||
|
|
||||||
|
Put this code in `vimrc` |
||||||
|
|
||||||
|
```vim |
||||||
|
autocmd User Startified setlocal buflisted |
||||||
|
``` |
||||||
|
|
||||||
|
- #### I want to use another shell in the terminal. (e.g. Use fish instead of bash) |
||||||
|
|
||||||
|
Set `shell` option in your `vimrc`: |
||||||
|
|
||||||
|
```vim |
||||||
|
set shell=/path/to/shell |
||||||
|
``` |
||||||
|
|
||||||
|
- #### I would like to customize the style of the floating terminal window |
||||||
|
|
||||||
|
Use `autocmd`. For example |
||||||
|
|
||||||
|
```vim |
||||||
|
function s:floatermSettings() |
||||||
|
setlocal number |
||||||
|
" more settings |
||||||
|
endfunction |
||||||
|
|
||||||
|
autocmd FileType floaterm call s:floatermSettings() |
||||||
|
``` |
@ -0,0 +1,323 @@ |
|||||||
|
" ============================================================================ |
||||||
|
" FileName: autocmd/floaterm.vim |
||||||
|
" Description: |
||||||
|
" Author: voldikss <dyzplus@gmail.com> |
||||||
|
" GitHub: https://github.com/voldikss |
||||||
|
" ============================================================================ |
||||||
|
|
||||||
|
" `hidden` option must be set, otherwise the floating terminal would be wiped |
||||||
|
" out, see #17 |
||||||
|
set hidden |
||||||
|
|
||||||
|
" Note: |
||||||
|
" The data structure of the floaterm chain is a double circular linkedlist |
||||||
|
" g:floaterm.count is the count of the terminal node |
||||||
|
" g:floaterm.index is the pointer |
||||||
|
" g:floaterm.head is the HEAD node which only have 'prev' and 'next' |
||||||
|
" g:floaterm_node is the node prototype to create a terminal node |
||||||
|
let g:floaterm = {} |
||||||
|
let g:floaterm.count = 0 |
||||||
|
let g:floaterm.head = {} |
||||||
|
let g:floaterm.head.next = g:floaterm.head |
||||||
|
let g:floaterm.head.prev = g:floaterm.head |
||||||
|
let g:floaterm.index = g:floaterm.head |
||||||
|
|
||||||
|
let g:floaterm_node = { |
||||||
|
\ 'bufnr': 0, |
||||||
|
\ 'border_bufnr': 0, |
||||||
|
\ 'next': v:null, |
||||||
|
\ 'prev': v:null |
||||||
|
\ } |
||||||
|
|
||||||
|
if g:floaterm_border_color == v:null |
||||||
|
let g:floaterm_border_color = floaterm#util#get_normalfloat_fg() |
||||||
|
endif |
||||||
|
|
||||||
|
if g:floaterm_background == v:null |
||||||
|
let g:floaterm_background = floaterm#util#get_normalfloat_bg() |
||||||
|
endif |
||||||
|
|
||||||
|
" Remove a node if it was closed(the buffer doesn't exist) |
||||||
|
function! g:floaterm.kickout() dict abort |
||||||
|
if self.count == 0 | return | endif |
||||||
|
let self.index.prev.next = self.index.next |
||||||
|
let self.index.next.prev = self.index.prev |
||||||
|
let self.count -= 1 |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! g:floaterm.toggle() dict abort |
||||||
|
let found_winnr = self.find_term_win() |
||||||
|
if found_winnr > 0 |
||||||
|
if &buftype ==# 'terminal' |
||||||
|
execute found_winnr . ' wincmd q' |
||||||
|
else |
||||||
|
execute found_winnr . ' wincmd w | startinsert' |
||||||
|
endif |
||||||
|
else |
||||||
|
while v:true |
||||||
|
if self.count == 0 |
||||||
|
call self.open(0) |
||||||
|
return |
||||||
|
endif |
||||||
|
" If the current node is HEAD(which doesn't have 'bufnr' key), |
||||||
|
" skip and point to the node after HEAD |
||||||
|
if self.index == self.head |
||||||
|
let self.index = self.head.next |
||||||
|
endif |
||||||
|
let found_bufnr = self.index.bufnr |
||||||
|
if found_bufnr != 0 && bufexists(found_bufnr) |
||||||
|
call self.open(found_bufnr) |
||||||
|
return |
||||||
|
else |
||||||
|
call self.kickout() |
||||||
|
let self.index = self.index.next |
||||||
|
endif |
||||||
|
endwhile |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! g:floaterm.new() dict abort |
||||||
|
call self.hide() |
||||||
|
call self.open(0) |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! g:floaterm.next() dict abort |
||||||
|
call self.hide() |
||||||
|
while v:true |
||||||
|
if self.count == 0 |
||||||
|
call floaterm#util#show_msg('No more terminal buffers', 'warning') |
||||||
|
return |
||||||
|
endif |
||||||
|
" If the current node is the end node(whose next node is HEAD), |
||||||
|
" skip and point to the HEAD's next node |
||||||
|
if self.index.next == self.head |
||||||
|
let self.index = self.head.next |
||||||
|
else |
||||||
|
let self.index = self.index.next |
||||||
|
endif |
||||||
|
let next_bufnr = self.index.bufnr |
||||||
|
if next_bufnr != 0 && bufexists(next_bufnr) |
||||||
|
call self.open(next_bufnr) |
||||||
|
return |
||||||
|
else |
||||||
|
call self.kickout() |
||||||
|
endif |
||||||
|
endwhile |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! g:floaterm.prev() dict abort |
||||||
|
call self.hide() |
||||||
|
while v:true |
||||||
|
if self.count == 0 |
||||||
|
call floaterm#util#show_msg('No more terminal buffers', 'warning') |
||||||
|
return |
||||||
|
endif |
||||||
|
" If the current node is the node after HEAD(whose previous node is HEAD), |
||||||
|
" skip and point to the HEAD's prev node(the end node) |
||||||
|
if self.index.prev == self.head |
||||||
|
let self.index = self.head.prev |
||||||
|
else |
||||||
|
let self.index = self.index.prev |
||||||
|
endif |
||||||
|
let prev_bufnr = self.index.bufnr |
||||||
|
if prev_bufnr != 0 && bufexists(prev_bufnr) |
||||||
|
call self.open(prev_bufnr) |
||||||
|
return |
||||||
|
else |
||||||
|
call self.kickout() |
||||||
|
endif |
||||||
|
endwhile |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Hide the current terminal before opening another terminal window |
||||||
|
" Therefore, you cannot have two terminals displayed at once |
||||||
|
function! g:floaterm.hide() dict abort |
||||||
|
while v:true |
||||||
|
let found_winnr = self.find_term_win() |
||||||
|
if found_winnr > 0 |
||||||
|
execute found_winnr . ' wincmd q' |
||||||
|
else |
||||||
|
break |
||||||
|
endif |
||||||
|
endwhile |
||||||
|
endfunction |
||||||
|
|
||||||
|
" Find if there is a terminal among all opened windows |
||||||
|
" If found, hide it or jump into it |
||||||
|
function! g:floaterm.find_term_win() abort |
||||||
|
let found_winnr = 0 |
||||||
|
for winnr in range(1, winnr('$')) |
||||||
|
if getbufvar(winbufnr(winnr), '&filetype') ==# 'floaterm' |
||||||
|
let found_winnr = winnr |
||||||
|
endif |
||||||
|
endfor |
||||||
|
return found_winnr |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! g:floaterm.open(found_bufnr) dict abort |
||||||
|
let height = g:floaterm_height == v:null ? 0.6 : g:floaterm_height |
||||||
|
if type(height) == v:t_float | let height = height * &lines | endif |
||||||
|
let height = float2nr(height) |
||||||
|
|
||||||
|
let width = g:floaterm_width == v:null ? 0.6 : g:floaterm_width |
||||||
|
if type(width) == v:t_float | let width = width * &columns | endif |
||||||
|
let width = float2nr(width) |
||||||
|
|
||||||
|
if g:floaterm_type ==# 'floating' |
||||||
|
let [bufnr, border_bufnr] = s:open_floating_terminal(a:found_bufnr, height, width) |
||||||
|
else |
||||||
|
let bufnr = s:open_floating_normaml(a:found_bufnr, height, width) |
||||||
|
let border_bufnr = 0 |
||||||
|
endif |
||||||
|
if bufnr != 0 |
||||||
|
" Build a terminal node |
||||||
|
let node = deepcopy(g:floaterm_node) |
||||||
|
let node.bufnr = bufnr |
||||||
|
let node.prev = self.index |
||||||
|
let node.next = self.index.next |
||||||
|
" If current node is the end node, let HEAD's prev point to the new node |
||||||
|
if self.index.next == self.head |
||||||
|
let self.head.prev = node |
||||||
|
endif |
||||||
|
let self.index.next = node |
||||||
|
let self.index = self.index.next |
||||||
|
let self.count += 1 |
||||||
|
endif |
||||||
|
if border_bufnr != 0 |
||||||
|
let self.index.border_bufnr = border_bufnr |
||||||
|
endif |
||||||
|
call s:on_open() |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! s:on_open() abort |
||||||
|
setlocal cursorline |
||||||
|
setlocal filetype=floaterm |
||||||
|
|
||||||
|
" Find the true background(not 'hi link') for floating |
||||||
|
if has('nvim') |
||||||
|
execute 'setlocal winblend=' . g:floaterm_winblend |
||||||
|
execute 'hi FloatTermNormal term=NONE guibg='. g:floaterm_background |
||||||
|
setlocal winhighlight=NormalFloat:FloatTermNormal,FoldColumn:FloatTermNormal |
||||||
|
|
||||||
|
augroup close_floaterm_window |
||||||
|
autocmd! |
||||||
|
autocmd TermClose <buffer> if &filetype ==# 'floaterm' | |
||||||
|
\ bdelete! | |
||||||
|
\ endif |
||||||
|
autocmd TermClose,BufHidden <buffer> if exists('g:floaterm.index.border_bufnr') |
||||||
|
\ && bufexists(g:floaterm.index.border_bufnr) |
||||||
|
\ && g:floaterm.index.border_bufnr != 0 | |
||||||
|
\ execute 'bw ' . g:floaterm.index.border_bufnr | |
||||||
|
\ endif |
||||||
|
augroup END |
||||||
|
endif |
||||||
|
|
||||||
|
startinsert |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! s:open_floating_terminal(found_bufnr, height, width) abort |
||||||
|
let [row, col, vert, hor] = floaterm#util#floating_win_pos(a:width, a:height) |
||||||
|
|
||||||
|
let border_opts = { |
||||||
|
\ 'relative': 'editor', |
||||||
|
\ 'anchor': vert . hor, |
||||||
|
\ 'row': row, |
||||||
|
\ 'col': col, |
||||||
|
\ 'width': a:width + 2, |
||||||
|
\ 'height': a:height + 2, |
||||||
|
\ 'style':'minimal' |
||||||
|
\ } |
||||||
|
let top = g:floaterm_borderchars[4] . |
||||||
|
\ repeat(g:floaterm_borderchars[0], a:width) . |
||||||
|
\ g:floaterm_borderchars[5] |
||||||
|
let mid = g:floaterm_borderchars[3] . |
||||||
|
\ repeat(' ', a:width) . |
||||||
|
\ g:floaterm_borderchars[1] |
||||||
|
let bot = g:floaterm_borderchars[7] . |
||||||
|
\ repeat(g:floaterm_borderchars[2], a:width) . |
||||||
|
\ g:floaterm_borderchars[6] |
||||||
|
let lines = [top] + repeat([mid], a:height) + [bot] |
||||||
|
let border_bufnr = nvim_create_buf(v:false, v:true) |
||||||
|
call nvim_buf_set_option(border_bufnr, 'synmaxcol', 3000) " #27 |
||||||
|
call nvim_buf_set_lines(border_bufnr, 0, -1, v:true, lines) |
||||||
|
call nvim_open_win(border_bufnr, v:false, border_opts) |
||||||
|
" Floating window border highlight |
||||||
|
augroup floaterm_border_highlight |
||||||
|
autocmd! |
||||||
|
autocmd FileType floaterm_border ++once execute printf( |
||||||
|
\ 'syn match Border /.*/ | hi Border guibg=%s guifg=%s', |
||||||
|
\ g:floaterm_background, |
||||||
|
\ g:floaterm_border_color |
||||||
|
\ ) |
||||||
|
augroup END |
||||||
|
call nvim_buf_set_option(border_bufnr, 'filetype', 'floaterm_border') |
||||||
|
|
||||||
|
"" |
||||||
|
" TODO: |
||||||
|
" Use 'relative': 'cursor' for the border window |
||||||
|
" Use 'relative':'win'(which behaviors not as expected...) for content window |
||||||
|
let opts = { |
||||||
|
\ 'relative': 'editor', |
||||||
|
\ 'anchor': vert . hor, |
||||||
|
\ 'row': row + (vert ==# 'N' ? 1 : -1), |
||||||
|
\ 'col': col + (hor ==# 'W' ? 1 : -1), |
||||||
|
\ 'width': a:width, |
||||||
|
\ 'height': a:height, |
||||||
|
\ 'style':'minimal' |
||||||
|
\ } |
||||||
|
|
||||||
|
if a:found_bufnr > 0 |
||||||
|
call nvim_open_win(a:found_bufnr, v:true, opts) |
||||||
|
return [0, border_bufnr] |
||||||
|
else |
||||||
|
let bufnr = nvim_create_buf(v:false, v:true) |
||||||
|
call nvim_open_win(bufnr, v:true, opts) |
||||||
|
terminal |
||||||
|
return [bufnr, border_bufnr] |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! s:open_floating_normaml(found_bufnr, height, width) abort |
||||||
|
if a:found_bufnr > 0 |
||||||
|
if &lines > 30 |
||||||
|
execute 'botright ' . a:height . 'split' |
||||||
|
execute 'buffer ' . a:found_bufnr |
||||||
|
else |
||||||
|
botright split |
||||||
|
execute 'buffer ' . a:found_bufnr |
||||||
|
endif |
||||||
|
return |
||||||
|
else |
||||||
|
if &lines > 30 |
||||||
|
if has('nvim') |
||||||
|
execute 'botright ' . a:height . 'split term://' . &shell |
||||||
|
else |
||||||
|
botright terminal |
||||||
|
resize a:height |
||||||
|
endif |
||||||
|
else |
||||||
|
if has('nvim') |
||||||
|
execute 'botright split term://' . &shell |
||||||
|
else |
||||||
|
botright terminal |
||||||
|
endif |
||||||
|
endif |
||||||
|
return bufnr('%') |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! floaterm#start(action) abort |
||||||
|
if !floaterm#util#is_floaterm_available() |
||||||
|
return |
||||||
|
endif |
||||||
|
|
||||||
|
if a:action ==# 'new' |
||||||
|
call g:floaterm.new() |
||||||
|
elseif a:action ==# 'next' |
||||||
|
call g:floaterm.next() |
||||||
|
elseif a:action ==# 'prev' |
||||||
|
call g:floaterm.prev() |
||||||
|
elseif a:action ==# 'toggle' |
||||||
|
call g:floaterm.toggle() |
||||||
|
endif |
||||||
|
endfunction |
@ -0,0 +1,149 @@ |
|||||||
|
" ============================================================================ |
||||||
|
" FileName: autoload/floaterm/util.vim |
||||||
|
" Description: |
||||||
|
" Author: voldikss <dyzplus@gmail.com> |
||||||
|
" GitHub: https://github.com/voldikss |
||||||
|
" ============================================================================ |
||||||
|
|
||||||
|
function! floaterm#util#floating_win_pos(width, height) abort |
||||||
|
if g:floaterm_position ==# 'topright' |
||||||
|
let row = 0 |
||||||
|
let col = &columns |
||||||
|
let vert = 'N' |
||||||
|
let hor = 'E' |
||||||
|
elseif g:floaterm_position ==# 'topleft' |
||||||
|
let row = 0 |
||||||
|
let col = 0 |
||||||
|
let vert = 'N' |
||||||
|
let hor = 'W' |
||||||
|
elseif g:floaterm_position ==# 'bottomright' |
||||||
|
let row = &lines |
||||||
|
let col = &columns |
||||||
|
let vert = 'S' |
||||||
|
let hor = 'E' |
||||||
|
elseif g:floaterm_position ==# 'bottomleft' |
||||||
|
let row = &lines |
||||||
|
let col = 0 |
||||||
|
let vert = 'S' |
||||||
|
let hor = 'W' |
||||||
|
elseif g:floaterm_position ==# 'center' |
||||||
|
let row = (&lines - a:height)/2 |
||||||
|
let col = (&columns - a:width)/2 |
||||||
|
let vert = 'N' |
||||||
|
let hor = 'W' |
||||||
|
|
||||||
|
if row < 0 |
||||||
|
let row = 0 |
||||||
|
endif |
||||||
|
if col < 0 |
||||||
|
let col = 0 |
||||||
|
endif |
||||||
|
else " at the cursor place |
||||||
|
let curr_pos = getpos('.') |
||||||
|
let row = curr_pos[1] - line('w0') |
||||||
|
let col = curr_pos[2] |
||||||
|
|
||||||
|
if row + a:height <= &lines |
||||||
|
let vert = 'N' |
||||||
|
else |
||||||
|
let vert = 'S' |
||||||
|
endif |
||||||
|
|
||||||
|
if col + a:width <= &columns |
||||||
|
let hor = 'W' |
||||||
|
else |
||||||
|
let hor = 'E' |
||||||
|
endif |
||||||
|
endif |
||||||
|
|
||||||
|
return [row, col, vert, hor] |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! floaterm#util#is_floaterm_available() abort |
||||||
|
if exists('*nvim_win_set_config') |
||||||
|
if g:floaterm_type == v:null |
||||||
|
let g:floaterm_type = 'floating' |
||||||
|
endif |
||||||
|
elseif has('terminal') |
||||||
|
let g:floaterm_type = 'normal' |
||||||
|
else |
||||||
|
let message = 'Terminal feature is required, please upgrade your vim/nvim' |
||||||
|
call floaterm#util#show_msg(message, 'error') |
||||||
|
return v:false |
||||||
|
endif |
||||||
|
return v:true |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! s:echo(group, msg) abort |
||||||
|
if a:msg ==# '' | return | endif |
||||||
|
execute 'echohl' a:group |
||||||
|
echo a:msg |
||||||
|
echon ' ' |
||||||
|
echohl NONE |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! s:echon(group, msg) abort |
||||||
|
if a:msg ==# '' | return | endif |
||||||
|
execute 'echohl' a:group |
||||||
|
echon a:msg |
||||||
|
echon ' ' |
||||||
|
echohl NONE |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! floaterm#util#show_msg(message, ...) abort |
||||||
|
if a:0 == 0 |
||||||
|
let msg_type = 'info' |
||||||
|
else |
||||||
|
let msg_type = a:1 |
||||||
|
endif |
||||||
|
|
||||||
|
if type(a:message) != 1 |
||||||
|
let message = string(a:message) |
||||||
|
else |
||||||
|
let message = a:message |
||||||
|
endif |
||||||
|
|
||||||
|
call s:echo('Constant', '[vim-floaterm]') |
||||||
|
|
||||||
|
if msg_type ==# 'info' |
||||||
|
call s:echon('Normal', message) |
||||||
|
elseif msg_type ==# 'warning' |
||||||
|
call s:echon('WarningMsg', message) |
||||||
|
elseif msg_type ==# 'error' |
||||||
|
call s:echon('Error', message) |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! floaterm#util#get_normalfloat_fg() abort |
||||||
|
let hiGroup = 'NormalFloat' |
||||||
|
while v:true |
||||||
|
let hiInfo = execute('hi ' . hiGroup) |
||||||
|
let fgcolor = matchstr(hiInfo, 'guifg=\zs\S*') |
||||||
|
let hiGroup = matchstr(hiInfo, 'links to \zs\S*') |
||||||
|
if fgcolor !=# '' || hiGroup ==# '' |
||||||
|
break |
||||||
|
endif |
||||||
|
endwhile |
||||||
|
" If the foreground color isn't found eventually, use white |
||||||
|
if fgcolor ==# '' |
||||||
|
let fgcolor = '#FFFFFF' |
||||||
|
endif |
||||||
|
return fgcolor |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! floaterm#util#get_normalfloat_bg() abort |
||||||
|
let hiGroup = 'NormalFloat' |
||||||
|
while v:true |
||||||
|
let hiInfo = execute('hi ' . hiGroup) |
||||||
|
let bgcolor = matchstr(hiInfo, 'guibg=\zs\S*') |
||||||
|
let hiGroup = matchstr(hiInfo, 'links to \zs\S*') |
||||||
|
if bgcolor !=# '' || hiGroup ==# '' |
||||||
|
break |
||||||
|
endif |
||||||
|
endwhile |
||||||
|
" If the background color isn't found eventually, use black |
||||||
|
if bgcolor ==# '' |
||||||
|
let bgcolor = '#000000' |
||||||
|
endif |
||||||
|
return bgcolor |
||||||
|
endfunction |
@ -0,0 +1,160 @@ |
|||||||
|
*floaterm.txt* Neovim's floating terminal plugin Last change: 2019-12-28 |
||||||
|
|
||||||
|
Author : voldikss <https://github.com/voldikss> |
||||||
|
License: MIT license |
||||||
|
============================================================================== |
||||||
|
CONTENTS *floaterm-contents* |
||||||
|
|
||||||
|
Introduction |floaterm-introduction| |
||||||
|
Install |floaterm-install| |
||||||
|
Features |floaterm-features| |
||||||
|
Variables |floaterm-variables| |
||||||
|
Keymappings |floaterm-key-mappings| |
||||||
|
Commands |floaterm-commands| |
||||||
|
Q-A |floaterm-q&a| |
||||||
|
Repository |floaterm-repository| |
||||||
|
|
||||||
|
|
||||||
|
============================================================================== |
||||||
|
INTRODUCTION *floaterm-introduction* |
||||||
|
|
||||||
|
Use neovim terminal in the floating window. |
||||||
|
|
||||||
|
|
||||||
|
============================================================================== |
||||||
|
INSTALL *floaterm-install* |
||||||
|
|
||||||
|
With vim-plug: |
||||||
|
> |
||||||
|
Plug 'voldikss/vim-floaterm' |
||||||
|
< |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
FEATURES *floaterm-features* |
||||||
|
|
||||||
|
- Toggle terminal window quickly |
||||||
|
|
||||||
|
- Multiple terminal instances |
||||||
|
|
||||||
|
- Customizable floating terminal style |
||||||
|
|
||||||
|
- Switch/Preview floating terminal buffer using [vim-clap](https://github.com/liuchengxu/vim-clap)(try `:Clap floaterm`) |
||||||
|
|
||||||
|
|
||||||
|
============================================================================== |
||||||
|
VARIABLES *floaterm-variables* |
||||||
|
|
||||||
|
g:floaterm_type *g:floaterm_type* |
||||||
|
|
||||||
|
Available:`'floating'`(neovim only), `'normal'`(vim8 and neovim) |
||||||
|
|
||||||
|
Default: `'floating'` |
||||||
|
|
||||||
|
g:floaterm_width *g:floaterm_width* |
||||||
|
|
||||||
|
Type: `int` (number of columns) or `float` (between 0 and 1). |
||||||
|
If `float`, the width is relative to `&columns`. |
||||||
|
Default: `0.6` |
||||||
|
|
||||||
|
g:floaterm_height *g:floaterm_height* |
||||||
|
|
||||||
|
|
||||||
|
Type: `int` (number of lines) or `float` (between 0 and 1). |
||||||
|
If `float`, the height is relative to `&lines`. |
||||||
|
Default: `0.6` |
||||||
|
|
||||||
|
|
||||||
|
g:floaterm_winblend *g:floaterm_winblend* |
||||||
|
|
||||||
|
Description: The opacity of the floating terminal |
||||||
|
|
||||||
|
Default: `0` |
||||||
|
|
||||||
|
g:floaterm_position *g:floaterm_position* |
||||||
|
|
||||||
|
Available: `'center'`, `'topleft'`, `'topright'`, `'bottomleft'`, |
||||||
|
`'bottomright'`, `'auto'` |
||||||
|
|
||||||
|
Default: `'center'` |
||||||
|
|
||||||
|
g:floaterm_background *g:floaterm_background* |
||||||
|
|
||||||
|
Type: string(e.g. `'#000000'`, `'black'`) |
||||||
|
|
||||||
|
Default: background color of normal floating window |
||||||
|
|
||||||
|
g:floaterm_borderchars *g:floaterm_borderchars* |
||||||
|
|
||||||
|
Default: `['─', '│', '─', '│', '┌', '┐', '┘', '└']` |
||||||
|
|
||||||
|
g:floaterm_border_color *g:floaterm_border_color* |
||||||
|
|
||||||
|
Type: string(e.g. `'#FFFFFF'`, `'white'`) |
||||||
|
|
||||||
|
Default: foreground color of normal floating window |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
|
||||||
|
MAPPINGS *floaterm-key-mappings* |
||||||
|
|
||||||
|
This plugin doesn't supply any default mappings. |
||||||
|
> |
||||||
|
""" Example configuration |
||||||
|
let g:floaterm_keymap_new = '<F7>' |
||||||
|
let g:floaterm_keymap_prev = '<F8>' |
||||||
|
let g:floaterm_keymap_next = '<F9>' |
||||||
|
let g:floaterm_keymap_toggle = '<F10>' |
||||||
|
< |
||||||
|
|
||||||
|
|
||||||
|
============================================================================== |
||||||
|
COMMANDS *floaterm-commands* |
||||||
|
|
||||||
|
:FloatermNew *:FloatermNew* |
||||||
|
|
||||||
|
|
||||||
|
:FloatermNext *:FloatermNext* |
||||||
|
|
||||||
|
|
||||||
|
:FloatermPrev *:FloatermPrev* |
||||||
|
|
||||||
|
|
||||||
|
:FloatermToggle *:FloatermToggle* |
||||||
|
|
||||||
|
|
||||||
|
============================================================================== |
||||||
|
Q-A *floaterm-q&a* |
||||||
|
|
||||||
|
- This plugin leaves an empty buffer on startify window |
||||||
|
|
||||||
|
Put this code in `vimrc` |
||||||
|
> |
||||||
|
autocmd User Startified setlocal buflisted |
||||||
|
< |
||||||
|
- I want to use another shell in the terminal. (e.g. Use fish instead of bash) |
||||||
|
|
||||||
|
Set `shell` option in your `vimrc`: |
||||||
|
> |
||||||
|
set shell=/path/to/shell |
||||||
|
|
||||||
|
- I would like to customize the style of the floating terminal window |
||||||
|
|
||||||
|
Use `autocmd`. For example |
||||||
|
> |
||||||
|
function s:floatermSettings() |
||||||
|
setlocal number |
||||||
|
" more settings |
||||||
|
endfunction |
||||||
|
|
||||||
|
autocmd FileType floaterm call s:floatermSettings() |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
REPOSITORY *floaterm-repository-page* |
||||||
|
|
||||||
|
|vim-floaterm| is developed on GitHub. |
||||||
|
|
||||||
|
https://github.com/voldikss/vim-floaterm |
||||||
|
|
||||||
|
|
||||||
|
============================================================================== |
||||||
|
vim:tw=78:nosta:noet:ts=8:sts=0:ft=help:noet:fen:fdm=marker: |
@ -0,0 +1,47 @@ |
|||||||
|
" ============================================================================ |
||||||
|
" FileName: plugin/floaterm.vim |
||||||
|
" Description: |
||||||
|
" Author: voldikss <dyzplus@gmail.com> |
||||||
|
" GitHub: https://github.com/voldikss |
||||||
|
" ============================================================================ |
||||||
|
|
||||||
|
scriptencoding utf-8 |
||||||
|
|
||||||
|
let g:floaterm_type = get(g:, 'floaterm_type', v:null) |
||||||
|
let g:floaterm_width = get(g:, 'floaterm_width', v:null) |
||||||
|
let g:floaterm_height = get(g:, 'floaterm_height', v:null) |
||||||
|
let g:floaterm_winblend = get(g:, 'floaterm_winblend', 0) |
||||||
|
let g:floaterm_position = get(g:, 'floaterm_position', 'auto') |
||||||
|
let g:floaterm_background = get(g:, 'floaterm_background', v:null) |
||||||
|
let g:floaterm_borderchars = get(g:, 'floaterm_borderchars', ['─', '│', '─', '│', '┌', '┐', '┘', '└']) |
||||||
|
let g:floaterm_border_color = get(g:, 'floaterm_border_color', v:null) |
||||||
|
|
||||||
|
let g:floaterm_keymap_new = get(g:, 'floaterm_keymap_new', v:null) |
||||||
|
let g:floaterm_keymap_prev = get(g:, 'floaterm_keymap_prev', v:null) |
||||||
|
let g:floaterm_keymap_next = get(g:, 'floaterm_keymap_next', v:null) |
||||||
|
let g:floaterm_keymap_toggle = get(g:, 'floaterm_keymap_toggle', v:null) |
||||||
|
|
||||||
|
command! -nargs=0 FloatermNew call floaterm#start('new') |
||||||
|
command! -nargs=0 FloatermPrev call floaterm#start('prev') |
||||||
|
command! -nargs=0 FloatermNext call floaterm#start('next') |
||||||
|
command! -nargs=0 FloatermToggle call floaterm#start('toggle') |
||||||
|
|
||||||
|
function! s:install_keymap() |
||||||
|
if g:floaterm_keymap_new != v:null |
||||||
|
exe printf('nnoremap <silent> %s :FloatermNew<CR>', g:floaterm_keymap_new) |
||||||
|
exe printf('tnoremap <silent> %s <C-\><C-n>:FloatermNew<CR>', g:floaterm_keymap_new) |
||||||
|
endif |
||||||
|
if g:floaterm_keymap_prev != v:null |
||||||
|
exe printf('nnoremap <silent> %s :FloatermPrev<CR>', g:floaterm_keymap_prev) |
||||||
|
exe printf('tnoremap <silent> %s <C-\><C-n>:FloatermPrev<CR>', g:floaterm_keymap_prev) |
||||||
|
endif |
||||||
|
if g:floaterm_keymap_next != v:null |
||||||
|
exe printf('nnoremap <silent> %s :FloatermNext<CR>', g:floaterm_keymap_next) |
||||||
|
exe printf('tnoremap <silent> %s <C-\><C-n>:FloatermNext<CR>', g:floaterm_keymap_next) |
||||||
|
endif |
||||||
|
if g:floaterm_keymap_toggle != v:null |
||||||
|
exe printf('nnoremap <silent> %s :FloatermToggle<CR>', g:floaterm_keymap_toggle) |
||||||
|
exe printf('tnoremap <silent> %s <C-\><C-n>:FloatermToggle<CR>', g:floaterm_keymap_toggle) |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
call s:install_keymap() |
Loading…
Reference in new issue