The Molybdenum Replacer

Recursive, line-based search and replace CLI application.

Installation

Directly via cargo

From source code

Basic usage

Following commands demonstrate how mo can be used to accomplish different tasks:

Next to this, mo detects if input comes from a console or redirection, and will act accordingly, as well as for its output: mo can be used to report or make replacements in a piped stream as well.

Interactive file selection

Following bash functions allows you to open a file (o) or change to a folder (c) based on the fuzzy search functionality of fzf. You can pass them any argument that mo accepts, making them handy interactive tools. They rely on bat to provide a preview, and nvr to open the selected file in a new or already running instance of neovim, and zoxide to register and track your most popular folders.

```

Open file using bat as preview

o() { mo -l $* | fzf --multi --preview 'bat --style=numbers --color=always --line-range :500 {}' --preview-window 'right:60%' | xargs -I % nvr --remote-tab % }

Open file using mo as preview

s() { export allargs="$*" mo -l $* | fzf --multi --preview 'mo -c -i ${allargs} -C {}' --preview-window 'right:60%' | xargs -I % nvr --remote-tab % }

Change to dir using z

c() { z mo -L $* | fzf } ```

Yet another tool?

Powerful search can be found without problems, eg, grep, ack, ag, ripgrep or broot.

Tools for replacing recursively in a folder are more difficult to find, although some exist: fart-it. Typically, people use a combination of searching, xargs and a replacement tool like sed or rpl.

I use code searching a lot to investigate a large source code base before attempting a replace. Even with 100k files, search is fast and fairly easy. Recursively replacing text is much more dangerous, especially if it requires the combination of several less frequently used tools; it's difficult to remember a search-xargs-replace combination if not used on a daily basis. On top of this, the search tool used to filter the set of files and perform a dry-run, is not per-se using the same search query as the replace tool. After all, these are different tools. It would be better if a single tool could be used for every-day searching and replacing. This is exactly what The Molybdenum Replacer intends to achieve.

In addition, I find it difficult to use ag and rg to filter against the file path and search for content in the remaining files; the -g option for ag and rg is confusing in my opinion. As such, I would expect ag -g /auro/ -w test to search for the word test in all files that have /auro/ in their path, but that is not what actually happens. It filters with /auro/ and test against the filename (or something that looks like it).

The real reason, of course, is that I had some free time and was looking for a nice project/excuse to learn rust.

Implemented Features

Following features are implemented and usable in the current version:

Future Features

Following features might be added sooner or later:

Performance

Count all files in a folder

`` Scenario: count all files Runningmo -l -u -U -a | wc` Elapsed time: 0:00.29 Output: 184675 187146 16959297

Running rg --files -uu -a | wc Elapsed time: 0:00.15 Output: 184675 187146 16589947

Running ag -l -uu -a | wc Elapsed time: 0:00.66 Output: 184675 187146 16589947 ```

Search for word in C++ source code

`` Scenario: search for wordtestin .cpp files in subfoldercorewhere path contains /auro/ Runningmo -C core -e cpp -f /auro/ -w -p test -l | wc` Elapsed time: 0:00.03 Output: 165 165 9008

Running rg -t cpp --files core | rg /auro/ | rg '.cpp$' | tr '\n' '\0' | xargs -0 rg -i -w test -l | wc Elapsed time: 0:00.01 Output: 165 165 9008

Running ag --cpp -l . core | ag /auro/ | ag '.cpp$' | tr '\n' '\0' | xargs -0 ag -w test -l | wc Elapsed time: 0:00.05 Output: 165 165 9008

```

I don't know how I can accomplish this scenario with ag and rg in a single command without relying on xargs and tr.

Changelog

v0.1.6