Repository: elm-tooling/elm-language-server
Pull request #660 (2021-11-18 01:42:55)

addImport refactoring should respect module docs
If we have no imports, we need to add our import
after the module doc, if it exists.

Otherwise just add it after the module.

Fixes https://github.com/elm-tooling/elm-language-server/issues/659


Patch:
diff --git a/src/util/refactorEditUtils.ts b/src/util/refactorEditUtils.ts
index 3dcc68f..1672158 100644
--- a/src/util/refactorEditUtils.ts
+++ b/src/util/refactorEditUtils.ts
@@ -200,6 +200,7 @@ export class RefactorEditUtils {
   ): TextEdit | undefined {
     const lastImportNode =
       TreeUtils.getLastImportNode(tree) ??
+      TreeUtils.getModuleNameCommentNode(tree) ??
       TreeUtils.getModuleNameNode(tree)?.parent;
 
     return TextEdit.insert(
diff --git a/src/util/treeUtils.ts b/src/util/treeUtils.ts
index ae5c66b..b748131 100644
--- a/src/util/treeUtils.ts
+++ b/src/util/treeUtils.ts
@@ -35,6 +35,14 @@ export class TreeUtils {
     return moduleDeclaration?.childForFieldName("name") ?? undefined;
   }
 
+  public static getModuleNameCommentNode(tree: Tree): SyntaxNode | undefined {
+    const moduleDeclaration: SyntaxNode | undefined =
+      this.findModuleDeclaration(tree);
+    return moduleDeclaration?.nextNamedSibling?.type === "block_comment"
+      ? moduleDeclaration.nextNamedSibling
+      : undefined;
+  }
+
   public static getModuleExposingListNodes(tree: Tree): SyntaxNode[] {
     const moduleNode = TreeUtils.findModuleDeclaration(tree);
 


Test patch:
diff --git a/test/completionProvider.test.ts b/test/completionProvider.test.ts
index 86cfb6b..2c6dd4b 100644
--- a/test/completionProvider.test.ts
+++ b/test/completionProvider.test.ts
@@ -47,9 +47,8 @@ describe("CompletionProvider", () => {
     await treeParser.init();
     const completionProvider = new MockCompletionProvider();
 
-    const { newSources, position, fileWithCaret } = getCaretPositionFromSource(
-      source,
-    );
+    const { newSources, position, fileWithCaret } =
+      getCaretPositionFromSource(source);
 
     if (!position) {
       throw new Error("Getting position failed");
@@ -1147,7 +1146,6 @@ test = Module.{-caret-}
     const source = `
 --@ Module.elm
 module Module exposing (..)
-
 testFunc = ""
 
 type Msg = Msg1 | Msg2
@@ -1156,7 +1154,6 @@ type alias Model = { field : String }
 
 --@ Test.elm
 module Test exposing (..)
-
 test = div [] [ Module.{-caret-} ]
 `;
 
@@ -1204,6 +1201,70 @@ test = div [] [ Module.{-caret-} ]
     );
   });
 
+  it("Non imported qualified modules should have value completions with auto imports after module docs", async () => {
+    const source = `
+--@ Module.elm
+module Module exposing (..)
+testFunc = ""
+
+type Msg = Msg1 | Msg2
+
+type alias Model = { field : String }
+
+--@ Test.elm
+module Test exposing (..)
+{-| Test
+-}
+
+{-| test
+-}
+test = div [] [ Module.{-caret-} ]
+`;
+
+    await testCompletions(
+      source,
+      [
+        {
+          label: "testFunc",
+          detail: "Auto import module 'Module'",
+          additionalTextEdits: [
+            TextEdit.insert(Position.create(3, 0), "import Module\n"),
+          ],
+        },
+        {
+          label: "Msg",
+          detail: "Auto import module 'Module'",
+          additionalTextEdits: [
+            TextEdit.insert(Position.create(3, 0), "import Module\n"),
+          ],
+        },
+        {
+          label: "Msg1",
+          detail: "Auto import module 'Module'",
+          additionalTextEdits: [
+            TextEdit.insert(Position.create(3, 0), "import Module\n"),
+          ],
+        },
+        {
+          label: "Msg2",
+          detail: "Auto import module 'Module'",
+          additionalTextEdits: [
+            TextEdit.insert(Position.create(3, 0), "import Module\n"),
+          ],
+        },
+        {
+          label: "Model",
+          detail: "Auto import module 'Module'",
+          additionalTextEdits: [
+            TextEdit.insert(Position.create(3, 0), "import Module\n"),
+          ],
+        },
+      ],
+      "exactMatch",
+      "triggeredByDot",
+    );
+  });
+
   // Ref: https://github.com/elm-tooling/elm-language-server/issues/288
   it("Record completions should not interfere with Module completions", async () => {
     const source = `