diff options
Diffstat (limited to 'extension/src/util')
| -rw-r--r-- | extension/src/util/util.ts | 115 | ||||
| -rw-r--r-- | extension/src/util/vscode.ts | 152 | 
2 files changed, 267 insertions, 0 deletions
diff --git a/extension/src/util/util.ts b/extension/src/util/util.ts new file mode 100644 index 00000000..d33593e1 --- /dev/null +++ b/extension/src/util/util.ts @@ -0,0 +1,115 @@ +import { RangeInFile, SerializedDebugContext } from "../client"; +import * as fs from "fs"; + +function charIsEscapedAtIndex(index: number, str: string): boolean { +  if (index === 0) return false; +  if (str[index - 1] !== "\\") return false; +  return !charIsEscapedAtIndex(index - 1, str); +} + +export function convertSingleToDoubleQuoteJSON(json: string): string { +  const singleQuote = "'"; +  const doubleQuote = '"'; +  const isQuote = (char: string) => +    char === doubleQuote || char === singleQuote; + +  let newJson = ""; +  let insideString = false; +  let enclosingQuoteType = doubleQuote; +  for (let i = 0; i < json.length; i++) { +    if (insideString) { +      if (json[i] === enclosingQuoteType && !charIsEscapedAtIndex(i, json)) { +        // Close string with a double quote +        insideString = false; +        newJson += doubleQuote; +      } else if (json[i] === singleQuote) { +        if (charIsEscapedAtIndex(i, json)) { +          // Unescape single quote +          newJson = newJson.slice(0, -1); +        } +        newJson += singleQuote; +      } else if (json[i] === doubleQuote) { +        if (!charIsEscapedAtIndex(i, json)) { +          // Escape double quote +          newJson += "\\"; +        } +        newJson += doubleQuote; +      } else { +        newJson += json[i]; +      } +    } else { +      if (isQuote(json[i])) { +        insideString = true; +        enclosingQuoteType = json[i]; +        newJson += doubleQuote; +      } else { +        newJson += json[i]; +      } +    } +  } + +  return newJson; +} + +export async function readRangeInFile( +  rangeInFile: RangeInFile +): Promise<string> { +  const range = rangeInFile.range; +  return new Promise((resolve, reject) => { +    fs.readFile(rangeInFile.filepath, (err, data) => { +      if (err) { +        reject(err); +      } else { +        let lines = data.toString().split("\n"); +        if (range.start.line === range.end.line) { +          resolve( +            lines[rangeInFile.range.start.line].slice( +              rangeInFile.range.start.character, +              rangeInFile.range.end.character +            ) +          ); +        } else { +          let firstLine = lines[range.start.line].slice(range.start.character); +          let lastLine = lines[range.end.line].slice(0, range.end.character); +          let middleLines = lines.slice(range.start.line + 1, range.end.line); +          resolve([firstLine, ...middleLines, lastLine].join("\n")); +        } +      } +    }); +  }); +} + +export function codeSelectionsToVirtualFileSystem( +  codeSelections: RangeInFile[] +): { +  [filepath: string]: string; +} { +  let virtualFileSystem: { [filepath: string]: string } = {}; +  for (let cs of codeSelections) { +    if (!cs.filepath) continue; +    if (cs.filepath in virtualFileSystem) continue; +    let content = fs.readFileSync(cs.filepath, "utf8"); +    virtualFileSystem[cs.filepath] = content; +  } +  return virtualFileSystem; +} + +export function addFileSystemToDebugContext( +  ctx: SerializedDebugContext +): SerializedDebugContext { +  ctx.filesystem = codeSelectionsToVirtualFileSystem(ctx.rangesInFiles); +  return ctx; +} + +export function debounced(delay: number, fn: Function) { +  let timerId: NodeJS.Timeout | null; +  return function (...args: any[]) { +    if (timerId) { +      clearTimeout(timerId); +    } +    timerId = setTimeout(() => { +      fn(...args); +      timerId = null; +    }, delay); +  }; +} diff --git a/extension/src/util/vscode.ts b/extension/src/util/vscode.ts new file mode 100644 index 00000000..4eab98a7 --- /dev/null +++ b/extension/src/util/vscode.ts @@ -0,0 +1,152 @@ +import * as vscode from "vscode"; +import * as path from "path"; +import * as fs from "fs"; + +export function translate(range: vscode.Range, lines: number): vscode.Range { +  return new vscode.Range( +    range.start.line + lines, +    range.start.character, +    range.end.line + lines, +    range.end.character +  ); +} + +export function getNonce() { +  let text = ""; +  const possible = +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; +  for (let i = 0; i < 32; i++) { +    text += possible.charAt(Math.floor(Math.random() * possible.length)); +  } +  return text; +} + +export function getTestFile( +  filename: string, +  createFile: boolean = false +): string { +  let basename = path.basename(filename).split(".")[0]; +  switch (path.extname(filename)) { +    case ".py": +      basename += "_test"; +      break; +    case ".js": +    case ".jsx": +    case ".ts": +    case ".tsx": +      basename += ".test"; +      break; +    default: +      basename += "_test"; +  } + +  const directory = path.join(path.dirname(filename), "tests"); +  const testFilename = path.join(directory, basename + path.extname(filename)); + +  // Optionally, create the file if it doesn't exist +  if (createFile && !fs.existsSync(testFilename)) { +    if (!fs.existsSync(directory)) { +      fs.mkdirSync(directory); +    } +    fs.writeFileSync(testFilename, ""); +  } + +  return testFilename; +} + +export function getExtensionUri(): vscode.Uri { +  return vscode.extensions.getExtension("Continue.continue")!.extensionUri; +} + +export function getViewColumnOfFile( +  filepath: string +): vscode.ViewColumn | undefined { +  for (let tabGroup of vscode.window.tabGroups.all) { +    for (let tab of tabGroup.tabs) { +      if ( +        (tab?.input as any)?.uri && +        (tab.input as any).uri.fsPath === filepath +      ) { +        return tabGroup.viewColumn; +      } +    } +  } +  return undefined; +} + +export function getRightViewColumn(): vscode.ViewColumn { +  // When you want to place in the rightmost panel if there is already more than one, otherwise use Beside +  let column = vscode.ViewColumn.Beside; +  let columnOrdering = [ +    vscode.ViewColumn.One, +    vscode.ViewColumn.Beside, +    vscode.ViewColumn.Two, +    vscode.ViewColumn.Three, +    vscode.ViewColumn.Four, +    vscode.ViewColumn.Five, +    vscode.ViewColumn.Six, +    vscode.ViewColumn.Seven, +    vscode.ViewColumn.Eight, +    vscode.ViewColumn.Nine, +  ]; +  for (let tabGroup of vscode.window.tabGroups.all) { +    if ( +      columnOrdering.indexOf(tabGroup.viewColumn) > +      columnOrdering.indexOf(column) +    ) { +      column = tabGroup.viewColumn; +    } +  } +  return column; +} + +export async function readFileAtRange( +  range: vscode.Range, +  filepath: string +): Promise<string> { +  return new Promise((resolve, reject) => { +    fs.readFile(filepath, (err, data) => { +      if (err) { +        reject(err); +      } else { +        let lines = data.toString().split("\n"); +        if (range.isSingleLine) { +          resolve( +            lines[range.start.line].slice( +              range.start.character, +              range.end.character +            ) +          ); +        } else { +          let firstLine = lines[range.start.line].slice(range.start.character); +          let lastLine = lines[range.end.line].slice(0, range.end.character); +          let middleLines = lines.slice(range.start.line + 1, range.end.line); +          resolve([firstLine, ...middleLines, lastLine].join("\n")); +        } +      } +    }); +  }); +} + +export function openEditorAndRevealRange( +  editorFilename: string, +  range?: vscode.Range, +  viewColumn?: vscode.ViewColumn +): Promise<vscode.TextEditor> { +  return new Promise((resolve, _) => { +    // Check if the editor is already open +    vscode.workspace.openTextDocument(editorFilename).then((doc) => { +      vscode.window +        .showTextDocument( +          doc, +          getViewColumnOfFile(editorFilename) || viewColumn +        ) +        .then((editor) => { +          if (range) { +            editor.revealRange(range); +          } +          resolve(editor); +        }); +    }); +  }); +}  | 
