diff --git a/docs/KEYBINDINGS.md b/docs/KEYBINDINGS.md
index e3faf495..782da6eb 100644
--- a/docs/KEYBINDINGS.md
+++ b/docs/KEYBINDINGS.md
@@ -32,103 +32,114 @@ Here is an example:
**Mark Text menu (macOS only):**
-| Id | Description |
-| ----------------- | --------------------------------------- |
-| `mtHide` | Hide Mark Text |
-| `mtHideOthers` | Hide all other windows except Mark Text |
-| `filePreferences` | Open settings window |
-| `fileQuit` | Quit Mark Text |
+| Id | Default | Description |
+| ----------------- | ---------------------------------------------- | --------------------------------------- |
+| `mtHide` | Command+H | Hide Mark Text |
+| `mtHideOthers` | Command+Alt+H | Hide all other windows except Mark Text |
+| `filePreferences` | Command+, | Open settings window |
+| `fileQuit` | Command+Q | Quit Mark Text |
**File menu:**
-| Id | Description |
-|:----------------- | ----------------------------------------- |
-| `fileNewFile` | New file |
-| `fileNewTab` | New tab |
-| `fileOpenFile` | Open markdown file |
-| `fileOpenFolder` | Open folder |
-| `fileSave` | Save |
-| `fileSaveAs` | Save as... |
-| `filePreferences` | Open settings window (Linux/Windows only) |
-| `fileCloseTab` | Close tab |
-| `fileCloseWindow` | Close window |
-| `fileQuit` | Quit Mark Text (Linux/Windows only) |
+| Id | Default | Description |
+|:----------------- | -------------------------------------------------- | ----------------------------------------- |
+| `fileNewFile` | CmdOrCtrl+N | New file |
+| `fileNewTab` | CmdOrCtrl+T | New tab |
+| `fileOpenFile` | CmdOrCtrl+O | Open markdown file |
+| `fileOpenFolder` | CmdOrCtrl+Shift+O | Open folder |
+| `fileSave` | CmdOrCtrl+S | Save |
+| `fileSaveAs` | CmdOrCtrl+Shift+S | Save as... |
+| `filePrint` | Ctrl+P | Print current tab |
+| `filePreferences` | Ctrl+, | Open settings window (Linux/Windows only) |
+| `fileCloseTab` | CmdOrCtrl+W | Close tab |
+| `fileCloseWindow` | CmdOrCtrl+Shift+W | Close window |
+| `fileQuit` | CmdOrCtrl+Q | Quit Mark Text (Linux/Windows only) |
**Edit menu:**
-| Id | Description |
-|:--------------------- | ----------------------------------------------- |
-| `editUndo` | Undo last operation |
-| `editRedo` | Redo last operation |
-| `editCut` | Cut selected text |
-| `editCopy` | Copy selected text |
-| `editPaste` | Paste text |
-| `editCopyAsMarkdown` | Copy selected text as markdown |
-| `editCopyAsPlaintext` | Copy selected text as plaintext |
-| `editSelectAll` | Select all text of the document |
-| `editDuplicate` | Duplicate the current paragraph |
-| `editCreateParagraph` | Create a new paragraph after the current one |
-| `editDeleteParagraph` | Delete current paragraph |
-| `editFind` | Find information in the document |
-| `editFindNext` | Continue the search and find the next match |
-| `editFindPrevious` | Continue the search and find the previous match |
-| `editReplace` | Replace the information with a replacement |
-| `editAidou` | Show Aidou dialog |
-| `editScreenshot` | Get the screenshot |
+| Id | Default | Description |
+|:--------------------- | -------------------------------------------------- | ----------------------------------------------- |
+| `editUndo` | CmdOrCtrl+Z | Undo last operation |
+| `editRedo` | CmdOrCtrl+Shift+Z | Redo last operation |
+| `editCut` | CmdOrCtrl+X | Cut selected text |
+| `editCopy` | CmdOrCtrl+C | Copy selected text |
+| `editPaste` | CmdOrCtrl+V | Paste text |
+| `editCopyAsMarkdown` | CmdOrCtrl+Shift+C | Copy selected text as markdown |
+| `editCopyAsPlaintext` | CmdOrCtrl+Shift+V | Copy selected text as plaintext |
+| `editSelectAll` | CmdOrCtrl+A | Select all text of the document |
+| `editDuplicate` | CmdOrCtrl+Shift+P | Duplicate the current paragraph |
+| `editCreateParagraph` | CmdOrCtrl+Shift+N | Create a new paragraph after the current one |
+| `editDeleteParagraph` | CmdOrCtrl+Shift+D | Delete current paragraph |
+| `editFind` | CmdOrCtrl+F | Find information in the document |
+| `editFindNext` | CmdOrCtrl+Alt+U | Continue the search and find the next match |
+| `editFindPrevious` | CmdOrCtrl+Shift+U | Continue the search and find the previous match |
+| `editReplace` | CmdOrCtrl+Alt+F | Replace the information with a replacement |
+| `editAidou` | CmdOrCtrl+/ | Show Aidou dialog |
+| `editScreenshot` | Command+Alt+A | Get the screenshot (macOS only) |
**Paragraph menu:**
-| Id | Description |
-| -------------------------- | ---------------------------------------- |
-| `paragraphHeading1` | Set line as heading 1 |
-| `paragraphHeading2` | Set line as heading 2 |
-| `paragraphHeading3` | Set line as heading 3 |
-| `paragraphHeading4` | Set line as heading 4 |
-| `paragraphHeading5` | Set line as heading 5 |
-| `paragraphHeading6` | Set line as heading 6 |
-| `paragraphUpgradeHeading` | Upgrade a heading |
-| `paragraphDegradeHeading` | Degrade a heading |
-| `paragraphTable` | Insert a table |
-| `paragraphCodeFence` | Insert a code block |
-| `paragraphQuoteBlock` | Insert a quote block |
-| `paragraphMathBlock` | Insert a math block |
-| `paragraphHtmlBlock` | Insert a HTML block |
-| `paragraphOrderList` | Insert a ordered list |
-| `paragraphBulletList` | Insert a unordered list |
-| `paragraphTaskList` | Insert a task list |
-| `paragraphLooseListItem` | Convert a list item to a loose list item |
-| `paragraphParagraph` | Convert a heading to a paragraph |
-| `paragraphHorizontalLine` | Add a horizontal line |
-| `paragraphYAMLFrontMatter` | Insert a YAML frontmatter block |
+| Id | Default | Description |
+| -------------------------- | -------------------------------------------------- | ------------------------------------------------- |
+| `paragraphHeading1` | CmdOrCtrl+1 | Set line as heading 1 |
+| `paragraphHeading2` | CmdOrCtrl+2 | Set line as heading 2 |
+| `paragraphHeading3` | CmdOrCtrl+3 | Set line as heading 3 |
+| `paragraphHeading4` | CmdOrCtrl+4 | Set line as heading 4 |
+| `paragraphHeading5` | CmdOrCtrl+5 | Set line as heading 5 |
+| `paragraphHeading6` | CmdOrCtrl+6 | Set line as heading 6 |
+| `paragraphUpgradeHeading` | CmdOrCtrl+= | Upgrade a heading |
+| `paragraphDegradeHeading` | CmdOrCtrl+- | Degrade a heading |
+| `paragraphTable` | CmdOrCtrl+T | Insert a table |
+| `paragraphCodeFence` | CmdOrCtrl+Alt+C | Insert a code block |
+| `paragraphQuoteBlock` | CmdOrCtrl+Alt+Q | Insert a quote block |
+| `paragraphMathBlock` | CmdOrCtrl+Alt+M | Insert a math block |
+| `paragraphHtmlBlock` | CmdOrCtrl+Alt+J/H | Insert a HTML block (`J` on macOS, `H` otherwise) |
+| `paragraphOrderList` | CmdOrCtrl+Alt+O | Insert a ordered list |
+| `paragraphBulletList` | CmdOrCtrl+Alt+U | Insert a unordered list |
+| `paragraphTaskList` | CmdOrCtrl+Alt+X | Insert a task list |
+| `paragraphLooseListItem` | CmdOrCtrl+Alt+L | Convert a list item to a loose list item |
+| `paragraphParagraph` | CmdOrCtrl+0 | Convert a heading to a paragraph |
+| `paragraphHorizontalLine` | CmdOrCtrl+Alt+- | Add a horizontal line |
+| `paragraphYAMLFrontMatter` | CmdOrCtrl+Alt+Y | Insert a YAML frontmatter block |
**Format menu:**
-| Id | Description |
-| ------------------- | ------------------------------------------- |
-| `formatStrong` | Set the font of the selected text to bold |
-| `formatEmphasis` | Set the font of the selected text to italic |
-| `formatUnderline` | Change the selected text to underline |
-| `formatInlineCode` | Change the selected text to inline code |
-| `formatStrike` | Strike through the selected text |
-| `formatHyperlink` | Insert a hyperlink |
-| `formatImage` | Insert a image |
-| `formatClearFormat` | Clear the formatting of the selected text |
+| Id | Default | Description |
+| ------------------- | -------------------------------------------------- | ------------------------------------------- |
+| `formatStrong` | CmdOrCtrl+B | Set the font of the selected text to bold |
+| `formatEmphasis` | CmdOrCtrl+I | Set the font of the selected text to italic |
+| `formatUnderline` | CmdOrCtrl+U | Change the selected text to underline |
+| `formatInlineCode` | CmdOrCtrl+` | Change the selected text to inline code |
+| `formatInlineMath` | CmdOrCtrl+Shift+M | Change the selected text to inline math |
+| `formatStrike` | CmdOrCtrl+D | Strike through the selected text |
+| `formatHyperlink` | CmdOrCtrl+L | Insert a hyperlink |
+| `formatImage` | CmdOrCtrl+Shift+I | Insert a image |
+| `formatClearFormat` | CmdOrCtrl+Shift+R | Clear the formatting of the selected text |
**Window menu:**
-| Id | Description |
-| ------------------------ | ---------------------- |
-| `windowMinimize` | Minimize the window |
-| `windowToggleFullScreen` | Toggle fullscreen mode |
+| Id | Default | Description |
+| ---------------- | --------------------------------- | ------------------- |
+| `windowMinimize` | CmdOrCtrl+M | Minimize the window |
**View menu:**
-| Id | Description |
-| ----------------------------- | ---------------------------------------- |
-| `viewSourceCodeMode` | Switch to source code mode |
-| `viewTypewriterMode` | Enable typewriter mode |
-| `viewFocusMode` | Enable focus mode |
-| `viewToggleSideBar` | Toggle sidebar |
-| `viewToggleTabBar` | Toggle tabbar |
-| `viewDevToggleDeveloperTools` | Toggle developer tools (debug mode only) |
-| `viewDevReload` | Reload window (debug mode only) |
+| Id | Default | Description |
+| ----------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------ |
+| `viewToggleFullScreen` | F11 | Toggle fullscreen mode (or Ctrl+Command+F on macOS) |
+| `viewSourceCodeMode` | CmdOrCtrl+Alt+S | Switch to source code mode |
+| `viewTypewriterMode` | CmdOrCtrl+Alt+T | Enable typewriter mode |
+| `viewFocusMode` | CmdOrCtrl+Shift+F | Enable focus mode |
+| `viewToggleSideBar` | CmdOrCtrl+J | Toggle sidebar |
+| `viewToggleTabBar` | CmdOrCtrl+Alt+B | Toggle tabbar |
+| `viewDevToggleDeveloperTools` | CmdOrCtrl+Alt+I | Toggle developer tools (debug mode only) |
+| `viewDevReload` | CmdOrCtrl+R | Reload window (debug mode only) |
+
+**Misc**
+
+| Id | Default | Description |
+| ------------------- | ---------------------------------------------------- | ---------------------------- |
+| `tabsCycleForward` | CmdOrCtrl+Tab | Cycle through tabs |
+| `tabsCycleBackward` | CmdOrCtrl+Shift+Tab | Cycle backwards through tabs |
+| `tabsSwitchToLeft` | CmdOrCtrl+PageUp | Switch tab to the left |
+| `tabsSwitchToRight` | CmdOrCtrl+PageDown | Switch tab to the right |
diff --git a/src/main/keyboard/shortcutHandler.js b/src/main/keyboard/shortcutHandler.js
index 60ae3068..3a732ef3 100644
--- a/src/main/keyboard/shortcutHandler.js
+++ b/src/main/keyboard/shortcutHandler.js
@@ -21,11 +21,11 @@ class Keybindings {
this.configPath = path.join(userDataPath, 'keybindings.json')
this.keys = new Map([
- // marktext - macOS only
+ // Mark Text - macOS only
['mtHide', 'Command+H'],
['mtHideOthers', 'Command+Alt+H'],
- // file menu
+ // File menu
['fileNewFile', 'CmdOrCtrl+N'],
['fileNewTab', 'CmdOrCtrl+Shift+T'],
['fileOpenFile', 'CmdOrCtrl+O'],
@@ -38,7 +38,7 @@ class Keybindings {
['fileCloseWindow', 'CmdOrCtrl+Shift+W'],
['fileQuit', 'CmdOrCtrl+Q'],
- // edit menu
+ // Edit menu
['editUndo', 'CmdOrCtrl+Z'],
['editRedo', 'CmdOrCtrl+Shift+Z'],
['editCut', 'CmdOrCtrl+X'],
@@ -57,7 +57,7 @@ class Keybindings {
['editAidou', 'CmdOrCtrl+/'],
['editScreenshot', 'CmdOrCtrl+Alt+A'],
- // paragraph menu
+ // Paragraph menu
['paragraphHeading1', 'CmdOrCtrl+1'],
['paragraphHeading2', 'CmdOrCtrl+2'],
['paragraphHeading3', 'CmdOrCtrl+3'],
@@ -79,7 +79,7 @@ class Keybindings {
['paragraphHorizontalLine', 'CmdOrCtrl+Alt+-'],
['paragraphYAMLFrontMatter', 'CmdOrCtrl+Alt+Y'],
- // format menu
+ // Format menu
['formatStrong', 'CmdOrCtrl+B'],
['formatEmphasis', 'CmdOrCtrl+I'],
['formatUnderline', 'CmdOrCtrl+U'],
@@ -90,10 +90,10 @@ class Keybindings {
['formatImage', 'CmdOrCtrl+Shift+I'],
['formatClearFormat', 'Shift+CmdOrCtrl+R'],
- // window menu
+ // Window menu
['windowMinimize', 'CmdOrCtrl+M'],
- // view menu
+ // View menu
['viewToggleFullScreen', isOsx ? 'Ctrl+Command+F' : 'F11'],
['viewSourceCodeMode', 'CmdOrCtrl+Alt+S'],
['viewTypewriterMode', 'CmdOrCtrl+Alt+T'],
@@ -101,7 +101,13 @@ class Keybindings {
['viewToggleSideBar', 'CmdOrCtrl+J'],
['viewToggleTabBar', 'CmdOrCtrl+Alt+B'],
['viewDevToggleDeveloperTools', 'CmdOrCtrl+Alt+I'],
- ['viewDevReload', 'CmdOrCtrl+R']
+ ['viewDevReload', 'CmdOrCtrl+R'],
+
+ // Misc
+ ['tabsCycleForward', 'CmdOrCtrl+Tab'],
+ ['tabsCycleBackward', 'CmdOrCtrl+Shift+Tab'],
+ ['tabsSwitchToLeft', 'CmdOrCtrl+PageUp'],
+ ['tabsSwitchToRight', 'CmdOrCtrl+PageDown']
])
// fix non-US keyboards
diff --git a/src/main/menu/index.js b/src/main/menu/index.js
index 151487aa..1b1e25cf 100644
--- a/src/main/menu/index.js
+++ b/src/main/menu/index.js
@@ -164,7 +164,7 @@ class AppMenu {
}
}
- buildEditorMenu (createShortcutMap, recentUsedDocuments) {
+ buildEditorMenu (createShortcutMap, recentUsedDocuments = null) {
if (!recentUsedDocuments) {
recentUsedDocuments = this.getRecentlyUsedDocuments()
}
@@ -175,6 +175,7 @@ class AppMenu {
let shortcutMap = null
if (createShortcutMap) {
shortcutMap = parseMenu(menuTemplate)
+ this._appendMiscShortcuts(shortcutMap)
}
return {
@@ -282,6 +283,37 @@ class AppMenu {
})
}
+ _appendMiscShortcuts = shortcutMap => {
+ shortcutMap.push({
+ accelerator: this._keybindings.getAccelerator('tabsCycleForward'),
+ click: (menuItem, win) => {
+ win.webContents.send('mt::tabs-cycle-right')
+ },
+ id: null
+ })
+ shortcutMap.push({
+ accelerator: this._keybindings.getAccelerator('tabsCycleBackward'),
+ click: (menuItem, win) => {
+ win.webContents.send('mt::tabs-cycle-left')
+ },
+ id: null
+ })
+ shortcutMap.push({
+ accelerator: this._keybindings.getAccelerator('tabsSwitchToLeft'),
+ click: (menuItem, win) => {
+ win.webContents.send('mt::tabs-cycle-left')
+ },
+ id: null
+ })
+ shortcutMap.push({
+ accelerator: this._keybindings.getAccelerator('tabsSwitchToRight'),
+ click: (menuItem, win) => {
+ win.webContents.send('mt::tabs-cycle-right')
+ },
+ id: null
+ })
+ }
+
_setApplicationMenu (menu) {
if (isLinux && !menu) {
// WORKAROUND for Electron#16521: We cannot hide the (application) menu on Linux.
diff --git a/src/renderer/pages/app.vue b/src/renderer/pages/app.vue
index 2fa7e8d2..5f3ab77c 100644
--- a/src/renderer/pages/app.vue
+++ b/src/renderer/pages/app.vue
@@ -140,6 +140,7 @@ export default {
dispatch('LINTEN_FOR_SET_LINE_ENDING')
dispatch('LISTEN_FOR_NEW_TAB')
dispatch('LISTEN_FOR_CLOSE_TAB')
+ dispatch('LISTEN_FOR_TAB_CYCLE')
dispatch('LINTEN_FOR_PRINT_SERVICE_CLEARUP')
dispatch('LINTEN_FOR_EXPORT_SUCCESS')
dispatch('LISTEN_FOR_FILE_CHANGE')
diff --git a/src/renderer/store/editor.js b/src/renderer/store/editor.js
index 6ae6a5af..778d4727 100644
--- a/src/renderer/store/editor.js
+++ b/src/renderer/store/editor.js
@@ -544,6 +544,15 @@ const actions = {
})
},
+ LISTEN_FOR_TAB_CYCLE ({ commit, state, dispatch }) {
+ ipcRenderer.on('mt::tabs-cycle-left', e => {
+ dispatch('CYCLE_TABS', false)
+ })
+ ipcRenderer.on('mt::tabs-cycle-right', e => {
+ dispatch('CYCLE_TABS', true)
+ })
+ },
+
CLOSE_TAB ({ dispatch }, file) {
const { isSaved } = file
if (isSaved) {
@@ -553,6 +562,36 @@ const actions = {
}
},
+ // Direction is a boolean where false is left and true right.
+ CYCLE_TABS ({ commit, state }, direction) {
+ const { tabs, currentFile } = state
+ if (tabs.length <= 1) {
+ return
+ }
+
+ const currentIndex = tabs.findIndex(t => t.id === currentFile.id)
+ if (currentIndex === -1) {
+ console.error('CYCLE_TABS: Cannot find current tab index.')
+ return
+ }
+
+ let nextTabIndex = 0
+ if (!direction) {
+ // Switch tab to the left.
+ nextTabIndex = currentIndex === 0 ? tabs.length - 1 : currentIndex - 1
+ } else {
+ // Switch tab to the right.
+ nextTabIndex = (currentIndex + 1) % tabs.length
+ }
+
+ const nextTab = tabs[nextTabIndex]
+ if (!nextTab || !nextTab.id) {
+ console.error(`CYCLE_TABS: Cannot find next tab (index="${nextTabIndex}").`)
+ return
+ }
+ commit('SET_CURRENT_FILE', nextTab)
+ },
+
/**
* Create a new untitled tab optional from a markdown string.
*