A very tiny vim in Texmacs

(This is supposed to be a toy :grinning: )Try the following code with your TeXmacs document.

Use C-] to entor the vim mode in the text mode. Esc key does not work. You can use 0, $, h, j, k, l to move your cursor around. I left the other keys unchanged.

(define-public vim-mode? #f)
(define (zzzz) vim-mode?)
    (in-vim% (zzzz)))

  (:mode in-text?)
  ("C-]" (set! vim-mode? (not vim-mode?))))

(tm-define (keyboard-press key time)
  (:require vim-mode?)
	((== key "$") (kbd-end-line))
	((== key "0") (kbd-start-line))
	((== key "h") (kbd-left))
	((== key "l") (kbd-right))
	((== key "j") (kbd-down))
	((== key "k") (kbd-up))
	(else (former key time))))

Why do you say it is supposed to be a toy ? To me it’s more like “It will be total world domination”
A true modal editing experience inside TeXmacs could be awesome !
Knowing all the power it brings to text editors, imagine what a command, editing and normal mode could bring to Texmacs …

We can go further and push the reflexion towards what Spacemacs has done which is realy realy nice …

1 Like
  1. I could not find API relating to visual aids of locating the cursor. The cursor movement functionality would be very limited. Found some clue set-mouse-ponter may be useful. Experimenting later: Slow so that TeXmacs would not start.

  2. It seems that the operation on character, word, search (I am not really comfortable with searching via a box dialog) is not fully implemented yet from what I see from generic/generic-kbd.scm.

  3. I think the rest of the programming should be easy if one only wants a limited set of vim.

I spent last weekends on adding a little bit more keybindings to this.

See https://github.com/chxiaoxn/texmacs-vi-experiment


More goodies … thanks :slight_smile:

Don’t know if emacs’s Evil implementation could help in finding inspiration


My God, if Texmacs could benefit in a modal editing experience …

It also makes sense to include C-[, not C-], to enter vi-mode. By the way, I don’t know whether it is possible to use OOP to encapsulate such a mode, if it does not affect the efficiency. I heard that the performance of OOP as implemented in SICP is not good.

