Skip to content

Commit

Permalink
feat: add Vim mode integration (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
rahulyadav-57 authored Aug 20, 2024
1 parent 254528e commit 096dc11
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 3 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"moment": "^2.29.4",
"monaco-editor-textmate": "^4.0.0",
"monaco-textmate": "^3.0.1",
"monaco-vim": "^0.4.1",
"next": "13.0.7",
"onigasm": "^2.2.5",
"react": "18.2.0",
Expand Down
5 changes: 4 additions & 1 deletion src/components/workspace/Editor/Editor.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
z-index: 1;
display: flex;
gap: 1rem;
justify-content: flex-end;
justify-content: space-between;
font-size: 0.8rem;
padding: 0.2rem 1rem;
.vimStatuBar {
font-family: monospace;
}
}

.editor {
Expand Down
26 changes: 25 additions & 1 deletion src/components/workspace/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ const Editor: FC<Props> = ({ file, projectId, className = '' }) => {
const { updateFileContent, getFileContent, updateOpenFile } =
useWorkspaceActions();

const { isFormatOnSave } = useSettingAction();
const { isFormatOnSave, getSettingStateByKey } = useSettingAction();

const [isLoaded, setIsLoaded] = useState(false);
const [isEditorInitialized, setIsEditorInitialized] = useState(false);
const [cursorPosition, setCursorPosition] = useState<[number, number]>([
0, 0,
]);
const editorMode = getSettingStateByKey('editorMode');

// Using this extra state to trigger save file from js event
const [saveFileCounter, setSaveFileCounter] = useState(1);
Expand All @@ -42,6 +43,10 @@ const Editor: FC<Props> = ({ file, projectId, className = '' }) => {

const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
const monacoRef = useRef<Monaco | null>(null);
const vimStatusBarRef = useRef(null);
const vimModeRef = useRef<{
dispose: () => void;
} | null>(null);

// eslint-disable-next-line prefer-const
let lspWebSocket: ReconnectingWebSocket | null;
Expand Down Expand Up @@ -157,6 +162,21 @@ const Editor: FC<Props> = ({ file, projectId, className = '' }) => {
updateOpenFile(file.id, { isDirty: true }, projectId);
};

useEffect(() => {
(async () => {
if (!editorRef.current) return;
if (editorMode === 'vim') {
const { initVimMode } = await import('monaco-vim');
vimModeRef.current = initVimMode(
editorRef.current,
vimStatusBarRef.current as unknown as HTMLElement,
);
} else {
vimModeRef.current?.dispose();
}
})().catch(() => {});
}, [editorRef, editorMode]);

useEffect(() => {
if (!isEditorInitialized) {
return;
Expand All @@ -180,6 +200,7 @@ const Editor: FC<Props> = ({ file, projectId, className = '' }) => {
lspWebSocket?.close();
};
return () => {
vimModeRef.current?.dispose();
lspWebSocket?.close();
};
}, []);
Expand All @@ -191,6 +212,9 @@ const Editor: FC<Props> = ({ file, projectId, className = '' }) => {
return (
<div className={`${s.container} ${className}`}>
<div className={s.editorInfo}>
<div>
<span className={s.vimStatuBar} ref={vimStatusBarRef} />
</div>
<span>
Ln {cursorPosition[0]}, Col {cursorPosition[1]}
</span>
Expand Down
19 changes: 18 additions & 1 deletion src/components/workspace/WorkspaceSidebar/WorkspaceSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AppData } from '@/constant/AppData';
import { useSettingAction } from '@/hooks/setting.hooks';
import { useWorkspaceActions } from '@/hooks/workspace.hooks';
import { Project } from '@/interfaces/workspace.interface';
import { Form, Input, Popover, Switch } from 'antd';
import { Form, Input, Popover, Select, Switch } from 'antd';
import Link from 'next/link';
import { FC } from 'react';
import s from './WorkspaceSidebar.module.scss';
Expand Down Expand Up @@ -38,9 +38,12 @@ const WorkspaceSidebar: FC<Props> = ({
getTonAmountForInteraction,
isAutoBuildAndDeployEnabled,
toggleAutoBuildAndDeploy,
getSettingStateByKey,
updateEditorMode,
} = useSettingAction();

const hasEditAccess = isProjectEditable();
const editorMode = getSettingStateByKey('editorMode') ?? 'default';

const menuItems: MenuItem[] = [
{
Expand Down Expand Up @@ -112,6 +115,20 @@ const WorkspaceSidebar: FC<Props> = ({
</small>
</p>
</div>
<div className={s.settingItem}>
<Form.Item label="Editor Mode">
<Select
style={{ width: '10rem' }}
value={editorMode}
onChange={(value) => {
updateEditorMode(value as 'default' | 'vim');
}}
>
<Select.Option value="default">Default</Select.Option>
<Select.Option value="vim">Vim</Select.Option>
</Select>
</Form.Item>
</div>

<div className={s.settingItem}>
<Form.Item
Expand Down
7 changes: 7 additions & 0 deletions src/hooks/setting.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export function useSettingAction() {
getTonAmountForInteraction,
isAutoBuildAndDeployEnabled,
toggleAutoBuildAndDeploy,
updateEditorMode,
};

function updateStateByKey(dataByKey: Partial<SettingInterface>) {
Expand Down Expand Up @@ -71,4 +72,10 @@ export function useSettingAction() {
autoBuildAndDeploy: active,
});
}

function updateEditorMode(mode: 'default' | 'vim') {
updateStateByKey({
editorMode: mode,
});
}
}
1 change: 1 addition & 0 deletions src/interfaces/setting.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface SettingInterface {
formatOnSave?: boolean;
autoBuildAndDeploy?: boolean;
tonAmountForInteraction?: string;
editorMode: 'default' | 'vim';
}
1 change: 1 addition & 0 deletions src/state/setting.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const settingState = atom<SettingInterface>({
formatOnSave: false,
autoBuildAndDeploy: true,
tonAmountForInteraction: '0.05',
editorMode: 'default',
},
effects_UNSTABLE: [persistAtom],
});
7 changes: 7 additions & 0 deletions types/monaco-vim.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare module 'monaco-vim' {
export function initVimMode(
editor: monaco.editor.IStandaloneCodeEditor,
statusBar: HTMLElement,
options?: { keyHandler?: Record<string, any>; override?: boolean },
): { dispose: () => void };
}

0 comments on commit 096dc11

Please sign in to comment.