1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-vim-wasm

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
README.md 38 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 07.06.2025 14:45 7cded5c

иконка vim.wasm: Vim, перенесённый в WebAssembly

Статус сборки Версия npm

Этот проект — экспериментальная ветка [редактора Vim][] от @rhysd для компиляции его в WebAssembly с использованием emscripten и binaryen. Vim работает на Web Worker и взаимодействует с основным потоком через SharedArrayBuffer.

Цель этого проекта — запуск редактора Vim в браузерах без утраты мощных функций Vim, скомпилировав исходные коды C в WebAssembly.

Основное окно

Попробуйте его с помощью вашего браузера- ИСПОЛЬЗОВАНИЕ

  • Почти все мощные функции Vim (синтаксическое выделение, Vim-скрипты, текстовые объекты, и т. д.) включая последние функции (всплывающие окна, и т. д.) поддерживаются.
  • Перетаскивание файлов в вкладку браузера открывает их в Vim.
  • Команда :write записывает файл только в память. Скачайте текущий буфер с помощью :export или конкретный файл с помощью :export {file}.
  • Регистр буфера Clipboard "* поддерживается. Например, вставьте текст из системного буфера в Vim с помощью "*p или :put *, и скопируйте текст из Vim в системный буфер с помощью "*y или :yank *. Если вы хотите синхронизировать буфер Clipboard Vim с системным буфером, команда :set clipboard=unnamed должна работать как в обычном Vim.
  • Файлы под директорией ~/.vim сохраняются персистентно в Indexed DB. Пожалуйста, напишите вашу любимую конфигурацию в ~/.vim/vimrc (НЕ ~/.vimrc).
  • file={filepath}={url} загружает файл с {url} в {filepath}. Любые удалённые файлы могут быть открыты (учтите CORS).
  • По умолчанию используется схема цветов onedark.vim, но vim-monokai также доступен как схема цветов с высокой контрастностью.
  • Команда :! /path/to/file.js выполняет JavaScript-код в браузере. :! % выполняет текущий буфер.
  • Уроки Vim доступны через :e tutor.
  • Добавьте параметры запроса arg= (например, ?arg=~%2f.vim%2fvimrc&arg=hello.txt) для добавления аргументов командной строки Vim.
  • Пожалуйста, прочитайте документацию по использованию.

monokai: https://github.com/sjl/greyshade.vimmd) для более подробной информации.onedark: https://github.com/dimonomid/onedark.vim monokai: https://github.com/sjl/gxv/tree/master/scripts/vim-monokai idb: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API [vim editor]: https://www.vim.org/ @rhysd: https://github.com/rhysd webassembly: https://webassembly.org/ emscripten: https://emscripten.org/ binaryen: https://github.com/WebAssembly/binaryen web worker: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API shared-array-buffer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer try it: https://rhysd.github.io/vim-wasm/ travis-ci-badge: https://img.shields.io/travis/rhysd/vim-wasm npm-badge: https://img.shields.io/npm/v/vim-wasm travis-ci: https://travis-ci.org/rhysd/vim-wasm npm-package: https://www.npmjs.com/package/vim-wasm

Уведомление

  • Пожалуйста, используйте десктопную версию Chrome, Firefox, Safari или браузеры на основе Chromium, так как этот проект использует SharedArrayBuffer и Atomics. В Firefox или Safari для текущего времени необходимо включить флаги функций (javascript.options.shared_memory для Firefox).
  • vim.wasm принимает клавишные вводы из события keydown DOM. Пожалуйста, отключите расширения вашего браузера, которые перехватывают клавишные события (режим инкогнито будет наилучшим вариантом).
  • Этот проект находится на очень ранней стадии эксперимента. Вы можете заметить, что он содержит ошибки при попытке его использования.
  • Если ввод не приводит к изменениям, попробуйте нажать мышью на любом месте страницы. Возможно, Vim потерял фокус.
  • Vim завершает работу при вводе :quit, но это не закрывает вкладку браузера. Пожалуйста, закройте её вручную.Этот проект упакован в виде npm пакета vim-wasm для удобного использования в веб-приложениях. Пожалуйста, ознакомьтесь с документацией для получения дополнительной информации.

Текущая версия Vim, перенесенная в WebAssembly, — это 8.2.0055 с наборами функций 'normal' и 'small'. Пожалуйста, проверьте журнал изменений для истории обновлений.

Связанные проекты

