Giter Site home page Giter Site logo

replit / codemirror-vim Goto Github PK

View Code? Open in Web Editor NEW
276.0 37.0 27.0 599 KB

Vim keybindings for CM6

Home Page: https://www.npmjs.com/package/@replit/codemirror-vim

License: MIT License

TypeScript 11.07% JavaScript 83.03% HTML 5.87% Nix 0.03%
vim codemirror editor codemirror-6

codemirror-vim's Introduction

Vim keybindings for CM6

Run on Replit badge NPM version badge

Installation

npm i @replit/codemirror-vim

Usage

import { basicSetup, EditorView } from 'codemirror';
import { vim } from "@replit/codemirror-vim"

let view = new EditorView({
  doc: "",
  extensions: [
    // make sure vim is included before other keymaps
    vim(), 
    // include the default keymap and all other keymaps you want to use in insert mode
    basicSetup, 
  ],
  parent: document.querySelector('#editor'),
})

Note: if you are not using basicSetup, make sure you include the drawSelection plugin to correctly render the selection in visual mode.

Usage of cm5 vim extension api

The same api that could be used in previous version of codemirror https://codemirror.net/doc/manual.html#vimapi, can be used with this plugin too, just replace the old editor instance with view.cm in your code

import {Vim, getCM} from "@replit/codemirror-vim"

let cm = getCM(view)
// use cm to access the old cm5 api
Vim.exitInsertMode(cm)
Vim.handleKey(cm, "<Esc>")

Define additional ex commands

Vim.defineEx('write', 'w', function() {
    // save the file
});

Map keys

Vim.map("jj", "<Esc>", "insert"); // in insert mode
Vim.map("Y", "y$"); // in normal mode

Unmap keys

Vim.unmap("jj", "insert");

Add custom key

  defaultKeymap.push({ keys: 'gq', type: 'operator', operator: 'hardWrap' });
  Vim.defineOperator("hardWrap", function(cm, operatorArgs, ranges, oldAnchor, newHead) {
    // make changes and return new cursor position
  });

codemirror-vim's People

Contributors

alex23rodriguez avatar dependabot[bot] avatar kometenstaub avatar lishid avatar lunaroyster avatar masad-frost avatar meruzhanharutyunyan avatar naseelniyas avatar nightwing avatar opisek avatar sergeichestakov avatar timdown avatar tomodachi94 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codemirror-vim's Issues

Cannot/Buggy jump to the next/previous occurrence of a character in visual mode

Steps to reproduce

I tested things here: https://codemirror.net/5/demo/vim.html

Example 1 - Cannot jump to the previous occurrence of a character in visual mode

  1. Type a line (the line has to contain a character that occurs two times), e.g. type 123 123 123 in a line
  2. Go to the 3 in the middle in normal mode
  3. Type v to go into the visual mode, and type F3 to find the previous occurrence of 3
  • Expected result: It should highlight 3 123
  • Actual result: It cannot find the previous option, even typing ;

Additional information

  • It won’t work only when the cursor is highlighting the character that you are searching for, and the highlight is going in the “forward” direction
    • This means, if your cursor is on 2 and do vF3 it will work (highlight 3 12)
    • Or if you cursor highlighted 23 and currently placed on top of 2, and do vF2 it will also work (highlight 23 123)
    • But if your cursor is highlighting 23 and the cursor is placed on top of 3, and do vF3 it will not work
  • After it’s stuck, typing ; will not move the cursor forwards (backwards in the line) but typing , will move the cursor backwards (forwards in the line).
  • Forward search in visual mode works, i.e. vf3 will work
  • Backward search in normal mode also works, i.e. just F3 will jump to the previous occurrence

Example 2 - Buggy jump to the next occurrence of a character in visual mode under some situation

1234567
beehive

Assuming the word beehive is at position 1-7:

  • If the cursor is on position 3: do vfe will highlight positions 3-7 as expected (ehive)
  • If the cursor is on position 2: do vfe will highlight positions 2-7 instead of 2-3 (eehive, instead of ee)
  • If the cursor is on position 3: do vFe the cursor doesn’t move, instead of highlighting 3-2, which is the issue pointed out in example 1

