{"id":14981766,"url":"https://github.com/i60r/page","last_synced_at":"2025-04-06T15:12:16.454Z","repository":{"id":41481020,"uuid":"112975196","full_name":"I60R/page","owner":"I60R","description":"Use neovim as pager","archived":false,"fork":false,"pushed_at":"2024-07-29T11:10:30.000Z","size":503,"stargazers_count":221,"open_issues_count":9,"forks_count":5,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-06T15:12:10.517Z","etag":null,"topics":["cli","neovim","pager"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/I60R.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-04T00:14:33.000Z","updated_at":"2025-02-16T20:30:40.000Z","dependencies_parsed_at":"2024-09-28T06:20:33.743Z","dependency_job_id":null,"html_url":"https://github.com/I60R/page","commit_stats":{"total_commits":327,"total_committers":5,"mean_commits":65.4,"dds":0.03975535168195721,"last_synced_commit":"cf1a6dbf2b5639642b60144f318ca54fd909fec2"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/I60R%2Fpage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/I60R%2Fpage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/I60R%2Fpage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/I60R%2Fpage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/I60R","download_url":"https://codeload.github.com/I60R/page/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247500468,"owners_count":20948880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","neovim","pager"],"created_at":"2024-09-24T14:04:13.238Z","updated_at":"2025-04-06T15:12:16.436Z","avatar_url":"https://github.com/I60R.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Page\n\n[![Rust Build](https://github.com/I60R/page/actions/workflows/rust_build.yml/badge.svg)](https://github.com/I60R/page/actions/workflows/rust_build.yml)\n[![Lines Of Code](https://tokei.rs/b1/github/I60R/page)](https://github.com/I60R/page)\n\nAllows you to redirect text into [neovim](https://github.com/neovim/neovim).\nYou can set it as `$PAGER` to view logs, diffs, various command outputs.\n\nANSI escape sequences will be interpreted by :term buffer, which makes `page` noticeably faster than [vimpager](https://github.com/rkitover/vimpager) and [nvimpager](https://github.com/lucc/nvimpager).\nAnd text will be displayed instantly as it arrives - no need to wait until EOF.\n\nAlso, text from neovim :term buffer will be redirected directly into a new buffer in the same neovim instance - no nested neovim will be spawned.\nThat's by utilizing `$NVIM` variable like [neovim-remote](https://github.com/mhinz/neovim-remote) does.\n\n**Bonus**: another binary named `nv` is included, which reimplements `neovim-remote` but with interface similar to `page`. There's no intention to have all `nvim --remote` features — it should be only a simple file picker that prevents spawning nested neovim instance. Also, in contrast with `neovim-remote` there are some safeguards e.g. it won't open non-text files unless explicit flag is provided for that so `nv *` opens only text files in current directory. I recommend to read `--help` output and experiment with options a bit.\n\nUltimately, `page` and `nv` reuses all of neovim's text editing+navigating+searching facilities and will either facilitate all of plugins+mappings+options set in your neovim config.\n\n## Usage\n\n* *under regular terminal*\n\n![usage under regular terminal](https://imgur.com/lxDCPpn.gif)\n\n* *under neovim's terminal*\n\n![usage under neovim's terminal](https://i.imgur.com/rcLEM6X.gif)\n\n---\n\n## CLI\n\n\u003cdetails\u003e\u003csummary\u003e expand \u003ccode\u003epage --help\u003c/code\u003e\u003c/summary\u003e\n\n```xml\nUsage: page [OPTIONS] [FILE]...\n\nArguments:\n  [FILE]...  Open provided file in separate buffer [without other flags revokes implied by default -o or -p\n             option]\n\nOptions:\n  -o                         Create and use output buffer (to redirect text from page's stdin) [implied by\n                             default unless -x and/or \u003cFILE\u003e provided without other flags]\n  -O [\u003cNOOPEN_LINES\u003e]        Prefetch \u003cNOOPEN_LINES\u003e from page's stdin: if all input fits then print it to\n                             stdout and exit without neovim usage (to emulate `less --quit-if-one-screen`)\n                             [empty: term height - 3 (space for prompt); negative: term height -\n                             \u003cNOOPEN_LINES\u003e; 0: disabled and default; ignored with -o, -p, -x and when page\n                             isn't piped]\n  -p                         Print path of pty device associated with output buffer (to redirect text from\n                             commands respecting output buffer size and preserving colors) [implied if page\n                             isn't piped unless -x and/or \u003cFILE\u003e provided without other flags]\n  -P                         Set $PWD as working directory at output buffer (to navigate paths with `gf`)\n  -q [\u003cQUERY_LINES\u003e]         Read no more than \u003cQUERY_LINES\u003e from page's stdin: next lines should be\n                             fetched by invoking :Page \u003cQUERY\u003e command or 'r'/'R' keypress on neovim side\n                             [empty: term height - 2 (space for tab and buffer lines); negative: term\n                             height - \u003cQUERY_LINES\u003e; 0: disabled and default; \u003cQUERY\u003e is optional and\n                             defaults to \u003cQUERY_LINES\u003e; doesn't take effect on \u003cFILE\u003e buffers]\n  -f                         Cursor follows content of output buffer as it appears instead of keeping top\n                             position (like `tail -f`)\n  -F                         Cursor follows content of output and \u003cFILE\u003e buffers as it appears instead of\n                             keeping top position\n  -t \u003cFILETYPE\u003e              Set filetype on output buffer (to enable syntax highlighting) [pager: default;\n                             not works with text echoed by -O]\n  -b                         Return back to current buffer\n  -B                         Return back to current buffer and enter into INSERT/TERMINAL mode\n  -n \u003cNAME\u003e                  Set title for output buffer (to display it in statusline) [env:\n                             PAGE_BUFFER_NAME=]\n  -w                         Do not remap i, I, a, A, u, d, x, q (and r, R with -q) keys [wouldn't unmap on\n                             connected instance output buffer]\n  -z [\u003cPAGERIZE\u003e]            Pagerize output when it exceeds \u003cPAGERIZE\u003e lines (to view `journalctl`)\n                             [default: disabled; empty: 100_000]\n                              ~ ~ ~\n\n                              ~ ~ ~\n  -a \u003cADDRESS\u003e               TCP/IP socked address or path to named pipe listened by running host neovim\n                             process [env: NVIM=/run/user/1000/nvim.9389.0]\n  -A \u003cARGUMENTS\u003e             Arguments that will be passed to child neovim process spawned when \u003cADDRESS\u003e\n                             is missing [env: NVIM_PAGE_ARGS=]\n  -c \u003cCONFIG\u003e                Config that will be used by child neovim process spawned when \u003cADDRESS\u003e is\n                             missing [file:$XDG_CONFIG_HOME/page/init.vim]\n  -C                         Enable PageConnect PageDisconnect autocommands\n  -e \u003cCOMMAND\u003e               Run command  on output buffer after it was created\n      --e \u003cLUA\u003e              Run lua expr on output buffer after it was created\n  -E \u003cCOMMAND_POST\u003e          Run command  on output buffer after it was created or connected as instance\n      --E \u003cLUA_POST\u003e         Run lua expr on output buffer after it was created or connected as instance\n                              ~ ~ ~\n  -i \u003cINSTANCE\u003e              Create output buffer with \u003cINSTANCE\u003e tag or use existed with replacing its\n                             content by text from page's stdin\n  -I \u003cINSTANCE_APPEND\u003e       Create output buffer with \u003cINSTANCE_APPEND\u003e tag or use existed with appending\n                             to its content text from page's stdin\n  -x \u003cINSTANCE_CLOSE\u003e        Close  output buffer with \u003cINSTANCE_CLOSE\u003e tag if it exists [without other\n                             flags revokes implied by defalt -o or -p option]\n                              ~ ~ ~\n  -W                         Flush redirection protection that prevents from producing junk and possible\n                             overwriting of existed files by invoking commands like `ls \u003e $(NVIM= page -E\n                             q)` where the RHS of \u003e operator evaluates not into /path/to/pty as expected\n                             but into a bunch of whitespace-separated strings/escape sequences from neovim\n                             UI; bad things happens when some shells interpret this as many valid targets\n                             for text redirection. The protection is only printing of a path to the existed\n                             dummy directory always first before printing of a neovim UI might occur; this\n                             makes the first target for text redirection from page's output invalid and\n                             disrupts the whole redirection early before other harmful writes might occur.\n                             [env:PAGE_REDIRECTION_PROTECT; (0 to disable)]\n                              ~ ~ ~\n  -l...                      Split left  with ratio: window_width  * 3 / (\u003cl-PROVIDED\u003e + 1)\n  -r...                      Split right with ratio: window_width  * 3 / (\u003cr-PROVIDED\u003e + 1)\n  -u...                      Split above with ratio: window_height * 3 / (\u003cu-PROVIDED\u003e + 1)\n  -d...                      Split below with ratio: window_height * 3 / (\u003cd-PROVIDED\u003e + 1)\n  -L \u003cSPLIT_LEFT_COLS\u003e       Split left  and resize to \u003cSPLIT_LEFT_COLS\u003e  columns\n  -R \u003cSPLIT_RIGHT_COLS\u003e      Split right and resize to \u003cSPLIT_RIGHT_COLS\u003e columns\n  -U \u003cSPLIT_ABOVE_ROWS\u003e      Split above and resize to \u003cSPLIT_ABOVE_ROWS\u003e rows\n  -D \u003cSPLIT_BELOW_ROWS\u003e      Split below and resize to \u003cSPLIT_BELOW_ROWS\u003e rows\n                              ^\n  -+                         With any of -r -l -u -d -R -L -U -D open floating window instead of split [to\n                             not overwrite data in the current terminal]\n                              ~ ~ ~\n  -h, --help                 Print help information\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e expand \u003ccode\u003env --help\u003c/code\u003e\u003c/summary\u003e\n\n```xml\nUsage: nv [OPTIONS] [FILE]...\n\nArguments:\n  [FILE]...  Open provided files as editable [if none provided nv opens last modified file in currend\n             directory]\n\nOptions:\n  -o                          Open non-text files including directories, binaries, images etc\n  -O [\u003cRECURSE_DEPTH\u003e]        Ignoring [FILE] open all text files in the current directory and recursively\n                              open all text files in its subdirectories [0: disabled and default; empty:\n                              defaults to 1 and implied if no \u003cRECURSE_DEPTH\u003e provided; \u003cRECURSE_DEPTH\u003e:\n                              also opens in subdirectories at this level of depth]\n  -v                          Open in `page` instead (just postfix shortcut)\n                               ~ ~ ~\n  -f                          Open each [FILE] at last line\n  -p \u003cPATTERN\u003e                Open and search for a specified \u003cPATTERN\u003e\n  -P \u003cPATTERN_BACKWARDS\u003e      Open and search backwars for a specified \u003cPATTERN_BACKWARDS\u003e\n  -b                          Return back to current buffer\n  -B                          Return back to current buffer and enter into INSERT/TERMINAL mode\n  -k                          Keep `nv` process until buffer is closed (for editing git commit message)\n  -K                          Keep `nv` process until first write occur, then close buffer and neovim if\n                              it was spawned by `nv`\n                               ~ ~ ~\n  -a \u003cADDRESS\u003e                TCP/IP socket address or path to named pipe listened by running host neovim\n                              process [env: NVIM=/run/user/1000/nvim.604327.0]\n  -A \u003cARGUMENTS\u003e              Arguments that will be passed to child neovim process spawned when \u003cADDRESS\u003e\n                              is missing [env: NVIM_PAGE_PICKER_ARGS=]\n  -c \u003cCONFIG\u003e                 Config that will be used by child neovim process spawned when \u003cADDRESS\u003e is\n                              missing [file: $XDG_CONFIG_HOME/page/init.vim]\n  -t \u003cFILETYPE\u003e               Override filetype on each [FILE] buffer (to enable custom syntax highlighting\n                              [text: default]\n                               ~ ~ ~\n  -e \u003cCOMMAND\u003e                Run command  on each [FILE] buffer after it was created\n      --e \u003cLUA\u003e               Run lua expr on each [FILE] buffer after it was created\n  -x \u003cCOMMAND_ONLY\u003e           Just run command  with ignoring all other options\n      --x \u003cLUA_ONLY\u003e          Just run lua expr with ignoring all other options\n                               ~ ~ ~\n  -l...                       Split left  with ratio: window_width  * 3 / (\u003cl-PROVIDED\u003e + 1)\n  -r...                       Split right with ratio: window_width  * 3 / (\u003cr-PROVIDED\u003e + 1)\n  -u...                       Split above with ratio: window_height * 3 / (\u003cu-PROVIDED\u003e + 1)\n  -d...                       Split below with ratio: window_height * 3 / (\u003cd-PROVIDED\u003e + 1)\n  -L \u003cSPLIT_LEFT_COLS\u003e        Split left  and resize to \u003cSPLIT_LEFT_COLS\u003e  columns\n  -R \u003cSPLIT_RIGHT_COLS\u003e       Split right and resize to \u003cSPLIT_RIGHT_COLS\u003e columns\n  -U \u003cSPLIT_ABOVE_ROWS\u003e       Split above and resize to \u003cSPLIT_ABOVE_ROWS\u003e rows\n  -D \u003cSPLIT_BELOW_ROWS\u003e       Split below and resize to \u003cSPLIT_BELOW_ROWS\u003e rows\n                               ^\n  -+                          With any of -r -l -u -d -R -L -U -D open floating window instead of split\n                              [to not overwrite data in the current terminal]\n                               ~ ~ ~\n  -h, --help                  Print help information\n```\n\n\u003c/details\u003e\n\n**Note**: `page` and `nv` may be unergonomic to type so I suggest users to create alias like `p` and `v`\n\n## `nvim/init.lua` customizations\n\n```lua\n-- Opacity of popup window spawned with -+ option\nvim.g.page_popup_winblend = 25\n```\n\n## `nvim/init.lua` customizations (pager only)\n\nStatusline appearance:\n\n```lua\n-- String that will append to buffer name\nvim.g.page_icon_pipe = '|' -- When piped\nvim.g.page_icon_redirect = '\u003e' -- When exposes pty device\nvim.g.page_icon_instance = '$' -- When `-i, -I` flags provided\n```\n\nAutocommand hooks:\n\n```lua\n-- Will run once when output buffer is created\nvim.api.create_autocmd('User', {\n    pattern = 'PageOpen',\n    callback = lua_function,\n})\n\n-- Will run once when file buffer is created\nvim.api.create_autocmd('User', {\n    pattern = 'PageOpenFile',\n    callback = lua_function,\n})\n```\n\nOnly with `-C` option provided:\n\n```lua\n-- will run always when output buffer is created\n-- and also when `page` connects to instance `-i, -I` buffers:\nvim.api.create_autocmd('User', {\n    pattern = 'PageConnect',\n    callback = lua_function,\n})\n\n-- Will run when page process exits\nvim.api.create_autocmd('User', {\n    pattern = 'PageDisconnect',\n    callback = lua_function,\n})\n```\n\n## Shell hacks\n\nTo use as `$PAGER` without [scrollback overflow](https://github.com/I60R/page/issues/7):\n\n```zsh\nexport PAGER=\"page -q 90000\"\n\n# Alternatively\n\nexport PAGER=\"page -z 90000\" # will pagerize output\n\n# And you can combine both\n\nexport PAGER=\"page -q 90000 -z 90000\"\n```\n\nTo configure:\n\n```zsh\nexport PAGER=\"page -WfC -q 90000 -z 90000\" # some sensible flags\nalias page=\"$PAGER\"\n\n# Usage\nls | page -q 100 # you can specify the same flag multiple times:\n                 # last provided will override previous\n```\n\nTo use as `$MANPAGER`:\n\n```zsh\nexport MANPAGER=\"page -t man\"\n\n# Alternatively, to pick a bit better `man` highlighting:\n\nman () {\n    PROGRAM=\"${@[-1]}\"\n    SECTION=\"${@[-2]}\"\n    page -W \"man://$PROGRAM${SECTION:+($SECTION)}\"\n}\n```\n\nTo set `nv` as popup `git` commit message editor:\n\n```zsh\n# Will spawn popup editor and exit on first write\ngit config --global core.editor \"nv -K -+-R 80 -B\"\n```\n\nTo cd into directory passed to `nv`\n\n```zsh\nnv() {\n    #stdin_is_term #one_argument   #it's_dir\n    if [ -t 1 ] \u0026\u0026 [ 1 -eq $# ] \u0026\u0026 [ -d $1 ]; then\n        cd $1\n    else\n        nv $*\n    fi\n}\n\ncompdef _nv nv # if you have completions installed\n```\n\nTo automatically `lcd` into terminal's directory:\n\n```zsh\nchpwd () {\n    [ ! -z \"$NVIM\" ] \u0026\u0026 nv -x \"lcd $PWD\"\n}\n```\n\nTo circumvent neovim config picking:\n\n```zsh\npage -c NONE\n\n# Alternatively, to override neovim config create this file:\n\ntouch $XDG_CONFIG_HOME/page/init.lua # init.vim is also supported\n```\n\nTo set output buffer name as first two words from invoked command (zsh only):\n\n```zsh\npreexec () {\n    if [ -z \"$NVIM\" ]; then\n        export PAGE_BUFFER_NAME=\"page\"\n    else\n        WORDS=(${1// *|*})\n        export PAGE_BUFFER_NAME=\"${WORDS[@]:0:2}\"\n    fi\n}\n```\n\n## Buffer defaults (pager)\n\n\n\u003cdetails\u003e\u003csummary\u003e expand \u003c/summary\u003e\n\nThese commands are run on each `page` buffer creation:\n\n```lua\nvim.b.page_alternate_bufnr = {$initial_buf_nr}\nif vim.wo.scrolloff \u003e 999 or vim.wo.scrolloff \u003c 0 then\n    vim.g.page_scrolloff_backup = 0\nelse\n    vim.g.page_scrolloff_backup = vim.wo.scrolloff\nend\nvim.bo.scrollback, vim.wo.scrolloff, vim.wo.signcolumn, vim.wo.number =\n    100000, 999, 'no', false\n{$filetype}\n{$edit}\nvim.api.nvim_create_autocmd('BufEnter', {\n    buffer = 0,\n    callback = function() vim.wo.scrolloff = 999 end\n})\nvim.api.nvim_create_autocmd('BufLeave', {\n    buffer = 0,\n    callback = function() vim.wo.scrolloff = vim.g.page_scrolloff_backup end\n})\n{$notify_closed}\n{$pre}\nvim.cmd 'silent doautocmd User PageOpen | redraw'\n{$lua_provided_by_user}\n{$cmd_provided_by_user}\n{$after}\n```\n\nWhere:\n\n```lua\n--{$initial_buf_nr}\n-- Is always set on all buffers created by page\n\n'number of parent :term buffer or -1 when page isn't spawned from :term'\n```\n\n```lua\n--{$filetype}\n-- Is set only on output buffers.\n-- On files buffers filetypes are detected automatically.\n\nvim.bo.filetype='value of -t argument or \"pager\"'\n```\n\n```lua\n--{$edit}\n-- Is appended when no -w option provided\n\nvim.bo.modifiable = false\n_G.page_echo_notification = function(message)\n    vim.defer_fn(function()\n        local msg = \"-- [PAGE] \" .. message .. \" --\"\n        vim.api.nvim_echo({{ msg, 'Comment' }, }, false, {})\n        vim.cmd 'au CursorMoved \u003cbuffer\u003e ++once echo'\n    end, 64)\nend\n_G.page_bound = function(top, message, move)\n    local row, col, search\n    if top then\n        row, col, search = 1, 1, { '\\\\S', 'c' }\n    else\n        row, col, search = 9999999999, 9999999999, { '\\\\S', 'bc' }\n    end\n    vim.api.nvim_call_function('cursor', { row, col })\n    vim.api.nvim_call_function('search', search)\n    if move ~= nil then move() end\n    _G.page_echo_notification(message)\nend\n_G.page_scroll = function(top, message)\n    vim.wo.scrolloff = 0\n    local move\n    if top then\n        local key = vim.api.nvim_replace_termcodes('z\u003cCR\u003eM', true, false, true)\n        move = function() vim.api.nvim_feedkeys(key, 'nx', true) end\n    else\n        move = function() vim.api.nvim_feedkeys('z-M', 'nx', false) end\n    end\n    _G.page_bound(top, message, move)\n    vim.wo.scrolloff = 999\nend\n_G.page_close = function()\n    local buf = vim.api.nvim_get_current_buf()\n    if buf ~= vim.b.page_alternate_bufnr and\n        vim.api.nvim_buf_is_loaded(vim.b.page_alternate_bufnr)\n    then\n        vim.api.nvim_set_current_buf(vim.b.page_alternate_bufnr)\n    end\n    vim.api.nvim_buf_delete(buf, { force = true })\n    local exit = true\n    for _, b in ipairs(vim.api.nvim_list_bufs()) do\n        local bt = vim.api.nvim_buf_get_option(b, 'buftype')\n        if bt == \"\" or bt == \"acwrite\" or bt == \"terminal\" or bt == \"prompt\" then\n            local bm = vim.api.nvim_buf_get_option(b, 'modified')\n            if bm then\n                exit = false\n                break\n            end\n            local bl = vim.api.nvim_buf_get_lines(b, 0, -1, false)\n            if #bl ~= 0 and bl[1] ~= \"\" and #bl \u003e 1 then\n                exit = false\n                break\n            end\n        end\n    end\n    if exit then\n        vim.cmd \"qa!\"\n    end\nend\nlocal function page_map(key, expr)\n    vim.api.nvim_buf_set_keymap(0, '', key, expr, { nowait = true })\nend\npage_map('I', '\u003cCMD\u003elua _G.page_scroll(true, \"in the beginning of scroll\")\u003cCR\u003e')\npage_map('A', '\u003cCMD\u003elua _G.page_scroll(false, \"at the end of scroll\")\u003cCR\u003e')\npage_map('i', '\u003cCMD\u003elua _G.page_bound(true, \"in the beginning\")\u003cCR\u003e')\npage_map('a', '\u003cCMD\u003elua _G.page_bound(false, \"at the end\")\u003cCR\u003e')\npage_map('q', '\u003cCMD\u003elua _G.page_close()\u003cCR\u003e')\npage_map('u', '\u003cC-u\u003e')\npage_map('d', '\u003cC-d\u003e')\npage_map('x', 'G')\n```\n\n```lua\n--{$notify_closed}\n-- Is set only on output buffers\n\nlocal closed = 'rpcnotify({channel}, \"page_buffer_closed\", \"{page_id}\")'\nvim.api.nvim_create_autocmd('BufDelete', {\n    buffer = 0,\n    command = 'silent! call ' .. closed\n})\n```\n\n```lua\n--{$pre}\n-- Is appended when -q provided\n\nvim.b.page_query_size = {$query_lines_count}\nlocal def_args = '{channel}, \"page_fetch_lines\", \"{page_id}\", '\nlocal def = 'command! -nargs=? Page call rpcnotify(' .. def_args .. '\u003cargs\u003e)'\nvim.cmd(def)\nvim.api.create_autocmd('BufEnter', {\n    buffer = 0,\n    command = def,\n})\n\n-- Also if -q provided and no -w provided\n\npage_map('r', '\u003cCMD\u003ecall rpcnotify(' .. def_args .. 'b:page_query_size * v:count1)\u003cCR\u003e')\npage_map('R', '\u003cCMD\u003ecall rpcnotify(' .. def_args .. '99999)\u003cCR\u003e')\n\n-- If -P provided ({pwd} is $PWD value)\n\nvim.b.page_lcd_backup = getcwd()\nvim.cmd 'lcd {pwd}'\nvim.api.nvim_create_autocmd('BufEnter', {\n    buffer = 0,\n    command = 'lcd {pwd}'\n})\nvim.api.nvim_create_autocmd('BufLeave', {\n    buffer = 0,\n    command = 'exe \"lcd\" . b:page_lcd_backup'\n})\n```\n\n```lua\n--{$lua_provided_by_user}\n-- Is appended when --e provided\n\n'value of --e flag'\n```\n\n```lua\n--{$cmd_provided_by_user}\n-- Is appended when -e provided\n\nvim.cmd [====[{$command}]====]\n```\n\n```lua\n--{$after}\n-- Is appended only on file buffers\n\nvim.api.nvim_exec_autocmds('User', {\n    pattern = 'PageOpenFile',\n})\n```\n\n\u003c/details\u003e\n\n## Limitations (pager)\n\n* Only ~100000 lines can be displayed (that's neovim terminal limit)\n* No reflow: text that doesnt't fit into window will be lost on resize  ([due to data structures inherited from vim](https://github.com/neovim/neovim/issues/2514#issuecomment-580035346))\n\n## Installation\n\n* From binaries\n  * Grab binary for your platform from [releases](https://github.com/I60R/page/releases) (currently Linux and OSX are supported)\n\n* Arch Linux:\n  * Package [page-git](https://aur.archlinux.org/packages/page-git/) is available on AUR\n  * Or: `git clone git@github.com:I60R/page.git \u0026\u0026 cd page \u0026\u0026 makepkg -ef \u0026\u0026 sudo pacman -U page-git*.pkg.tar.xz`\n\n* Homebrew:\n  * Package [page](https://formulae.brew.sh/formula/page) is available on [Homebrew](https://brew.sh/)\n\n* Manually:\n  * Install `rustup` from your distribution package manager\n  * Configure toolchain: `rustup install stable \u0026\u0026 rustup default stable`\n  * `git clone git@github.com:I60R/page.git \u0026\u0026 cd page \u0026\u0026 cargo install --path .`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fi60r%2Fpage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fi60r%2Fpage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fi60r%2Fpage/lists"}