diff --git a/README.md b/README.md index 884cfd4..5cec4fa 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,12 @@ [![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/heyman/heynote)](https://github.com/heyman/heynote/releases) [![Build Status](https://github.com/heyman/heynote/workflows/Tests/badge.svg)](https://github.com/heyman/heynote/actions?query=workflow%3ATests) + + +## General Information + +- Website: [heynote.com](https://heynote.com) +- Documentation: [heynote.com](https://heynote.com/docs/) Heynote is a dedicated scratchpad for developers. It functions as a large persistent text buffer where you can write down anything you like. Works great for that Slack message you don't want to accidentally send, a JSON response from an API you're working with, notes from a meeting, your daily to-do list, etc. @@ -16,7 +22,7 @@ Available for Mac, Windows, and Linux. - Block-based - Syntax highlighting: - C++, C#, Clojure, CSS, Erlang, Go, Groovy, HTML, Java, JavaScript, JSX, Kotlin, TypeScript, TOML, TSX, JSON, Lezer, Markdown, PHP, Python, Ruby, Rust, Shell, SQL, Swift, XML, YAML + C++, C#, Clojure, CSS, Erlang, Dart, Go, Groovy, HTML, Java, JavaScript, JSX, Kotlin, TypeScript, TOML, TSX, JSON, Lezer, Markdown, PHP, Python, Ruby, Rust, Shell, SQL, Swift, XML, YAML - Language auto-detection - Auto-formatting @@ -28,19 +34,9 @@ Available for Mac, Windows, and Linux. - Default or Emacs-like key bindings -## Installation +## Documentation -Download the appropriate (Mac, Windows or Linux) version from the latest Github release (or from [heynote.com](https://heynote.com)). The Windows build is not signed, so you might see some scary warning (I can not justify paying a yearly fee for a certificate just to get rid of that). - -### Notes on Linux installation - -It's been reported [(#48)](https://github.com/heyman/heynote/issues/48) that ChromeOS's Debian VM need the following packages installed to run the Heynote AppImage: - -``` -libfuse2 -libnss3 -libnspr4 -``` +[Documentation](https://heynote.com/docs/) is available on the Heynote website. ## Development @@ -70,49 +66,12 @@ To run the tests in the Playwright UI: I'm happy to merge contributions that fit my vision for the app. Bug fixes are always welcome. -## Math Blocks - -Heynote's Math blocks are powered by [Math.js expressions](https://mathjs.org/docs/expressions). Checkout their [documentation](https://mathjs.org/docs/) to see what [syntax](https://mathjs.org/docs/expressions/syntax.html), [functions](https://mathjs.org/docs/reference/functions.html), and [constants](https://mathjs.org/docs/reference/constants.html) are available. - -### Accessing the previous result - -The variable `prev` can be used to access the previous result. For example: - -``` -128 -prev * 2 # 256 -``` - -### Changing how the results of Math blocks are formatted? - -You can define a custom `format` function within the Math block like this: - -``` -_format = format # store reference to the built in format -format(x) = _format(x, {notation:"exponential"}) -``` - -You can also do something like this to show the number with your default locale or provide a [custom one](https://www.w3.org/International/articles/language-tags/): - -``` -format(x) = x.toLocaleString(); -format(x) = x.toLocaleString('en-GB'); -``` - -See the [Math.js format()](https://mathjs.org/docs/reference/functions/format.html) function for more info on what's supported. - ## FAQ ### Where is the buffer data stored? -The default paths for the buffer data for the respective OS are: - -- Mac: `~/Library/Application Support/Heynote/buffer.txt` -- Windows: `%APPDATA%\Heynote\buffer.txt` -- Linux: `~/.config/Heynote/buffer.txt` - -From version >=1.5.0, symlinks will be supported and you'll be able to configure the path where `buffer.txt` is stored. +See the [documentation](https://heynote.com/docs/#user-content-the-buffer-file). ### Can you make a mobile app? @@ -126,38 +85,7 @@ I can totally see the usefulness of such a feature, and it's definitely somethin ### What are the default keyboard shortcuts? -**On Mac** - -``` -⌘ + Enter Add new block below the current block -⌥ + Enter Add new block before the current block -⌘ + Shift + Enter Add new block at the end of the buffer -⌥ + Shift + Enter Add new block at the start of the buffer -⌘ + ⌥ + Enter Split the current block at cursor position -⌘ + L Change block language -⌘ + Down Goto next block -⌘ + Up Goto previous block -⌘ + A Select all text in a note block. Press again to select the whole buffer -⌘ + ⌥ + Up/Down Add additional cursor above/below -⌥ + Shift + F Format block content (works for JSON, JavaScript, HTML, CSS and Markdown) -``` - -**On Windows and Linux** - -``` -Ctrl + Enter Add new block below the current block -Alt + Enter Add new block before the current block -Ctrl + Shift + Enter Add new block at the end of the buffer -Alt + Shift + Enter Add new block at the start of the buffer -Ctrl + Alt + Enter Split the current block at cursor position -Ctrl + L Change block language -Ctrl + Down Goto next block -Ctrl + Up Goto previous block -Ctrl + A Select all text in a note block. Press again to select the whole buffer -Ctrl + Alt + Up/Down Add additional cursor above/below -Alt + Shift + F Format block content (works for JSON, JavaScript, HTML, CSS and Markdown) -Alt Show menu -``` +See the [documentation](https://heynote.com/docs/#user-content-default-key-bindings). ## Thanks! diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..ab7990d --- /dev/null +++ b/docs/index.md @@ -0,0 +1,89 @@ +# Heynote Documentation + +Heynote is a dedicated scratchpad for developers. It functions as a large persistent text buffer where you can write down anything you like. Works great for that Slack message you don't want to accidentally send, a JSON response from an API you're working with, notes from a meeting, your daily to-do list, etc. + +The Heynote buffer is divided into blocks, and each block can have its own Language set (e.g. JavaScript, JSON, Markdown, etc.). This gives you syntax highlighting and lets you auto-format that JSON response. + +## Default Key Bindings + + + +**On Mac** + +``` +⌘ + Enter Add new block below the current block +⌥ + Enter Add new block before the current block +⌘ + Shift + Enter Add new block at the end of the buffer +⌥ + Shift + Enter Add new block at the start of the buffer +⌘ + ⌥ + Enter Split the current block at cursor position +⌘ + L Change block language +⌘ + Down Goto next block +⌘ + Up Goto previous block +⌘ + A Select all text in a note block. Press again to select the whole buffer +⌘ + ⌥ + Up/Down Add additional cursor above/below +⌥ + Shift + F Format block content (works for JSON, JavaScript, HTML, CSS and Markdown) +``` + +**On Windows and Linux** + +``` +Ctrl + Enter Add new block below the current block +Alt + Enter Add new block before the current block +Ctrl + Shift + Enter Add new block at the end of the buffer +Alt + Shift + Enter Add new block at the start of the buffer +Ctrl + Alt + Enter Split the current block at cursor position +Ctrl + L Change block language +Ctrl + Down Goto next block +Ctrl + Up Goto previous block +Ctrl + A Select all text in a note block. Press again to select the whole buffer +Ctrl + Alt + Up/Down Add additional cursor above/below +Alt + Shift + F Format block content (works for JSON, JavaScript, HTML, CSS and Markdown) +Alt Show menu +``` + +## Download/Installation + +Download the appropriate (Mac, Windows or Linux) version from [heynote.com](https://heynote.com). The Windows build is not signed, so you might see some scary warning (I can not justify paying a yearly fee for a certificate just to get rid of that). + +### Notes on Linux installation + +It's been reported [(#48)](https://github.com/heyman/heynote/issues/48) that ChromeOS's Debian VM need the following packages installed to run the Heynote AppImage: + +``` +libfuse2 +libnss3 +libnspr4 +``` + +## Math Blocks + +Heynote's Math blocks are powered by [Math.js expressions](https://mathjs.org/docs/expressions). Checkout their [documentation](https://mathjs.org/docs/) to see what [syntax](https://mathjs.org/docs/expressions/syntax.html), [functions](https://mathjs.org/docs/reference/functions.html), and [constants](https://mathjs.org/docs/reference/constants.html) are available. + +### Accessing the previous result + +The variable `prev` can be used to access the previous result. For example: + +``` +128 +prev * 2 # 256 +``` + +### Changing how the results of Math blocks are formatted + +You can define a custom `format` function within the Math block like this: + +``` +_format = format # store reference to the built in format +format(x) = _format(x, {notation:"exponential"}) +``` + +See the [Math.js format()](https://mathjs.org/docs/reference/functions/format.html) function for more info on what's supported. + +## The buffer file + +The default paths for the buffer data for the respective operating systems are: + +- Mac: `~/Library/Application Support/Heynote/buffer.txt` +- Windows: `%APPDATA%\Heynote\buffer.txt` +- Linux: `~/.config/Heynote/buffer.txt` + diff --git a/electron/config.js b/electron/config.js index 7c443ea..f3ecd97 100644 --- a/electron/config.js +++ b/electron/config.js @@ -35,6 +35,8 @@ const schema = { "showInMenu": {type: "boolean", default: false}, "alwaysOnTop": {type: "boolean", default: false}, "bracketClosing": {type: "boolean", default: false}, + "defaultBlockLanguage": {type: "string"}, + "defaultBlockLanguageAutoDetect": {type: "boolean"}, // when default font settings are used, fontFamily and fontSize is not specified in the // settings file, so that it's possible for us to change the default settings in the diff --git a/electron/main/menu.ts b/electron/main/menu.ts index 39f942c..9e4a2a4 100644 --- a/electron/main/menu.ts +++ b/electron/main/menu.ts @@ -131,7 +131,14 @@ const template = [ role: 'help', submenu: [ { - label: 'Learn More', + label: 'Documentation', + click: async () => { + const { shell } = require('electron') + await shell.openExternal('https://heynote.com/docs/') + } + }, + { + label: 'Website', click: async () => { const { shell } = require('electron') await shell.openExternal('https://heynote.com') diff --git a/package-lock.json b/package-lock.json index 8ed82f3..64982b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Heynote", - "version": "1.7.0", + "version": "1.8.0-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Heynote", - "version": "1.7.0", + "version": "1.8.0-beta", "license": "Commons Clause MIT", "dependencies": { "electron-log": "^5.0.1" @@ -25,6 +25,7 @@ "@codemirror/lang-python": "^6.1.3", "@codemirror/lang-rust": "^6.0.1", "@codemirror/lang-sql": "^6.5.4", + "@codemirror/lang-vue": "^0.1.3", "@codemirror/lang-xml": "^6.0.2", "@codemirror/language": "^6.9.3", "@codemirror/legacy-modes": "^6.3.3", @@ -41,13 +42,13 @@ "@types/node": "^20.10.5", "@vitejs/plugin-vue": "^4.0.0", "debounce": "^1.2.1", - "electron": "^28.0.0", + "electron": "^31.1.0", "electron-builder": "^23.6.0", "electron-builder-notarize": "^1.5.1", "electron-store": "^8.1.0", "electron-updater": "^6.1.7", "fs-jetpack": "^5.1.0", - "prettier": "^3.1.1", + "prettier": "^3.3.2", "rollup-plugin-license": "^3.0.1", "sass": "^1.57.1", "typescript": "^4.9.4", @@ -427,6 +428,20 @@ "@lezer/lr": "^1.0.0" } }, + "node_modules/@codemirror/lang-vue": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz", + "integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==", + "dev": true, + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/lang-javascript": "^6.1.2", + "@codemirror/language": "^6.0.0", + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.3.1" + } + }, "node_modules/@codemirror/lang-xml": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.0.2.tgz", @@ -992,9 +1007,9 @@ "dev": true }, "node_modules/@lezer/common": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.1.2.tgz", - "integrity": "sha512-V+GqBsga5+cQJMfM0GdnHmg4DgWvLzgMWjbldBg0+jC3k9Gu6nJNZDLJxXEBT1Xj8KhRN4jmbC5CY7SIL++sVw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", + "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==", "dev": true }, "node_modules/@lezer/cpp": { @@ -2262,12 +2277,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -3063,9 +3078,9 @@ "dev": true }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, "dependencies": { "jake": "^10.8.5" @@ -3078,14 +3093,14 @@ } }, "node_modules/electron": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-28.0.0.tgz", - "integrity": "sha512-eDhnCFBvG0PGFVEpNIEdBvyuGUBsFdlokd+CtuCe2ER3P+17qxaRfWRxMmksCOKgDHb5Wif5UxqOkZSlA4snlw==", + "version": "31.1.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-31.1.0.tgz", + "integrity": "sha512-TBOwqLxSxnx6+pH6GMri7R3JPH2AkuGJHfWZS0p1HsmN+Qr1T9b0IRJnnehSd/3NZAmAre4ft9Ljec7zjyKFJA==", "dev": true, "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", - "@types/node": "^18.11.18", + "@types/node": "^20.9.0", "extract-zip": "^2.0.1" }, "bin": { @@ -3474,15 +3489,6 @@ "node": ">= 10.0.0" } }, - "node_modules/electron/node_modules/@types/node": { - "version": "18.19.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", - "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3684,9 +3690,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -5005,9 +5011,9 @@ } }, "node_modules/prettier": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", - "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" diff --git a/package.json b/package.json index 2730a80..135f076 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Heynote", - "version": "1.7.0", + "version": "1.8.0-beta", "main": "dist-electron/main/index.js", "description": "A dedicated scratch pad", "author": "Jonatan Heyman (https://heyman.info)", @@ -44,6 +44,7 @@ "@codemirror/lang-python": "^6.1.3", "@codemirror/lang-rust": "^6.0.1", "@codemirror/lang-sql": "^6.5.4", + "@codemirror/lang-vue": "^0.1.3", "@codemirror/lang-xml": "^6.0.2", "@codemirror/language": "^6.9.3", "@codemirror/legacy-modes": "^6.3.3", @@ -60,13 +61,13 @@ "@types/node": "^20.10.5", "@vitejs/plugin-vue": "^4.0.0", "debounce": "^1.2.1", - "electron": "^28.0.0", + "electron": "^31.1.0", "electron-builder": "^23.6.0", "electron-builder-notarize": "^1.5.1", "electron-store": "^8.1.0", "electron-updater": "^6.1.7", "fs-jetpack": "^5.1.0", - "prettier": "^3.1.1", + "prettier": "^3.3.2", "rollup-plugin-license": "^3.0.1", "sass": "^1.57.1", "typescript": "^4.9.4", diff --git a/public/langdetect-worker.js b/public/langdetect-worker.js index 95ca257..a519b4a 100644 --- a/public/langdetect-worker.js +++ b/public/langdetect-worker.js @@ -1,6 +1,6 @@ importScripts("guesslang.min.js") -GUESSLANG_LANGUAGES = ["json","py","html","sql","md","java","php","css","xml","cpp","rs","cs","rb","sh","yaml","toml","go","clj","erl","js","ts","swift","kt","groovy","ps1"] +GUESSLANG_LANGUAGES = ["json","py","html","sql","md","java","php","css","xml","cpp","rs","cs","rb","sh","yaml","toml","go","clj","erl","js","ts","swift","kt","groovy","ps1","dart"] const guessLang = new self.GuessLang() diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..a4b2915 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,11 @@ +{ + "name": "Heynote", + "short_name": "Heynote", + "icons": [ + { + "src": "/icon.ico", + "sizes": "256x256" + } + ], + "display": "standalone" +} diff --git a/src/components/App.vue b/src/components/App.vue index 4f400bc..08234d5 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -122,6 +122,8 @@ :bracketClosing="settings.bracketClosing" :fontFamily="settings.fontFamily" :fontSize="settings.fontSize" + :defaultBlockLanguage="settings.defaultBlockLanguage || 'text'" + :defaultBlockLanguageAutoDetect="settings.defaultBlockLanguageAutoDetect === undefined ? true : settings.defaultBlockLanguageAutoDetect" class="editor" ref="editor" @openLanguageSelector="openLanguageSelector" diff --git a/src/components/Editor.vue b/src/components/Editor.vue index 7171a80..b3bc938 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -29,6 +29,8 @@ }, fontFamily: String, fontSize: Number, + defaultBlockLanguage: String, + defaultBlockLanguageAutoDetect: Boolean, }, components: {}, @@ -78,6 +80,7 @@ }) window._heynote_editor = this.editor window.document.addEventListener("currenciesLoaded", this.onCurrenciesLoaded) + this.editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect) // set up buffer change listener window.heynote.buffer.onChangeCallback((event, content) => { @@ -145,12 +148,18 @@ fontSize() { this.editor.setFont(this.fontFamily, this.fontSize) }, + defaultBlockLanguage() { + this.editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect) + }, + defaultBlockLanguageAutoDetect() { + this.editor.setDefaultBlockLanguage(this.defaultBlockLanguage, this.defaultBlockLanguageAutoDetect) + }, }, methods: { setLanguage(language) { if (language === "auto") { - this.editor.setCurrentLanguage("text", true) + this.editor.setCurrentLanguage(null, true) } else { this.editor.setCurrentLanguage(language, false) } diff --git a/src/components/settings/Settings.vue b/src/components/settings/Settings.vue index 42c9ee6..57d98e9 100644 --- a/src/components/settings/Settings.vue +++ b/src/components/settings/Settings.vue @@ -1,10 +1,14 @@