Add .gitignore, update dependencies, and implement deep link registration for Windows

This commit is contained in:
monoid 2025-06-26 21:19:00 +09:00
parent b5db7ba2d5
commit e978c542df
6 changed files with 117 additions and 9 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target/**/*

11
Cargo.lock generated
View file

@ -157,6 +157,7 @@ dependencies = [
"serde",
"serde_json",
"shellexpand",
"winreg",
]
[[package]]
@ -474,3 +475,13 @@ name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
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",
]

View file

@ -9,3 +9,5 @@ dirs = "5.0.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
shellexpand = "3.1.0"
[target.'cfg(windows)'.dependencies]
winreg = "0.52"

41
GEMINI.md Normal file
View 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

View file

@ -60,12 +60,17 @@ fn handle_open(path: &str) -> Result<(), String> {
}
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());
Command::new(explorer)
.arg(full_path)
.arg(result)
.output()
.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.
// https://crates.io/crates/defer
let mut isSet = false;
let mut is_set = false;
if let Some(explorer) = explorer {
println!("Setting the file explorer to: {}", explorer);
config.explorer = Some(explorer.clone());
isSet = true;
is_set = true;
}
if let Some(base_path) = base_path {
println!("Setting the base path to: {}", base_path);
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
println!("Current configuration:");
println!("Explorer: {:?}", config.explorer.unwrap_or("Not set".into()));

View file

@ -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> {
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> {
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(())
}