mirror of
https://github.com/CodedotAl/code-clippy-vscode.git
synced 2024-10-05 17:58:19 +03:00
Added out directory (to start the project without install dependencies)
This commit is contained in:
parent
652bebf1b4
commit
c3083df667
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
out
|
||||
|
||||
node_modules
|
||||
.vscode-test/
|
||||
*.vsix
|
||||
|
8
out/config.js
Normal file
8
out/config.js
Normal file
@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const CSConfig = {
|
||||
SEARCH_ENDPOINT: `https://www.google.com/search?q=site%3Astackoverflow.com+`,
|
||||
SEARCH_PHARSE_START: `//find`,
|
||||
SEARCH_PHARSE_END: `.`
|
||||
};
|
||||
exports.default = CSConfig;
|
47
out/extension.js
Normal file
47
out/extension.js
Normal file
@ -0,0 +1,47 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.activate = void 0;
|
||||
const vscode = require("vscode");
|
||||
const config_1 = require("./config");
|
||||
const search_1 = require("./utils/search");
|
||||
function activate(context) {
|
||||
const disposable = vscode.commands.registerCommand('extension.copilot-clone-settings', () => {
|
||||
vscode.window.showInformationMessage('Show settings');
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
const provider = {
|
||||
provideInlineCompletionItems: async (document, position, context, token) => {
|
||||
const textBeforeCursor = document.getText(new vscode.Range(position.with(undefined, 0), position));
|
||||
if (textBeforeCursor.indexOf(config_1.default.SEARCH_PHARSE_START) == 0 && textBeforeCursor[textBeforeCursor.length - 1] === config_1.default.SEARCH_PHARSE_END) {
|
||||
let rs;
|
||||
try {
|
||||
rs = await search_1.search(textBeforeCursor);
|
||||
}
|
||||
catch (err) {
|
||||
vscode.window.showErrorMessage(err.toString());
|
||||
return { items: [] };
|
||||
}
|
||||
if (rs == null) {
|
||||
return { items: [] };
|
||||
}
|
||||
const items = new Array();
|
||||
rs.results.forEach((item, i) => {
|
||||
const output = `\n// Source: https://stackoverflow.com${item.sourceURL}\n${item.code}`;
|
||||
items.push({
|
||||
text: output,
|
||||
range: new vscode.Range(position.translate(0, output.length), position),
|
||||
trackingId: `snippet-${i}`,
|
||||
});
|
||||
});
|
||||
return { items };
|
||||
}
|
||||
return { items: [] };
|
||||
},
|
||||
};
|
||||
vscode.languages.registerInlineCompletionItemProvider({ pattern: "**" }, provider);
|
||||
// Be aware that the API around `getInlineCompletionItemController` will not be finalized as is!
|
||||
vscode.window.getInlineCompletionItemController(provider).onDidShowCompletionItem(e => {
|
||||
const id = e.completionItem.trackingId;
|
||||
});
|
||||
}
|
||||
exports.activate = activate;
|
18
out/utils/extractGoogleResults.js
Normal file
18
out/utils/extractGoogleResults.js
Normal file
@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.extractGoogleResults = void 0;
|
||||
const config_1 = require("../config");
|
||||
const fetchPageContent_1 = require("./fetchPageContent");
|
||||
// Get search results from google, then return a list of stackoverflow links
|
||||
function extractGoogleResults(keyword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return fetchPageContent_1.fetchPageTextContent(`${config_1.default.SEARCH_ENDPOINT}${keyword.replace(/\s/, '+')}`)
|
||||
.then(rs => {
|
||||
let urls = rs.textContent.match(/(https:\/\/stackoverflow.com\/[a-z0-9-/]+)/g);
|
||||
urls && (urls = urls.filter((url, i, list) => list.indexOf(url) === i));
|
||||
resolve(urls);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
exports.extractGoogleResults = extractGoogleResults;
|
37
out/utils/extractStackOverflowResults.js
Normal file
37
out/utils/extractStackOverflowResults.js
Normal file
@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.extractSnippetResults = void 0;
|
||||
const jsdom_1 = require("jsdom");
|
||||
// Extract and sort stackoverflow answers
|
||||
function extractSnippetResults(options) {
|
||||
var doc = new jsdom_1.JSDOM(options.textContent);
|
||||
let answersWithCodeBlock = Array.from(doc.window.document.querySelectorAll(".answer"))
|
||||
.filter((item) => item.querySelector("code") != null);
|
||||
let results = answersWithCodeBlock
|
||||
.map((item) => ({
|
||||
textContent: item.textContent,
|
||||
votes: parseInt(item.querySelector(".js-vote-count").textContent),
|
||||
// TODO: Handle answers with more than one code block
|
||||
// p/s: they often about explaining the something
|
||||
code: item.querySelector("code").textContent,
|
||||
sourceURL: item.querySelector(".js-share-link").href,
|
||||
hasCheckMark: item.querySelector("iconCheckmarkLg") != null
|
||||
}))
|
||||
.filter(item => isCodeValid(item.code));
|
||||
results.sort(sortSnippetResultFn);
|
||||
return { url: options.url, results };
|
||||
}
|
||||
exports.extractSnippetResults = extractSnippetResults;
|
||||
function sortSnippetResultFn(a, b) {
|
||||
if (a.hasCheckMark != b.hasCheckMark) {
|
||||
return a.hasCheckMark ? 1 : -1;
|
||||
}
|
||||
let result = b.votes - a.votes;
|
||||
return result === 0 ? b.code.length - a.code.length : result;
|
||||
}
|
||||
// Check whether the input should be considered as code input or random text
|
||||
function isCodeValid(input) {
|
||||
// This is just a temporary solution,
|
||||
// it would filter codes that are too short
|
||||
return input.length > 12;
|
||||
}
|
13
out/utils/fetchPageContent.js
Normal file
13
out/utils/fetchPageContent.js
Normal file
@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fetchPageTextContent = void 0;
|
||||
const node_fetch_1 = require("node-fetch");
|
||||
function fetchPageTextContent(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return node_fetch_1.default(url)
|
||||
.then(rs => rs.text())
|
||||
.then(textContent => resolve({ textContent, url }))
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
exports.fetchPageTextContent = fetchPageTextContent;
|
33
out/utils/search.js
Normal file
33
out/utils/search.js
Normal file
@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.search = void 0;
|
||||
const extractGoogleResults_1 = require("./extractGoogleResults");
|
||||
const extractStackOverflowResults_1 = require("./extractStackOverflowResults");
|
||||
const fetchPageContent_1 = require("./fetchPageContent");
|
||||
// Send search query to google, get answers from stackoverflow
|
||||
// then extract and return code results
|
||||
async function search(keyword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
extractGoogleResults_1.extractGoogleResults(keyword)
|
||||
.then(async (urls) => {
|
||||
if (urls === null) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
let results = [];
|
||||
try {
|
||||
let fetchResult;
|
||||
for (const i in urls.splice(0, 6)) {
|
||||
if (urls[i]) {
|
||||
fetchResult = await fetchPageContent_1.fetchPageTextContent(urls[i]);
|
||||
results = results.concat(extractStackOverflowResults_1.extractSnippetResults(fetchResult).results);
|
||||
}
|
||||
}
|
||||
resolve({ results });
|
||||
}
|
||||
catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
||||
exports.search = search;
|
@ -4,7 +4,7 @@
|
||||
"target": "es2019",
|
||||
"lib": ["ES2019"],
|
||||
"outDir": "out",
|
||||
"sourceMap": true,
|
||||
"sourceMap": false,
|
||||
"strict": true,
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
|
Loading…
Reference in New Issue
Block a user