mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-05-15 20:21:38 +00:00
init
This commit is contained in:
95
src/core/autocomplete/context-detection.ts
Normal file
95
src/core/autocomplete/context-detection.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import { generateRandomString } from "./utils";
|
||||
|
||||
const UNIQUE_CURSOR = `${generateRandomString(16)}`;
|
||||
const HEADER_REGEX = `^#+\\s.*${UNIQUE_CURSOR}.*$`;
|
||||
const UNORDERED_LIST_REGEX = `^\\s*(-|\\*)\\s.*${UNIQUE_CURSOR}.*$`;
|
||||
const TASK_LIST_REGEX = `^\\s*(-|[0-9]+\\.) +\\[.\\]\\s.*${UNIQUE_CURSOR}.*$`;
|
||||
const BLOCK_QUOTES_REGEX = `^\\s*>.*${UNIQUE_CURSOR}.*$`;
|
||||
const NUMBERED_LIST_REGEX = `^\\s*\\d+\\.\\s.*${UNIQUE_CURSOR}.*$`
|
||||
const MATH_BLOCK_REGEX = /\$\$[\s\S]*?\$\$/g;
|
||||
const INLINE_MATH_BLOCK_REGEX = /\$[\s\S]*?\$/g;
|
||||
const CODE_BLOCK_REGEX = /```[\s\S]*?```/g;
|
||||
const INLINE_CODE_BLOCK_REGEX = /`.*`/g;
|
||||
|
||||
enum Context {
|
||||
Text = "Text",
|
||||
Heading = "Heading",
|
||||
BlockQuotes = "BlockQuotes",
|
||||
UnorderedList = "UnorderedList",
|
||||
NumberedList = "NumberedList",
|
||||
CodeBlock = "CodeBlock",
|
||||
MathBlock = "MathBlock",
|
||||
TaskList = "TaskList",
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Context {
|
||||
export function values(): Array<Context> {
|
||||
return Object.values(Context).filter(
|
||||
(value) => typeof value === "string"
|
||||
) as Array<Context>;
|
||||
}
|
||||
|
||||
export function getContext(prefix: string, suffix: string): Context {
|
||||
if (new RegExp(HEADER_REGEX, "gm").test(prefix + UNIQUE_CURSOR + suffix)) {
|
||||
return Context.Heading;
|
||||
}
|
||||
if (new RegExp(BLOCK_QUOTES_REGEX, "gm").test(prefix + UNIQUE_CURSOR + suffix)) {
|
||||
return Context.BlockQuotes;
|
||||
}
|
||||
|
||||
if (new RegExp(TASK_LIST_REGEX, "gm").test(prefix + UNIQUE_CURSOR + suffix)) {
|
||||
return Context.TaskList;
|
||||
}
|
||||
|
||||
if (
|
||||
isCursorInRegexBlock(prefix, suffix, MATH_BLOCK_REGEX) ||
|
||||
isCursorInRegexBlock(prefix, suffix, INLINE_MATH_BLOCK_REGEX)
|
||||
) {
|
||||
return Context.MathBlock;
|
||||
}
|
||||
|
||||
if (isCursorInRegexBlock(prefix, suffix, CODE_BLOCK_REGEX) || isCursorInRegexBlock(prefix, suffix, INLINE_CODE_BLOCK_REGEX)) {
|
||||
return Context.CodeBlock;
|
||||
}
|
||||
if (new RegExp(NUMBERED_LIST_REGEX, "gm").test(prefix + UNIQUE_CURSOR + suffix)) {
|
||||
return Context.NumberedList;
|
||||
}
|
||||
if (new RegExp(UNORDERED_LIST_REGEX, "gm").test(prefix + UNIQUE_CURSOR + suffix)) {
|
||||
return Context.UnorderedList;
|
||||
}
|
||||
|
||||
return Context.Text;
|
||||
}
|
||||
|
||||
export function get(value: string) {
|
||||
for (const context of Context.values()) {
|
||||
if (value === context) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function isCursorInRegexBlock(
|
||||
prefix: string,
|
||||
suffix: string,
|
||||
regex: RegExp
|
||||
): boolean {
|
||||
const text = prefix + UNIQUE_CURSOR + suffix;
|
||||
const codeBlocks = extractBlocks(text, regex);
|
||||
for (const block of codeBlocks) {
|
||||
if (block.includes(UNIQUE_CURSOR)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function extractBlocks(text: string, regex: RegExp) {
|
||||
const codeBlocks = text.match(regex);
|
||||
return codeBlocks ? codeBlocks.map((block) => block.trim()) : [];
|
||||
}
|
||||
|
||||
export default Context;
|
||||
Reference in New Issue
Block a user