diff --git a/quick-commands/CHANGELOG.md b/quick-commands/CHANGELOG.md index 9438da0..116cb0c 100644 --- a/quick-commands/CHANGELOG.md +++ b/quick-commands/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.3.1 - 2026-10-04 + +- `\u`_XXXX_ will complete to the Unicode character whose code point is + given by hexadecimal _XXXX_. +- Autocompletions can now have escaped newlines `\n` and Unicode + characters in `\u`_XXXX_ notation. + ## 0.3.0 - 2026-10-02 - Reworked for simplicity, efficiency and functionality. diff --git a/quick-commands/README.md b/quick-commands/README.md index 89adaca..b598039 100644 --- a/quick-commands/README.md +++ b/quick-commands/README.md @@ -1,4 +1,4 @@ -# `jv-quick-commands` +# `quick-commands` This is an augmented re-implementation of the QOwnNotes `quick-commands` script. @@ -6,13 +6,14 @@ This is an augmented re-implementation of the QOwnNotes `quick-commands` script. When this script is enabled, you can use the QOwnNotes auto-completion feature with a number of predefined completions. -| key | value | -| :----------- | :----------------------------------- | -| `\today` | Formatted current date and time | -| `\tomorrow` | Formatted date and time of tomorrow | -| `\yesterday` | Formatted date and time of yesterday | -| `\week` | Formatted week | -| `\now` | 2026-10-01T17:04:01 | +| key | value | +|:-------------|:-----------------------------------------| +| `\today` | Formatted current date and time | +| `\tomorrow` | Formatted date and time of tomorrow | +| `\yesterday` | Formatted date and time of yesterday | +| `\week` | Formatted week | +| `\now` | 2026-10-01T17:04:01 | +| `\u`_XXXX_ | Unicode character with code point _XXXX_ | For date and time, a popup will allow choosing one of: * `01-10` (day month) @@ -25,6 +26,8 @@ For week, a popup will allow choosing one of: * `40-2026` (ISO week number and year) * `w40-2026` (ISO week number and year) +For Unicode code points, the value _XXXX_ must be exactly four hexadecimal characters. + ## Custom completions In the script settings dialog, you can add your own completions. For example: @@ -43,6 +46,11 @@ Now `\App` will complete to `Qownnotes`. Yes, you see that good, if the command starts with an uppercase letter the result will have its first letter uppercased too. +Custom completions may contain escaped newline and Unicode characters, e.g. +``` +smile smile\u263a\nand again +``` + ### Placeholders In the completions you can use a number of _placeholders_ to obtain substitutions for actual date and time values (table adapted from [QOwnNotes](https://www.qownnotes.org/scripting/methods-and-objects.html#formatting-dates-and-times): diff --git a/quick-commands/info.json b/quick-commands/info.json index 011c66b..a0e4495 100644 --- a/quick-commands/info.json +++ b/quick-commands/info.json @@ -4,8 +4,8 @@ "script": "quick-commands.qml", "authors": ["@LockeBirdsey","@sciurius"], "platforms": ["linux", "macos", "windows"], - "version": "0.3.0", + "version": "0.3.1", "minAppVersion": "25.4.1", - "description": "Short commands to help with repetive and/or annoying things to write frequently such as timestamps.\n\nEach command starts with a backslash (\\) and a single word for the command. Select the autocomplete option you desire and the command text will be replace.\n\nDefault commands are: today, tomorrow, yesterday, now, week.\n\nCustom commands can also be specified. Each line starts with the command name followed by one or more replacement values separated by spaces. Enclose multi-word values in double quotes, for example: myname \"Firstname Lastname\". Date and time values can be substituted with {dd}, {MM} and so on.", + "description": "Short commands to help with repetive and/or annoying things to write frequently such as timestamps.\n\nEach command starts with a backslash (\\) and a single word for the command. Select the autocomplete option you desire and the command text will be replace.\n\nDefault commands are: today, tomorrow, yesterday, now, week.\n\nCustom commands can also be specified. Each line starts with the command name followed by one or more replacement values separated by spaces. Enclose multi-word values in double quotes, for example: myname \"Firstname Lastname\". Date and time values can be substituted with {dd}, {MM} and so on.\n\nReplacement values may have escaped newlines \"\\n\" and Unicode characters in the form \"\\uXXXX\".", "resources": ["command-parser.js"] } diff --git a/quick-commands/quick-commands.qml b/quick-commands/quick-commands.qml index 554e6ea..a85198e 100644 --- a/quick-commands/quick-commands.qml +++ b/quick-commands/quick-commands.qml @@ -63,19 +63,27 @@ Script { // script.log("command: " + command); const av = commands[command]; if ( av == null || av.length === 0 ) { - return []; - } - // script.log("commands: " + av); - - // Substitute actual values. - const ucfirst = command.match( /^[A-Z]/ ); // should use POSIX - for ( let i = 0; i < av.length; i++ ) { - if ( ucfirst ) { - availableCommands.push(capitalizeFirstLetter(substitute(av[i]))); + // Try Unicode literal \uXXXX. + if ( command.match( /^u[0-9a-fA-F]{4}$/ ) ) { + availableCommands = [ unescapeUnicode(word) ]; } else { - availableCommands.push(substitute(av[i])); - } + return []; + } + } + else { + // script.log("commands: " + av); + + // Substitute actual values. + const ucfirst = command.match( /^[A-Z]/ ); // should use POSIX + for ( let i = 0; i < av.length; i++ ) { + if ( ucfirst ) { + availableCommands.push(capitalizeFirstLetter(substitute(av[i]))); + } + else { + availableCommands.push(substitute(av[i])); + } + } } // QOwnNotes replaces only word characters during completion, so remove @@ -137,6 +145,9 @@ Script { // Perform the substitutions. function substitute(format) { + // Handle newline and unicode escapes. + format = unescapeUnicode(format.replace( /\\n/g, "\n")); + // Break out the {...} elements. let m = format.split( /(\{.*?\})/g ); if ( m.length == 1 ) { @@ -230,4 +241,11 @@ Script { return string[0].toUpperCase() + string.slice(1); } + // Helper: Return UTF8 character from a \uXXXX string. + // Simplified version of https://mojoauth.com/dev-guides/unicode-escaping-in-javascript-in-browser#how-to-convert-between-characters-and-code-points-at-runtime. + function unescapeUnicode(str) { + return str.replace( /\\u([0-9a-fA-F]{4})/g, + (_, hex) => String.fromCodePoint(parseInt(hex, 16)) ); + } + }