Repository: astral-sh/ruff
File: crates/ty_ide/src/completion.rs (Rust)

Code before:
    Event,
    Operator,
    TypeParameter,
}

#[derive(Clone, Debug, Default)]
pub struct CompletionSettings {
    pub auto_import: bool,
}

pub fn completion<'db>(
    db: &'db dyn Db,
    settings: &CompletionSettings,
    file: File,
    offset: TextSize,
) -> Vec<Completion<'db>> {
    let parsed = parsed_module(db, file).load(db);

    let tokens = tokens_start_before(parsed.tokens(), offset);

    if is_in_no_completions_place(db, tokens, file) {
        return vec![];
    }

    if let Some(completions) = keyword_completions(tokens) {
        return vec![completions];
    }

    let typed = find_typed_text(db, file, &parsed, offset);
    let typed_query = typed
        .as_deref()
        .map(QueryPattern::new)
        .unwrap_or_else(QueryPattern::matches_all_symbols);

    let Some(target_token) = CompletionTargetTokens::find(&parsed, offset) else {
        return vec![];
    };
    let Some(target) = target_token.ast(&parsed, offset) else {
        return vec![];
    };

    let model = SemanticModel::new(db, file);
    let (semantic_completions, scoped) = match target {
        CompletionTargetAst::ObjectDot { expr } => (model.attribute_completions(expr), None),
        CompletionTargetAst::ObjectDotInImport { import, name } => {
            (model.import_submodule_completions(import, name), None)
        }
        CompletionTargetAst::ObjectDotInImportFrom { import } => {
            (model.from_import_submodule_completions(import), None)
        }
        CompletionTargetAst::ImportFrom { import, name } => {

Review comment (suggestion):
I don't think it's true in the long term that all locations where we might want to offer a keyword completion are places where we definitely won't want to offer any non-keyword completions. For example `pass` (a keyword) and `print` (a non-keyword) should both be included in our completion suggestions in this example:

```py
match x:
    case int():
        p<CURSOR>
```

so the semantics you're adding in this PR are totally correct, but that might imply a different code structure here that would be more extensible in the future

Code after:
    Event,
    Operator,
    TypeParameter,
}

#[derive(Clone, Debug, Default)]
pub struct CompletionSettings {
    pub auto_import: bool,
}

pub fn completion<'db>(
    db: &'db dyn Db,
    settings: &CompletionSettings,
    file: File,
    offset: TextSize,
) -> Vec<Completion<'db>> {
    let parsed = parsed_module(db, file).load(db);
    let tokens = tokens_start_before(parsed.tokens(), offset);
    let typed = find_typed_text(db, file, &parsed, offset);

    if is_in_no_completions_place(db, tokens, file) {
        return vec![];
    }
    if let Some(completions) = only_keyword_completion(tokens, typed.as_deref()) {
        return vec![completions];
    }

    let typed_query = typed
        .as_deref()
        .map(QueryPattern::new)
        .unwrap_or_else(QueryPattern::matches_all_symbols);

    let Some(target_token) = CompletionTargetTokens::find(&parsed, offset) else {
        return vec![];
    };
    let Some(target) = target_token.ast(&parsed, offset) else {
        return vec![];
    };

    let model = SemanticModel::new(db, file);
    let (semantic_completions, scoped) = match target {
        CompletionTargetAst::ObjectDot { expr } => (model.attribute_completions(expr), None),
        CompletionTargetAst::ObjectDotInImport { import, name } => {
            (model.import_submodule_completions(import, name), None)
        }
        CompletionTargetAst::ObjectDotInImportFrom { import } => {
            (model.from_import_submodule_completions(import), None)
        }
        CompletionTargetAst::ImportFrom { import, name } => {
            (model.from_import_completions(import, name), None)
        }