Следующие проекты связаны с этим npm пакетом и могут быть более подходящими для вашего случая использования.

  • react-vim-wasm: React компонент для vim.wasm. Редактор Vim можно встроить в ваше веб-приложение на основе React.
  • vimwasm-try-plugin: Командная строка для открытия vim.wasm, включающего указанный плагин Vim, сразу. Вы можете попробовать плагин Vim без его установки!
  • vim.wasm.ipynb: Интеграция Jupyter Notebook с vim.wasm. Попробуйте онлайн!

Презентации и блог-посты

Как это работает

Взаимодействие с пользователемВзаимодействие с пользователем

В рабочем потоке запускается скомпилированный в Wasm Vim. Рабочий поток запускается как отдельный Web Worker от главного потока при открытии страницы.

Предположим, вы вводите что-то с клавиатуры. Браузер принимает это как KeyboardEvent на событии keydown. JavaScript в главном потоке ловит событие и сохраняет информацию о нажатии клавиши в буфер общей памяти.

Буфер общей памяти делится между рабочим потоком. Vim ждет и получает информацию о нажатии клавиш, опрашивая буфер общей памяти с помощью API Atomics JavaScript. Когда информация о нажатии клавиш обнаруживается в буфере, она загружается и вычисляется последовательность нажатий. С помощью API JS to Wasm, благодаря emscripten, последовательность добавляется в буфер ввода Vim в Wasm.

Последовательность в буфере ввода обрабатывается ядром редактора (обновление буфера, экрана, ...). Из-за этих обновлений происходят события отрисовки, такие как отрисовка текста, отрисовка прямоугольников, прокрутка областей, ...

Эти события отрисовки отправляются JavaScript в рабочем потоке из Wasm благодаря API JS to C emscripten. Учитывая соотношение пикселей устройства и API <canvas/>, вычисляется способ рендеринга этих событий, и вычисленные события рендеринга передаются из рабочего потока в главный поток с помощью передачи сообщений с помощью postMessage().JavaScript в главном потоке получает и помещает эти события рендеринга в очередь. На каждом кадре анимации они рендерятся на <canvas/>.

В итоге вы видите отрендеренный экран на странице.

Процесс сборки

Процесс сборки

WebAssembly-интерфейс для Vim реализован как новый графический интерфейс пользователя для Vim, подобно другим графическим интерфейсам, таким как GTK-интерфейс. Исходные коды C компилируются в отдельные файлы LLVM-биткода, а затем они объединяются в один файл биткода vim.bc с помощью emcc. emcc в конечном итоге компилирует vim.bc в двоичный файл vim.wasm с помощью binaryen и генерирует HTML/JavaScript-временную среду выполнения.

Первое, с чем я столкнулся, это отсутствие библиотеки терминалов, такой как ncurses. Я изменил скрипт configure, чтобы игнорировать проверку библиотеки терминалов. Это нормально, так как графический интерфейс пользователя для Wasm всегда используется вместо консольного интерфейса пользователя. Мне пришлось использовать множество обходных путей, чтобы пройти проверки configure.Emscripten предоставляет Unix-подобную среду. Поэтому os_unix.c может поддерживать Wasm. Однако некоторые функции не поддерживаются emscripten. Я добавил множество #ifdef FEAT_GUI_WASM для отключения функций, которые не могут быть поддерживаемы Wasm (например, поддержка fork(2), поддержка PTY, обработчики сигналов являются заглушками, ...). Я создал gui_wasm.c, heavily опираясь на gui_mac.c и gui_w32.c. Цикл событий (gui_mch_update() и gui_mch_wait_for_chars()) реализован с использованием блокирующего ожидания. И почти все события отрисовки UI передаются на JavaScript-уровень путем вызова функций JavaScript из C благодаря emscripten.Исходные коды C скомпилированы (с множеством оптимизаций) в LLVM bitcode с Clang, который интегрирован в emscripten. Затем все файлы bitcode (.o) связываются в один файл bitcode vim.bc с помощью llvm-link (также интегрированного в emscripten).

Я также создал JavaScript-таймайнт на TypeScript для отрисовки событий отрисовки, отправленных из C. JavaScript-таймайнт разделен на две части: основной поток и поток рабочего процесса. wasm/main.ts предназначен для основного потока. Он запускает Vim в потоке рабочего процесса и отрисовывает экран Vim на <canvas>, получая события отрисовки от Vim. wasm/runtime.ts и wasm/pre.ts предназначены для потока рабочего процесса. Они написаны с использованием API emscripten.

