vim.wasm: vim ported to webassembly Этот проект представляет собой экспериментальную вилку редактора VIM от @Rhysd, чтобы собрать его в Webassembly с использованием Emscripten и Binaryen. Vim работает на веб -работнике и взаимодействует с основной веткой через SharedArrayBuffer .
Цель этого проекта - управлять редактором VIM в браузерах, не теряя мощных функциональных возможностей VIM, собирая источники VIM C в Webassembly.

Использование
:write только файл в памяти. Загрузите текущий буфер с помощью :export или конкретный файл по :export {file} .:set clipboard=unnamed буфера :yank * "*y "* "*p :put *~/.vim постоянно хранятся в индексированном DB. Пожалуйста, напишите свою любимую конфигурацию в ~/.vim/vimrc (не ~/.vimrc ).file={filepath}={url} получает файл из {url} до {filepath} . Можно открыть произвольные удаленные файлы (забота о CORS).:!/path/to/file.js оценивает код JavaScript в браузере. :!% Оценивает текущий буфер.:e tutor .vim параметры arg= Query (например ?arg=~%2f.vim%2fvimrc&arg=hello.txtУВЕДОМЛЕНИЕ
SharedArrayBuffer и Atomics . На Firefox или Safari флаги функции ( javascript.options.shared_memory для Firefox) должны быть включены на данный момент.keydown Event. Пожалуйста, отключите расширения вашего браузера, которые перехватывают ключевые события (режим инкогнито будет лучшим).:quit , но он не закрывает вкладку браузера. Пожалуйста, закройте его вручную :) Этот проект упакован как vim-wasm NPM Pacakge, который будет легко использовать в веб-приложении. Пожалуйста, прочтите документацию для более подробной информации.
Текущая версия портированной VIM составляет 8.2.0055 с «нормальными» и «небольшими» наборами функций. Пожалуйста, проверьте ChangeLog для истории обновления.
Следующие проекты связаны с этим пакетом NPM и могут быть более подходящими для вашего варианта использования.

В рабочей ветке Vim работает с составлением в WASM. Рабочий поток порожден как выделенный веб -работник из основного потока при открытии страницы.
Допустим, вы вводите что -то с клавиатурой. Браузер воспринимает его как KeyboardEvent на мероприятии keydown . JavaScript в основном потоке завораживает событие и хранит информацию о ключах в общем буфере памяти.
Буфер разделен с рабочей веткой. Вим ждет и получает информацию о Keydown, опросывая общий буфер памяти через API JavaScript Atomics . Когда ключевая информация находится в буфере, она загружает информацию и вычисляет последовательность ключей. Через JS в WASM API благодаря Emscripten, последовательность добавляется в входной буфер VIM в WASM.
Последовательность в входном буфере обрабатывается с помощью логики редактора Core (буфер обновления, экран, ...). Из -за обновлений случаются некоторые события рисования, такие как текст рисования, рисовать прямые, области прокрутки, ...
Эти события рисования отправляются в JavaScript в рабочей ветке от WASM благодаря JS Emscripten JS до C API. Учитывая соотношение пикселей устройства и <canvas/> api, как разыгрываться событиями, и эти расчетные события рендеринга передаются из потока работника в основной потоковой потоки через передачу сообщения с postMessage() .
Основная нить JavaScript получает и включает в себя эти события рендеринга. На анимационной рамке это делает их в <canvas/> .
Наконец, вы можете увидеть визуализированный экран на странице.

