├── .gitignore
├── LICENSE
├── README.md
├── assets
├── demo.cast
└── demo.gif
├── go.mod
├── go.sum
├── pathos
└── pathos.go
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | # Misc
18 | pathos.sh
19 | debug.log
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright © 2022 Chip Castle Dot Com, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the “Software”), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pathos - CLI for editing a PATH env variable
2 |
3 | ## Ruby Version
4 |
5 | [chip/pathos.rb](https://github.com/chip/pathos.rb)
6 |
7 | ## Go Version
8 |
9 | This is the Go version.
10 |
11 | ## Background
12 |
13 | If you're like me, you might have a number of `export PATH` statements
14 | littering your shell resource file (e.g., `.zshrc`, `.bashrc`, etc). Over time,
15 | many directory entries get added and revised. Those that remain eventually
16 | become unnecessary, are mistakenly duplicated, or represent directories that no
17 | longer exist on the system. This is my attempt at cleaning up `PATH`
18 | environment variable. Hopefully, others will find this to be useful.
19 |
20 | ## Demo
21 |
22 | 
23 |
24 | ### Built with the following:
25 |
26 | * [Go](https://go.dev/)
27 | * [Bubble Tea](https://github.com/charmbracelet/bubbletea)
28 | * [Bubbles](https://github.com/charmbracelet/bubbles)
29 | * [Lip Gloss](https://github.com/charmbracelet/lipgloss)
30 |
31 | ## Installation
32 | go install github.com/chip/pathos@latest
33 |
34 | ## IMPORTANT
35 |
36 | Be sure to save your changes with `S` *(uppercase letter S)* before quitting
37 | `pathos`, as **changes will not be saved automatically**.
38 |
39 | Each time you save your changes to the directory list, `pathos` will build a
40 | revised `export $PATH` statement that is written to `$HOME/pathos.sh`.
41 |
42 | To use the new PATH, `~/pathos.sh` **MUST BE SOURCED** to take effect within your
43 | shell.
44 |
45 | source $HOME/pathos.sh
46 |
47 | ## Navigation
48 |
49 | Like any typical [Bubble Tea](https://github.com/charmbracelet/bubbletea) app,
50 | you have the following keys that are available for navigation:
51 |
52 | Key | Description
53 | ---|---
54 | k | Move up the list of directories
55 | j | Move down the list of directories
56 | l | Move to the next page
57 | h | Move to the previous page
58 | g/home | Move to the top of the list
59 | G/end | Move to the end of the list
60 | q | Quit pathos **(does NOT save changes)**
61 | ? | Toggle between regular and full help
62 |
63 | ## Commands
64 |
65 | Key | Description
66 | ---|---
67 | N | Add a new directory to the list at the current cursor position
68 | D | Delete a directory at the current cursor position
69 | S | Save all changes made to the list of directories
70 |
71 | ## Color Highlighting
72 |
73 | Color | Description
74 | ---|---
75 | Yellow | Shows current cursor position
76 | Red | Indicates directories that **do not exist**
77 | Aqua | Indicates duplicate directories
78 |
--------------------------------------------------------------------------------
/assets/demo.cast:
--------------------------------------------------------------------------------
1 | {"version": 2, "width": 130, "height": 37, "timestamp": 1658958487, "env": {"SHELL": "/bin/zsh", "TERM": "screen"}}
2 | [0.231236, "o", "\u001b]0;~\u0007"]
3 | [0.238591, "o", "\r\n"]
4 | [0.239073, "o", "\u001b[0m\u001b[23m\u001b[24m\u001b[J\u001b[34m~\u001b[39m\r\n\r\u001b[35m❯\u001b[39m \u001b[K\u001b[?2004h"]
5 | [0.855894, "o", "p"]
6 | [1.255468, "o", "\bpa"]
7 | [1.52025, "o", "t"]
8 | [1.708333, "o", "h"]
9 | [1.914453, "o", "o"]
10 | [2.177444, "o", "s"]
11 | [3.898204, "o", "\u001b[?2004l\r\r\n"]
12 | [3.898502, "o", "\u001b]0;chip: pathos\u0007"]
13 | [3.913634, "o", "\u001b[?25l"]
14 | [3.914511, "o", "\u001b[?1049h\u001b[0;0H"]
15 | [3.931985, "o", " PATHOS - CLI Manager of the PATH env variable \r\r\n \r\r\n \u001b[38;2;119;119;119m53 items\u001b[0m \r\r\n \r\r\n \u001b[93m> /Users/chip/.luarocks/bin\u001b[0m \r\r\n /Users/chip/perl5/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin \r\r\n /usr/local/opt/openssl@1.1/bin \r\r\n /usr/local/opt/openssl/bin \r\r\n /Users/chip/.rbenv/shims \r\r\n \u001b[96m/Users/chip/bin\u001b[0m \r\r\n ./bin \r\r\n \u001b[91m/usr/X11/bin"]
16 | [3.932511, "o", "\u001b[0m \r\r\n /usr/local/bin \r\r\n /usr/local/sbin \r\r\n \u001b[91m/usr/local/git/bin\u001b[0m \r\r\n /bin \r\r\n /usr/bin \r\r\n /sbin \r\r\n /usr/sbin \r\r\n \u001b[96m/Users/chip/bin\u001b[0m \r\r\n /usr/local/opt/ruby/bin \r\r\n \u001b[91m/Users/chip/.gem/ruby/2.6.0/cache\u001b[0m \r\r\n \u001b[91m/opt/local/bin\u001b[0m \r\r\n \u001b[91m/opt/local/sbin\u001b[0m \r\r\n /Users/chip/code/go/bin "]
17 | [3.932742, "o", " \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n \r\r\n \u001b[38;2;151;151;151m•\u001b[0m\u001b[38;2;60;60;60m•\u001b[0m \r\r\n \r\r\n \u001b[38;2;97;97;97m↑/k\u001b[0m \u001b[38;2;73;73;73mup\u001b[0m\u001b[38;2;60;60;60m • \u001b[0m\u001b[38;2;97;97;97m↓/j\u001b[0m \u001b[38;2;73;73;73mdown\u001b[0m\u001b[38;2;60;60;60m • \u001b[0m\u001b[38;2;97;97;97mN\u001b[0m \u001b[38;2;73;73;73mnew\u001b[0m\u001b[38;2;60;60;60m • \u001b[0m\u001b[38;2;97;97;97mD\u001b[0m \u001b[38;2;73;73;73mdelete\u001b[0m\u001b[38;2;60;60;60m • \u001b[0m\u001b[38;2;97;97;97mS\u001b[0m \u001b[38;2;73;73;73msave paths\u001b[0m\u001b[38;2;60;60;60m • \u001b[0m\u001b[38;2;97;97;97mq\u001b[0m \u001b[38;2;73;73;73mquit\u001b["]
18 | [3.93318, "o", "0m\u001b[38;2;60;60;60m • \u001b[0m\u001b[38;2;97;97;97m?\u001b[0m \u001b[38;2;73;73;73mmore\u001b[0m\u001b[35;0H"]
19 | [5.282009, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B /Users/chip/.luarocks/bin \r\r\n \u001b[93m> /Users/chip/perl5/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
20 | [5.481361, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B /Users/chip/perl5/bin \r\r\n \u001b[93m> /Users/chip/.npm-packages/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
21 | [5.684106, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /Users/chip/.npm-packages/bin \r\r\n \u001b[93m> /usr/local/opt/python@3.8/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
22 | [5.850707, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/local/opt/python@3.8/bin \r\r\n \u001b[93m> /usr/local/opt/openssl@1.1/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
23 | [6.031715, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/local/opt/openssl@1.1/bin \r\r\n \u001b[93m> /usr/local/opt/openssl/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
24 | [6.218064, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/local/opt/openssl/bin \r\r\n \u001b[93m> /Users/chip/.rbenv/shims\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
25 | [6.382554, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /Users/chip/.rbenv/shims \r\r\n \u001b[93m> /Users/chip/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
26 | [7.098561, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B \u001b[38;2;119;119;119m52 items\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[93m> ./bin\u001b[0m \r\r\n \u001b[91m/usr/X11/bin\u001b[0m \r\r\n /usr/local/bin \r\r\n /usr/local/sbin \r\r\n \u001b[91m/usr/local/git/bin\u001b[0m \r\r\n /bin \r\r\n /usr/bin \r\r\n /sbin "]
27 | [7.098824, "o", " \r\r\n /usr/sbin \r\r\n /Users/chip/bin \r\r\n /usr/local/opt/ruby/bin \r\r\n \u001b[91m/Users/chip/.gem/ruby/2.6.0/cache\u001b[0m \r\r\n \u001b[91m/opt/local/bin\u001b[0m \r\r\n \u001b[91m/opt/local/sbin\u001b[0m \r\r\n /Users/chip/code/go/bin \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
28 | [7.732753, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B ./bin \r\r\n \u001b[91m> /usr/X11/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
29 | [8.681979, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B \u001b[38;2;119;119;119m51 items\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[93m> /usr/local/bin\u001b[0m \r\r\n /usr/local/sbin \r\r\n \u001b[91m/usr/local/git/bin\u001b[0m \r\r\n /bin \r\r\n /usr/bin \r\r\n /sbin \r\r\n /usr/sbin \r\r\n /Users/chip/bin "]
30 | [8.682233, "o", " \r\r\n /usr/local/opt/ruby/bin \r\r\n \u001b[91m/Users/chip/.gem/ruby/2.6.0/cache\u001b[0m \r\r\n \u001b[91m/opt/local/bin\u001b[0m \r\r\n \u001b[91m/opt/local/sbin\u001b[0m \r\r\n /Users/chip/code/go/bin \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
31 | [9.0475, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/local/bin \r\r\n \u001b[93m> /usr/local/sbin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
32 | [9.218234, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/local/sbin \r\r\n \u001b[91m> /usr/local/git/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
33 | [9.684537, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B \u001b[38;2;119;119;119m50 items\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[93m> /bin\u001b[0m \r\r\n /usr/bin \r\r\n /sbin \r\r\n /usr/sbin \r\r\n /Users/chip/bin \r\r\n /usr/local/opt/ruby/bin \r\r\n \u001b[91m/Users/chip/.gem/ruby/2.6.0/cache\u001b[0m \r\r\n \u001b[91m/opt/local/bin\u001b[0m "]
34 | [9.68479, "o", " \r\r\n \u001b[91m/opt/local/sbin\u001b[0m \r\r\n /Users/chip/code/go/bin \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin \r\r\n \u001b[91m/usr/local/opt/qt@5.5/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
35 | [11.148407, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /bin \r\r\n \u001b[93m> /usr/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
36 | [11.348015, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/bin \r\r\n \u001b[93m> /sbin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
37 | [11.48167, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /sbin \r\r\n \u001b[93m> /usr/sbin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
38 | [11.665341, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/sbin \r\r\n \u001b[93m> /Users/chip/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
39 | [11.833678, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /Users/chip/bin \r\r\n \u001b[93m> /usr/local/opt/ruby/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
40 | [12.000552, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B /usr/local/opt/ruby/bin \r\r\n \u001b[91m> /Users/chip/.gem/ruby/2.6.0/cache\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
41 | [12.501855, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B \u001b[38;2;119;119;119m49 items\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[91m> /opt/local/bin\u001b[0m \r\r\n \u001b[91m/opt/local/sbin\u001b[0m \r\r\n /Users/chip/code/go/bin \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin "]
42 | [12.502152, "o", " \r\r\n /usr/local/opt/python@3.8/bin \r\r\n \u001b[91m/usr/local/opt/qt@5.5/bin\u001b[0m \r\r\n /usr/local/opt/openssl/bin \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
43 | [12.965198, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B \u001b[38;2;119;119;119m48 items\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[91m> /opt/local/sbin\u001b[0m \r\r\n /Users/chip/code/go/bin \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin "]
44 | [12.96548, "o", " \r\r\n \u001b[91m/usr/local/opt/qt@5.5/bin\u001b[0m \r\r\n /usr/local/opt/openssl/bin \r\r\n \u001b[91m/usr/local/heroku/bin\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
45 | [13.130925, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B \u001b[38;2;119;119;119m47 items\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[93m> /Users/chip/code/go/bin\u001b[0m \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin \r\r\n \u001b[91m/usr/local/opt/qt@5.5/bin\u001b[0m "]
46 | [13.131149, "o", " \r\r\n /usr/local/opt/openssl/bin \r\r\n \u001b[91m/usr/local/heroku/bin\u001b[0m \r\r\n /Users/chip/perl5/bin \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
47 | [16.432181, "o", "\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n \r\r\n \u001b[38;2;119;119;119m47 items\u001b[0m \r\r\n \r\r\n /Users/chip/.luarocks/bin \r\r\n /Users/chip/perl5/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin \r\r\n /usr/local/opt/openssl@1.1/bin \r\r\n /usr/local/opt/openssl/bin \r\r\n /Users/chip/.rbenv/shims \r\r\n ./bin "]
48 | [16.432475, "o", " \r\r\n /usr/local/bin \r\r\n /usr/local/sbin \r\r\n /bin \r\r\n /usr/bin \r\r\n /sbin \r\r\n /usr/sbin \r\r\n /Users/chip/bin \r\r\n /usr/local/opt/ruby/bin \r\r\n \u001b[93m> /Users/chip/code/go/bin\u001b[0m \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n \r\r\n \u001b[38;2;151;151;151m•\u001b[0m\u001b[38;2;60;60;60m•\u001b[0m\u001b[38;2;60;60;60m•\u001b[0m "]
49 | [16.432781, "o", " \r\r\n \r\r\n \u001b[38;2;97;97;97m↑/k\u001b[0m \u001b[38;2;97;97;97m \u001b[0m\u001b[38;2;73;73;73mup\u001b[0m \u001b[38;2;60;60;60m \u001b[0m\u001b[38;2;97;97;97mN\u001b[0m\u001b[38;2;97;97;97m \u001b[0m\u001b[38;2;73;73;73mnew\u001b[0m \u001b[38;2;60;60;60m \u001b[0m\u001b[38;2;97;97;97mq\u001b[0m\u001b[38;2;97;97;97m \u001b[0m\u001b[38;2;73;73;73mquit\u001b[0m \u001b[38;2;60;60;60m \u001b[0m\r\r\n \u001b[38;2;97;97;97m↓/j\u001b[0m \u001b[38;2;73;73;73mdown\u001b[0m \u001b[38;2;97;97;97mD\u001b[0m \u001b[38;2;73;73;73mdelete\u001b[0m \u001b[38;2;97;97;97m?\u001b[0m \u001b[38;2;73;73;73mclose help\u001b[0m \r\r\n \u001b[38;2;97;97;97m→/l/pgdn\u001b[0m \u001b[38;2;73;73;73mnext page\u001b[0m \u001b[38;2;97;97;97mS\u001b[0m \u001b[38;2;73;73;73msave paths\u001b[0m \r\r\n \u001b[38;2;97;97;97m←/h/pgup\u001b[0m \u001b[38;2;73;73;73mprev page\u001b[0m \r\r\n \u001b[38;2;97;97;97mg/home\u001b[0m \u001b[38;2;73;73;73mgo to start\u001b[0m \r\r\n \u001b[38;2;97;97;97mG/end\u001b[0m \u001b[38;2;73;73;73mgo to end\u001b[0m "]
50 | [16.433057, "o", " \u001b[35;0H"]
51 | [19.498231, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B /Users/chip/code/go \r\r\n /usr/local/opt/fzf/bin \r\r\n \u001b[93m> /Users/chip/n/bin\u001b[0m \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n "]
52 | [19.498408, "o", " \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n \r\r\n\u001b[1B \u001b[38;2;60;60;60m•\u001b[0m\u001b[38;2;60;60;60m•\u001b[0m\u001b[38;2;151;151;151m•\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
53 | [20.46679, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B \u001b[93m> /usr/local/opt/fzf/bin\u001b[0m \r\r\n /Users/chip/n/bin \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
54 | [20.849149, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B \u001b[93m> /Users/chip/code/go\u001b[0m \r\r\n /usr/local/opt/fzf/bin \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
55 | [21.265324, "o", "\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[1A\u001b[1A\u001b[1A\u001b[130D\u001b[2K PATHOS - CLI Manager of the PATH env variable \r\r\n\u001b[1B\u001b[1B\u001b[1B \u001b[93m> /Users/chip/.luarocks/bin\u001b[0m \r\r\n /Users/chip/perl5/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n /usr/local/opt/python@3.8/bin \r\r\n /usr/local/opt/openssl@1.1/bin \r\r\n /usr/local/opt/openssl/bin \r\r\n /Users/chip/.rbenv/shims \r\r\n ./bin \r\r\n /usr/local/bin \r\r\n /usr/local/sbin \r\r\n /bin \r\r\n /usr/bin "]
56 | [21.265602, "o", " \r\r\n /sbin \r\r\n /usr/sbin \r\r\n /Users/chip/bin \r\r\n /usr/local/opt/ruby/bin \r\r\n /Users/chip/code/go/bin \r\r\n /Users/chip/Library/Android/sdk/platform-tools \r\r\n /Users/chip/Library/Android/sdk/tools \r\r\n /usr/local/opt/fzf/bin \r\r\n /Users/chip/n/bin \r\r\n /Users/chip/.npm-packages/bin \r\r\n\u001b[1B \u001b[38;2;151;151;151m•\u001b[0m\u001b[38;2;60;60;60m•\u001b[0m\u001b[38;2;60;60;60m•\u001b[0m \r\r\n\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[1B\u001b[35;0H"]
57 | [24.04758, "o", "\u001b[2K\u001b[?1049l\u001b[?1002l\u001b[?1003l\u001b[?25h"]
58 | [24.049996, "o", "\u001b]0;~\u0007"]
59 | [24.052086, "o", "\r\n"]
60 | [24.052329, "o", "\u001b[0m\u001b[23m\u001b[24m\u001b[J\u001b[34m~\u001b[39m \u001b[33m20s\u001b[39m\r\n\r\u001b[35m❯\u001b[39m \u001b[K\u001b[?2004h"]
61 | [25.260657, "o", "b"]
62 | [25.391203, "o", "\bba"]
63 | [25.646255, "o", "t"]
64 | [26.068318, "o", " "]
65 | [27.368184, "o", "~"]
66 | [28.640352, "o", "/"]
67 | [29.600013, "o", "p"]
68 | [29.79521, "o", "a"]
69 | [29.95117, "o", "t"]
70 | [30.014937, "o", "h"]
71 | [30.148022, "o", "o"]
72 | [30.272317, "o", "s"]
73 | [30.604964, "o", "."]
74 | [30.940537, "o", "s"]
75 | [31.066592, "o", "h"]
76 | [31.432928, "o", "\u001b[?2004l\r\r\n"]
77 | [31.433221, "o", "\u001b]0;chip: bat ~/pathos.sh\u0007"]
78 | [31.505658, "o", "\u001b[?1h\u001b=\r"]
79 | [31.505881, "o", "\u001b[38;5;238m───────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[m\r\n \u001b[38;5;238m│ \u001b[0mFile: \u001b[1m/Users/chip/pathos.sh\u001b[0m\u001b[m\r\n\u001b[38;5;238m───────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[m\r\n"]
80 | [31.519844, "o", "\u001b[38;5;238m 1\u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;249;38;114mexport\u001b[0m\u001b[38;2;255;255;255m \u001b[0m\u001b[38;2;255;255;255mPATH\u001b[0m\u001b[38;2;249;38;114m=\u001b[0m\u001b[38;2;230;219;116m/Users/chip/.luarocks/bin:/Users/chip/perl5/bin:/Users/chip/.npm-packages/bin:/usr/local/opt/python@3.8/bin:/\u001b[0m\u001b[m\r\n"]
81 | [31.520203, "o", "\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116musr/local/opt/openssl@1.1/bin:/usr/local/opt/openssl/bin:/Users/chip/.rbenv/shims:./bin:/usr/local/bin:/usr/local/sbin:/b\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116min:/usr/bin:/sbin:/usr/sbin:/Users/chip/bin:/usr/local/opt/ruby/bin:/Users/chip/code/go/bin:/Users/chip/Library/Android/s\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116mdk/platform-tools:/Users/chip/Library/Android/sdk/tools:/usr/local/opt/fzf/bin:/Users/chip/n/bin:/Users/chip/.npm-package\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116ms/bin:/usr/local/opt/python@3.8/bin:/usr/local/opt/qt@5.5/bin:/usr/local/opt/openssl/bin:/usr/local/heroku/bin:/Users/chi\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116mp/perl5/bin:/Users/chip/.rbenv/shims:/Users/chip/.rbenv/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:./bin\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116m:/usr/X11/bin:"]
82 | [31.520305, "o", "/usr/local/bin:/usr/local/sbin:/usr/local/git/bin:/bin:/usr/bin:/sbin:/usr/sbin:/Users/chip/bin:/usr/local/\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116mopt/ruby/bin:/Users/chip/.gem/ruby/2.6.0/cache:/opt/local/bin:/opt/local/sbin:/Users/chip/code/go:/usr/local/opt/fzf/bin:\u001b[0m\u001b[m\r\n\u001b[38;5;238m \u001b[0m \u001b[38;5;238m│\u001b[0m \u001b[38;2;230;219;116m/Users/chip/n/bin\u001b[0m\u001b[m\r\n"]
83 | [31.520335, "o", "\u001b[38;5;238m───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\u001b[m\r\n"]
84 | [31.520523, "o", "\r\u001b[K\u001b[?1l\u001b>"]
85 | [31.532703, "o", "\u001b]0;~\u0007"]
86 | [31.534015, "o", "\r\n"]
87 | [31.534261, "o", "\u001b[0m\u001b[23m\u001b[24m\u001b[J\u001b[34m~\u001b[39m\r\n\r\u001b[35m❯\u001b[39m \u001b[K\u001b[?2004h"]
88 |
--------------------------------------------------------------------------------
/assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chip/pathos/134beafa5971b61f5a59ae1bd85bab05b8709df8/assets/demo.gif
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/chip/pathos
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/charmbracelet/bubbles v0.13.0
7 | github.com/charmbracelet/bubbletea v0.22.0
8 | github.com/charmbracelet/lipgloss v0.5.0
9 | )
10 |
11 | require (
12 | github.com/atotto/clipboard v0.1.4 // indirect
13 | github.com/containerd/console v1.0.3 // indirect
14 | github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
15 | github.com/mattn/go-isatty v0.0.14 // indirect
16 | github.com/mattn/go-runewidth v0.0.13 // indirect
17 | github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
18 | github.com/muesli/cancelreader v0.2.1 // indirect
19 | github.com/muesli/reflow v0.3.0 // indirect
20 | github.com/muesli/termenv v0.12.0 // indirect
21 | github.com/rivo/uniseg v0.2.0 // indirect
22 | github.com/sahilm/fuzzy v0.1.0 // indirect
23 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
24 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
25 | )
26 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
2 | github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
3 | github.com/charmbracelet/bubbles v0.13.0 h1:zP/ROH3wJEBqZWKIsD50ZKKlx3ydLInq3LdD/Nrlb8w=
4 | github.com/charmbracelet/bubbles v0.13.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc=
5 | github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4=
6 | github.com/charmbracelet/bubbletea v0.22.0 h1:E1BTNSE3iIrq0G0X6TjGAmrQ32cGCbFDPcIuImikrUc=
7 | github.com/charmbracelet/bubbletea v0.22.0/go.mod h1:aoVIwlNlr5wbCB26KhxfrqAn0bMp4YpJcoOelbxApjs=
8 | github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
9 | github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8=
10 | github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
11 | github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
12 | github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
13 | github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
14 | github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
15 | github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
16 | github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
17 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
18 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
19 | github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
20 | github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
21 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
22 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
23 | github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
24 | github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
25 | github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
26 | github.com/muesli/cancelreader v0.2.0/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
27 | github.com/muesli/cancelreader v0.2.1 h1:Xzd1B4U5bWQOuSKuN398MyynIGTNT89dxzpEDsalXZs=
28 | github.com/muesli/cancelreader v0.2.1/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
29 | github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
30 | github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
31 | github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
32 | github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
33 | github.com/muesli/termenv v0.11.1-0.20220212125758-44cd13922739/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
34 | github.com/muesli/termenv v0.12.0 h1:KuQRUE3PgxRFWhq4gHvZtPSLCGDqM5q/cYr1pZ39ytc=
35 | github.com/muesli/termenv v0.12.0/go.mod h1:WCCv32tusQ/EEZ5S8oUIIrC/nIuBcxCVqlN4Xfkv+7A=
36 | github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
37 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
38 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
39 | github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
40 | github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
41 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
42 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
43 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
44 | golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
45 | golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
46 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
47 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
48 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
49 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM=
50 | golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
51 |
--------------------------------------------------------------------------------
/pathos:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chip/pathos/134beafa5971b61f5a59ae1bd85bab05b8709df8/pathos
--------------------------------------------------------------------------------
/pathos.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "log"
7 | "os"
8 | "strings"
9 |
10 | "github.com/charmbracelet/bubbles/help"
11 | "github.com/charmbracelet/bubbles/key"
12 | "github.com/charmbracelet/bubbles/list"
13 | "github.com/charmbracelet/bubbles/textinput"
14 | tea "github.com/charmbracelet/bubbletea"
15 | "github.com/charmbracelet/lipgloss"
16 | )
17 |
18 | var duplicatePaths map[string]struct{}
19 |
20 | // this is an enum for Go
21 | type sessionState uint
22 |
23 | const (
24 | listView sessionState = iota
25 | inputView
26 | )
27 |
28 | type savePathMsg struct {
29 | path string
30 | cursor int
31 | }
32 | type deletePathMsg int
33 | type saveShellSourceMsg struct {
34 | m model
35 | }
36 |
37 | type errMsg error
38 |
39 | // TODO Show color legend
40 | const listHeight = 35
41 |
42 | // Colors: https://www.ditig.com/256-colors-cheat-sheet
43 | var (
44 | titleStyle = lipgloss.NewStyle().MarginLeft(2)
45 | itemStyle = lipgloss.NewStyle().PaddingLeft(4)
46 | selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("11")) // Xterm Yellow (SYSTEM)
47 | doesNotExistItemStyle = lipgloss.NewStyle().PaddingLeft(4).Foreground(lipgloss.Color("9")) // Xterm Red (SYSTEM)
48 | selectedAndDoesNotExistItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("9"))
49 | duplicateItemStyle = lipgloss.NewStyle().PaddingLeft(4).Foreground(lipgloss.Color("14")) // Xterm Aqua (SYSTEM)
50 | selectedAndDuplicateItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("14"))
51 | quitTextStyle = lipgloss.NewStyle().Margin(1, 0, 2, 4)
52 | )
53 |
54 | type item string
55 |
56 | func (i item) FilterValue() string { return "" }
57 |
58 | type itemDelegate struct{}
59 |
60 | func (d itemDelegate) Height() int { return 1 }
61 | func (d itemDelegate) Spacing() int { return 0 }
62 | func (d itemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { return nil }
63 | func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
64 |
65 | i, ok := listItem.(item)
66 | if !ok {
67 | return
68 | }
69 | str := string(i)
70 |
71 | fn := itemStyle.Render
72 |
73 | if !directoryExists(str) {
74 | fn = doesNotExistItemStyle.Render
75 | } else if duplicatePath(str) {
76 | fn = duplicateItemStyle.Render
77 | }
78 |
79 | if index == m.Index() {
80 | fn = func(s string) string {
81 | if directoryExists(s) {
82 | return selectedItemStyle.Render("> " + s)
83 | } else if duplicatePath(str) {
84 | return selectedAndDuplicateItemStyle.Render("> " + s)
85 | } else {
86 | return selectedAndDoesNotExistItemStyle.Render("> " + s)
87 | }
88 | }
89 | }
90 |
91 | fmt.Fprint(w, fn(str))
92 | }
93 |
94 | type model struct {
95 | keys HelpKeyMap
96 | help help.Model
97 | list list.Model
98 | items []item
99 |
100 | textInput textinput.Model
101 | msg tea.Msg
102 | err error
103 | state sessionState
104 | showPagination bool
105 | }
106 |
107 | func additionalKeys() []key.Binding {
108 | return []key.Binding{
109 | keys.NewPath,
110 | keys.DeletePath,
111 | keys.SaveShellSource,
112 | }
113 | }
114 |
115 | func initialModel() model {
116 | ti := setupTextInput()
117 |
118 | items := createPaths()
119 | duplicatePaths = findDuplicatePaths(items)
120 |
121 | const defaultWidth = 60
122 |
123 | l := list.New(items, itemDelegate{}, defaultWidth, listHeight)
124 | l.Title = "pathos - CLI for editing a PATH env variable"
125 |
126 | l.SetShowHelp(true)
127 | l.SetShowStatusBar(true)
128 | l.SetFilteringEnabled(false)
129 | l.Styles.Title = titleStyle
130 |
131 | l.AdditionalFullHelpKeys = additionalKeys
132 | l.AdditionalShortHelpKeys = additionalKeys
133 |
134 | m := model{
135 | keys: keys,
136 | help: help.New(),
137 | list: l,
138 | textInput: ti,
139 | err: nil,
140 | state: listView,
141 | showPagination: false,
142 | }
143 | return m
144 | }
145 |
146 | func directoryExists(dir string) bool {
147 | if _, err := os.Stat(dir); os.IsNotExist(err) {
148 | return false
149 | }
150 | return true
151 | }
152 |
153 | func savePathCmd(cursor int, path string) tea.Cmd {
154 | return func() tea.Msg {
155 | return savePathMsg{path: path, cursor: cursor}
156 | }
157 | }
158 |
159 | func deletePathCmd(m model, id int) tea.Cmd {
160 | return func() tea.Msg {
161 | return deletePathMsg(id)
162 | }
163 | }
164 |
165 | func saveShellSourceCmd(m model) tea.Cmd {
166 | return func() tea.Msg {
167 | return saveShellSourceMsg{m: m}
168 | }
169 | }
170 |
171 | func saveShellSource(m model) (int, error) {
172 | s := []string{}
173 | for _, listItem := range m.list.Items() {
174 | i, _ := listItem.(item)
175 | path := string(i)
176 | if path != "" {
177 | s = append(s, path)
178 | }
179 | }
180 | data := "export PATH=" + strings.Join(s, ":")
181 |
182 | HOME := os.Getenv("HOME")
183 | filename := HOME + "/pathos.sh"
184 |
185 | file, err := os.Create(filename)
186 | if err != nil {
187 | return -1, err
188 | }
189 | defer file.Close()
190 |
191 | return file.WriteString(data)
192 | }
193 |
194 | func (m model) Init() tea.Cmd {
195 | return tea.EnterAltScreen
196 | }
197 |
198 | func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
199 | var cmd tea.Cmd
200 | var cmds []tea.Cmd
201 |
202 | switch msg := msg.(type) {
203 | case tea.WindowSizeMsg:
204 | m.list.SetWidth(msg.Width)
205 | return m, nil
206 |
207 | case savePathMsg:
208 | m.list.InsertItem(msg.cursor, item(msg.path))
209 | duplicatePaths = findDuplicatePaths(m.list.Items())
210 | return m, nil
211 |
212 | case deletePathMsg:
213 |
214 | m.list.RemoveItem(int(msg))
215 | duplicatePaths = findDuplicatePaths(m.list.Items())
216 | return m, nil
217 |
218 | case saveShellSourceMsg:
219 | saveShellSource(m)
220 | return m, nil
221 |
222 | case tea.KeyMsg:
223 | switch {
224 |
225 | case key.Matches(msg, keys.Quit):
226 | return m, tea.Quit
227 |
228 | case key.Matches(msg, keys.Enter):
229 |
230 | if m.state == inputView {
231 | text := strings.TrimSpace(m.textInput.Value())
232 | if text != "" {
233 | cursor := m.list.Cursor()
234 | value := m.textInput.Value()
235 | cmds = append(cmds, savePathCmd(cursor, value))
236 | m.state = listView
237 | }
238 | }
239 |
240 | case key.Matches(msg, keys.NewPath):
241 | m.state = inputView
242 | return m, nil
243 |
244 | case key.Matches(msg, keys.DeletePath):
245 | if m.state == listView {
246 | i := m.list.Index()
247 | cmds = append(cmds, deletePathCmd(m, i))
248 | }
249 |
250 | case key.Matches(msg, keys.SaveShellSource):
251 | cmds = append(cmds, saveShellSourceCmd(m))
252 |
253 | }
254 |
255 | // We handle errors just like any other message
256 | case errMsg:
257 | m.err = msg
258 | return m, nil
259 | }
260 | // Update different view states
261 | switch m.state {
262 | case inputView:
263 | m.textInput, cmd = m.textInput.Update(msg)
264 | case listView:
265 | m.list, cmd = m.list.Update(msg)
266 | }
267 | cmds = append(cmds, cmd)
268 |
269 | return m, tea.Batch(cmds...)
270 | }
271 |
272 | func (m model) View() string {
273 | switch m.state {
274 | case inputView:
275 | return m.textInput.View()
276 | default:
277 |
278 | return m.list.View()
279 | }
280 | }
281 |
282 | func getPaths() []string {
283 | PATH := os.Getenv("PATH")
284 | return strings.Split(PATH, ":")
285 | }
286 |
287 | func createPaths() []list.Item {
288 | paths := getPaths()
289 | items := make([]list.Item, len(paths))
290 | for i, path := range paths {
291 | items[i] = item(path)
292 | }
293 | return items
294 | }
295 |
296 | func setupTextInput() textinput.Model {
297 | ti := textinput.New()
298 | ti.Prompt = "Enter directory: "
299 | ti.Placeholder = "/"
300 | ti.SetValue("")
301 | ti.Blink()
302 | ti.Focus()
303 | ti.CharLimit = 156
304 | ti.Width = 50
305 |
306 | return ti
307 | }
308 |
309 | func duplicatePath(path string) bool {
310 | _, isPresent := duplicatePaths[path]
311 | return isPresent
312 | }
313 |
314 | func findDuplicatePaths(items []list.Item) map[string]struct{} {
315 | pathMap := make(map[string]int)
316 | duplicates := make(map[string]struct{})
317 |
318 | for _, listItem := range items {
319 | i, ok := listItem.(item)
320 | if ok {
321 | path := string(i)
322 | if value, ok := pathMap[path]; ok {
323 | pathMap[path] = value + 1
324 | } else {
325 | pathMap[path] = 0
326 | }
327 | }
328 | }
329 | for path, count := range pathMap {
330 | if count > 1 {
331 | duplicates[path] = struct{}{}
332 | }
333 | }
334 | return duplicates
335 | }
336 |
337 | type HelpKeyMap struct {
338 | Help key.Binding
339 | Quit key.Binding
340 | NewPath key.Binding
341 | DeletePath key.Binding
342 | SaveShellSource key.Binding
343 | Enter key.Binding
344 | }
345 |
346 | var keys = HelpKeyMap{
347 | Enter: key.NewBinding(
348 | key.WithKeys("enter"),
349 | key.WithHelp("enter", "submit new path"),
350 | ),
351 | NewPath: key.NewBinding(
352 | key.WithKeys("N"),
353 | key.WithHelp("N", "new"),
354 | ),
355 | DeletePath: key.NewBinding(
356 | key.WithKeys("D"),
357 | key.WithHelp("D", "delete"),
358 | ),
359 | SaveShellSource: key.NewBinding(
360 | key.WithKeys("S"),
361 | key.WithHelp("S", "save paths"),
362 | ),
363 | }
364 |
365 | func main() {
366 | if os.Getenv("HELP_DEBUG") != "" {
367 | if f, err := tea.LogToFile("debug.log", "help"); err != nil {
368 | fmt.Println("Couldn't open a file for logging:", err)
369 | os.Exit(1)
370 | } else {
371 | log.SetOutput(f)
372 | defer f.Close()
373 | }
374 | }
375 |
376 | if err := tea.NewProgram(initialModel()).Start(); err != nil {
377 | fmt.Printf("Could not start program :(\n%v\n", err)
378 | os.Exit(1)
379 | }
380 | }
381 |
--------------------------------------------------------------------------------