emcc (C-компилятор emscripten) компилирует vim.bc и runtime.js в vim.wasm, vim.js и vim.data с заранее загруженными файлами runtime Vim (например, схемами цветов) с помощью binaryen. Файлы runtime загружаются на виртуальную файловую систему, предоставленную браузером emscripten. Здесь эти файлы компилируются для потока рабочего процесса. wasm/main.js запускает отдельного Web Worker, загружающего vim.js.

Наконец, я создал небольшой wasm/index.html, который содержит <canvas/> для отрисовки экрана Vim и загрузки wasm/main.js.

Теперь, размещая wasm/index.html с помощью веб-сервера и доступ к нему с помощью браузера, можно запустить Vim. Он работает.### Как реализовать sleep() на JavaScript

Самая сложная часть этого переноса заключалась в том, как реализовать блокирующее ожидание (обычно выполняемое с помощью sleep()).

Так как блокировка основного потока на веб-странице означает блокировку взаимодействия пользователя, это, в основном, запрещено. Почти все операции, требующие времени, реализованы как асинхронные API на JavaScript. Wasm, работающий в основном потоке, не может блокировать поток, кроме как с помощью busy loop.Но C-программы часто используют функцию sleep(), поэтому это проблема при переносе программ. GUI-фронтенд Vim также ожидает ввод пользователя с использованием блокирующего ожидания. Emscripten предлагает обходной путь для решения этой проблемы, Emterpreter. С использованием Emterpreter, Emscripten предоставляет (псевдо) блокирующие функции ожидания, такие как emscripten_sleep(). Когда они используются в C-функции, emcc компилирует функцию в Emterpreter-байт-код вместо Wasm. И во время выполнения байт-код выполняется интерпретатором (на Wasm). Когда интерпретатор достигает точки вызова emscripten_sleep(), он приостанавливает выполнение байт-кода и устанавливает таймер (с помощью функции setTimeout на JavaScript). После истечения времени интерпретатор возобновляет состояние и продолжает выполнение. С этой механикой асинхронное ожидание на JavaScript выглядит как синхронное ожидание из мира C. Вначале я использовал Emterpreter, и это работало. Однако были несколько проблем.- Он разделяет исходные файлы Vim на две части: чистый Wasm-код, который выполняется напрямую, и Emterpreter-байт-код, который выполняется на интерпретаторе. Мне приходилось поддерживать длинный список функций, которые должны быть скомпилированы в Emterpreter-байт-код. Когда список неверен, Vim падает.

  • Emterpreter не так быстр, поэтому замедляет всю программу.
  • Emterpreter делает программу нестабильной. Например, взаимодействие JS и C не работает в некоторых ситуациях.
  • Emterpreter увеличивает размер собранного бинарника и время компиляции. Компиляция C-кода в Emterpreter-байт-код очень медленная, так как требует огромных трансформаций кода. Emterpreter-байт-код очень прост, поэтому его размер бинарника больше.

Я искал альтернативу и нашел Atomics.wait(). Atomics.wait() — это низкоуровневая синхронная примитивная функция. Она ожидает, пока определенный байт в буфере совместного доступа к памяти не будет обновлен. Это блокирующее ожидание. Конечно, оно недоступно на основном потоке. Его следует использовать на потоке рабочего процесса.

Я перенес базу Wasm-кода в Web Worker, выполняющийся на рабочем потоке, хотя рендеринг <canvas/> все еще выполняется в основном потоке.

Проверка последовательностей вводаVim использует Atomics.wait() для ожидания ввода пользователя, наблюдая за буфером совместного доступа к памяти. Когда происходит событие клавиши, основной поток сохраняет данные события клавиши в буфер совместного доступа к памяти и уведомляет о новом событии клавиши с помощью Atomics.notify(). Рабочий поток обнаруживает, что буфер был обновлен с помощью Atomics.wait(), и загружает данные события клавиши из буфера. Vim вычисляет последовательность клавиш из данных и добавляет её в буфер ввода. Наконец, Vim обрабатывает событие и отправляет события рисования в основной поток через JavaScript.В качестве бонуса взаимодействие пользователя больше не блокируется, так как почти вся логика, включая весь Vim, выполняется в рабочем потоке.

Разработка

