diff --git a/src/renderer/codeMirror/index.css b/src/renderer/codeMirror/index.css index 9df36cfe..eb1f0fd9 100644 --- a/src/renderer/codeMirror/index.css +++ b/src/renderer/codeMirror/index.css @@ -4,4 +4,153 @@ } .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: rgb(178, 215, 254); -} \ No newline at end of file +} +.CodeMirror-search-label{ + +} +.CodeMirror-dialog { + position: fixed !important; + width: 600px !important; + /* padding: 0 !important; */ + top: 40px !important; + left: unset !important; + right: 20px !important; + border-radius: 3px !important; + box-shadow: var(--floatShadow) !important; + background: var(--floatBgColor) !important; + display: flex; + flex-direction: row; +} +.CodeMirror-dialog .left-arrow { + width: 20px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} +.CodeMirror-dialog .left-arrow:hover { + background: var(--floatHoverColor); +} +.CodeMirror-dialog .left-arrow svg { + height: 12px; + width: 12px; +} +.CodeMirror-dialog .left-arrow svg.arrow-right { + transform: rotate(-90deg); +} + +.CodeMirror-dialog .right-controls { + flex: 1; +} +.CodeMirror-dialog .search, .replace { + height: 28px; + display: flex; + padding: 4px 10px 0 4px; + margin-bottom: 5px; +} + +.CodeMirror-dialog .button { + outline: none; + cursor: pointer; + box-sizing: border-box; + height: 28px; + width: 28px; + text-align: center; + padding: 5px; + display: inline-block; + font-weight: 500; + color: var(--sideBarIconColor); + &.left { + margin-right: 10px; + } + &.right { + margin-left: 10px; + } +} +.button.active { + color: var(--themeColor); +} +.CodeMirror-dialog .button > svg { + width: 16px; + height: 16px; +} +.CodeMirror-dialog .button:active { + opacity: .5; +} +.CodeMirror-dialog .input-wrapper { + display: flex; + flex: 1; + position: relative; + border: 1px solid var(--inputBgColor); + background: var(--inputBgColor); + border-radius: 3px; + overflow: visible; +} +.CodeMirror-dialog .input-wrapper.error { + border: 1px solid var(--notificationErrorBg); + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.CodeMirror-dialog .input-wrapper .controls { + position: absolute; + top: 6px; + right: 10px; + font-size: 12px; + display: flex; + color: var(--sideBarTitleColor); + & > span.search-result { + height: 20px; + margin-right: 5px; + line-height: 17px; + } + & > span:not(.search-result) { + cursor: pointer; + width: 20px; + height: 20px; + margin-left: 2px; + margin-right: 2px; + &:hover { + color: var(--sideBarIconColor); + } + & > svg { + fill: var(--sideBarIconColor); + &:hover { + fill: var(--highlightThemeColor); + } + } + &.active svg { + fill: var(--highlightThemeColor); + } + } +} + +.CodeMirror-dialog .input-wrapper .error-msg { + position: absolute; + top: 27px; + width: calc(100% + 2px); + height: 28px; + left: -1px; + padding: 0 8px; + box-sizing: border-box; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + background: var(--notificationErrorBg); + line-height: 28px; + color: #ffffff; + font-size: 14px; + z-index: 1; +} + +.CodeMirror-dialog .input-wrapper input { + flex: 1; + padding: 0 8px; + height: 26px; + outline: none; + border: none; + box-sizing: border-box; + font-size: 14px; + color: var(--editorColor); + padding: 0 8px; + background: transparent; +} diff --git a/src/renderer/codeMirror/index.js b/src/renderer/codeMirror/index.js index 5e07fa2e..e68d9bc7 100644 --- a/src/renderer/codeMirror/index.js +++ b/src/renderer/codeMirror/index.js @@ -1,6 +1,10 @@ import { filter } from 'fuzzaldrin' import 'codemirror/addon/edit/closebrackets' import 'codemirror/addon/edit/closetag' +import 'codemirror/addon/search/searchcursor' +import 'codemirror/addon/dialog/dialog' +import 'codemirror/addon/search/search' +import 'codemirror/addon/search/jump-to-line' import 'codemirror/addon/selection/active-line' import 'codemirror/mode/meta' import codeMirror from 'codemirror/lib/codemirror' @@ -10,6 +14,7 @@ import overlayMode from './overlayMode' import multiplexMode from './mltiplexMode' import languages from './modes' import 'codemirror/lib/codemirror.css' +import 'codemirror/addon/dialog/dialog.css' import './index.css' import 'codemirror/theme/railscasts.css' diff --git a/src/renderer/components/editorWithTabs/editor.vue b/src/renderer/components/editorWithTabs/editor.vue index 0b407039..d20bd487 100644 --- a/src/renderer/components/editorWithTabs/editor.vue +++ b/src/renderer/components/editorWithTabs/editor.vue @@ -836,13 +836,13 @@ export default { }, handleUndo () { - if (this.editor) { + if (this.editor && this.sourceCode === false) { this.editor.undo() } }, handleRedo () { - if (this.editor) { + if (this.editor && this.sourceCode === false) { this.editor.redo() } }, @@ -920,6 +920,7 @@ export default { }, handleFindAction (action) { + if (this.sourceCode) { return } const searchMatches = this.editor.find(action) this.$store.dispatch('SEARCH', searchMatches) this.scrollToHighlight() diff --git a/src/renderer/components/editorWithTabs/sourceCode.vue b/src/renderer/components/editorWithTabs/sourceCode.vue index 687a505d..94a6e146 100644 --- a/src/renderer/components/editorWithTabs/sourceCode.vue +++ b/src/renderer/components/editorWithTabs/sourceCode.vue @@ -94,6 +94,14 @@ export default { bus.$on('file-changed', this.handleFileChange) bus.$on('selectAll', this.handleSelectAll) bus.$on('image-action', this.handleImageAction) + bus.$on('undo', this.handleUndo) + bus.$on('redo', this.handleRedo) + bus.$on('find', this.handleFind) + bus.$on('replace', this.handleReplace) + bus.$on('findNext', this.handleFindNext) + bus.$on('findPrev', this.handleFindPrev) + document.addEventListener('click', this.docClick) + document.addEventListener('keyup', this.docKeyup) setMode(editor, 'markdown') this.listenChange() @@ -126,6 +134,14 @@ export default { bus.$off('file-changed', this.handleFileChange) bus.$off('selectAll', this.handleSelectAll) bus.$off('image-action', this.handleImageAction) + bus.$off('undo', this.handleUndo) + bus.$off('redo', this.handleRedo) + bus.$off('find', this.handleFind) + bus.$off('replace', this.handleReplace) + bus.$off('findNext', this.handleFindNext) + bus.$off('findPrev', this.handleFindPrev) + document.removeEventListener('click', this.docClick) + document.removeEventListener('keyup', this.docKeyup) const { editor } = this const { cursor, markdown } = this.getMarkdownAndCursor(editor) @@ -252,6 +268,49 @@ export default { this.tabId = null // invalidate tab id } }, + handleUndo () { + if (this.editor && this.sourceCode) { + this.editor.execCommand('undo') + } + }, + + handleRedo () { + if (this.editor && this.sourceCode) { + this.editor.execCommand('redo') + } + }, + docKeyup (event) { + if (this.editor && this.sourceCode && event.key === 'Escape') { + this.editor.execCommand('clearSearch') + } + }, + + docClick () { + if (this.editor && this.sourceCode) { this.editor.execCommand('clearSearch') } + }, + handleFind () { + if (this.editor && this.sourceCode) { + this.editor.execCommand('findPersistent') + } + }, + + handleReplace () { + if (this.editor && this.sourceCode) { + this.editor.execCommand('replace') + } + }, + + handleFindNext () { + if (this.editor && this.sourceCode) { + this.editor.execCommand('findNext') + } + }, + + handleFindPrev () { + if (this.editor && this.sourceCode) { + this.editor.execCommand('findPrev') + } + }, handleSelectAll () { if (!this.sourceCode) {