I60R / Page
Programming Languages
Projects that are alternatives of or similar to Page
Page
Allows you to redirect text into neovim.
You can set it as $PAGER
to view logs, diffs, various command outputs.
ANSI escape sequences will be interpreted by :term buffer, which makes it noticeably faster than vimpager and nvimpager.
Also, text will be displayed instantly as it arrives - no need to wait until EOF.
Text from neovim :term buffer will be redirected directly into a new buffer in the same neovim instance - no nested neovim will be spawned.
That's by utilizing $NVIM_LISTEN_ADDRESS
as neovim-remote does.
Ultimately, page
will reuse all of neovim text editing+navigating+searching facilities and will pick all of plugins+mappings+options set in your neovim config.
Usage
- under regular terminal
- under neovim's terminal
CLI
expand `page --help`
USAGE:
page [FLAGS] [OPTIONS] [FILES]...
FLAGS:
-o Create and use new output buffer (to display text from page stdin) [implied]
-p Print path to buffer pty (to redirect `command > /path/to/output`) [implied when page not piped]
-P Set $PWD as working dir for output buffer (to navigate paths with `gf`)
-b Return back to current buffer
-B Return back to current buffer and enter INSERT mode
-f Follow output instead of keeping top position (like `tail -f`)
-F Follow output instead of keeping top position also for each of <FILES>
-W Flush redirecting protection that prevents from producing junk and possible overwriting of existed
files by invoking commands like "ls > $(NVIM_LISTEN_ADDRESS= page -E q)" where the RHS of >
operator evaluates not into /path/to/sink as expected but into a bunch of whitespace-separated
strings/escapes from neovim UI which some shells also interpret as valid targets for text
redirection. The protection consists of printing of a path to the existed dummy directory always
first before printing of a neovim UI will begin in order to make the first target for text
redirection from page's output invalid and to disrupt harmful redirection early before other writes
might occur. [env:PAGE_REDIRECTION_PROTECT: (0 to disable)]
-C Enable PageConnect PageDisconnect autocommands
-r Split right with ratio: window_width * 3 / (<r-provided> + 1)
-l Split left with ratio: window_width * 3 / (<l-provided> + 1)
-u Split above with ratio: window_height * 3 / (<u-provided> + 1)
-d Split below with ratio: window_height * 3 / (<d-provided> + 1)
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-a <address> Neovim session address [env: NVIM_LISTEN_ADDRESS=/tmp/nvimycgkAf/0]
-A <arguments> Neovim arguments for new child process [env: NVIM_PAGE_ARGS=]
-c <config> Neovim config path for new child process [file:$XDG_CONFIG_HOME/page/init.vim]
-e <command> Run command in output buffer after it's created
-E <command-post> Run command in output buffer after it's created or connected as instance
-i <instance> Connect or create named output buffer. When connected, new content overwrites previous
-I <instance-append> Connect or create named output buffer. When connected, new content appends to previous
-x <instance-close> Close instance buffer with this name if exist [revokes implied options]
-n <name> Set output buffer name (displayed in statusline) [env: PAGE_BUFFER_NAME=./page --help]
-t <filetype> Set output buffer filetype (for syntax highlighting) [default: pager]
-q <query-lines> Enable on-demand stdin reading with :Page <query_lines> command [default: 0]
-R <split-right-cols> Split right and resize to <split_right_cols> columns
-L <split-left-cols> Split left and resize to <split_left_cols> columns
-U <split-above-rows> Split above and resize to <split_above_rows> rows
-D <split-below-rows> Split below and resize to <split_below_rows> rows
ARGS:
<FILES>... Open provided files in separate buffers [revokes implied options]
Customization
Statusline appearance settings:
let g:page_icon_instance = '$'
let g:page_icon_redirect = '>'
let g:page_icon_pipe = '|'
Autocommand hooks:
" Will be run once when output buffer is created
autocmd User PageOpen { your settings }
" Will be run once when file buffer is created
autocmd User PageOpenFile { your settings }
" Only if -C option provided.
" Will be run always when output buffer is created
" and also when `page` connects to instance `-i, -I` buffers:
autocmd User PageConnect { your settings }
autocmd User PageDisconnect { your settings }
Hotkey for closing page
buffers on <C-c>
:
function! PageClose(page_alternate_bufnr)
bd!
if bufnr('%') == a:page_alternate_bufnr && mode('%') == 'n'
norm a
endif
endfunction
autocmd User PageOpen
\| exe 'map <buffer> <C-c> :call PageClose(b:page_alternate_bufnr)<CR>'
\| exe 'tmap <buffer> <C-c> :call PageClose(b:page_alternate_bufnr)<CR>'
Shell hacks
To use as $PAGER
without scrollback overflow:
export PAGER="page -q 90000"
To use as $MANPAGER
without error:
export MANPAGER="page -C -e 'au User PageDisconnect sleep 100m|%y p|enew! |bd! #|pu p|set ft=man'"
To override neovim config (create this file or use -c option):
$XDG_CONFIG_HOME/page/init.vim
To circumvent neovim config picking:
page -c NONE
To set output buffer name as first two words from invoked command (zsh only):
preexec() {
echo "${1// *|*}" | read -A words
export PAGE_BUFFER_NAME="${words[@]:0:2}"
}
Buffer defaults
These commands are run on each page
buffer creation:
let b:page_alternate_bufnr={initial_buf_nr}
let b:page_scrolloff_backup=&scrolloff
setl scrollback=100000 scrolloff=999 signcolumn=no nonumber nomodifiable {filetype}
exe 'au BufEnter <buffer> set scrolloff=999'
exe 'au BufLeave <buffer> let &scrolloff=b:page_scrolloff_backup'
{cmd_pre}
exe 'silent doautocmd User PageOpen'
redraw
{cmd_provided_by_user}
{cmd_post}
Where:
{initial_buf_nr}
number of parent :term buffer or -1 when page isn't spawned from neovim terminal
Is always set on all buffers created by page
{filetype}
filetype=value of -t argument or "pager"
Is set only on output buffers.
On files buffers filetypes are detected automatically.
{cmd_pre}
exe 'com! -nargs=? Page call rpcnotify(0, ''page_fetch_lines'', ''{page_id}'', <args>)'
exe 'au BufEnter <buffer> com! -nargs=? Page call rpcnotify(0, ''page_fetch_lines'', ''{page_id}'<args>)'
exe 'au BufDelete <buffer> call rpcnotify(0, ''page_buffer_closed'', ''{page_id}'')'
Is appended when -q is provided
{cmd_pre}
let b:page_lcd_backup = getcwd()
lcd {pwd}
exe 'au BufEnter <buffer> lcd {pwd}'
exe 'au BufLeave <buffer> lcd ' .. b:page_lcd_backup
Is also appended when -P is provided.
{pwd} is $PWD value
{cmd_provided_by_user}
value of -e argument
Is appended when -e is provided
{cmd_post}
this executes PageOpenFile autocommand
Is appended only on file buffers
Limitations
- Only ~100000 lines can be displayed (it's neovim terminal limit)
- Text that doesn't fit in window width on resize will be lost (due to data structures inherited from vim)
-
MANPAGER=page -t man
not works becauseset ft=man
fails on :term buffer (other filetypes may be affected as well)
Installation
-
From binaries
- Grab binary for your platform from releases (currently Linux and OSX are supported)
-
Arch Linux:
- Package page-git is available on AUR
- Or:
git clone [email protected]:I60R/page.git && cd page && makepkg -ef && sudo pacman -U page-git*.pkg.tar.xz
-
Manually:
- Install
rustup
from your distribution package manager - Configure toolchain:
rustup install stable && rustup default stable
git clone [email protected]:I60R/page.git && cd page && cargo install --path .
- Install