Пожалуйста, убедитесь, что установлены Emscripten (я использую 1.38.37) и binaryen (я использую v84). Если вы используете macOS, они могут быть установлены с помощью brew install emscripten binaryen.

Пожалуйста, используйте скрипт build.sh для работы над этим проектом. Просто после клонирования этого репозитория запустите ./build.sh. Он собирает vim.wasm в директории wasm/. Это требует времени и мощности процессора. Наконец, разместите wasm/ напрямую на localhost с помощью веб-сервера, такого как python -m http.server 1234. Доступ к localhost:1234?debug запустит Vim с отладочными логами. Обратите внимание, что это намного медленнее, чем выпускная сборка, так как включены многие отладочные возможности. Пожалуйста, прочитайте wasm/README.md для получения дополнительной информации.

Пожалуйста, обратите внимание, что ветка wasm этого репозитория часто объединяет последнюю версию vim/vim master ветки. Если вы хотите работать над этим проектом, убедитесь, что вы создали свою собственную ветку и объединили ветку wasm в вашу ветку с помощью git merge.

Знаменитые проблемы- ~~WebAssembly и JavaScript не предоставляют sleep(). По умолчанию, emscripten

компилирует sleep() в бесконечный цикл. Поэтому vim.wasm использует Emterpreter который предоставляет emscripten_sleep(). Некоторые функции, разрешенные в белом списке, выполняются с использованием Emterpreter. Однако эта функция не так стабильна. Она увеличивает размер сборки и затягивает процесс компиляции.~~ Это было исправлено в #30

  • JavaScript к C не работает полностью с Emterpreter. Например, вызов некоторых C API нарушает стек Emterpreter. Это также означает, что вызов функций C из JavaScript, передавая параметр типа string, не работает. Это было исправлено в #30
  • Поддерживается только браузеры Chrome и Chromium. Firefox и Safari требуют включения флагов функций. Это связано с тем, что SharedArrayBuffer отключен из-за уязвимости Spectre. Это можно исправить с помощью Asyncify. Работа ведется и отслеживается в PR #35.## TODO

Разработка управляется в GitHub Projects.

  • Рассмотреть поддержку более широкого набора функций ('large' и 'huge')
  • Использовать поддержку многопоточности WebAssembly с Atomic instructions вместо JavaScript Atomics API
  • Отрисовка <canvas/> в рабочем потоке с использованием Offscreen Canvas В настоящее время недоступно. Пожалуйста, прочитайте заметки.
  • Поддержка мыши
  • Поддержка IME
  • Упаковка vim.wasm как Web Component

Особая благодарность

Этот проект был вдохновлен впечатляющим проектом vim.js от Lu Wang.

ЛицензияВсе дополнительные файлы в этом репозитории лицензированы под тем же лицензионным соглашением, что и Vim (VIM LICENSE). Пожалуйста, обратитесь к :help license для получения дополнительной информации. [Vim editor]: https://www.vim.org/

Логотип VimСтатус сборки Travis Статус сборки Appveyor Статус сборки Cirrus Статус охвата Сканирование Coverity Оценка языка: C/C++ CI Debian Пакеты Для переводов этого README смотрите конец файла.

Что такое Vim?

Vim — это значительно улучшенная версия хорошего старого UNIX-редактора Vi. В нём добавлено множество новых функций: многоуровневое отмену действий, синтаксическое выделение, историю командной строки, онлайн-справку, проверку орфографии, автозавершение имен файлов, операции с блоками, языки сценариев и т.д. Также доступен графический интерфейс пользователя (GUI). При этом сохранена совместимость с Vi, поэтому те, кто привык к Vi, будут чувствовать себя как дома. Различия между Vim и Vi можно найти в файле runtime/doc/vi_diff.txt.Этот редактор очень полезен для редактирования программ и других текстовых файлов. Все команды вводятся с помощью обычных символов клавиатуры, поэтому те, кто умеет печатать двумя руками, могут работать очень быстро. Кроме того, пользователь может назначить функциональным клавишам команды, а также использовать мышь.

Vim работает под MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh, VMS и почти всех версиях UNIX. Портация на другие системы не должна быть слишком сложной. Старые версии Vim работают под MS-DOS, MS-Windows 95/98/Me, Amiga DOS, Atari MiNT, BeOS, RISC OS и OS/2. Эти версии больше не поддерживаются.

Распространение

Часто вы можете использовать свой любимый менеджер пакетов для установки Vim. На Mac и Linux предустановлен небольшой вариант Vim, но если вам нужны дополнительные функции, вам всё равно потребуется установить Vim.

