Preview is not rendered when searching for choices in choices
Hi John π
I'm a Windows User which implemented a own version of snippets
I have a json file which operates as my database
{
"snippetGroups": [
{
"id": "439aea2c-a45d-46ef-9cdf-6feb78288dc9",
"name": "JavaScript",
"choices": [
{
"id": "d896362c-0229-4264-b932-b76084e8669b",
"name": "Hello",
"code": "console.log('hello world')",
"description": "World",
"language": "js",
"group": "JavaScript"
}
]
},
{
"id": "ff87ad52-b632-43ef-ada1-d21078182b4f",
"name": "Shell",
"choices": [
{
"id": "ac60560a-38c7-4a54-804b-883c791a418a",
"name": "WSL Ubuntu search",
"code": "sudo apt-search pack",
"language": "shell",
"description": "Searches for packages",
"group": "Shell"
},
{
"id": "d5d95f81-0099-416f-812f-9f3e510ced0f",
"name": "WSL Ubuntu remove package",
"code": "sudo apt-get remove pack",
"language": "shell",
"description": "Removes given package",
"group": "Shell"
},
{
"id": "464f5ad4-2646-477a-bda9-bcb67cd7aa48",
"name": "WSL Ubuntu update package list",
"code": "sudo apt-get update",
"language": "shell",
"description": "Fetches new versions of installed packages",
"group": "Shell"
},
{
"id": "b2b33cae-592e-444f-82f0-131e31ebf223",
"name": "WSL Ubuntu update packages",
"code": "sudo apt-get upgrade",
"language": "shell",
"description": "Comes after the apt-get update --> Installs new updates for packages",
"group": "Shell"
},
{
"id": "42432726-0208-4f2f-b582-4288f90ed4e2",
"name": "WSL Ubuntu install new packages",
"code": "sudo apt-get install pa",
"language": "shell",
"description": "Installs new linux packages same like {npm install xyz}",
"group": "Shell"
},
{
"id": "c1ea9c6a-3f33-4337-8659-1bed6e0ca559",
"name": "SDKMan List Java Version",
"code": "sdk list java",
"language": "shell",
"description": "List available Java Versions",
"group": "Shell"
},
{
"id": "7ad54028-f1d5-46ba-879d-65daad78cd7c",
"name": "npm update package helper",
"code": "npx npm-check-updates",
"description": "Command to update npm packages via npx.",
"language": "shell",
"group": "Shell"
},
{
"id": "450b6686-3e36-4a5e-8e12-cbbc523129ac",
"name": "docker remove unused images",
"code": "docker rmi $(docker images --filter \"dangling=true\" -q --no-trunc)",
"description": "Remove unused docker images.",
"language": "shell",
"group": "Shell"
}
]
},
{
"id": "2a1c8a00-0719-4328-bf14-9ee57ddb32b0",
"name": "CSS",
"choices": [
{
"id": "729bd81e-5d22-4757-b5d4-f3848fc7cb4f",
"name": "SCSS color adjust lighter",
"code": "color.adjust($some-color, $lightness: 45%)",
"description": "Makes the given color lighter by a specific amount in %",
"language": "scss",
"group": "CSS"
}
]
}
]
}
My script:
// Shortcut: command shift option control f11
// Menu: Snippets
// Description: Easily organize your code snippets π₯
// Author: Altrim Beqiri + cle
// Group: Utility
import '@johnlindquist/kit'
import {PromptConfig} from '@johnlindquist/kit'
const wrapCode = (html: string): string => `<pre class="px-4">
<style type="text/css">
code {
font-size: 0.75rem !important;
width: 100%;
white-space: pre-wrap;
}
pre {
display: flex;
}
p {
margin-bottom: 1rem;
}
</style>
<code style="font-size:0.85rem !important">
${html.trim()}
</code>
</pre>`
const highlightJavaScript = async ({contents, language}): Promise<string> => {
const {default: highlight} = await npm('highlight.js')
let highlightedContents = language
? highlight.highlight(contents, {language}).value
: highlight.highlightAuto(contents).value
return wrapCode(highlightedContents)
}
type SnippetGroup = {
id: string
name: string
choices?: any // Choices are the actual snippets
}
type Snippet = {
id: string
code?: any
description?: string
group: string,
html?: any
language?: string,
name: string
preview?: any
tags?: string[]
}
// Write saves the database in it's current state
const {snippetGroups, write}: {
snippetGroups: SnippetGroup[];
write: () => Promise<void>
} = await db('code-snippets-db', {
snippetGroups: []
})
const onNoChoices = async (input) => {
if (input) {
setPanel(
md(`## Creating snippet <code>${input}</code>
Creates a new code snippet with the contents of the clipboard.`)
)
} else {
setPlaceholder(`Enter a snippet name`)
}
}
const onChoices = async () => {
setPanel(``)
}
const loadSnippets = async () => {
try {
return snippetGroups.filter((snippetGroup: Partial<SnippetGroup>) => {
return snippetGroup.choices.map((snippet: Snippet) => {
snippet.preview = async () => {
if (snippet?.code) {
return await highlightJavaScript({contents: snippet?.code, language: snippet?.language})
}
return ''
}
return snippet
})
})
} catch (error) {
return [error.message]
}
}
const config: PromptConfig & Partial<{ onChoices: () => Promise<void> }> = {
placeholder: 'Enter new snippet name',
strict: false,
onChoices,
onNoChoices,
width: 2200,
height: 800,
flags: {
updateCode: {
group: 'Actions',
name: 'π¨βπ» Code',
description: 'Update the snippet code'
},
removeSnippet: {
group: 'Actions',
name: 'β Remove',
description: 'Delete snippet'
},
updateName: {
group: 'Actions',
name: 'βΎοΈ Name',
description: 'Update the snippet name'
},
updateDescription: {
group: 'Actions',
name: 'π Description',
description: 'Update the snippet description'
},
updateLanguage: {
group: 'Actions',
name: 'π§ Language',
description: 'Update the snippet code language'
},
updateGroup: {
group: 'Actions',
name: 'π΅ Group',
description: 'Update the snippet group'
}
}
}
const manageSnippets = async () => {
const snippet: Snippet | string = await arg(config, await loadSnippets())
const availableSnippetGroups = snippetGroups.map((snippetGroup: SnippetGroup) => snippetGroup.name)
// Condition is hit when user enters a new snippet
if (typeof snippet === 'string' && snippet) {
const group: string = await arg('Enter group', availableSnippetGroups)
const clipboard: string = await paste()
snippetGroups.find((snippetGroup: SnippetGroup) => snippetGroup.name === group).choices.push({
group: group,
id: uuid(),
name: snippet,
code: clipboard.trim()
})
await write()
await manageSnippets()
// Condition is hit when user updates existing snippets
} else if (typeof snippet !== 'string' && snippet?.id) {
const pendingSnippetGroup = snippetGroups.find((snippetGroup: SnippetGroup) => snippetGroup.choices.map((snippet: Snippet) => snippet.id).includes(typeof snippet !== 'string' ? snippet.id : ''))
const pendingSnippetList = pendingSnippetGroup.choices
const foundSnippet: Snippet = pendingSnippetList.find((s: Snippet): boolean => s?.id === snippet.id)
if (flag?.updateDescription) {
foundSnippet.description = await arg(foundSnippet.description)
await write()
await manageSnippets()
}
if (flag?.updateLanguage) {
foundSnippet.language = await arg(foundSnippet.language)
await write()
await manageSnippets()
}
if (flag?.updateName) {
foundSnippet.name = await arg(foundSnippet.name)
await write()
await manageSnippets()
}
if (flag?.updateCode) {
foundSnippet.code = await editor({
value: snippet.code,
language: snippet.language,
footer: `STRG + S - Save`
})
await write()
await manageSnippets()
}
if (flag.updateGroup) {
foundSnippet.group = await arg('New group', availableSnippetGroups)
// Removing the snippet from the old group
pendingSnippetGroup.choices = pendingSnippetGroup.choices.filter((snippet: {
id: string
}) => snippet.id !== foundSnippet.id)
// Adding the snippet to the new group
snippetGroups.find((snippetGroup: SnippetGroup) => snippetGroup.name === foundSnippet.group).choices.push(foundSnippet)
await write()
await manageSnippets()
}
if (flag?.removeSnippet) {
let choice: string = await arg('Do you really want to remove the snippet?', [
'Yes',
'No'
])
if (choice === 'No') {
await manageSnippets()
} else {
const index: number = pendingSnippetList.findIndex((s: Snippet): boolean => s?.id === snippet.id)
if (index > -1) {
pendingSnippetList.splice(index, 1)
}
await write()
await manageSnippets()
}
}
await setSelectedText(foundSnippet.code)
}
}
onTab('Snippets', manageSnippets)
So I adjusted my script that the actual snippets are grouped by a specific group. If I do scroll through the snippets without searching, the preview of those snippets is rendered just fine. But If I do enter a search so that choices (actual snippets) are listed, the preview does not work.
What am I missing here or maybe it really is a bug?
Also are you planning on improving the search for? e.g "WSL se" the search works but If I search for "WSL sea" it does not work anymore while the search term is actually more precise. That is kinda strange to me. Is this something that can be enhanced? Maybe there is a limit like 6 characters or some? :) Also would it be possible in the search to cover all possible permutations of a search input? Similar to the search in IntelliJ IDEA, if you're familiar with that π
I honestly love your work and really appreciate this project!
Would love to hear from you.
Kind regards, cle βοΈ