diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -513,8 +513,9 @@ return {Offset - 1, Offset}; // We could choose either this byte or the previous. Usually we prefer the // character on the right of the cursor (or under a block cursor). - // But if that's whitespace, we likely want the token on the left. - if (isWhitespace(Buf[Offset]) && !isWhitespace(Buf[Offset - 1])) + // But if that's whitespace/semicolon, we likely want the token on the left. + auto IsIgnoredChar = [](char C) { return isWhitespace(C) || C == ';'; }; + if (IsIgnoredChar(Buf[Offset]) && !IsIgnoredChar(Buf[Offset - 1])) return {Offset - 1, Offset}; return {Offset, Offset + 1}; } diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -234,6 +234,7 @@ {"void foo() { [[foo^()]]; }", "CallExpr"}, {"void foo() { [[foo^]] (); }", "DeclRefExpr"}, {"int bar; void foo() [[{ foo (); }]]^", "CompoundStmt"}, + {"int x = [[42]]^;", "IntegerLiteral"}, // Ignores whitespace, comments, and semicolons in the selection. {"void foo() { [[foo^()]]; /*comment*/^}", "CallExpr"}, @@ -271,7 +272,6 @@ // FIXME: Ideally we'd get a declstmt or the VarDecl itself here. // This doesn't happen now; the RAV doesn't traverse a node containing ;. {"int x = 42;^", nullptr}, - {"int x = 42^;", nullptr}, // Common ancestor is logically TUDecl, but we never return that. {"^int x; int y;^", nullptr}, diff --git a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp @@ -88,11 +88,8 @@ R"cpp( // Single statement in TU. [[int v = [[1^00]]]]; )cpp", - // FIXME: No node found associated to the position. R"cpp( // Cursor at end of VarDecl. - void func() { - int v = 100 + 100^; - } + [[int v = [[100]]^]]; )cpp", // FIXME: No node found associated to the position. R"cpp( // Cursor in between spaces.