mirror of
https://github.com/beekeeper-studio/beekeeper-studio.git
synced 2026-03-13 10:12:54 +08:00
Merge pull request #2989 from beekeeper-studio/fix/text-editor-vim
Fix query editor vim keymaps
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
:vim-config="vimConfig"
|
||||
:line-wrapping="wrapText"
|
||||
:keymap="userKeymap"
|
||||
:vim-keymaps="vimKeymaps"
|
||||
:entities="entities"
|
||||
:columns-getter="columnsGetter"
|
||||
:default-schema="defaultSchema"
|
||||
@@ -352,6 +353,7 @@
|
||||
import { FormatterDialect, dialectFor } from "@shared/lib/dialects/models"
|
||||
import { findSqlQueryIdentifierDialect } from "@/lib/editor/CodeMirrorPlugins";
|
||||
import { registerQueryMagic } from "@/lib/editor/CodeMirrorPlugins";
|
||||
import { getVimKeymapsFromVimrc } from "@/lib/editor/vim";
|
||||
|
||||
const log = rawlog.scope('query-editor')
|
||||
const isEmpty = (s) => _.isEmpty(_.trim(s))
|
||||
@@ -399,6 +401,7 @@
|
||||
containerResizeObserver: null,
|
||||
onTextEditorBlur: null,
|
||||
wrapText: false,
|
||||
vimKeymaps: [],
|
||||
|
||||
/**
|
||||
* NOTE: Use focusElement instead of focusingElement or blurTextEditor()
|
||||
@@ -1043,6 +1046,8 @@
|
||||
await this.$nextTick()
|
||||
this.focusElement = 'text-editor'
|
||||
}
|
||||
|
||||
this.vimKeymaps = await getVimKeymapsFromVimrc()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if(this.split) {
|
||||
|
||||
@@ -31,14 +31,18 @@ async function readVimrc(pathToVimrc?: string): Promise<string[]> {
|
||||
return [];
|
||||
}
|
||||
|
||||
export async function setKeybindingsFromVimrc(codeMirrorVimInstance: any): Promise<void> {
|
||||
export async function getVimKeymapsFromVimrc(): Promise<IMapping[]> {
|
||||
const potentialCommands = await readVimrc();
|
||||
|
||||
if (potentialCommands.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mappings = createVimCommands(potentialCommands);
|
||||
return createVimCommands(potentialCommands);
|
||||
}
|
||||
|
||||
export async function setKeybindingsFromVimrc(codeMirrorVimInstance: any): Promise<void> {
|
||||
const mappings = await getVimKeymapsFromVimrc();
|
||||
|
||||
for (let j = 0; j < mappings.length; j++) {
|
||||
codeMirrorVimInstance.map(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
| `keybindings` | `object` | Object contiaining keybindings where the key is a combination of keys and the value is a function. For example, `{ 'Ctrl-Enter': function submit(){}, 'Cmd-Enter': function submit(){} }`. | `undefined` |
|
||||
| `keymap` | `string` | Configure the keymap to use. Possible values are 'default', 'vim', 'emacs' and 'sublime'. | `default` |
|
||||
| `vimConfig` | `object` | Configure vim mode. | `undefined` |
|
||||
| `vimKeymaps` | `array` | Configure custom key mappings in vim. See documentation in `texteditor/mixin.ts` for more details. | `undefined` |
|
||||
| `columnsGetter` | `(entityName: string) => (string[] \| Promise<string[]>)` | If provided, this function will be called for autocompleting column names instead of using the `entities.columns` property. Expect one argument of type `string` representing a combination of schema name (if exists) and entity name. Accepts async or non-async function. | `undefined` |
|
||||
| `defaultSchema` | `string` | The default schema to use when autocompleting entity names. Schemas that match this will be prioritized in the autocompletion list. | `public` |
|
||||
| `mode` | `string` \| `object` | The CodeMirror's mode to use. Modes are JavaScript programs that help color (and optionally indent) text written in a given language. Please refer to CodeMirror's [mode api](https://codemirror.net/5/doc/manual.html#modeapi) learn more | `text/x-sql` |
|
||||
|
||||
@@ -21,7 +21,7 @@ import "codemirror/addon/merge/merge";
|
||||
import 'codemirror/keymap/vim.js'
|
||||
import CodeMirror, { TextMarker } from "codemirror";
|
||||
import _ from "lodash";
|
||||
import { setKeybindings, applyConfig, Register, Config } from "./vim";
|
||||
import { setKeybindings, Config, extendVimOnCodeMirror } from "./vim";
|
||||
import { divider, InternalContextItem, openMenu } from "../context-menu/menu";
|
||||
import { writeClipboard, readClipboard } from "../../utils/clipboard";
|
||||
import { cmCtrlOrCmd } from "../../utils/platform"
|
||||
@@ -152,6 +152,14 @@ export default {
|
||||
forceInitialize() {
|
||||
this.initialize();
|
||||
},
|
||||
keymap() {
|
||||
this.editor.setOption("keyMap", this.keymap);
|
||||
|
||||
if (this.keymap === "vim") {
|
||||
const cmEl = this.$refs.editor.parentNode.querySelector(".CodeMirror");
|
||||
extendVimOnCodeMirror(cmEl, this.vimConfig, this.vimKeymaps);
|
||||
}
|
||||
},
|
||||
vimKeymaps() {
|
||||
if (!this.editor || this.keymap !== 'vim') {
|
||||
return
|
||||
@@ -372,32 +380,7 @@ export default {
|
||||
cmEl.addEventListener("contextmenu", this.showContextMenu);
|
||||
|
||||
if (this.keymap === "vim") {
|
||||
const codeMirrorVimInstance = cmEl.CodeMirror.constructor.Vim;
|
||||
|
||||
if (!codeMirrorVimInstance) {
|
||||
console.error("Could not find code mirror vim instance");
|
||||
} else {
|
||||
if (this.vimConfig) {
|
||||
applyConfig(codeMirrorVimInstance, this.vimConfig);
|
||||
}
|
||||
|
||||
const vimKeymaps = this.vimKeymaps ?? [];
|
||||
if (_.isArray(vimKeymaps)) {
|
||||
setKeybindings(codeMirrorVimInstance, vimKeymaps);
|
||||
} else {
|
||||
console.error("vimKeymaps must be an array");
|
||||
}
|
||||
|
||||
// cm throws if this is already defined, we don't need to handle that case
|
||||
try {
|
||||
codeMirrorVimInstance.defineRegister(
|
||||
"*",
|
||||
new Register(navigator)
|
||||
);
|
||||
} catch (e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
extendVimOnCodeMirror(cmEl, this.vimConfig, this.vimKeymaps);
|
||||
}
|
||||
|
||||
if (this.plugins) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import _ from "lodash";
|
||||
|
||||
export type IMapping = {
|
||||
mappingMode: string;
|
||||
lhs: string;
|
||||
@@ -102,4 +104,30 @@ export class Register {
|
||||
}
|
||||
}
|
||||
|
||||
export function extendVimOnCodeMirror(cmEl: any, vimConfig?: Config, vimKeymaps: IMapping[] = []) {
|
||||
const codeMirrorVimInstance = cmEl.CodeMirror.constructor.Vim;
|
||||
|
||||
if (!codeMirrorVimInstance) {
|
||||
console.error("Could not find code mirror vim instance");
|
||||
} else {
|
||||
if (vimConfig) {
|
||||
applyConfig(codeMirrorVimInstance, vimConfig);
|
||||
}
|
||||
|
||||
if (_.isArray(vimKeymaps)) {
|
||||
setKeybindings(codeMirrorVimInstance, vimKeymaps);
|
||||
} else {
|
||||
console.error("vimKeymaps must be an array");
|
||||
}
|
||||
|
||||
// cm throws if this is already defined, we don't need to handle that case
|
||||
try {
|
||||
codeMirrorVimInstance.defineRegister(
|
||||
"*",
|
||||
new Register(navigator)
|
||||
);
|
||||
} catch (e) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user