Существуют отдельные дистрибутивы для Unix, PC, Amiga и некоторых других систем. Этот файл README.md прилагается к архиву runtime. В него входят документация, файлы синтаксического анализа и другие файлы, используемые во время работы. Чтобы запустить Vim, вам нужно получить либо один из двоичных архивов, либо архив исходного кода. Какой именно вам нужен, зависит от системы, на которой вы хотите его запустить, и от того, хотите ли вы или должны сами скомпилировать его. Проверьте http://www.vim.org/download.php для обзора доступных дистрибутивов.Некоторые популярные места для получения последней версии Vim:

  • Вы можете получить репозиторий git с github.
  • Получите исходный код в виде архива.
  • Получите исполняемый файл для Windows из репозитория vim-win32-installer.

Компиляция

Если вы получили двоичный дистрибутив, вам не нужно компилировать Vim. Если вы получили дистрибутив исходного кода, все необходимые файлы для компиляции Vim находятся в директории src. Инструкции по компиляции можно найти в файле src/INSTALL.

Установка

Для получения системно-специфических инструкций обратитесь к одному из этих файлов. Или в директории READMEdir (в репозитории), или в корневой директории (если вы распаковали архив):

README_ami.txt		Amiga
README_unix.txt		Unix
README_dos.txt		MS-DOS и MS-Windows
README_mac.txt		Macintosh
README_vms.txt		VMS

Есть и другие файлы README_*.txt, в зависимости от используемой версии дистрибутива.

Документация

Уроки Vim для начинающих представляют собой учебный курс продолжительностью один час. Часто его можно запустить как vimtutor. Для получения дополнительной информации увидьте :help tutor.

Лучше всего использовать :help в Vim. Если у вас ещё нет исполняемого файла, прочитайте runtime/doc/help.txt. В этом файле содержатся ссылки на другие документы. Пользовательский справочник написан в виде книги и рекомендуется для изучения использования Vim. Увидьте :help user-manual.## Копирование ##

Vim — это программа с благотворительной лицензией. Вы можете использовать и копировать её столько, сколько вам угодно, но вы поощряетесь сделать пожертвование, чтобы помочь сиротам в Уганде. Пожалуйста, прочитайте файл runtime/doc/uganda.txt для получения подробностей (выполните :help uganda внутри Vim).

Краткое содержание лицензии: нет никаких ограничений на использование или распространение неизменённой копии Vim. Части Vim также могут быть распространены, но текст лицензии всегда должен быть включён. Для изменённых версий применяются некоторые ограничения. Лицензия совместима с GPL, вы можете скомпилировать Vim с библиотеками GPL и распространять его.

Спонсорство

Исправление ошибок и добавление новых функций требует много времени и усилий. Чтобы выразить свою благодарность за выполненную работу и мотивировать Брама и других продолжать работу над Vim, пожалуйста, отправьте пожертвование.

Так как Брам вернулся к оплачиваемой работе, деньги теперь будут использованы для помощи детям в Уганде. Увидьте runtime/doc/uganda.txt. Но при этом пожертвования увеличивают мотивацию Брама продолжать работу над Vim!

Для получения самой последней информации о спонсорстве посмотрите на веб-сайте Vim: http://www.vim.org/sponsor/

Вклад ##Если вы хотите помочь улучшить Vim, увидите файл CONTRIBUTING.md.

Информация

Последние новости о Vim можно найти на домашней странице Vim: http://www.vim.org/

Если у вас возникли проблемы, посмотрите документацию или советы: http://www.vim.org/docs.php http://vim.wikia.com/wiki/Vim_Tips_Wiki

Если у вас все еще возникают проблемы или у вас есть другие вопросы, используйте одну из рассылок, чтобы обсудить их с пользователями и разработчиками Vim: http://www.vim.org/maillist.php

Если ничего больше не помогает, сообщите об ошибках напрямую: Bram Moolenaar Bram@vim.org

Основной автор

Отправьте любые другие комментарии, патчи, цветы и предложения на: Bram Moolenaar Bram@vim.org

Это README.md для версии 8.2 Vim: Vi IMproved.

Переводы этого README

Корейский

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-vim-wasm.git
git@api.gitlife.ru:oschina-mirror/mirrors-vim-wasm.git
oschina-mirror
mirrors-vim-wasm
mirrors-vim-wasm
wasm