Hope this helps, thank you!

Null access error throw with command in keydown handler

looks like command can be null here in some rare cases so CM Vim will throw an error when we try to access it's types as part of the keydown handler. Seems to be a more recent regression. Not sure if this is something we should be checking for.

Hard to get an exact repro but here's a screenshot of the stack trace we've seen in the wild:

Screenshot 2023-03-03 at 11 37 34 AM

Up/Down arrow stop working for visual-block mode

Upgrading to 0.20 it looks like the up/down arrow stopped working for selection up/down lines in visual mode via Shift+V.

The selection seems to reset itself and go back to normal mode at the end of the line when using up/down, but it works as expected using j/k.

Repro steps are:

  • shift+v to enter line selection
  • up arrow

International keyboard fix for opt-[key]

I think I found a fix for enabling things like ci[ on macOS international keyboards.

I logged the keyboard events to the console in the adapter.

image

When I press opt, it is of type keydown and not keypress.

image

I changed it in this line:

if (e.type == "keypress" && e.altKey && !e.metaKey && !e.ctrlKey) {

image

Then I ran npm run dev and tested it in the browser, now combos like ci{ or va[ work for me.

I tested it with both German and French locale on macOS. It also works with combos that require shift, like opt-shift-5 for French, which is used for [.

Incorrect token targeted when using ci" or di" at the start of a string

Pretty minor bug but it seems that sometimes when executing ci" or di" (and related commands) at the start of a string (e.g. when your cursor is on the first " char), it targets the wrong token if that same char (") exists earlier in the line.

See example gif below. Notice that when executing di" at the start of "cat" it deletes the chars before it until the next quote rather than inside it (e.g. cat). Doing so at the start of "animal" here works as expected because there is no quote behind it. Also notice that doing this command in the middle of the string works as expected:

cm-vim-bug-repro

Note that the expected result is to delete everything inside the string here as it does in Vim.

Curly braces and @ not working

I tested the key presses here.

Unfortunately pressing the keybinding on mac on the swiss keyboard layout for curly braces (option 8 and option 9) does not move the cursor in normal mode to the next paragraph. (It does work in MacVim and terminal vim, though.)

Pressing the combo for "@" (right option + g) does also not work for using a macro.

It seems the issue has been fixed on windows with altgr (here). Maybe the bug fix is similar?
Although I have to admit I do not know how to test the approach mentioned in the linked fix for my application, since I do not know how to run CM6. I just use it through obsidian as well.

How to programmatically change modes?

Let's say I have a CM instance with text. User changes text in insert mode. I then update the value in CM editor and want to change the mode from insert to normal mode, how do I do that?

Here's a demo:

vim-demo

I want to change to normal mode after the answer is correct. I'm not sure exactly how to do that. Can I call a method or something on CodeMirror and tell it to change modes?

Visual modes do not highlight selection

Visual modes appear to work, but there is no highlighting or any other visual clue (other than in the status bar) when using it, so it is easy to get an unexpected selection.

Is there some kind of styling that needs to happen?

Custom Commands

Say we wanted to map :w to "Save" in our app. Are there currently any ways to add that in as a custom command?

How do I write vim-latex like custom key bindings into the Overleaf (Codemirror) editor?

I am aware that Tampermonkey (https://www.tampermonkey.net/) could potentially do this. For example, the first block shown below works, but the second doesn't.

`
// ==UserScript==
// @name Overleaf Editor Custom VIM Keybindings
// @namespace http://tampermonkey.net/
// @Version 0.1
// @match https://www.overleaf.com/project/*
// @grant none
// ==/UserScript==

(function() {
'use strict';

window.addEventListener("UNSTABLE_editor:extensions", (event) => {
const { CodeMirror, CodeMirrorVim, extensions } = event.detail;

// add custom keybindings - insert mode applies on insert
CodeMirrorVim.Vim.map("jj", "", "insert");
`

This (the above) works fine but the below doesn't. How can I write these bindings into, say, a userscript for Overleaf?

'
// CodeMirrorVim.Vim.map("kk", "Right-Right", "insert");
// CodeMirrorVim.Vim.map("ECI", "\cite{<++>}<++>", "insert");
// CodeMirrorVim.Vim.map("aa", "", "insert");
// CodeMirrorVim.Vim.imap("`a", "\alpha", "insert");
// CodeMirrorVim.IMAP('FMB', "\mathbb{<++>}<++>", 'insert');
'

Thanks!!

p.s. In vim-latex, there are built-in keybindings for different modes. E.g., in insert mode, typing a specific three-letter combination automatically creates an equation environment with placeholders "<++>" in it in the .tex file.

\begin{equation}
<++>
\label{<++>}
\end{end}

One can also create custom keybindings for vim-latex.

Cursor moves past end of line in vim

Copied from codemirror/codemirror5#5422:

To reproduce

  • Open the vim demo.
  • Enter normal mode.
  • Click past the end of a line.

Expected

Cursor should be over the last character in the line.
expected

Actual

Cursor moves past the last character in the line.
actual
Interestingly, if you move the cursor left, it goes to the correct position, and then it can't be moved right again, so it looks like CodeMirror already knows that this is an illegal position.

I'd like to help with a pull request, but I'm not sure where to start- any pointers would be appreciated :)

Cursor not visible in insert mode

I am not sure if this is a bug or not (could be related to the theme) but when you're in insert mode, you can't see the cursor.

Normal Mode

image

Insert Mode

image

<C-o> and <C-i> style jumplist

Hi, I'm using Vim for Obsidian, which I understand uses codemirror underlying. Is it possible to get vim-like <C-o> and <C-i> behavior, where those keys jump to the last and next spots in a document you have visited?
esm7/obsidian-vimrc-support#121 for more context (although discussing ctrl F and B instead of O and I)
Looking for a jumplist returning you to recent locations within a file, not just to the previous/next file.

Error using with Sandpack

Error: Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.

I dealt with an issue trying to get @codesandbox/sandpack-react to work with @replit/codemirror-vim recently, this was due to a mismatch of the @codemirror/state component (which happens when extensions have mismatching versions of this package). In this case it looks like @replit/codemirror-vim has a more up-to-date version than the latest @codesandbox/sandpack-react. To fix this issue in the meantime you can install:

npm i @replit/[email protected]

This is the last compatible version with the current instance of sandpack, the version I am using is: @codesandbox/sandpack-react": "^1.15.1".

This is NOT an issue with this package, but took me a good amount of looking to find the solution and this issue exists to save people some time in the meantime.

[vim] Implement insert mode <Ctrl-r> to insert the contents of a register #2298

codemirror/codemirror5#2298 (comment)
In vim, I can paste previously yanked text without leaving insert mode with <Ctrl-r>". Similarly for other registers like % (current file name), - (last small delete), and = (arbitrary vimscript expression entered at resulting prompt).

CodeMirror doesn't support this. Pressing in insert mode tries to reload the page, even for Chrome apps opened as a standalone window.

===
How about it ?

Building locally does not work

Getting the minimal example described on the README works when installing the pacakge from npm works fine. But cloning the repo, building it, and then importing it using

{  
  "dependencies": {
    "@replit/codemirror-vim": "file:../codemirror-vim",
    "codemirror": "^6.0.1"
  }
}

doesn't work: it causes the following error when run:

Uncaught Error: Unrecognized extension value in extension set ([object Object]). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.
    inner index.js:2017
    inner index.js:1992
    inner index.js:1992
    flatten index.js:2021
    resolve index.js:1929
    create index.js:2756
    EditorView index.js:6295
    setupEditor editor.ts:9
    <anonymous> main.ts:21

This happens for both the latest commit (66891bc) as well as the 6.0.4 commit (2c5931f).

Any tips on how I should be building / what I am doing wrong?

Yanking And Pasting From System Clipboard

Can you please make "+y or *+y and "+p or *+p available, it is very important and basic command and yet not implemented from vim. I know there a command to tell the vim use system clipboard. But vim mess with clipboard a lot so it is better imo to not to do that and instead use a different command for that.

thanks

Global delete

Global delete does not work in editors that implement codemirror-vim. This is reproducible in editors that include it, using this demo and this demo.

In all cases, global search returns the expected result, but when a delete command is added, it fails.

Steps to reproduce
Using vim-mode for editing, in a file containing a list of completed tasks (markdown syntax)

- [x] Task

execute :g/^-\s\[x\]/d

Expected result
Matching lines are deleted

Actual result
:43d not an editor command (line number changes based on file, result does not).

Dead keys don't work as expected in normal mode

Dead keys such as the backtick and ^ (German keyboard layout), when pressed in normal mode, insert the character directly into the text instead of waiting for a space or some other character.

This makes it (as examples) impossible to use ^ for going to the beginning of a line or using the backtick in f motions.

Shift-a + parenthesis + '.' is broken

Hi, I noticed the following behavior:

  1. Use the command A (shift+a) to go to the end of a line and type (abc)
  2. Press esc to go to normal mode
  3. Move to another line
  4. Press . to repeat the above action

This causes the text ()abc to be inserted at the end of the line, instead of (abc). The same happens for [] and {} as well.

Here is the same bug reported in Obsidian (it is marked as archived when there was a major version update, but the bug is still in fact there).

Ctrl+I doesn't work as expected

Cited from Vim official help.

  					*jumplist*

Jumps are remembered in a jump list. With the CTRL-O and CTRL-I command you
can go to cursor positions before older jumps, and back again. Thus you can

2022-06-21_12h18_19.mp4

[Feature] `gq`/`gw` format operators

gw and gq are very useful for formatting text (in particular, for word-wrapping large paragraphs).

Operator documentation:

gq{motion}		Format the lines that {motion} moves over.
			The cursor is left on the first non-blank of the last
			formatted line.
gw{motion}		Format the lines that {motion} moves over.  Similar to
			|gq| but puts the cursor back at the same position in
			the text.

They were requested for codemirror5 in codemirror/codemirror5#5529

Characters needing `AltGr` don't work in normal mode

In Vim mode, keyboard shortcuts such as fx, tx, vix don’t work if x is a character that requires pressing AltGr, such as {[]}€@\ on the German keyboard layout.

Downstream Bug report: https://forum.obsidian.md/t/vim-mode-shortcuts-involving-altgr-dont-work/36211

I can reproduce the bug in both Firefox and Chromium on Linux in the playground: https://codemirror-vim--util.repl.co/

The behaviour is different for each key. For { it jumps a paragraph up, for [ it activates the first of two [[ presses, on the second it jumps to the top of the document. For |, it goes to the beginning of the line.

Motion maps from 'i' & 'a' causes 'ciw', 'caw', and others to fail

Hello,

I'm unable to run commands using the motions 'iw' & 'aw' after using the following remaps:

noremap i h
noremap a j

This deviates from Vim behavior since Vim allows iw & aw to be used to manipulate words as expected from ciw daw yaw etc

After doing some code skimming, I believe the issue stems from the following items in the map getting out-prioritized whenever a motion map using 'i' or 'a' as the target keys is created using mapCommand():

    { keys: 'a<character>', type: 'motion', motion: 'textObjectManipulation' },
    { keys: 'i<character>', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }},

This is because _mapCommand() method writes user-defined maps to the beginning of the defaultKeymap using .unshift()

I'm thinking the issue would be resolved by ensuring that these a<character> and i<character> commands don't lose priority. This can be accomplished is by keeping these items at the front of map.

Here's a possible solution:

  • create a var invariantMap that contains the a<character> and i<character> mappings
  • create a var userMap that contains the user-defined mappings
  • instead of accessing defaultKeymap directly throughout the code, we could replace it with a getCombinedKeymap() method that returns a map that union of the invariantMap, userMap, and thedefaultKeymap (respecting that order for priority). This way, the invariant mappings remains prioritized over the user-defined mappings, and the user-defined mappings remains prioritized over the default mappings.

Would this strategy make sense?

newbie question: how to add custom keymap for `<Esc>`

I tried my best reading the source code, existing issues, and the docs for codemirror and I'm still at a loss. I'm going to continue trying to solve this myself, but in the meantime, I figured I'd ask for help. Thanks!

Could not resolve "@codemirror/fold"

The @codemirror/fold dependency is not listed as a peer dependency but is required to use this extension.

node_modules/@replit/codemirror-vim/dist/index.js:7:25:
  7 │ import { foldCode } from '@codemirror/fold';

S behaves strangely in normal mode

First wanted to say thanks for undertaking this large project. If I can help, please let me know how.

I noticed "S" was behaving a little strangely in normal mode:

Expected behavior: insert starting from the first character in the line
Actual behavior: insert mode starting from the 0 position of the line.

Ctrl+A doesn't increment the number

Thank you for the great plugin :)

I found a bug that Ctrl+A doesn't increment the number. On the other hand, Ctrl+X works correctly.

2022-06-21_12h07_35.mp4

Best regards.

`diw` at the end of a file with a new line throws an error

See title. Repro is pretty straightfoward, simply move your cursor to the last line and type diw while in normal mode.

This will result in a type error from accessing a null variable being thrown in the console rather than the line being deleted which is what's expected.

See repro below:

diw-throw-cm-vim

How to define leader key mappings in normal mode?

I'm new to Codemirror and wonder if I can define <localleader>lv in normal mode. For now, [s can be mapped to trigger a custom function, as below:

    // Access the functions by defining them as actions first
    CodeMirrorVim.Vim.defineAction('forwardsearch', buctton_click_forward_search);
    CodeMirrorVim.Vim.defineAction('WritefullPrevious', writefull_previous_error);
    CodeMirrorVim.Vim.defineAction('WritefullNext', writefull_next_error);

    // Assign functions to key mappings.
    // CodeMirror.Vim.unmap(';');  // Cannot put this here - if uncommented, [s and ]s won't work
    CodeMirrorVim.Vim.mapCommand("[s", 'action', 'WritefullPrevious');
    CodeMirrorVim.Vim.mapCommand("]s", 'action', 'WritefullNext');
    CodeMirror.Vim.unmap(';');
    CodeMirrorVim.Vim.mapCommand(";lv", 'action', 'forwardsearch');  // This doesn't work.

Here is my current attempt in full - https://gist.github.com/llinfeng/f50211be8ff2c8816934da266403f47d. The goal is to revive this old script for Overleaf.

Ctrl-[ does not act as escape

Issue: Instead of acting as an escape key, Ctrl-[ decreases the indent level.

Observed in:

As far as I can tell this only happens on Linux and Windows. MacOS is unaffected.

Vim commands using dead characters don't work in Firefox

OS: Ubuntu 22.04
Browser with bug: Firefox 111.0.1
Browser without bug: Chromium 111.0.5563.146

Steps to reproduce

  1. Set keyboard to spanish (with dead keys)
  2. Move cursor to the end of a line
  3. Press ^
  4. Enter insert mode and write "hello"

Expected behaviour

The line should start with "hello"

Actual behaviour

The line starts with "olleh"

Entering insert mode elsewhere will also reset the cursor to the wrong location.

2023-04-04.14-36-41.mp4

Inserting unwanted characters when scrolling with j or k, Linux fcitx-skk/ibus-skk

Although it is rare, when the editor is in normal mode, moving around with j, k, w, etc., actually results in j, k, w, etc., being entered as text.
This occurs frequently when the host application is running slow.

It occurred on Linux when using the input methods fcitx-skk or ibus-skk; it did not occur when using direct alphabetical input with ibus.

Note that I could not reproduce the problem with https://codemirror.net/demo/vim.html.

  • OS: Linux junior 5.18.10-zen1-1-zen #1 ZEN SMP PREEMPT_DYNAMIC Thu, 07 Jul 2022 17:18:11 +0000 x86_64 GNU/Linux
  • Window Manager: i3 version 4.20.1 (2021-11-03)
  • Input Method: IBus 1.5.26, ibus-skk 1.4.3
Peek.2022-07-15.12-06.mp4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.