{"id":15637483,"url":"https://github.com/milescranmer/vim-stream","last_synced_at":"2025-04-14T13:10:36.920Z","repository":{"id":22116245,"uuid":"95345200","full_name":"MilesCranmer/vim-stream","owner":"MilesCranmer","description":"vims - use vim like sed","archived":false,"fork":false,"pushed_at":"2024-01-05T08:13:28.000Z","size":86,"stargazers_count":111,"open_issues_count":4,"forks_count":8,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-07T07:21:51.170Z","etag":null,"topics":["awk","ex","regex","sed","stdin","text-processing","unix-command","unix-pipes","vim","vim-stream","vims"],"latest_commit_sha":null,"homepage":"","language":"Shell","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/MilesCranmer.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-06-25T07:30:33.000Z","updated_at":"2025-02-01T11:29:50.000Z","dependencies_parsed_at":"2024-01-05T05:23:29.178Z","dependency_job_id":"5d0896ff-dc4c-4a9e-bfc7-b9ea957d7117","html_url":"https://github.com/MilesCranmer/vim-stream","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MilesCranmer%2Fvim-stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MilesCranmer%2Fvim-stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MilesCranmer%2Fvim-stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MilesCranmer%2Fvim-stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MilesCranmer","download_url":"https://codeload.github.com/MilesCranmer/vim-stream/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248886327,"owners_count":21177643,"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":["awk","ex","regex","sed","stdin","text-processing","unix-command","unix-pipes","vim","vim-stream","vims"],"created_at":"2024-10-03T11:11:48.312Z","updated_at":"2025-04-14T13:10:36.348Z","avatar_url":"https://github.com/MilesCranmer.png","language":"Shell","readme":"# vims \n\n[![CI](https://github.com/MilesCranmer/vim-stream/actions/workflows/CI.yml/badge.svg)](https://github.com/MilesCranmer/vim-stream/actions/workflows/CI.yml) [![Codecov branch](https://img.shields.io/codecov/c/github/MilesCranmer/vim-stream/master.svg)](https://codecov.io/gh/MilesCranmer/vim-stream)\n\n![Demo](https://i.imgur.com/dntK3MP.gif)\n\n\nEver wish you could simply apply a vim command to every line\nin a command output automatically?\nIf you use vim as your primary editor, this is likely much much easier\nthan having to look up sed commands every time you filter a command output.\n\nE.g., `cat file.txt | vims -l 'f|d$'` will go through every line, and run \"f|d$\",\nwhich is the vim command for deleting every character after \"|\". \nSee below for many other useful features.\n\n# Install \n\n1. Download the file [`vims`](https://raw.githubusercontent.com/MilesCranmer/vim-stream/master/vims)\n2. Put this file somewhere on your `PATH` environment variable, such as `/usr/bin` or `$HOME/.local/bin`\n3. Make it executable with `chmod +x vims`. That's it!\n\n\n# Usage\n\n`... | vims [...]`\n- (default) `-t [EX_CMD]` Ex mode. Works as if you typed \":\" in vim.\n- `-s [CMD]` Simple command mode. Starts on the first line in command mode (e.g., `x` deletes a char).\n- `-l [CMD]` Line command mode. Runs the command on every line. \n- `-e [REGEX] [CMD]` Exe mode. Runs the command on every line matching `REGEX` (uses vim regex).\n- `-r [REGEX] [CMD]` Inverse exe mode. Runs the command on every line not matching `REGEX` (uses vim regex).\n- `-n` quiet. Don't print lines to stdout. You will then have to use `:p` command to print manually.\n- `-h` help. Print this documentation.\n\nNote that for commands, you can write `\\\u003cesc\u003e` to hit the escape key, or `\\\u003cc-o\u003e` to hit ctrl-O.\n\n```\n{command} | vims [-n|--quiet]\n                 [-e|--exe-mode] [-r|--inverse-exe-mode]\n                 [-s|--simple-mode] [-l|--line-exe-mode]\n                 [-t|--turn-off-mode]\n                 [-h|--help]\n                 [ \u003cargs\u003e... ]\n```\n\nCall `vims` on piped input, providing a list of arguments that you\nwould use in vim command-line mode. All lines not deleted are printed\nby default, but you can turn this off with a `-n|--quiet` flag.\n\n## Discussion:\n\nTrigger \"exe\" mode using the `-e|--exe-mode` flag, which creates macros\nfor `'%g/$1/exe \"norm $2\"'` (see [the power of `:g`](http://vim.wikia.com/wiki/Power_of_g)),\nwhere `$1` is the first arg of a pair,\nand `$2` is the last arg of a pair. This lets you type non-text characters,\nlike `\\\u003cesc\u003e`, `\\\u003cc-o\u003e`, etc.\n\nLikewise, `-l|--line-exe-mode` translates to `%g/.*/exe \"norm$1\"`, meaning\nit executes a command on ALL lines.\n\nInverse exe mode is done with the `-r|--inverse-exe-mode` flag, which\ndoes the same as exe mode, but only on lines NOT matching the regex.\n\nUse simple mode with the `-s|--simple-mode` flag, which is as vanilla\nas it gets. This translates every passed argument to: `exe \"norm $1\"`, meaning\nthat you can run commands just like you opened the editor, starting\nat line 1. Use the same backslashes (`\\\u003center\u003e`) as you do for exe mode.\n\nModes are activated for all the proceeding args. You can switch\nmodes partway, by calling the flag for the other mode you want, or you\ncan turn off any activated mode with `-t|--turn-off-mode`.\n\n## Example 1\nDelete lines 10-15, and print the remainder:\n\n```bash\ncat myfile.txt | vims '10,15d'\n```\n\n- `10,15` - A range from 10-15 - see `:help :range` in vim for a huge number of options.\n- `d` - The delete (from ex) command - see `:help :d` in vim.\n\n## Example 2\nDelete blank lines, then lower-case everything:\n\n```bash\ncat mylog.log | vims -e '^\\s*$' 'dd' '.' 'Vu'\n```\n\n- `-e` - Turn on exe mode\n- `^\\s*$` - Line only containing whitespace\n- `dd` - Delete it.\n- `.` - Line containing anything (Every pair of arguments triggers a new `exe` command)\n- `Vu` - Select the line, then lower-case all alphabetical characters\n\nOr, with line exe mode (a shorthand for `.*`):\n\n```bash\ncat mylog.log | vims -e '^\\s*$' 'dd' -l 'Vu'\n```\n\n- `-l` - Turn off exe mode, turn on line exe mode\n\n## Example 3\n\nAdd a comment (`#`) on every line NOT containing foo:\n\n```bash\ncat script.sh | vims -r 'foo' 'A # Comment'\n```\n\n- `-r` - Work on all lines not matching regex\n- `foo` - Match all lines with the word \"foo\"\n- `A # Comment` - At the end of the line, type \" # Comment\"\n\n## Example 4\n\nDelete all modifications to files in a git repo:\n\n```bash\ngit status | vims '1,/modified/-1d' '$?modified?,$d' -l 'df:dw' | xargs git checkout --\n```\n\n- `git status` - View which files are modified\n- `vims` - Start vims in normal mode\n- `1,/modified/-1d` - Delete all lines up to the first line with \"modified\"\n- `$?modified?+1,$d` - Delete all lines from below the last line with \"modified\"\n- `-l` - Turn on line exe mode (execute a command on each line)\n- `df:dw` - Delete until the \":\", then delete the white space\n- `xargs git checkout --` - Pass all the filenames to `git checkout --`\n\n## Example 5\n\nMove all Python classes to the bottom of a file:\n```bash\ncat myscript.py | vims -e '^class' 'V/^\\\\S\\\u003center\u003ekdGp'\n```\n\n- `'^class' 'V/^\\\\S\\\u003center\u003ekdGp'` becomes `'%g/^class/exe \"norm V/^\\S\\\u003center\u003ekdGp\"'`\n     - `%g/^class/` - Every line starting with \"class\"\n     - `exe` - Execute the following, including escaped sequences (so you can call `\\\u003cc-o\u003e` to mean Ctrl-o)\n     - `norm V/^\\S\\\u003center\u003ekdGp` Enter normal mode, visual select to the next zero-indentation line, move up a line, delete, paste it at the bottom \n     \n## Example 6\n\nOnly print the last 6 lines (just like tail)\n\n```bash\ncat txt | vims -n '$-5,$p'\n```\n- `-n` - Don't print all lines automatically\n- `$-5,$` - A range extending from 6th last line to the last line\n- `p` - Print\n\n## Example 7\n\nReplace all multi-whitespace sequences with a single space:\n\n```bash\ncat txt | vims '%s/\\s\\+/ /g'\n```\n\nWhich can also be done in exe mode:\n\n```bash\ncat txt | vims -e '.' ':s/\\\\s\\\\+/ /g\\\u003center\u003e'\n```\n\nNote the double back-slashes needed (only in the second string of a pair in an exe command!)\nwhen you are typing a character like `\\s`, but not like `\\\u003center\u003e`.\n\n## Example 8\nResolve all git conflicts by deleting the changes on HEAD (keep the bottom code):\n\n```bash\ncat my_conflict.cpp | vims -e '^=======$' 'V?^\u003c\u003c\u003c\u003c\u003c\u003c\u003c \\\u003center\u003ed' -t '%g/^\u003e\u003e\u003e\u003e\u003e\u003e\u003e /d'\n```\n\n- `-e` - Turn on exe mode\n- `^=======$` - Match the middle bit of a git conflict\n- `V?^\u003c\u003c\u003c\u003c\u003c\u003c\u003c \\\u003center\u003ed` - Highlight the line, backward search to the top of the conflict, delete it.\n- `-t` - Turn off exe mode\n- `%g/^\u003e\u003e\u003e\u003e\u003e\u003e\u003e /d` - Delete remaining conflict lines\n\n\n## Example 9\n\nUncomment all commented-out lines (comment char: `#`)\n\n```bash\ncat script.sh | vims -e '^\\s*#' '^x'\n```\n\n- `^\\s*#` - Work on lines with whitespace followed by a comment char, followed by anything\n- `^x` - Go to the first non-whitespace character, and delete it\n\n## Example 10\n\n\nDelete the first word of each line and put it at the end:\n\n```bash\ncat script.sh | vims -e '^[A-Za-z]' '\\\"kdwA \\\u003cesc\u003e\\\"kp'\n```\n\n- `^[A-Za-z]` - Only work on lines that start with an alphabetical character\n- `\\\"kdw` - Delete the word under the cursor and put it in register `k`\n- `A \\\u003cesc\u003e` - Start insert mode at front of line, type a space, hit escape key\n- `\\\"kp` - Paste from the register `k`\n\n## Example 11\n\nRun a super-vanilla long chain of commands in simple mode, starting from line 1 of a file:\n\n```bash\ncat python.py | vims -s '/^class\\\u003center\u003eO# This class broke\\\u003cesc\u003eGo\\\u003center\u003e# This file broke'\n```\n\n- `/^class\\\u003center\u003e` - Find the first class, and go to it\n- `O# This class broke` - Type above it: \"# This class broke\"\n- `\\\u003cesc\u003eGo\\\u003center\u003e` - Back to normal mode, make two blank lines at end of file\n- `# This file broke'` - Write at the end of the file: \"# This file broke\"\n\n\n## Example 12\n\nReverse a file:\n\n```bash\ncat text.txt | vims '%g/.*/m0'\n```\n\n- `%g` - Work on all lines that match a pattern\n- `.*` - Matches all lines\n- `m0` - Move line to start of file\n\n## Example 13\n\nSort the output of `ls -l` by file size, using the\nunix command `sort` (which you can use inside vim):\n\n```bash\nls -l | vims '1d' '%!sort -k5n'\n```\n\n- `1d` - Delete the first line of `ls -l`\n- `%!` - Call the following external command on all lines\n- `sort` - The unix sort command\n- `-k5n` - Sort by column 5, numerically\n\n## Example 14\n\nFind matching parentheses for a function call (something `sed` and other regexp tools can't do),\nand replace only those parentheses with square brackets:\n\n```bash\n\u003e echo \"0.9 * (sqrt(3.9 * (0.8 - 0.2)) / 20.0)\" | vims -e 'sqrt(' '/sqrt(\\\u003center\u003ef(lvh%hxhi[]\\\u003cesc\u003eP' -t '%s/]()/]/g'\n0.9 * (sqrt[3.9 * (0.8 - 0.2)] / 20.0)\n```\n\n- `-e 'sqrt('` - Only run this vim command on matching lines\n- `/sqrt(\\\u003center\u003e` - In vim, hit `/` to start a forward search, then search for \"sqrt(\" and go to the first match\n- `f(` - From the first character of \"sqrt\", go to the open bracket\n- `lv` - Move right, so we are inside the \"sqrt\". Start visually selecting.\n- `h%` - Move back left to the open bracket, and use vim's `%` command to move to the matching closing bracket\n- `hx` - Move left, so we are inside the \"sqrt\" (but now on the far side). Delete the contents (which is saved to the clipboard!)\n- `hi` - Move left, so we are now at the open bracket again.\n- `[]` - Write out `[]` which will be our new square brackets\n- `\\\u003cesc\u003e` - Back to normal mode\n- `P` - Paste the contents into the `[]`\n- `-t '%s/]()/]/g'` - This is a new command which simply cleans up the `()`\n\n# Credit\n\nThe heart of this script comes from a Google groups posting:\n[posting](https://groups.google.com/forum/#!msg/vim_use/NfqbCdUkDb5/Ir0faiNaFZwJ),\nand then from an answer on [SO](https://stackoverflow.com/questions/44745046/bash-pass-all-arguments-exactly-as-they-are-to-a-function-and-prepend-a-flag-on)\n\nThanks!\n\n## TODO\n\n- Find way around vim command limit (only can seem to launch ~8 commands at once to vims - see issue #1)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilescranmer%2Fvim-stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmilescranmer%2Fvim-stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilescranmer%2Fvim-stream/lists"}