Mirror: TypeScript LSP plugin that finds GraphQL documents in your code and provides diagnostics, auto-complete and hover-information.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

bring implementations closer together

+64 -116
+44 -79
packages/graphqlsp/src/autoComplete.ts
··· 53 53 ? bubbleUpCallExpression(node) 54 54 : bubbleUpTemplate(node); 55 55 56 + let text, cursor; 56 57 if ( 57 58 ts.isCallExpression(node) && 58 59 isCallExpression && ··· 65 66 66 67 const queryText = node.arguments[0].getText(); 67 68 const fragments = getAllFragments(filename, node, info); 68 - const cursor = new Cursor(foundToken.line, foundToken.start - 1); 69 - const text = `${queryText}\m${fragments.map(x => print(x)).join('\n')}`; 70 69 71 - const [suggestions, spreadSuggestions] = getSuggestionsInternal( 72 - schema.current, 73 - text, 74 - cursor 75 - ); 76 - 77 - return { 78 - isGlobalCompletion: false, 79 - isMemberCompletion: false, 80 - isNewIdentifierLocation: false, 81 - entries: [ 82 - ...suggestions.map(suggestion => ({ 83 - ...suggestion, 84 - kind: ts.ScriptElementKind.variableElement, 85 - name: suggestion.label, 86 - kindModifiers: 'declare', 87 - sortText: suggestion.sortText || '0', 88 - labelDetails: { 89 - detail: suggestion.type 90 - ? ' ' + suggestion.type?.toString() 91 - : undefined, 92 - description: suggestion.documentation, 93 - }, 94 - })), 95 - ...spreadSuggestions.map(suggestion => ({ 96 - ...suggestion, 97 - kind: ts.ScriptElementKind.variableElement, 98 - name: suggestion.label, 99 - insertText: '...' + suggestion.label, 100 - kindModifiers: 'declare', 101 - sortText: '0', 102 - labelDetails: { 103 - description: suggestion.documentation, 104 - }, 105 - })), 106 - ], 107 - }; 70 + text = `${queryText}\m${fragments.map(x => print(x)).join('\n')}`; 71 + cursor = new Cursor(foundToken.line, foundToken.start - 1); 108 72 } else if (ts.isTaggedTemplateExpression(node)) { 109 73 const { template, tag } = node; 110 74 ··· 113 77 const foundToken = getToken(template, cursorPosition); 114 78 if (!foundToken || !schema.current) return undefined; 115 79 116 - const { combinedText: text, resolvedSpans } = resolveTemplate( 80 + const { combinedText, resolvedSpans } = resolveTemplate( 117 81 node, 118 82 filename, 119 83 info ··· 129 93 130 94 foundToken.line = foundToken.line + amountOfLines; 131 95 132 - const cursor = new Cursor(foundToken.line, foundToken.start - 1); 133 - 134 - const [suggestions, spreadSuggestions] = getSuggestionsInternal( 135 - schema.current, 136 - text, 137 - cursor 138 - ); 139 - 140 - return { 141 - isGlobalCompletion: false, 142 - isMemberCompletion: false, 143 - isNewIdentifierLocation: false, 144 - entries: [ 145 - ...suggestions.map(suggestion => ({ 146 - ...suggestion, 147 - kind: ts.ScriptElementKind.variableElement, 148 - name: suggestion.label, 149 - kindModifiers: 'declare', 150 - sortText: suggestion.sortText || '0', 151 - labelDetails: { 152 - detail: suggestion.type 153 - ? ' ' + suggestion.type?.toString() 154 - : undefined, 155 - description: suggestion.documentation, 156 - }, 157 - })), 158 - ...spreadSuggestions.map(suggestion => ({ 159 - ...suggestion, 160 - kind: ts.ScriptElementKind.variableElement, 161 - name: suggestion.label, 162 - insertText: '...' + suggestion.label, 163 - kindModifiers: 'declare', 164 - sortText: '0', 165 - labelDetails: { 166 - description: suggestion.documentation, 167 - }, 168 - })), 169 - ], 170 - }; 96 + text = combinedText; 97 + cursor = new Cursor(foundToken.line, foundToken.start - 1); 171 98 } else { 172 99 return undefined; 173 100 } 101 + 102 + const [suggestions, spreadSuggestions] = getSuggestionsInternal( 103 + schema.current, 104 + text, 105 + cursor 106 + ); 107 + 108 + return { 109 + isGlobalCompletion: false, 110 + isMemberCompletion: false, 111 + isNewIdentifierLocation: false, 112 + entries: [ 113 + ...suggestions.map(suggestion => ({ 114 + ...suggestion, 115 + kind: ts.ScriptElementKind.variableElement, 116 + name: suggestion.label, 117 + kindModifiers: 'declare', 118 + sortText: suggestion.sortText || '0', 119 + labelDetails: { 120 + detail: suggestion.type 121 + ? ' ' + suggestion.type?.toString() 122 + : undefined, 123 + description: suggestion.documentation, 124 + }, 125 + })), 126 + ...spreadSuggestions.map(suggestion => ({ 127 + ...suggestion, 128 + kind: ts.ScriptElementKind.variableElement, 129 + name: suggestion.label, 130 + insertText: '...' + suggestion.label, 131 + kindModifiers: 'declare', 132 + sortText: '0', 133 + labelDetails: { 134 + description: suggestion.documentation, 135 + }, 136 + })), 137 + ], 138 + }; 174 139 } 175 140 176 141 export function getSuggestionsInternal(
+20 -37
packages/graphqlsp/src/quickInfo.ts
··· 11 11 import { resolveTemplate } from './ast/resolve'; 12 12 import { getToken } from './ast/token'; 13 13 import { Cursor } from './ast/cursor'; 14 - import { Logger } from '.'; 15 14 16 15 export function getGraphQLQuickInfo( 17 16 filename: string, ··· 19 18 schema: { current: GraphQLSchema | null }, 20 19 info: ts.server.PluginCreateInfo 21 20 ): ts.QuickInfo | undefined { 22 - const logger: Logger = (msg: string) => 23 - info.project.projectService.logger.info(`[GraphQLSP] ${msg}`); 24 21 const tagTemplate = info.config.template || 'gql'; 25 22 const isCallExpression = info.config.templateIsCallExpression ?? false; 26 23 ··· 34 31 ? bubbleUpCallExpression(node) 35 32 : bubbleUpTemplate(node); 36 33 34 + let cursor, text; 37 35 if ( 38 36 ts.isCallExpression(node) && 39 37 isCallExpression && ··· 44 42 const foundToken = getToken(node.arguments[0], cursorPosition); 45 43 if (!schema.current || !foundToken) return undefined; 46 44 47 - const queryText = node.arguments[0].getText(); 48 - const cursor = new Cursor(foundToken.line, foundToken.start - 1); 49 - const hoverInfo = getHoverInformation(schema.current, queryText, cursor); 50 - 51 - return { 52 - kind: ts.ScriptElementKind.string, 53 - textSpan: { 54 - start: cursorPosition, 55 - length: 1, 56 - }, 57 - kindModifiers: 'text', 58 - documentation: Array.isArray(hoverInfo) 59 - ? hoverInfo.map(item => ({ kind: 'text', text: item as string })) 60 - : [{ kind: 'text', text: hoverInfo as string }], 61 - }; 45 + text = node.arguments[0].getText(); 46 + cursor = new Cursor(foundToken.line, foundToken.start - 1); 62 47 } else if (ts.isTaggedTemplateExpression(node)) { 63 48 const { template, tag } = node; 64 49 if (!ts.isIdentifier(tag) || tag.text !== tagTemplate) return undefined; ··· 67 52 68 53 if (!foundToken || !schema.current) return undefined; 69 54 70 - const { combinedText: text, resolvedSpans } = resolveTemplate( 55 + const { combinedText, resolvedSpans } = resolveTemplate( 71 56 node, 72 57 filename, 73 58 info ··· 82 67 .reduce((acc, span) => acc + (span.lines - 1), 0); 83 68 84 69 foundToken.line = foundToken.line + amountOfLines; 85 - 86 - const hoverInfo = getHoverInformation( 87 - schema.current, 88 - text, 89 - new Cursor(foundToken.line, foundToken.start - 1) 90 - ); 91 - 92 - return { 93 - kind: ts.ScriptElementKind.label, 94 - textSpan: { 95 - start: cursorPosition, 96 - length: 1, 97 - }, 98 - kindModifiers: 'text', 99 - documentation: Array.isArray(hoverInfo) 100 - ? hoverInfo.map(item => ({ kind: 'text', text: item as string })) 101 - : [{ kind: 'text', text: hoverInfo as string }], 102 - } as ts.QuickInfo; 70 + text = combinedText; 71 + cursor = new Cursor(foundToken.line, foundToken.start - 1); 103 72 } else { 104 73 return undefined; 105 74 } 75 + 76 + const hoverInfo = getHoverInformation(schema.current, text, cursor); 77 + 78 + return { 79 + kind: ts.ScriptElementKind.label, 80 + textSpan: { 81 + start: cursorPosition, 82 + length: 1, 83 + }, 84 + kindModifiers: 'text', 85 + documentation: Array.isArray(hoverInfo) 86 + ? hoverInfo.map(item => ({ kind: 'text', text: item as string })) 87 + : [{ kind: 'text', text: hoverInfo as string }], 88 + } as ts.QuickInfo; 106 89 }