// Menu: Spongebob Mocking!// Description: Copy, run and paste!// Author: Ambushfall// Shortcut: ctrl shift ximport '@johnlindquist/kit'const str = await getSelectedText() || await clipboard.readText();const splitStr = str.split(' ')var newString = ''for (let i = 0; i < splitStr.length; i++) {for (let j = 0; j < splitStr[i].length; j++) {// get last char indexconst lastIndexOfSplit = splitStr[i].length - 1;// If the index matches the current add spaceconst addTrailingSpace = j == lastIndexOfSplit ? ' ' : ''const char = `${splitStr[i][j]}${addTrailingSpace}`const formatChar = j % 2 == 0 ? char.toLowerCase() : char.toUpperCase()newString += formatChar;}}await clipboard.writeText(newString);
// Preview: docs// Menu: Open Project// Description: Opens a project in vscode// Shortcut: command shift .import "@johnlindquist/kit";import * as fs from "fs"const envPath = await env('PROJECT_DIR');const projectDir = home(envPath);const unfilteredProjectList = await readdir(projectDir);const projectList = unfilteredProjectList.filter(value => !value.includes('.'));let { projects, write } = await db("projects", {projects: projectList,})projects.forEach(async val => {if (val.includes('.')) {projects.pop(val);await write()}})projectList.forEach(async value => {if (!projects.includes(value)) {projects.push(value);await write()}})onTab("Open", async () => {let project = await arg("Open project:", projects.map(project => project.split('\\').pop()))edit('', path.resolve(projectDir, project))})onTab("Add Path", async () => {while (true) {let project = await arg("Add path to project:",md(projects.map(project => `* ${project.split('\\').pop()}`).join("\n")))projects.push(project)await write()}})onTab("Remove", async () => {while (true) {let project = await arg("Open project:", projects.map(project => project.split('\\').pop()))let del = await arg(`Delete project dir: ${project}?`, ["yes", "no"])if (del === "yes") {fs.rmSync(path.resolve(projectDir, project), { recursive: true, force: true });}project.split(':').length > 1 ? await rm(path.resolve(project)) : await rm(path.resolve(projectDir, project))let indexOfProject = projects.indexOf(project)projects.splice(indexOfProject, 1)await write()}})onTab("New Project", async () => {while (true) {let project = await arg({placeholder: "Create new project:", debounceInput: 400,enter: "Create", validate: async (input) => {const dir = path.resolve(projectDir, input)const exists = await isDir(dir);if (exists) {return `${input} already exists`;} else {const { code, stderr, stdout } = mkdir(dir);if(stderr){throw stderr;}}const initorNot = await arg("Create git repo?", ["yes", "no"])if (initorNot === "yes") {cd(dir);execLog("git init");}edit('', dir)return true;}},)projects.push(project)mkdir(path.resolve(projectDir, project))await write()}})// Test gitpush
// Name: Obsidian Helper// Author: Ambushfall// Description: Usable script to easily add small additions to obsidian and allows preview and edit of markdown files directly.// This is just for speed of use.import '@johnlindquist/kit'import { Choice } from '@johnlindquist/kit'import { readFileSync } from 'fs'import _ from 'lodash'let { obsidiandir, write } = await db('obsidiandir')let route =obsidiandir.length > 0? await arg({placeholder: 'Select Obsidian vault',shortcuts: [{name: 'Cancel',key: 'escape',bar: 'right',onPress: () => mainScript(),visible: true}],onNoChoices: async input => {setPanel(md(`# Vault location not found <code>${input}</code>\n Type <kbd>enter</kbd> to create a new vault at this location: <code>${input}</code>`))},onChoiceFocus: async (_, state) => {const Files: string[] = await readdir(state.focused?.value)const FilteredDir: string[] = Files.filter((file: string) =>file.toLowerCase().includes('.md'))let html = `<h1>Note List:</h1><ul style="margin:20px; padding:10px;">\n`FilteredDir.forEach(e => {html += `<li>${e}</li>`})html += `</ul>`setPreview(html)}},obsidiandir.map((e: string) => {return {type: 'text',name: e.split('\\').at(-1),value: e}})): await path({hint: 'Paste path to your obsidian vault!'})if (!obsidiandir.find((e: string) => e == route) || obsidiandir.length == 0) {obsidiandir.push(route)await write()}if (isDir(route)) {const Files: string[] = await readdir(route)const FilteredDir: string[] = Files.filter((file: string) =>file.toLowerCase().includes('.md'))let { filename } = await arg({placeholder: 'select File'},(): Choice[] => {return FilteredDir.map((file: string) => {const str = readFileSync(path.join(route, file), 'utf-8')// log(str)return {type: 'text',name: file.replaceAll('.md', ''),value: {filename: file},preview: () => md(str)}})})/*** This is taken directly from the examples for editor functionality**/let changed = falselet filePath = path.join(route, filename)let autoSave = _.debounce(async input => {await writeFile(filePath, input.trim())}, 3000)let value = await ensureReadFile(filePath)let cmd = isWin ? 'ctrl' : 'cmd'let content = await editor({value,scrollTo: 'bottom',shortcuts: [{name: 'Save',key: `${cmd}+s`,onPress: input => {submit(input)},bar: 'right'},{name: 'Open',key: `${cmd}+o`,onPress: async () => {open(filePath)},bar: 'right'}],onEscape: async input => {submit(input)},onAbandon: async input => {submit(input)},onInput: async input => {changed = trueautoSave(input)}})hide()let trimmed = content.trim()if (changed) {await writeFile(filePath, trimmed)}}process.exit(0)
// Name: OCR// Description: Capture a screenshot and recognize the text using tesseract.jsimport "@johnlindquist/kit";//both win and linux implementations were created by chatgpt (gpt4), without _any_ tests!! 😅const captureScreenshot = async () => {const tmpFile = kenvTmpPath(`screenshot-${Date.now()}.png`);const scriptFile = kenvTmpPath('script.ps1');if (isMac) {await exec(`screencapture -i ${tmpFile}`);} else if (isWin) {const psScript = `Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('%{PRTSC}');Start-Sleep -m 500;$clipboardData = Get-Clipboard -Format Image;$clipboardData.Save('${tmpFile}', [System.Drawing.Imaging.ImageFormat]::Png);`;// Save to file as powershell inline parsing is tricky, there are special rules to this and it's a pain.// We already have write on disk, so there's really no point in encoding it as a string.await writeFile(scriptFile, psScript.replace(/\n/g, ''))// Execute saved fileawait exec(`powershell -File "${scriptFile}"`);} else if (isLinux) {// Check if gnome-screenshot is availabletry {await exec('gnome-screenshot --version');await exec(`gnome-screenshot -f ${tmpFile}`);} catch (error) {// If gnome-screenshot is not available, try using ImageMagick's 'import' commandawait exec(`import ${tmpFile}`);}}return tmpFile;};const recognizeText = async (filePath, language) => {const { createWorker } = await npm("tesseract.js");const worker = await createWorker();await worker.loadLanguage(language);await worker.initialize(language);const { data } = await worker.recognize(filePath);await worker.terminate();return data.text;};const languages = [{ name: "Spanish", value: "spa" },{ name: "French", value: "fra" },{ name: "Portuguese", value: "por" },{ name: "English", value: "eng" },];//@todo train a model for typescript (https://github.com/tesseract-ocr/tesstrain)// if ctrl is pressed, show a modal to select a languageconst selectedLanguage = flag.ctrl? await arg("Select a language:", languages): "eng";// Hide the Kit modal before capturing the screenshotawait hide();const filePath = await captureScreenshot();if (!await pathExists(filePath)) exit()const text = await recognizeText(filePath, selectedLanguage);if (text) {await clipboard.writeText(text.trim());await notify("Text recognized and copied to clipboard");} else {await notify("No text found in the screenshot");}// Clean up temporary fileawait remove(filePath);
// Name: Run .bat/.ps1/.sh// Description: Process Output to Kit via streamimport '@johnlindquist/kit'// @ts-expect-errorimport { backToMainShortcut, highlightJavaScript } from '@johnlindquist/kit'// --- Create a shell script to run -----------------// `tmpPath` will store the file here:// ~/.kenv/tmp/process-shell-script-output/example.*// Note: linux shell will only work with WSL or you can provide the Args for ps1 using the .sh extension if you have gitbashconst fileName = 'example'const selectedLang = {name: '',args: '',ext: '',echo: '',set setVal (keyValueList: string[]) {this[keyValueList[0]] = keyValueList[1]}}const objGen = (_lang: string, _ext: string, _args?: string) => {_args = _args ? _args : ''return {name: _lang,description: `Run Script using ${_lang}`,value: _lang,id: _ext,arguments: _args,preview: () => highlightJavaScript(tmpPath(`${fileName}.${_ext}`))}}const LangOptions = [objGen('PowerShell','ps1','powershell -NoProfile -NonInteractive –ExecutionPolicy Bypass -File '),objGen('Batch', 'bat'),objGen('Bash', 'sh')]const promptEditor = ['yes', 'no']const selectedValue = await arg('Use editor?', promptEditor)const useEditor = selectedValue === 'yes' ? true : false// define select optionsawait arg({placeholder: 'Select Scripting Language...',enter: 'Select',shortcuts: [backToMainShortcut],onChoiceFocus: async (input, { focused }) => {selectedLang.setVal = ['args', focused['arguments']]selectedLang.setVal = ['ext', focused.id]selectedLang.setVal = ['name', focused.name]selectedLang.setVal = ['echo',selectedLang.ext == 'bat' ? '@echo off' : '']}},LangOptions)const shellScriptPath = kenvTmpPath(`${fileName}.${selectedLang.ext}`)const editorConfig = {hint: `Write code for ${selectedLang.ext} file.`,description: 'Save to Run',onInputSubmit: async (input: any) => {selectedLang.ext == 'sh'? await submit(`${input}exit`): await submit(input)}}// Using ping to simulate waiting for a long process and because it's natively supported across PS and Bat files// Note: If you use a code that would natively not run in bat like "ls" it willlet scriptContents = useEditor? await editor(editorConfig): `${selectedLang.echo}echo "hello"echo "Done"${selectedLang.ext == 'sh' ? 'exit' : ''}`await writeFile(shellScriptPath, scriptContents)// Just a wrapper to highlight with code in PS styleconst codeWrapper = (string: string, extension: any) => `\`\`\`${extension}${string}\`\`\``let output = ``// This is used to avoid kit window closing on process exitlet divPromise = div()const outHandler = async (out: string) => {output += `${out}\n`setDiv(await highlight(`${codeWrapper(output, selectedLang.ext)}`))}// Note: We have to use this janky way of executing PS as it would launch in Notepad or fail entirely.const execArgs =selectedLang.ext == 'sh'? `cd ${tmpPath()} && bash ${fileName}.sh`: `${selectedLang.args}${shellScriptPath}`// inspect(execArgs)let { stdout } = execLog(execArgs, outHandler)setAlwaysOnTop(true)setIgnoreBlur(true)await divPromise
// Preview: docs// Menu: Open Project// Description: Opens a project in vscode// Shortcut: cmd shift .import "@johnlindquist/kit";const envPath = await env('PROJECT_DIR');const projectDir = home(envPath);const projectList = await readdir(projectDir);let { projects, write } = await db("projects", {projects: projectList,})projectList.forEach(async value => {if (!projects.includes(value)) {projects.push(value);await write()}})onTab("Open", async () => {let project = await arg("Open project:", projects.map(project => project.split('\\').pop()))edit('', path.resolve(projectDir, project))})onTab("Add Path", async () => {while (true) {let project = await arg("Add path to project:",md(projects.map(project => `* ${project.split('\\').pop()}`).join("\n")))projects.push(project)await write()}})onTab("Remove", async () => {while (true) {let project = await arg("Open project:", projects.map(project => project.split('\\').pop()))project.split(':').length > 1 ? await rm(path.resolve(project)) : await rm(path.resolve(projectDir, project))let indexOfProject = projects.indexOf(project)projects.splice(indexOfProject, 1)await write()}})onTab("New Project", async () => {while (true) {let project = await arg({placeholder: "Create new project:", debounceInput: 400,enter: "Create", validate: async (input) => {let exists = await isDir(path.resolve(projectDir, input));if (exists) {return `${input} already exists`;}return true;}},)projects.push(project)mkdir(path.resolve(projectDir, project))await write()}})