Webassembly Frontend для VIM реализован как новый графический интерфейс VIM, как и другой графический интерфейс, такой как GTK Frontend. Источники C скомпилируются в каждом файлах бит -кодов LLVM, а затем они связаны с одним файлом биткода vim.bc от emcc . emcc , наконец, составит vim.bc в BINARDAN vim.wasm с использованием Binaryen и генерирует время выполнения HTML/JavaScript.
Разница, с которой я столкнулся сначала, была отсутствие терминальной библиотеки, такой как NCURSES. Я изменил скрипт configure , чтобы игнорировать проверку библиотеки терминалов. Это нормально, так как GUI Frontend для WASM всегда используется вместо фронта CUI. Мне нужно было много обходных путей, чтобы пройти проверки configure .
Emscripten обеспечивает Unix-подобную среду. Таким образом, os_unix.c может поддержать WASM. Тем не менее, некоторые функции не поддерживаются Emscripten. Я добавил много #ifdef FEAT_GUI_WASM Guards, чтобы отключить функции, которые не могут быть поддержаны поддержкой WASM (IE fork (2) , поддержка PTY, обработчики сигналов загрязнены и т. Д.).
Я создал gui_wasm.c с большой ссылкой на gui_mac.c и gui_w32.c . Цикл события ( gui_mch_update() и gui_mch_wait_for_chars() ) просто реализуется с помощью блокировки ожидания. И почти все события рендеринга пользовательского интерфейса передаются на слой JavaScript, вызывая функции JavaScript из C благодаря Emscripten.
Источники C собираются (со многими оптимизациями) в биткод LLVM с кланг, который интегрирован в 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 предназначены для рабочей потока. Они написаны с использованием Emscripten API.
emcc (компилятор Emscripten C, компилятор vim.bc и runtime.js в vim.wasm , vim.js и vim.data с предварительно загруженными файлами выполнения VIM (IE colorscheme) с использованием Binaryen. Файлы времени выполнения загружаются в виртуальную файловую систему, предоставленную в браузере Emscripten. Здесь эти файлы скомпилированы для рабочего потока. wasm/main.js начинает выделенный веб -работник, загружающий vim.js
Наконец, я создал небольшой wasm/index.html , который содержит <canvas/> для рендеринга экрана VIM и загрузки wasm/main.js .
Теперь хостинг wasm/index.html с веб -сервером и доступ к нему с браузером открывает Vim. Оно работает.
sleep() на JavaScript Самым сложным для этого портирования было то, как реализовать блокирующее ожидание (обычно делается со sleep() ).
Поскольку блокировка основного потока на веб -странице означает блокирование взаимодействия пользователя, оно в основном запрещено. Почти все операции, занимающие время, реализуются как асинхронные API в JavaScript. WASM, работающий на главном потоке, не может заблокировать резьбу, за исключением цикла засыпания.
Но программы C случайно используют функцию sleep() так что это проблема при переносе программ. Ожидается также, что пользовательский ввод GUI также будет ждать блокировки.
Emscripten обеспечивает обходной путь для этой проблемы, эмчир. С помощью эммертора Emscripten обеспечивает (псевдо) блокирующие функции ожидания, такие как emscripten_sleep() . Когда они используются в функции C, emcc собирает функцию в код байта эмчита вместо WASM. И во время выполнения код байта запускается на переводчике (на WASM). Когда интерпретатор достигает точки вызова emscripten_sleep() , он приостанавливает выполнение байтового кода и устанавливает таймер (с функцией setTimeout JS). После истечения времени интерпретатор возобновляет состояние и продолжает исполнение.
По этому механизму асинхронное ожидание JavaScript выглядит так, как будто синхронное ожидание из мира C. Сначала я использовал эммерного, и это сработало. Однако было несколько проблем.
Я искал альтернативу и нашел Atomics.wait() . Atomics.wait() -низкоуровневая синхронная примитивная функция. Он ждет, пока не будет обновлен конкретный байт в буфере общего памяти. Это блокирует ожидание . Конечно, это не доступно в основной ветке. Он должен использоваться в рабочем потоке.
Я перенесла базу кода WASM в веб -работник, работающий в потоке работников, хотя рендеринг <canvas/> все еще выполняется в основной ветке.

Vim использует Atomics.wait() для ожидания ввода пользователя, просмотрев общий буфер памяти. Когда происходит ключевое событие, основной поток хранит данные о событиях ключа в буфере общей памяти и уведомляет, что новое ключевое событие появилось Atomics.notify() . Рабочий поток обнаруживает, что буфер был обновлен Atomics.wait() и загружает данные о событии ключа из буфера. VIM вычисляет последовательность ключей из данных и добавляет ее в входной буфер. Наконец, Vim обрабатывает событие и отправляет события Draw в основную ветку через JavaScript.
В качестве бонуса, взаимодействие с пользователем больше не предотвращается, поскольку почти вся логика, включая целую VIM, запускается в рабочем потоке.
Пожалуйста, убедитесь, что Emscripten (я использую 1.38.37) и Binaryen (я использую V84). Если вы используете MacOS, их можно установить с помощью brew install emscripten binaryen .
Пожалуйста, используйте сценарий build.sh , чтобы взломать этот проект. Сразу после клонирования этого репозитория просто запустите ./build.sh . Он строит Vim.Wasm в wasm/ Directory. Требуется время, и процессора много питает.
Наконец -то размещайте wasm/ непосредственно на localhost с веб -сервером, таким как python -m http.server 1234 . Доступ к localhost:1234?debug начнет Vim с журналами отладки. Обратите внимание, что он намного медленнее, чем сборка выпуска, поскольку многие функции отладки включены. Пожалуйста, прочитайте wasm/readme.md для более подробной информации.
Обратите внимание, что ветвь этого репозитория wasm часто объединяет новейшую главную ветвь VIM/Vim. Если вы хотите взломать этот проект, пожалуйста, убедитесь, что создать свой собственный филиал и объединить филиал wasm в вашем филиале с помощью git merge .
sleep() . По умолчанию Emscripten компилизируется sleep() в оживленную петлю. Таким образом, vim.wasm использует эммерный, который обеспечивает emscripten_sleep() . Некоторые функции белых списков выполняются с эммерным. Но эта функция не такая стабильная. Это делает встроенные двоичные файлы больше и компиляция дольше.string не работает.SharedArrayBuffer отключен из -за уязвимости безопасности. Это может быть исправлено с асинсификацией. Работа продолжается и отслеживается в PR #35. Развитие управляется в проектах GitHub.
<canvas/> in a Worker Thread с использованием вне экрана CanvasЭтот проект был сильно вдохновлен впечатляющим проектом Vim.js Лу Ван.
Все дополнительные файлы в этом репозитории лицензированы по той же лицензии, что и VIM (лицензия VIM). Пожалуйста, смотрите :help license для получения более подробной информации.
Оригинал Readme следующим.

Для переводов этого Readme см. Конец.
Vim - значительно улучшенная версия старого старого редактора UNIX VI. Было добавлено много новых функций: многоуровневая отмену, выделение синтаксиса, история командной строки, онлайн-помощь, проверка заклинаний, завершение имени файла, блочные операции, язык сценариев и т. Д. Существует также графический пользовательский интерфейс (GUI). Тем не менее, совместимость VI поддерживается, те, у кого есть VI «в пальцах», будут чувствовать себя как дома. См. runtime/doc/vi_diff.txt для различий с VI.
Этот редактор очень полезен для редактирования программ и других простых текстовых файлов. Все команды даны с обычными клавиатурными символами, поэтому те, кто может печатать с десятью пальцами, могут работать очень быстро. Кроме того, функциональные клавиши могут быть сопоставлены с командами пользователем, а мышь можно использовать.
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, ПК, Amiga и некоторых других систем. Этот файл README.md поставляется с архивом времени выполнения. Он включает в себя документацию, синтаксисные файлы и другие файлы, которые используются во время выполнения. Чтобы запустить VIM, вы должны получить один из бинарных архивов или исходного архива. Какой из них вам нужен зависит от системы, на которой вы хотите запустить, и хотите ли вы или должны скомпилировать ее самостоятельно. Проверьте http://www.vim.org/download.php для обзора доступных в настоящее время распределения.
Некоторые популярные места, чтобы получить последнюю Vim:
Если вы получили бинарное распределение, вам не нужно компилировать Vim. Если вы получили распределение источника, все вещи для составления VIM находится в каталоге src . Смотрите src/INSTALL для инструкций.
Смотрите один из этих файлов для системных инструкций. Либо в каталоге ReadMedIR (в репозитории), либо в верхнем каталоге (если вы распаковываете архив):
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
Есть другие файлы README_*.txt , в зависимости от используемого вами распределения.
The Vim Tutor - это часовой тренировочный курс для начинающих. Часто это может начинаться как vimtutor . См :help tutor для получения дополнительной информации.
Лучше всего использовать :help в Vim. Если у вас еще нет исполняемого файла, прочитайте runtime/doc/help.txt . Он содержит указатели на другие файлы документации. Руководство пользователя читается как книга, и рекомендуется научиться использовать VIM. Смотрите :help user-manual .
Vim - благотворительная программа. Вы можете использовать и скопировать его столько, сколько захотите, но вам рекомендуется сделать пожертвование, чтобы помочь сиротам в Уганде. Пожалуйста, прочитайте runtime/doc/uganda.txt для получения подробной информации (DO :help uganda внутри VIM).
Сводка лицензии: нет никаких ограничений на использование или распространение немодифицированной копии VIM. Части VIM также могут быть распределены, но текст лицензии всегда должен быть включен. Для измененных версий применяется несколько ограничений. Лицензия совместима с GPL, вы можете собрать VIM с библиотеками GPL и распределить ее.
Исправление ошибок и добавление новых функций занимает много времени и усилий. Чтобы выразить свою признательность за работу и мотивировать Брэма и других продолжать работать над VIM, пожалуйста, отправьте пожертвование.
Поскольку Брэм вернулся на оплачиваемую работу, теперь деньги теперь будут использованы, чтобы помочь детям в Уганде. Смотрите runtime/doc/uganda.txt . Но в то же время пожертвования увеличивают мотивацию Брэма, чтобы продолжать работать над VIM!
Для получения самой последней информации о спонсорском веб -сайте Vim: http://www.vim.org/sponsor/
Если вы хотите помочь сделать VIM лучше, см. Файл appling.md.
Последние новости о VIM можно найти на домашней странице VIM: http://www.vim.org/
Если у вас есть проблемы, посмотрите на документацию VIM или советы: http://www.vim.org/docs.php http://vim.wikia.com/wiki/vim_tips_wiki
Если у вас все еще есть проблемы или какие -либо другие вопросы, используйте один из списков рассылки, чтобы обсудить их с пользователями и разработчиками VIM: http://www.vim.org/maillist.php
Если больше ничего не работает, сообщите об ошибках напрямую: Bram Moolenaar [email protected]
Отправьте любые другие комментарии, патчи, цветы и предложения: Bram Moolenaar [email protected]
Это README.md для версии 8.2 Vim: Vi улучшен.
корейский