Skip to content

Commit 46f7e6b

Browse files
committed
자동 포멧팅 기능 개선
1 parent 49a6316 commit 46f7e6b

3 files changed

Lines changed: 92 additions & 62 deletions

File tree

src/ui/sql_editor/intellisense/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ use super::*;
3333

3434
const MAX_MERGED_SUGGESTIONS: usize = 100;
3535
const KEYUP_INTELLISENSE_DEBOUNCE_MS: u64 = 1;
36+
// One physical press may dispatch both KeyDown and Shortcut. A missing KeyUp
37+
// must not keep suppressing later presses indefinitely.
38+
const CTRL_ENTER_DUPLICATE_WINDOW: Duration = Duration::from_millis(100);
3639
const COLUMN_LOAD_WORKER_COUNT: usize = 4;
3740
const COLUMN_LOAD_CONTEXT_RETRY_DELAYS: [Duration; 3] = [
3841
Duration::from_millis(5),
@@ -82,7 +85,7 @@ enum NavigationKeyupState {
8285
enum EnterKeyupSuppression {
8386
None,
8487
PopupConfirm,
85-
CtrlEnterExecute,
88+
CtrlEnterExecute(std::time::Instant),
8689
#[cfg_attr(not(target_os = "macos"), allow(dead_code))]
8790
ImeCompositionEnter,
8891
}

src/ui/sql_editor/intellisense/runtime.rs

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,34 @@
11
impl SqlEditorWidget {
2+
fn should_suppress_ctrl_enter_dispatch(
3+
suppression: &mut EnterKeyupSuppression,
4+
now: std::time::Instant,
5+
) -> bool {
6+
if matches!(
7+
*suppression,
8+
EnterKeyupSuppression::CtrlEnterExecute(previous)
9+
if now.saturating_duration_since(previous) < CTRL_ENTER_DUPLICATE_WINDOW
10+
) {
11+
return true;
12+
}
13+
14+
*suppression = EnterKeyupSuppression::CtrlEnterExecute(now);
15+
false
16+
}
17+
18+
fn take_enter_keyup_suppression(
19+
key: Key,
20+
suppression: &mut EnterKeyupSuppression,
21+
) -> bool {
22+
if !matches!(key, Key::Enter | Key::KPEnter)
23+
|| matches!(*suppression, EnterKeyupSuppression::None)
24+
{
25+
return false;
26+
}
27+
28+
*suppression = EnterKeyupSuppression::None;
29+
true
30+
}
31+
232
/// Apply a merge produced by [`crate::ui::sql_editor::hangul_repair`] for
333
/// the macOS broken-first-Hangul-key bug.
434
#[cfg(target_os = "macos")]
@@ -1062,18 +1092,18 @@ impl SqlEditorWidget {
10621092
return true;
10631093
}
10641094
Key::Enter | Key::KPEnter => {
1065-
if matches!(
1066-
*enter_keyup_suppression_for_handle
1095+
let should_suppress = {
1096+
let mut suppression = enter_keyup_suppression_for_handle
10671097
.lock()
1068-
.unwrap_or_else(|poisoned| poisoned.into_inner()),
1069-
EnterKeyupSuppression::CtrlEnterExecute
1070-
) {
1098+
.unwrap_or_else(|poisoned| poisoned.into_inner());
1099+
Self::should_suppress_ctrl_enter_dispatch(
1100+
&mut suppression,
1101+
std::time::Instant::now(),
1102+
)
1103+
};
1104+
if should_suppress {
10711105
return true;
10721106
}
1073-
*enter_keyup_suppression_for_handle
1074-
.lock()
1075-
.unwrap_or_else(|poisoned| poisoned.into_inner()) =
1076-
EnterKeyupSuppression::CtrlEnterExecute;
10771107
widget_for_shortcuts.execute_statement_at_cursor();
10781108
return true;
10791109
}
@@ -1316,6 +1346,16 @@ impl SqlEditorWidget {
13161346
return false;
13171347
}
13181348

1349+
let consume_suppressed_enter_keyup = {
1350+
let mut suppression = enter_keyup_suppression_for_handle
1351+
.lock()
1352+
.unwrap_or_else(|poisoned| poisoned.into_inner());
1353+
Self::take_enter_keyup_suppression(key, &mut suppression)
1354+
};
1355+
if consume_suppressed_enter_keyup {
1356+
return true;
1357+
}
1358+
13191359
if shortcut_modified {
13201360
if popup_visible {
13211361
intellisense_popup_for_handle
@@ -1395,49 +1435,6 @@ impl SqlEditorWidget {
13951435
}
13961436
}
13971437

1398-
if matches!(key, Key::Enter | Key::KPEnter)
1399-
&& matches!(
1400-
*enter_keyup_suppression_for_handle
1401-
.lock()
1402-
.unwrap_or_else(|poisoned| poisoned.into_inner()),
1403-
EnterKeyupSuppression::ImeCompositionEnter
1404-
)
1405-
{
1406-
*enter_keyup_suppression_for_handle
1407-
.lock()
1408-
.unwrap_or_else(|poisoned| poisoned.into_inner()) =
1409-
EnterKeyupSuppression::None;
1410-
return true;
1411-
}
1412-
if matches!(key, Key::Enter | Key::KPEnter)
1413-
&& matches!(
1414-
*enter_keyup_suppression_for_handle
1415-
.lock()
1416-
.unwrap_or_else(|poisoned| poisoned.into_inner()),
1417-
EnterKeyupSuppression::PopupConfirm
1418-
)
1419-
{
1420-
*enter_keyup_suppression_for_handle
1421-
.lock()
1422-
.unwrap_or_else(|poisoned| poisoned.into_inner()) =
1423-
EnterKeyupSuppression::None;
1424-
return true;
1425-
}
1426-
if matches!(key, Key::Enter | Key::KPEnter)
1427-
&& matches!(
1428-
*enter_keyup_suppression_for_handle
1429-
.lock()
1430-
.unwrap_or_else(|poisoned| poisoned.into_inner()),
1431-
EnterKeyupSuppression::CtrlEnterExecute
1432-
)
1433-
{
1434-
*enter_keyup_suppression_for_handle
1435-
.lock()
1436-
.unwrap_or_else(|poisoned| poisoned.into_inner()) =
1437-
EnterKeyupSuppression::None;
1438-
return true;
1439-
}
1440-
14411438
// Navigation keys - hide popup and let editor handle cursor movement
14421439
if matches!(
14431440
key,
@@ -1758,18 +1755,18 @@ impl SqlEditorWidget {
17581755
}
17591756

17601757
if ctrl_or_cmd && matches!(key, Key::Enter | Key::KPEnter) {
1761-
if matches!(
1762-
*enter_keyup_suppression_for_handle
1758+
let should_suppress = {
1759+
let mut suppression = enter_keyup_suppression_for_handle
17631760
.lock()
1764-
.unwrap_or_else(|poisoned| poisoned.into_inner()),
1765-
EnterKeyupSuppression::CtrlEnterExecute
1766-
) {
1761+
.unwrap_or_else(|poisoned| poisoned.into_inner());
1762+
Self::should_suppress_ctrl_enter_dispatch(
1763+
&mut suppression,
1764+
std::time::Instant::now(),
1765+
)
1766+
};
1767+
if should_suppress {
17671768
return true;
17681769
}
1769-
*enter_keyup_suppression_for_handle
1770-
.lock()
1771-
.unwrap_or_else(|poisoned| poisoned.into_inner()) =
1772-
EnterKeyupSuppression::CtrlEnterExecute;
17731770
widget_for_shortcuts.execute_statement_at_cursor();
17741771
return true;
17751772
}

src/ui/sql_editor/intellisense/tests.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10007,6 +10007,36 @@ fn keyup_text_input_requires_a_real_unmodified_buffer_edit() {
1000710007
));
1000810008
}
1000910009

10010+
#[test]
10011+
fn ctrl_enter_duplicate_filter_expires_without_a_keyup() {
10012+
let started_at = std::time::Instant::now();
10013+
let mut suppression = EnterKeyupSuppression::None;
10014+
10015+
assert!(!SqlEditorWidget::should_suppress_ctrl_enter_dispatch(
10016+
&mut suppression,
10017+
started_at,
10018+
));
10019+
assert!(SqlEditorWidget::should_suppress_ctrl_enter_dispatch(
10020+
&mut suppression,
10021+
started_at + CTRL_ENTER_DUPLICATE_WINDOW / 2,
10022+
));
10023+
assert!(!SqlEditorWidget::should_suppress_ctrl_enter_dispatch(
10024+
&mut suppression,
10025+
started_at + CTRL_ENTER_DUPLICATE_WINDOW,
10026+
));
10027+
}
10028+
10029+
#[test]
10030+
fn ctrl_enter_keyup_clears_duplicate_filter() {
10031+
let mut suppression = EnterKeyupSuppression::CtrlEnterExecute(std::time::Instant::now());
10032+
10033+
assert!(SqlEditorWidget::take_enter_keyup_suppression(
10034+
Key::Enter,
10035+
&mut suppression,
10036+
));
10037+
assert_eq!(suppression, EnterKeyupSuppression::None);
10038+
}
10039+
1001010040
#[test]
1001110041
fn delete_auto_trigger_does_not_require_an_already_visible_popup() {
1001210042
assert!(SqlEditorWidget::should_auto_trigger_after_delete("a"));

0 commit comments

Comments
 (0)