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

Code before:
            false
        }
    };

    tokens
        .len()
        .checked_sub(2)
        .and_then(|i| tokens.get(i))
        .is_some_and(is_definition_keyword)
}

/// when the tokens indicate that the last token should be a keyword, we provide completions for that
fn keyword_completions<'db>(tokens: &[Token]) -> Option<Completion<'db>> {
    from_import_statement_keyword_completions(tokens)
}

/// Checks whether the tokens indicate that the last token is in the `import` section
/// of the `import_from` definition from <https://docs.python.org/3/reference/grammar.html>.
/// Being in this section means we match all of the parts of the definition up to `import`
/// and we have a `Name` token in place of the `import`.
fn from_import_statement_keyword_completions<'db>(tokens: &[Token]) -> Option<Completion<'db>> {
    if tokens.is_empty() {
        return None;
    }

    let from_index = tokens.iter().position(|t| t.kind() == TokenKind::From)?;

    let tokens_after_from = &tokens[from_index + 1..];

    if tokens_after_from.is_empty() {
        return None;
    }

    // Skip over '('.' | '...')*'
    let dots_count = tokens_after_from
        .iter()
        .map(Token::kind)
        .take_while(|t| matches!(t, TokenKind::Dot | TokenKind::Ellipsis))
        .count();

    let tokens_after_dots = &tokens_after_from[dots_count..];

    let (last_token, tokens_after_dots_before_last_name) = tokens_after_dots.split_last()?;

    if last_token.kind() == TokenKind::Name {
        // If we have `from .('.' | '...')* <name>` we can suggest `import`.
        // We check that we must have at least one `.` because we don't want to suggest `import` for `from <name>`.
        //
        // If we have `from ('.' | '...')* dotted_name <name>` we can suggest `import`.
        if (tokens_after_dots_before_last_name.is_empty() && dots_count > 0)
            || is_dotted_name(tokens_after_dots_before_last_name)

Review comment (bug):
The search here seems to be too permissive to me. What's preventing it from going across logical lines? 

Can you add some tests with multiple statements? I suspect that we now incorrectly match on import completions if there's **any** import statement before `<CURSOR>`. 



Code after:
            _ => return false,
        };
    }
    false
}

/// Looks for the text typed immediately before the cursor offset
/// given.
///
/// If there isn't any typed text or it could not otherwise be found,
/// then `None` is returned.
fn find_typed_text(
    db: &dyn Db,
    file: File,
    parsed: &ParsedModuleRef,
    offset: TextSize,
) -> Option<String> {
    let source = source_text(db, file);
    let tokens = tokens_start_before(parsed.tokens(), offset);
    let last = tokens.last()?;
    // It's odd to include `TokenKind::Import` here, but it
    // indicates that the user has typed `import`. This is
    // useful to know in some contexts.
    if !matches!(last.kind(), TokenKind::Name | TokenKind::Import) {
        return None;
    }
    // This one's weird, but if the cursor is beyond
    // what is in the closest `Name` token, then it's
    // likely we can't infer anything about what has
    // been typed. This likely means there is whitespace
    // or something that isn't represented in the token
    // stream. So just give up.
    if last.end() < offset {
        return None;
    }
    Some(source[last.range()].to_string())
}

/// Whether the last token is in a place where we should not provide completions.
fn is_in_no_completions_place(db: &dyn Db, tokens: &[Token], file: File) -> bool {
    is_in_comment(tokens) || is_in_string(tokens) || is_in_definition_place(db, tokens, file)
}

/// Whether the last token is within a comment or not.
fn is_in_comment(tokens: &[Token]) -> bool {
    tokens.last().is_some_and(|t| t.kind().is_comment())
}

/// Whether the last token is positioned within a string token (regular, f-string, t-string, etc).
///
/// Note that this will return `false` when the last token is positioned within an