[HN Gopher] Show HN: Scooter - Interactive find and replace in t...
       ___________________________________________________________________
        
       Show HN: Scooter - Interactive find and replace in the terminal
        
       Author : tomschafer
       Score  : 94 points
       Date   : 2024-11-15 16:45 UTC (6 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | lopkeny12ko wrote:
       | [flagged]
        
         | karanbhangui wrote:
         | "For a Linux user, you can already build such a system yourself
         | quite trivially by getting an FTP account, mounting it locally
         | with curlftpfs, and then using SVN or CVS on the mounted
         | filesystem"
         | 
         | https://news.ycombinator.com/item?id=8863
        
         | tomschafer wrote:
         | Not affiliated, I just built a little tool to make my life
         | easier and thought I'd share
        
           | sockaddr wrote:
           | I think it's cool. Thanks for sharing
        
           | dang wrote:
           | It's great and clearly the community appreciates it! I'll put
           | Show HN in the title since that's the convention for sharing
           | one's projects on HN
           | (https://news.ycombinator.com/showhn.html).
           | 
           | Btw, do you want to include some text giving the backstory of
           | how you came to work on this, and explaining what's different
           | about it? that's also the convention. If you post it in a
           | reply to this comment, I'll move your text to the top of the
           | thread.
        
         | dang wrote:
         | Can you please not post shallow dismissals of other people's
         | work? This is in the site guidelines:
         | https://news.ycombinator.com/newsguidelines.html.
         | 
         | It's important, when people share something they've made on HN,
         | that they don't run into this sort of bilious internet putdown.
         | 
         | Edit - these are other examples of the same thing (i.e. the
         | thing we don't want in HN threads, and which we'd appreciate if
         | you'd not do any more of):
         | 
         | https://news.ycombinator.com/item?id=41810426
         | 
         | https://news.ycombinator.com/item?id=41224056
        
       | oulipo wrote:
       | I'm using this quickly put-together shell script called replace
       | #!/usr/bin/env bash                  # Function to escape special
       | characters for sed         escape_sed_string() {
       | printf '%s\n' "$1" | gsed -e 's/[]\/$*.^[]/\\&/g'         }
       | help() {           gum style --foreground cyan --italic "\
       | Usage (everything optional, you will be prompted):\n\
       | $0\n\           --ext .js --ext .ts\n\           --from \"source
       | string\"\n\           --to \"replacement string\"\n\
       | --dir somePath"         }                  # Parse command line
       | arguments         while [[ "$#" -gt 0 ]]; do             case $1
       | in                 -h)                     help
       | exit 0                     ;;                 --help)
       | help                     exit 0                     ;;
       | --ext) EXTENSIONS+=("$2"); shift ;;                 --from)
       | REPLACE_FROM="$2"; shift ;;                 --to)
       | REPLACE_TO="$2"; shift ;;                 --dir) DIRECTORY="$2";
       | shift ;;                 *) gum style --foreground red --bold
       | "Unknown parameter: $1"; exit 1 ;;             esac
       | shift         done                  # Check for missing
       | parameters and prompt using gum         if [ -z
       | "${EXTENSIONS+set}" ]; then             EXTENSIONS=($(gum choose
       | \                 --no-limit \                 --selected
       | .ts,.mts,.tsx,.vue,.js,.cjs,.mjs \                 .ts .mts .tsx
       | .vue .js .cjs .mjs .txt .md .html .json))         fi
       | # Exit if no extension is selected         if [ ${#EXTENSIONS[@]}
       | -eq 0 ]; then             gum style --foreground red --bold "
       | Error: No extensions selected. Exiting."             exit 1
       | fi                  if [ -z "${REPLACE_FROM+set}" ]; then
       | REPLACE_FROM=$(gum input --placeholder "Search string:")
       | if [ -z "${REPLACE_FROM}" ]; then                 echo "No
       | replace from string, exiting"                 exit 1
       | fi         fi         if [ -z "${REPLACE_TO+set}" ]; then
       | REPLACE_TO=$(gum input --placeholder "Replace string:")
       | fi         if [ -z "${DIRECTORY+set}" ]; then
       | DIRECTORY="."         fi                  # Escape strings for
       | sed         ESCAPED_FROM=$(escape_sed_string "$REPLACE_FROM")
       | ESCAPED_TO=$(escape_sed_string "$REPLACE_TO")                  #
       | Run the replacement         for ext in "${EXTENSIONS[@]}"; do
       | gum style --foreground blue " Replacing ${ext} files..."
       | find "$DIRECTORY" -type f -name "*$ext" ! -path
       | "*/node_modules/*" -exec gsed -i "s/$ESCAPED_FROM/$ESCAPED_TO/g"
       | {} \;         done                  gum style --foreground green
       | --bold " Replacement complete."
        
       | agateau wrote:
       | Looks handy!
        
       | bloopernova wrote:
       | A useful feature of bash and zsh is the "edit command". The
       | standard shortcut is "ctrl-x ctrl-e".
       | 
       | It opens the current command line in $EDITOR, which often
       | defaults to vim.
        
         | dmd wrote:
         | That is very useful. What does it have to do with this?
        
           | bloopernova wrote:
           | If you want to search and replace a command line, there's
           | tools to do it in your favourite editor.
        
             | dmd wrote:
             | Ah, so you didn't click through and actually see what this
             | tool is, you just read the title.
        
               | bloopernova wrote:
               | I did click through, but misinterpreted what it was
               | doing. Apologies, I'm "multitasking".
        
       | aerzen wrote:
       | Cool.
       | 
       | I assumed it uses ripgrep (or the underlying walkdir) because
       | that's the established high-performance tool for this. But
       | apparently not.
        
         | tomschafer wrote:
         | It uses https://docs.rs/ignore/latest/ignore/ to walk dirs
         | while respecting ignore files
        
           | seritools wrote:
           | (And `ignore` uses `walkdir` internally)
        
             | burntsushi wrote:
             | For single threaded use cases. For multi-threaded, it has
             | its own parallel directory traversal. :-)
        
       | gurgeous wrote:
       | Also see the excellent https://github.com/your-tools/ruplacer.
       | 
       | For more advanced needs, I have a custom thing called greprep
       | that let's you make changes using your favorite editor. Workflow
       | is like this:                 1. $ rg -n .... > /tmp/lines.txt
       | 2. (edit lines.txt in vscode)       3. $ greprep /tmp/lines.txt
       | to apply the changes
        
         | jmarcher wrote:
         | In Emacs, there is [helm-ag-
         | edit](https://github.com/emacsorphanage/helm-ag) (but uses
         | ripgrep if present). It's almost identical to your workflow,
         | but all done inside the same app.
         | 
         | 1. helm-ag <pattern> # the search results are updated as you
         | type 2. helm-ag-edit # edit the search result as regular text.
         | Use multi-cursors, macros, whatever. 3. helm-ag-edit-save #
         | commits the changes to the affected files
         | 
         | All those commands have keybindings, so it's pretty fast. I'll
         | often open up Emacs just to do that and then go back to my
         | JetBrains IDE.
        
       | doylemark wrote:
       | nice! Find and replace across a codebase is one of the few times
       | I open an IDE.
       | 
       | Being able to interactively ignore instances for replacement is
       | great!
        
       | Freak_NL wrote:
       | Am I alone in initially thinking this was specifically for the
       | fish shell because of this tool's name?
        
         | darrenf wrote:
         | Perhaps. I as a fish user thought "oh, like `string replace`"
        
       | matt3210 wrote:
       | Very nice, it might be a good alternative when I can't use vscode
       | remote connections.
        
       | eevilspock wrote:
       | A Homebrew install option will help this take off on Macs.
       | https://github.com/thomasschafer/scooter/issues/6
        
         | rvz wrote:
         | That was my first problem with trying to install this. But
         | agree that it should be on Homebrew.
        
       | mg wrote:
       | You could also use vim in a loop. Say you want to replace "hello"
       | in all files in the current dir with "world" and confirm every
       | replace, then you would do:                   for f in $(grep -l
       | 'hello' *); do vim -c ':%s/hello/world/gc | wq' "$f"; done
       | 
       | Or if you want to use some more vim magic, this simpler command
       | will do the same:                   vim -c "argdo
       | %s/hello/world/gce | update" -c "qall" *
       | 
       | "argdo" will do the replace command for each file, the additional
       | e modifier in gce will ignore files that do not contain the
       | search string and the second command "qall" is to quit vim after
       | the work is done.
        
       | jph wrote:
       | Excellent, thank you. I do this with sed & awk & sometimes an
       | IDE, and scooter looks better in every way.
       | 
       | I'm adding scooter to my cargo install favorites:
       | 
       | https://github.com/sixarm/cargo-install-favorites
        
       | jmercouris wrote:
       | Feels like we just keep making tools that already exist in Emacs.
        
         | mway wrote:
         | I dunno, seems reasonable to me that we might have nice things
         | without requiring everyone to use emacs. (And for those who do
         | use emacs, I guess you're ahead of the curve?)
        
           | mananaysiempre wrote:
           | On the other hand, it seems reasonable that we should be able
           | to have nice things without giving up our editors. I know
           | I've been spoiled by Kakoune's cursors, but this feels like a
           | tool that should work by spawning $EDITOR in the middle of
           | its execution (or perhaps just having two phases and a
           | control file). I don't know if that's actually possible with
           | the current capabilities of $EDITORs (which are not Emacs). I
           | just feel, in the darkest hour of the night which I spend
           | reflecting on UIs, like it should be.
        
       | jmhobbs wrote:
       | Very cool! I currently use `sad` for this, if you're already an
       | fzf user you should check it out.
       | 
       | https://github.com/ms-jpq/sad
        
       | anthk wrote:
       | Similarly, on bash/ksh: set -o vi Ctrl-[ v (or ESC) set -o emacs
       | Ctrl-x e
        
       | rvz wrote:
       | There was another comment about the difficulty in installing
       | scooter and in the issues section, there are some requests to add
       | more installation options.
       | 
       | https://github.com/thomasschafer/scooter/issues/6
       | 
       | Not everyone has the Rust toolchain installed on their machine.
       | The `cargo install` installation directive needs to be
       | discouraged.
        
       | tpoacher wrote:
       | Neat ... but I'd probably just do this by opening a "grep -l"
       | list in nano for interactive replacement directly instead. Easy
       | peasy.
        
       | herrington_d wrote:
       | Cool! is it possible to support structural search like ast-
       | grep[1]? ast-grep has some interactive mode but it is nothing
       | near Scooter.
       | 
       | 1: https://ast-grep.github.io/
        
       | patatass wrote:
       | Couldn't find it in nixpkgs.
        
       | sigmonsays wrote:
       | We're losing the art of bash ``` find -type f -iname '*.go' |
       | xargs -r -n1 sed -i 's,foo,foobar,g' ```
        
       ___________________________________________________________________
       (page generated 2024-11-15 23:00 UTC)