Skip to content

Commit 8557840

Browse files
committed
♻️ Refactor clipboard chunking to pre-split with formatting awareness
- Splits text into chunks AFTER accounting for markdown formatting overhead - Prevents formatted chunks from exceeding character limits - Fixes logic for quote blocks to handle line-by-line prefixes properly - Fixes logic for code blocks to account for backticks overhead - Cleans up linter warnings (snake_case naming)
1 parent 54e5541 commit 8557840

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

src/main.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,8 @@ async fn get_location() -> Result<String, String> {
964964
#[derive(serde::Deserialize)]
965965
struct ApiResponse {
966966
city: Option<String>,
967-
regionName: Option<String>,
967+
#[serde(rename = "regionName")]
968+
region_name: Option<String>,
968969
country: Option<String>,
969970
lat: Option<f64>,
970971
lon: Option<f64>,
@@ -979,7 +980,7 @@ async fn get_location() -> Result<String, String> {
979980
.map_err(|e| format!("Failed to parse response: {}", e))?;
980981

981982
let city = data.city.unwrap_or_default();
982-
let region = data.regionName.unwrap_or_default();
983+
let region = data.region_name.unwrap_or_default();
983984
let country = data.country.unwrap_or_default();
984985
let lat = data.lat.unwrap_or_default();
985986
let lon = data.lon.unwrap_or_default();
@@ -1062,16 +1063,16 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
10621063

10631064
// Get the current clipboard contents
10641065
let clipboard_text = get_clipboard_string()?;
1065-
1066+
10661067
if clipboard_text.is_empty() {
10671068
return Ok("Clipboard is empty, nothing to paste".to_string());
10681069
}
10691070

10701071
let mut clipboard: ClipboardContext =
10711072
ClipboardProvider::new().map_err(|e| format!("Failed to initialize clipboard: {}", e))?;
1072-
1073+
10731074
let mut enigo = Enigo::new();
1074-
1075+
10751076
// Create chunks based on format type
10761077
let chunks: Vec<String> = match format {
10771078
"quote" => {
@@ -1080,7 +1081,7 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
10801081
let mut chunks_vec = Vec::new();
10811082
let mut current_chunk_lines = Vec::new();
10821083
let mut current_size = 0;
1083-
1084+
10841085
for line in lines {
10851086
// Calculate size with "> " prefix and newline
10861087
let formatted_line_size = line.chars().count() + 2; // +2 for "> "
@@ -1089,17 +1090,18 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
10891090
} else {
10901091
formatted_line_size + 1 // +1 for newline
10911092
};
1092-
1093+
10931094
// If adding this line would exceed chunk_size, start a new chunk
1094-
if current_size + size_with_newline > chunk_size && !current_chunk_lines.is_empty() {
1095+
if current_size + size_with_newline > chunk_size && !current_chunk_lines.is_empty()
1096+
{
10951097
// Format and save current chunk
10961098
let formatted_chunk = current_chunk_lines
10971099
.iter()
10981100
.map(|l| format!("> {}", l))
10991101
.collect::<Vec<String>>()
11001102
.join("\n");
11011103
chunks_vec.push(formatted_chunk);
1102-
1104+
11031105
// Start new chunk with current line
11041106
current_chunk_lines = vec![line];
11051107
current_size = formatted_line_size;
@@ -1109,7 +1111,7 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
11091111
current_size += size_with_newline;
11101112
}
11111113
}
1112-
1114+
11131115
// Don't forget the last chunk
11141116
if !current_chunk_lines.is_empty() {
11151117
let formatted_chunk = current_chunk_lines
@@ -1119,7 +1121,7 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
11191121
.join("\n");
11201122
chunks_vec.push(formatted_chunk);
11211123
}
1122-
1124+
11231125
chunks_vec
11241126
}
11251127
"code" | "codeblock" => {
@@ -1128,43 +1130,46 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
11281130
let available_size = if chunk_size > overhead {
11291131
chunk_size - overhead
11301132
} else {
1131-
return Err("Chunk size too small for code block formatting (needs at least 9 characters)".to_string());
1133+
return Err(
1134+
"Chunk size too small for code block formatting (needs at least 9 characters)"
1135+
.to_string(),
1136+
);
11321137
};
1133-
1138+
11341139
let chars: Vec<char> = clipboard_text.chars().collect();
11351140
let mut chunks_vec = Vec::new();
11361141
let mut i = 0;
1137-
1142+
11381143
while i < chars.len() {
11391144
let end = std::cmp::min(i + available_size, chars.len());
11401145
let chunk_text: String = chars[i..end].iter().collect();
11411146
let formatted_chunk = format!("```\n{}\n```", chunk_text);
11421147
chunks_vec.push(formatted_chunk);
11431148
i = end;
11441149
}
1145-
1150+
11461151
chunks_vec
11471152
}
11481153
_ => {
11491154
// "normal" - simple character-based splitting
11501155
let chars: Vec<char> = clipboard_text.chars().collect();
11511156
let mut chunks_vec = Vec::new();
11521157
let mut i = 0;
1153-
1158+
11541159
while i < chars.len() {
11551160
let end = std::cmp::min(i + chunk_size, chars.len());
11561161
let chunk: String = chars[i..end].iter().collect();
11571162
chunks_vec.push(chunk);
11581163
i = end;
11591164
}
1160-
1165+
11611166
chunks_vec
11621167
}
11631168
};
1164-
1169+
11651170
let total_chars = clipboard_text.chars().count();
11661171
let chunks_pasted = chunks.len();
1167-
1172+
11681173
// Paste each chunk
11691174
for formatted_chunk in &chunks {
11701175
// Set the clipboard to this formatted chunk
@@ -1174,18 +1179,18 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
11741179

11751180
// Wait a moment for the clipboard to be set
11761181
std::thread::sleep(std::time::Duration::from_millis(50));
1177-
1182+
11781183
// Emulate Ctrl+V
11791184
enigo.key_down(enigo::Key::Control);
11801185
enigo.key_click(enigo::Key::Layout('v'));
11811186
enigo.key_up(enigo::Key::Control);
1182-
1187+
11831188
// Wait a moment for the paste to complete
11841189
std::thread::sleep(std::time::Duration::from_millis(50));
1185-
1190+
11861191
// Press Enter to send the message
11871192
enigo.key_click(enigo::Key::Return);
1188-
1193+
11891194
// Wait at least 100ms before next chunk
11901195
std::thread::sleep(std::time::Duration::from_millis(100));
11911196
}
@@ -1426,7 +1431,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
14261431
}
14271432

14281433
if duck_ptt {
1429-
let mut thread_speak_stream =
1434+
let thread_speak_stream =
14301435
thread_speak_stream_mutex.lock().unwrap();
14311436
thread_speak_stream.stop_audio_ducking();
14321437
drop(thread_speak_stream);

0 commit comments

Comments
 (0)