diff --git a/package.json b/package.json index 84122956..99b81534 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "@types/markdown-it": "^12.2.3", "@types/markdown-it-link-attributes": "^3.0.1", "@types/node": "^17.0.4", + "@types/prettier": "^2.6.0", "@types/sanitize-html": "^2.6.2", "@types/webpack": "^5.28.0", "@typescript-eslint/eslint-plugin": "^5.8.0", diff --git a/src/main/menu/main.ts b/src/main/menu/main.ts index 3bde1442..69e6c92d 100644 --- a/src/main/menu/main.ts +++ b/src/main/menu/main.ts @@ -200,6 +200,15 @@ const editorMenu: MenuItemConstructorOptions[] = [ ) } }, + { + label: 'Format', + accelerator: 'Shift+CommandOrControl+F', + click: () => { + BrowserWindow.getFocusedWindow()?.webContents.send( + 'main-menu:format-snippet' + ) + } + }, { label: 'Preview Markdown', accelerator: 'Shift+CommandOrControl+M', diff --git a/src/main/store/module/preferences.ts b/src/main/store/module/preferences.ts index 7706ea76..83eb9515 100644 --- a/src/main/store/module/preferences.ts +++ b/src/main/store/module/preferences.ts @@ -19,7 +19,10 @@ export default new Store({ fontFamily: 'SF Mono, Consolas, Menlo', fontSize: 12, showInvisibles: false, - tabSize: 2 + tabSize: 2, + trailingComma: 'none', + semi: false, + singleQuote: true } } }) diff --git a/src/renderer/App.vue b/src/renderer/App.vue index a87d2389..60e8aa5c 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -24,7 +24,8 @@ import { onAddNewSnippet, onAddNewFragment, onAddNewFolder, - onCopySnippet + onCopySnippet, + emitter } from '@/composable' // По какой то причине необходимо явно установить роут в '/' @@ -115,12 +116,20 @@ ipc.on('main-menu:preview-markdown', async () => { ipc.on('main-menu:copy-snippet', () => { onCopySnippet() }) + +ipc.on('main-menu:format-snippet', () => { + emitter.emit('format-snippet', true) +}) + diff --git a/src/renderer/components/ui/menu/AppMenu.vue b/src/renderer/components/ui/menu/AppMenu.vue index 9a80deb3..498f4bab 100644 --- a/src/renderer/components/ui/menu/AppMenu.vue +++ b/src/renderer/components/ui/menu/AppMenu.vue @@ -11,8 +11,13 @@ {{ i.name }} -
- +
+ + +
@@ -39,9 +44,12 @@ const props = defineProps() const items = ref([]) const value = computed(() => props.modelValue) +const bodyRef = ref() const onClickItem = (item: Item) => { emit('update:modelValue', item.value) + const el = bodyRef.value?.querySelector('.ps') + if (el) el.scrollTop = 0 } const update = (value: string) => { @@ -55,15 +63,22 @@ provide('items', items.value) diff --git a/src/renderer/store/app.ts b/src/renderer/store/app.ts index 2e2e8730..97c513ba 100644 --- a/src/renderer/store/app.ts +++ b/src/renderer/store/app.ts @@ -8,7 +8,10 @@ const EDITOR_DEFAULTS: EditorSettings = { fontSize: 12, showInvisibles: false, tabSize: 2, - wrap: 'free' + wrap: 'free', + trailingComma: 'none', + semi: false, + singleQuote: true } export const useAppStore = defineStore('app', { diff --git a/src/renderer/views/Preferences.vue b/src/renderer/views/Preferences.vue index 56b4daaa..6293019c 100644 --- a/src/renderer/views/Preferences.vue +++ b/src/renderer/views/Preferences.vue @@ -45,16 +45,15 @@ track('preferences') margin: 0; } margin-top: var(--title-bar-height); - padding: var(--spacing-sm); } .title { + padding: var(--spacing-sm); display: flex; align-items: center; justify-content: space-between; } .body { - padding-top: var(--spacing-sm); + padding: 0 0 var(--spacing-sm) var(--spacing-sm); display: grid; - grid-template-columns: 200px 1fr; } diff --git a/src/shared/types/main/index.d.ts b/src/shared/types/main/index.d.ts index 48a120f7..9020dfb9 100644 --- a/src/shared/types/main/index.d.ts +++ b/src/shared/types/main/index.d.ts @@ -33,6 +33,7 @@ type MainMenuAction = | 'preferences' | 'new-snippet' | 'copy-snippet' + | 'format-snippet' | 'new-fragment' | 'new-folder' | 'search' diff --git a/src/shared/types/main/store.d.ts b/src/shared/types/main/store.d.ts index 1054d3a3..20b321ed 100644 --- a/src/shared/types/main/store.d.ts +++ b/src/shared/types/main/store.d.ts @@ -15,6 +15,9 @@ interface Editor { showInvisibles: boolean tabSize: number wrap: string + trailingComma: 'all' | 'none' | 'es5' + semi: boolean + singleQuote: boolean } export interface PreferencesStore { storagePath: string diff --git a/src/shared/types/renderer/composable/index.d.ts b/src/shared/types/renderer/composable/index.d.ts index ef47e98c..f1383e4d 100644 --- a/src/shared/types/renderer/composable/index.d.ts +++ b/src/shared/types/renderer/composable/index.d.ts @@ -2,4 +2,5 @@ export type EmitterEvents = { 'focus:snippet-name': boolean 'folder:click': any 'scroll-to:folder': string + 'format-snippet': boolean } diff --git a/src/shared/types/renderer/store/app.d.ts b/src/shared/types/renderer/store/app.d.ts index 566d497e..154ce014 100644 --- a/src/shared/types/renderer/store/app.d.ts +++ b/src/shared/types/renderer/store/app.d.ts @@ -18,6 +18,9 @@ export interface EditorSettings { fontFamily: string wrap: Ace.EditSessionOptions['wrap'] tabSize: number + trailingComma: 'all' | 'none' | 'es5' + semi: boolean + singleQuote: boolean } export interface State { platform: NodeJS.Platform diff --git a/yarn.lock b/yarn.lock index ab5ba0a9..30564de1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1851,6 +1851,11 @@ "@types/node" "*" xmlbuilder ">=11.0.1" +"@types/prettier@^2.6.0": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" + integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== + "@types/q@^1.5.1": version "1.5.5" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df"