Search Selected Text Anywhere in Windows
In my previous article, I shared how I streamlined my search process on Linux by creating a tool that allows me to quickly Google selected text without interrupting my workflow. After a week of enjoying that solution, I found myself wanting to replicate that same efficiency in my Windows environment.
While Windows lacks the “clipboard at selection” functionality I enjoyed on Linux, I realized I could still leverage the classic Ctrl+C
shortcut to access clipboard content. This led me to develop a simple application that allows me to quickly search selected text in my preferred browser, all while keeping my workflow intact.
The Challenge and Solution
My goal was to create a tool that could:
- Access the clipboard content.
- Format it into a search URL.
- Open a browser in incognito mode with that URL.
To achieve this, I opted for a straightforward, hardcoded solution (for now). Plus, it was a great opportunity to use Rust!
The Development Process
Here’s a detailed overview of how I built this tool:
Setting Up the Environment: I first installed the Windows build tools and Rustup to prepare my system for development.
Creating the Project: I created a new Rust project and added the necessary dependencies:
1
2
3cargo new sst_app
cd sst_app
cargo add clap clipboard urlencoding winresWriting the Code: this is the full implementation of the tool in
src/main.rs
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76use clipboard::{ClipboardContext, ClipboardProvider};
use clap::{Parser, ValueEnum};
use std::process::Command;
/// A simple program to search using the clipboard content.
struct Args {
/// Browser to use for opening the search
browser: String,
/// Search engine to use
engine: SearchEngine,
custom_prompt: Option<String>,
}
/// Supported search engines
enum SearchEngine {
Google,
Bing,
Duckduckgo,
Perplexity,
Phind,
Youtube,
}
fn main() {
let mut ctx: ClipboardContext = ClipboardProvider::new().unwrap();
let mut clipboard_content = ctx.get_contents().unwrap();
// Parse command-line arguments
let args = Args::parse();
if let Some(prompt) = &args.custom_prompt {
if matches!(args.engine, SearchEngine::Phind | SearchEngine::Perplexity) {
clipboard_content = prompt.to_owned() + &clipboard_content;
}
}
// Construct the search URL based on the chosen search engine
let search_url = match args.engine {
SearchEngine::Google => format!("https://www.google.com/search?q={}", urlencoding::encode(&clipboard_content)),
SearchEngine::Bing => format!("https://www.bing.com/search?q={}", urlencoding::encode(&clipboard_content)),
SearchEngine::Duckduckgo => format!("https://www.duckduckgo.com/?q={}", urlencoding::encode(&clipboard_content)),
SearchEngine::Perplexity => format!("https://www.perplexity.ai/search?q={}", urlencoding::encode(&clipboard_content)),
SearchEngine::Phind => format!("https://www.phind.com/search?q={}", urlencoding::encode(&clipboard_content)),
SearchEngine::Youtube => format!("https://www.youtube.com/results?search_query={}", urlencoding::encode(&clipboard_content)),
};
open_browser(&search_url, &args.browser);
}
fn open_browser(url: &str, browser: &str) {
let command = match browser.to_lowercase().as_str() {
"firefox" => format!("start firefox --private-window {}", url),
"chrome" => format!("start chrome --incognito {}", url),
"brave" => format!("start brave --private {}", url),
"edge" => format!("start msedge {}", url),
_ => format!("start chrome --incognito {}", url), // Default to Chrome
};
if let Err(e) = Command::new("cmd")
.arg("/C")
.arg(command)
.output()
{
eprintln!("Failed to open browser: {}", e);
}
}Configuring Dependencies: I tweaked up the
Cargo.toml
file a little to include the required dependencies and build settings necessary for winres:1
2
3
4
5
6
7
8
9
10
11
12
13
14[package]
name = "sst_app"
version = "0.1.0"
edition = "2024"
build = "build.rs"
[build-dependencies]
winres = "0.1.12"
[dependencies]
clap = { version = "4.5.20", features = ["derive"] }
clipboard = "0.5.0"
urlencoding = "2.1.3"
winres = "0.1.12"Adding an Icon: for the icon resource to be included during build, another file was needed
build.rs
1
2
3
4
5
6
7
8
9use std::io;
use winres::WindowsResource;
fn main() -> io::Result<()> {
WindowsResource::new()
.set_icon("icon.ico")
.compile()?;
Ok(())
}Building the Project: Finally, built the project with
cargo build --release
.
Using the Tool
To use this new search tool:
- Create a shortcut on your desktop that links to the executable.
- Add arguments in the shortcut properties. For example:
c:/path/to/sst_app.exe -b chrome -e phind
. - Assign a key binding to the shortcut (I personally use Ctrl+Alt+S).
Now, whenever you select text and press Ctrl+C, you can immediately use your assigned key binding to search that text in your preferred browser and search engine.
You can get help on available options by running sst_app --help
in the command prompt.
Conclusion
While this solution is already very good, there are plenty of opportunities for enhancement. In the future, I may look into integrating the Ctrl+C functionality directly into the app or maybe adding more customization options.
If you’re interested in trying out this tool or want to collaborate on its development, feel free to reach out.
Happy searching (again)!