As a long-time user of vim, I found Susoren’s idea of having a subset of vim available in Texmacs fascinating. I downloaded the latest files from GitHub. And now, being a Texmacs newbie, I’m a bit lost:

  1. List item where do I put vi.scm and normal.scm? In {Home}.TeXmacs/progs/ or {Home}.TeXmacs/packages/?

  2. List item how do I enter vim mode within Texmacs?

  3. List item what does C-[ exactly mean on a Mac keyboard? pressing control + [ ?

  4. List item and what exactly is meant by [ ? pressing option + 5 on a German keyboard?

These questions my sound rather silly to you, but if would really appreciate your help.

In {Home}.TeXmacs/progs/ or any subdirectory of it. Both files should be in the same subdirectory, since vi.scm is loading normal.scm with (load "normal.scm").
Moreover, if you put the files in a subdirectory of {Home}.TeXmacs/progs/, you have to modify the first line of vi.scm by adding the name of the subdirectory in the texmacs-module command: for example, if you put the files in {Home}.TeXmacs/progs/vi-mode, then the first line will be

(texmacs-module (vi-mode vi)
  ;;  (:use (generic generic-kbd)

Once that you have the files in the directory where you want them to be, you have to load them from your TeXmacs document. The way to do this is through the use-module macro, that you can for example put in your preamble (Menu Document->Part->Create Preamble)

Using again the same directories as in the example above, you would need the following

<use-module|(vi-mode vi)>

which you enter starting with a backslash (then the rest should be intuitive, use return to activate the macro once that you have typed \use-module, then an area for the argument will appear and you will be able to use the cursor to move to the argument area).

After that, I tested just a bit. As far as I understood, use esc to start vi mode, and o to exit when in the command mode of the vi mode.
Hopefully @susoren (or someone else who played with/used this mode) is still around to tell you more.

I did not understand this question, sorry. As far as I know on a German keyboard [ is AltGr + 8

And for your point 3, you need someone that uses a Mac keyboard.

If anything is not clear on how you make the files available to TeXmacs and load them in your document just ask.
The manuals for TeXmacs are at http://www.texmacs.org/tmweb/documents/manuals/texmacs-manual.en.pdf (the general manual) and (for the manual where the use of Scheme is documented
in details) http://www.texmacs.org/tmweb/documents/manuals/texmacs-scheme.en.pdf but they can be overwhelming especially as a first-time user.


Dear Giovanni,
thank you for your fast reply. Having followed your instructions, i.e. putting the files in the directory you suggested, applying the modification on the first line of vi.scm as well as loading <use-module|(vi-mode vi)> in the preamble of a tm-document, I was indeed able to start vi mode.

I’ll let you and the community know about my experiences with playing around with vi-mode.


PS1: On a German Mac keyboard AltGr seems to be option – typing option+5 yields [
PS2: If C is not meat to be the Meta-command it should be control on a Mac keyboard, I guess.

thank you for your interesting vi-mode for Texmacs. Having tested vim.scm as of 2020.05.05 a bit I found out that

  1. the movement command w does not move forward by word but to the end of the current word, despite the fact that the source-code in l. 246 says (“w” go-to-next-word)

  2. some of my favourite editing commands like r (repl. with next typed char), ~ (change case of char), . (repeat last edit cmd), J (join two lines) are not implemented.

  3. the extremely useful xp (transpose chars) and dwwP are not available

Having no scheme programming experience I wonder if these issues can easily be fixed or implemented.


Hi Tilda,
it is possible that @susoren is not reading the forum. You can try to send her/him a message through the Forum’s messaging system, maybe they will receive a notification by email (there is a user setting for that).

I was curious and checked a bit the TeXmacs code for your questions, I am able to answer the first only :slight_smile:

w brings you to the end of the current word, if you are inside a word, and to the end of the next, if you are at the end of the current. So it is a bit different from the vi command with the same name (I do not use vi since a lot of time, but I checked it yesterday).

I also checked how the commands used by the code by @susoren are implemented inside TeXmacs and I found out that for go-to-next-word they are implemented in C++. I have a faint understanding of how the whole program works, but here is a brief description of what I understand

Scheme (Guile in this case) is an extension program for the code written in C++: it can modify how the compiled program works—so one can control the behaviour of the program without recompilation.
It makes that through functions which “reach inside” the C++ code (I think they are called the “glue”).

As far as I understood (by reading the statements in the manuals) the functionality provided by the “glue” is enough to enable one to edit the document through Scheme commands and bind these to the keys that you want, so one should be able to do what you write in your points 2 and 3 but I haven’t yet mastered how to do it (by the way many functions are listed in the manuals but not yet documented, although some are documented as well).

I do not promise anything but if in the next days (or also later) I figure out how to find the next character through Scheme (and so to implement the r command), then I will post. It seems to me that I will have to learn how one distinguishes between the next character and the “next item” which isn’t a character inside the tree that represents the document.


@pireddag @Tilda

Thanks for the feedback. I have been reading the forum without logging in, some of your comments has been overlooked by me. Sorry for the very late reply.

I have put aside the ‘tiny vim’ for a while because of a lack of block cursor in Texmacs. I wonder the C++ developers be interested @darcy .
The functionality of the ‘tiny vim’ itself is quite limited, it is not difficult to extend it. However, it needs some familarity withe the TeXmacs Scheme API.

Also @mgubi could be interested.

Besides this, the TeXmacs-vi project would make for a very nice article on the (still experimental) TeXmacs wiki/blog, at https://texmacs.github.io/notes/docs/main.html :slight_smile:

I’m interested in it. But for now, I’m focusing on plugins and fonts.

I’d rather do small things and try to make it perfect than do big things but leave it buggy. For programming language syntax highlighting, there are still some remaining works to be done (eg. multi line support) after the release of TeXmacs 2.1.

1 Like

It will be a pity if this project would be forgotten, maybe one can put the current draft in tm-forge which has some visibility in the community, other people could use it as inspiration or could take it forward. If one has no time to package it only adding a small README.md file would help others to undestand the status of the projects, the things to do, the current contributors, etc… I could then put it on tm-forge. Does this sound reasonable?

1 Like

I think I may found time to reorganize a little bit next month and made it availabe as a package if any interested. Also, I can maybe use balloons as a visual aid to display cursor position.


That would be great. It does not have to be perfect.

@susoren no doubt that modal editing the vim way in TeXmacs will be a very sweet experience.
It’s awesome if you can make it happen.
Many thanks.

I guess that it is possible to show whether TeXmacs is in vi-mode (I would suggest to replace “vim” by “vi”) in the status bar.

This plugin is cute, but personally I think it’s more practical to call a decent editor

(delayed (lazy-keyboard-force)
   (:mode in-prog?)
   ("A-c E" (let ((fn (url-glue (url-temp) ".code")) ;; TODO: guess extension name
                  (snippet (tree-search-outer-first (cursor-tree) 'document)))
              (tree-export snippet fn "verbatim")
              (system-1 "emacsclient -a 'nvim-qt --nofork' " fn)
              (tree-set snippet (tree-ref (tree-import fn "verbatim") 0 0))))