Add .gitignore, update dependencies, and implement deep link registration for Windows
This commit is contained in:
parent
b5db7ba2d5
commit
e978c542df
6 changed files with 117 additions and 9 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
target/**/*
|
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -157,6 +157,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
|
"winreg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -474,3 +475,13 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
|
@ -9,3 +9,5 @@ dirs = "5.0.1"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
shellexpand = "3.1.0"
|
shellexpand = "3.1.0"
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winreg = "0.52"
|
||||||
|
|
41
GEMINI.md
Normal file
41
GEMINI.md
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Ionian Find
|
||||||
|
|
||||||
|
Ionian Find는 딥링크를 사용하여 파일 탐색기를 여는 간단한 Rust 애플리케이션입니다.
|
||||||
|
|
||||||
|
## 주요 기능
|
||||||
|
|
||||||
|
- **딥링크 등록:** `ionian-find://`와 같은 사용자 정의 딥링크를 시스템에 등록합니다.
|
||||||
|
- **경로 기반 파일 탐색기 열기:** 딥링크에 포함된 경로를 기반으로 파일 탐색기를 엽니다. 예를 들어, `ionian-find://C:/Users`는 `C:/Users` 폴더를 엽니다.
|
||||||
|
|
||||||
|
## 설정
|
||||||
|
|
||||||
|
- base_path: 딥링크가 열 때 사용할 기본 경로를 설정할 수 있습니다. 이 경로는 딥링크에 포함된 경로와 결합되어 최종 경로를 생성합니다.
|
||||||
|
- explore: 딥링크를 통해 파일 탐색기를 열 때 사용할 명령어를 설정할 수 있습니다. 기본적으로 Windows에서는 `explorer`가, Linux에서는 `xdg-open`이 사용됩니다.
|
||||||
|
|
||||||
|
## 사용법
|
||||||
|
|
||||||
|
1. **설치:**
|
||||||
|
```bash
|
||||||
|
cargo install --path .
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **딥링크 등록:**
|
||||||
|
```bash
|
||||||
|
ionian-find register
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **딥링크 사용:**
|
||||||
|
브라우저나 다른 애플리케이션에서 `ionian-find://<경로>` 형식의 딥링크를 엽니다.
|
||||||
|
|
||||||
|
## 기술 스택
|
||||||
|
|
||||||
|
- **Rust:** 핵심 애플리케이션 로직
|
||||||
|
- **clap:** 명령줄 인수 파싱
|
||||||
|
- **dirs:** 사용자 디렉토리 경로 확인
|
||||||
|
- **serde/serde_json:** 설정 파일 직렬화/역직렬화
|
||||||
|
- **shellexpand:** 셸 환경 변수 확장
|
||||||
|
|
||||||
|
## 플랫폼 지원
|
||||||
|
|
||||||
|
- Windows
|
||||||
|
- Linux
|
17
src/main.rs
17
src/main.rs
|
@ -60,12 +60,17 @@ fn handle_open(path: &str) -> Result<(), String> {
|
||||||
}
|
}
|
||||||
full_path.push(relative_path);
|
full_path.push(relative_path);
|
||||||
|
|
||||||
println!("Opening the file explorer to: {:?}", full_path);
|
let result = full_path.canonicalize()
|
||||||
|
.expect("Failed to canonicalize path")
|
||||||
|
.to_str()
|
||||||
|
.ok_or("Failed to convert path to string")?
|
||||||
|
.to_string();
|
||||||
|
println!("Opening the file explorer to: {:?}", result);
|
||||||
|
|
||||||
let explorer = config.explorer.unwrap_or_else(|| "xdg-open".to_string());
|
let explorer = config.explorer.unwrap_or_else(|| "xdg-open".to_string());
|
||||||
|
|
||||||
Command::new(explorer)
|
Command::new(explorer)
|
||||||
.arg(full_path)
|
.arg(result)
|
||||||
.output()
|
.output()
|
||||||
.map_err(|e| format!("Failed to execute file explorer: {}", e))?;
|
.map_err(|e| format!("Failed to execute file explorer: {}", e))?;
|
||||||
|
|
||||||
|
@ -87,18 +92,18 @@ fn handle_setting(explorer: &Option<String>, base_path: &Option<String>) -> Resu
|
||||||
// This is possible with the `defer` crate, but not in the standard library.
|
// This is possible with the `defer` crate, but not in the standard library.
|
||||||
// https://crates.io/crates/defer
|
// https://crates.io/crates/defer
|
||||||
|
|
||||||
let mut isSet = false;
|
let mut is_set = false;
|
||||||
if let Some(explorer) = explorer {
|
if let Some(explorer) = explorer {
|
||||||
println!("Setting the file explorer to: {}", explorer);
|
println!("Setting the file explorer to: {}", explorer);
|
||||||
config.explorer = Some(explorer.clone());
|
config.explorer = Some(explorer.clone());
|
||||||
isSet = true;
|
is_set = true;
|
||||||
}
|
}
|
||||||
if let Some(base_path) = base_path {
|
if let Some(base_path) = base_path {
|
||||||
println!("Setting the base path to: {}", base_path);
|
println!("Setting the base path to: {}", base_path);
|
||||||
config.base_path = Some(base_path.clone());
|
config.base_path = Some(base_path.clone());
|
||||||
isSet = true;
|
is_set = true;
|
||||||
}
|
}
|
||||||
if !isSet {
|
if !is_set {
|
||||||
// If no settings were provided, print the current configuration
|
// If no settings were provided, print the current configuration
|
||||||
println!("Current configuration:");
|
println!("Current configuration:");
|
||||||
println!("Explorer: {:?}", config.explorer.unwrap_or("Not set".into()));
|
println!("Explorer: {:?}", config.explorer.unwrap_or("Not set".into()));
|
||||||
|
|
|
@ -1,7 +1,55 @@
|
||||||
|
use std::env;
|
||||||
|
use winreg::enums::*;
|
||||||
|
use winreg::RegKey;
|
||||||
|
|
||||||
|
const PATH: &str = r"Software\Classes\ionian-find";
|
||||||
|
|
||||||
pub fn handle_register() -> Result<(), String> {
|
pub fn handle_register() -> Result<(), String> {
|
||||||
unimplemented!("Register is not yet implemented for Windows.");
|
println!("Registering the deep link for Windows...");
|
||||||
|
|
||||||
|
let exe_path = env::current_exe()
|
||||||
|
.map_err(|e| format!("Error getting current executable path: {}", e))?
|
||||||
|
.to_str()
|
||||||
|
.ok_or("Invalid UTF-8 in executable path")?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
let (key, disp) = hkcu.create_subkey(&PATH)
|
||||||
|
.map_err(|e| format!("Failed to create subkey: {}", e))?;
|
||||||
|
|
||||||
|
match disp {
|
||||||
|
REG_CREATED_NEW_KEY => println!("Created new registry key"),
|
||||||
|
REG_OPENED_EXISTING_KEY => println!("Opened existing registry key"),
|
||||||
|
}
|
||||||
|
|
||||||
|
key.set_value("", &"URL:ionian-find")
|
||||||
|
.map_err(|e| format!("Failed to set value: {}", e))?;
|
||||||
|
key.set_value("URL Protocol", &"")
|
||||||
|
.map_err(|e| format!("Failed to set value: {}", e))?;
|
||||||
|
|
||||||
|
let (shell_key, _) = key.create_subkey("shell")
|
||||||
|
.map_err(|e| format!("Failed to create subkey: {}", e))?;
|
||||||
|
let (open_key, _) = shell_key.create_subkey("open")
|
||||||
|
.map_err(|e| format!("Failed to create subkey: {}", e))?;
|
||||||
|
let (command_key, _) = open_key.create_subkey("command")
|
||||||
|
.map_err(|e| format!("Failed to create subkey: {}", e))?;
|
||||||
|
|
||||||
|
let command_value = format!(r#""{}" "open" "%1""#, exe_path);
|
||||||
|
command_key.set_value("", &command_value)
|
||||||
|
.map_err(|e| format!("Failed to set value: {}", e))?;
|
||||||
|
|
||||||
|
println!("Deep link registered successfully!");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_unregister() -> Result<(), String> {
|
pub fn handle_unregister() -> Result<(), String> {
|
||||||
unimplemented!("Unregister is not yet implemented for Windows.");
|
println!("Unregistering the deep link for Windows...");
|
||||||
|
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
|
||||||
|
hkcu.delete_subkey_all(PATH)
|
||||||
|
.map_err(|e| format!("Failed to delete subkey: {}", e))?;
|
||||||
|
|
||||||
|
println!("Deep link unregistered successfully!");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue