Vim.WASM: VIM portado para WebAssembly Este projeto é um fork experimental do VIM Editor da @RHYSD para compilá -lo em WebAssembly usando o Emscriptten e o Binaryen. O VIM é executado no Web Worker e interage com o thread principal via SharedArrayBuffer .
O objetivo deste projeto é executar o Editor VIM nos navegadores sem perder as poderosas funcionalidades do VIM compilando fontes de Vim C em WebAssembly.

USO
:write apenas grava o arquivo na memória. Faça o download do buffer atual por :export ou arquivo específico por :export {file} ."* é suportado. Por exemplo, colar o texto do sistema de transferência para vim com "*p ou :put * , e copie o texto em vim para o sistema de transferência do sistema com "*y ou: :set clipboard=unnamed :yank * .~/.vim são armazenados persistentemente no DB indexado. Escreva sua configuração favorita em ~/.vim/vimrc (não ~/.vimrc ).file={filepath}={url} busca um arquivo de {url} para {filepath} . Arquivos remotos arbitrários podem ser abertos (Care com CORS).:!/path/to/file.js avalia o código JavaScript no navegador. :!% Avalia o buffer atual.:e tutor .arg= Parâmetros de consulta (por exemplo ?arg=~%2f.vim%2fvimrc&arg=hello.txt ) para adicionar argumentos da linha de comando vim .PERCEBER
SharedArrayBuffer e Atomics . No Firefox ou Safari, os sinalizadores de recursos ( javascript.options.shared_memory for Firefox) devem ser ativados por enquanto.keydown . Desative as extensões do seu navegador que interceptam os principais eventos (o modo incógnito seria o melhor).:quit , mas não fecha uma guia do navegador. Por favor, feche manualmente :) Este projeto é empacotado como vim-wasm NPM PACAKGE para ser usado facilmente no aplicativo da web. Leia a documentação para mais detalhes.
A versão atual do VIM portada é 8.2.0055 com conjuntos de recursos 'Normal' e 'Small'. Por favor, verifique o Changelog para o histórico de atualização.
Os projetos a seguir estão relacionados a este pacote NPM e podem ser mais adequados para o seu caso de uso.

No segmento de trabalhador, o VIM está sendo compilado em WASM. O tópico do trabalhador é gerado como trabalhador da web dedicado do tópico principal ao abrir a página.
Digamos que você insira algo com o teclado. O navegador toma -o como KeyboardEvent no evento keydown . O JavaScript no encadeamento principal captura o evento e armazena informações de KeyDown para um buffer de memória compartilhado.
O buffer é compartilhado com o tópico do trabalhador. O VIM espera e obtém as informações do keydown, pesquisando o buffer de memória compartilhado através da API Atomics do JavaScript. Quando as informações importantes são encontradas no buffer, ele carrega as informações e calcula a sequência das principais. Via JS para WASM API graças ao EMSCRIPTEN, a sequência é adicionada ao buffer de entrada do VIM no WASM.
A sequência no buffer de entrada é processada pela lógica do editor do núcleo (buffer de atualização, tela, ...). Devido às atualizações, alguns eventos de desenho acontecem, como texto de desenho, retiradas de retões, regiões de rolagem, ...
Esses eventos de sorteio são enviados ao JavaScript em Thread Works da WASM, graças à API JS para C da EMSCRIPTEN. Considerando a relação pixel do dispositivo e a API <canvas/> , como renderizar os eventos é calculado e esses eventos de renderização calculados são passados do thread do trabalhador para o encadeamento principal por meio da passagem da mensagem com o postMessage() .
O tópico principal JavaScript recebe e envolve esses eventos de renderização. No quadro de animação, ele os renderiza para <canvas/> .
Finalmente, você pode ver a tela renderizada na página.

O front -end da WebAssembly para VIM é implementado como um novo front -end da GUI do VIM, como outros GUI, como o GTK Frontend. As fontes C são compiladas a cada arquivo de bitcode LLVM e, em seguida, estão vinculados a um arquivo bitcode vim.bc por emcc . emcc finalmente compilará o vim.bc em vim.wasm binário usando o binaryen e gera tempo de execução html/javascript.
A diferença que enfrentei inicialmente foi a falta de biblioteca de terminais, como o NCurses. Modifiquei o script configure para ignorar a verificação da biblioteca do terminal. Tudo bem, já que o front -end da GUI para WASM é sempre usado em vez do front -end da CUI. Eu precisava de muitas soluções alternativas para passar as verificações configure .
O EMSCRIPTEN fornece um ambiente semelhante ao UNIX. Portanto, os_unix.c podem suportar o WASM. No entanto, alguns recursos não são suportados pelo EMScript. Adicionei muitos #ifdef FEAT_GUI_WASM Guards para desativar os recursos que não podem ser suportados pelo suporte do WASM (ou seja, o suporte fork (2) , suporte PTY, manipuladores de sinal são extraídos, ... etc).
Criei gui_wasm.c referenciando fortemente gui_mac.c e gui_w32.c . LOOP EVENTO ( gui_mch_update() e gui_mch_wait_for_chars() ) é simplesmente implementado com o bloqueio de espera. E quase todos os eventos de renderização da interface do usuário são passados para a camada JavaScript, chamando funções JavaScript de C graças ao EMScriptten.
As fontes C são compiladas (com muitas otimizações) no LLVM Bitcode com Clang, que é integrado ao EMSCRIPTEN. Em seguida, todos os arquivos bitcode ( .o ) estão vinculados ao arquivo de bitcode vim.bc com o vinculador llvm-link (também integrado ao EMScriptten).
E criei o tempo de execução do JavaScript no TypeScript para desenhar os eventos de renderização enviados de C. JavaScript Runtime é separados em duas partes; Tópico principal e tópico do trabalhador. wasm/main.ts é para o thread principal. Ele inicia o VIM no thread de trabalhadores e desenha a tela VIM para <canvas> recebendo eventos de desenho do VIM. wasm/runtime.ts e wasm/pre.ts são para threads trabalhadores. Eles são escritos usando a API EMSCRIPTEN.
emcc (compilador C do EMSCRIPTEN) compila o vim.bc e runtime.js em vim.wasm , vim.js e vim.data com arquivos de tempo de execução VIM pré -carregados (ou seja, o colorcheme) usando o binaryen. Os arquivos de tempo de execução são carregados em um sistema de arquivos virtual fornecido em um navegador pela EMSCRIPTEN. Aqui, esses arquivos são compilados para o tópico do trabalhador. wasm/main.js inicia um trabalhador da web dedicado carregando vim.js
Finalmente, criei um pequeno wasm/index.html que contém <canvas/> para renderizar a tela VIM e carregar wasm/main.js .
Agora, hospedando wasm/index.html com um servidor da Web e acessando -o com ele com o navegador abre o VIM. Funciona.
sleep() em javascript A parte mais difícil para esta porta foi como implementar o bloqueio de espera (geralmente feito com sleep() ).
Como bloquear o thread principal na página da web significa bloquear a interação do usuário, ele é basicamente proibido. Quase todas as operações que levam tempo são implementadas como API assíncrona no JavaScript. O WASM em execução no encadeamento principal não pode bloquear o fio, exceto o loop ocupado.
Mas os programas C usam casualmente a função sleep() para que seja um problema ao portar os programas. O Frontend da GUI da Vim também deve esperar a entrada do usuário com a espera de bloqueio.
O EMSCRIPTEN fornece solução alternativa para esse problema, Emterpreter. Com o Emterpreter, o EMSCRIPTEN fornece funções de espera (pseudo) de bloqueio, como emscripten_sleep() . Quando eles são usados na função C, emcc compila a função no código de byte emerpreter em vez de wasm. E em tempo de execução, o código de bytes é executado em um intérprete (no WASM). Quando o intérprete atinge o ponto que chama emscripten_sleep() , ele suspende a execução do código de bytes e define o timer (com a função JS setTimeout ). Depois que o tempo expira, o intérprete retoma o estado e continua a execução.
Por esse mecanismo, a espera assíncrona de JavaScript parece que a espera síncrona do mundo. No começo, usei o Emterpreter e funcionou. No entanto, houve vários problemas.
Procurei uma alternativa e encontrei Atomics.wait() . Atomics.wait() é uma função primitiva síncrona de baixo nível. Ele espera até que um byte específico no buffer de memória compartilhado seja atualizado. Está bloqueando a espera . Claro que não está disponível no tópico principal. Ele deve ser usado em um tópico de trabalhador.
Mudei o código WASM Base para o Web Worker em execução no thread do trabalhador, embora a renderização <canvas/> ainda seja feita no thread principal.

O VIM usa Atomics.wait() para a entrada de usuário em espera assistindo a um buffer de memória compartilhado. Quando um evento -chave acontece, o principal thread armazena dados de eventos principais para o buffer de memória compartilhado e notifica que um novo evento -chave veio pelo Atomics.notify() . O tópico do trabalhador detecta que o buffer foi atualizado pelo Atomics.wait() e carrega os principais dados do evento do buffer. O VIM calcula uma sequência de chave dos dados e adicione -os ao buffer de entrada. Finalmente, o VIM lida com o evento e envia eventos de desenho para o tópico principal via JavaScript.
Como bônus, a interação do usuário não é mais evitada, pois quase toda a lógica, incluindo o VIM inteiro, é executado no thread do trabalhador.
Certifique -se de que o EMSCRIPTEN (estou usando 1.38.37) e Binaryen (estou usando o V84) estão instalados. Se você usar o MacOS, eles podem ser instalados com brew install emscripten binaryen .
Use o script build.sh para invadir este projeto. Logo após clonar este repositório, basta executar ./build.sh . Ele constrói vim.wasm no wasm/ diretório. Leva muito tempo e poder da CPU.
Finalmente, hospede o wasm/ diretamente no localhost com um servidor da Web, como python -m http.server 1234 . Acesso ao localhost:1234?debug Iniciará o VIM com logs de depuração. Observe que é muito mais lento do que a criação de liberação, pois muitos recursos de depuração estão ativados. Por favor, leia o WASM/README.MD para mais detalhes.
Observe que a filial wasm deste repositório freqüentemente mescla a última filial VIM/VIM Master. Se você deseja invadir este projeto, certifique -se de criar sua própria filial e mesclar a ramificação wasm em sua filial por git merge .
sleep() . Por padrão, o Emscriptten compila sleep() em um loop ocupado. Portanto, o vim.WASM está usando o Emterpreter que fornece emscripten_sleep() . Algumas funções em permissões são executadas com o Emterpreter. Mas esse recurso não é tão estável. Torna os binários construídos maiores e a compilação mais longa.string não funciona.SharedArrayBuffer está desativado devido à vulnerabilidade de segurança espectro. Isso pode ser corrigido com assíncrifos. O trabalho está em andamento e rastreado no PR #35. O desenvolvimento é gerenciado em projetos do GitHub.
<canvas/> no tópico de trabalhador usando tela fora da telaEste projeto foi fortemente inspirado pelo impressionante projeto Vim.JS por Lu Wang.
Todos os arquivos adicionais neste repositório são licenciados sob a mesma licença que o VIM (VIM License). Consulte :help license para obter mais detalhes.
Readme original está seguindo.

Para traduções deste Readme, consulte o fim.
O VIM é uma versão muito melhorada do bom e velho editor do UNIX VI. Muitos novos recursos foram adicionados: desfazer vários níveis, destaque da sintaxe, histórico de linhas de comando, ajuda on-line, verificação de ortografia, conclusão do nome do arquivo, operações de bloqueio, linguagem de script etc. Há também uma interface gráfica do usuário (GUI) disponível. Ainda assim, a compatibilidade do VI é mantida, aqueles que têm VI "nos dedos" se sentirão em casa. Consulte runtime/doc/vi_diff.txt para diferenças com VI.
Este editor é muito útil para editar programas e outros arquivos de texto sem formatação. Todos os comandos são fornecidos com caracteres normais do teclado, para que aqueles que podem digitar dez dedos podem funcionar muito rápido. Além disso, as teclas de função podem ser mapeadas para comandos pelo usuário, e o mouse pode ser usado.
O VIM corre sob o MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh, VMs e quase todos os sabores do Unix. Portar para outros sistemas não deve ser muito difícil. As versões mais antigas do VIM são executadas no MS-DOS, MS-Windows 95/98/ME, Amiga DOS, Atari Mint, Beos, Risc OS e OS/2. Estes não são mais mantidos.
Muitas vezes, você pode usar seu gerenciador de pacotes favorito para instalar o VIM. No Mac e Linux, uma pequena versão do VIM é pré-instalada, você ainda precisa instalar o VIM se desejar mais recursos.
Existem distribuições separadas para Unix, PC, Amiga e alguns outros sistemas. Este arquivo README.md vem com o arquivo de tempo de execução. Inclui a documentação, arquivos de sintaxe e outros arquivos usados em tempo de execução. Para executar o VIM, você deve obter um dos arquivos binários ou um arquivo de origem. Qual você precisa depende do sistema em que deseja executá -lo e se deseja ou deve compilá -lo sozinho. Verifique http://www.vim.org/download.php para obter uma visão geral das distribuições atualmente disponíveis.
Alguns lugares populares para obter o último vim:
Se você obteve uma distribuição binária, não precisa compilar o VIM. Se você obteve uma distribuição de origem, todo o material para compilar VIM está no diretório src . Consulte src/INSTALL para obter instruções.
Consulte um desses arquivos para obter instruções específicas do sistema. No diretório readmedir (no repositório) ou no diretório superior (se você desempacotar um arquivo):
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
Existem outros arquivos README_*.txt , dependendo da distribuição que você usou.
O Tutor do VIM é um curso de treinamento de uma hora para iniciantes. Muitas vezes, pode ser iniciado como vimtutor . Consulte :help tutor mais informações.
O melhor é usar :help no vim. Se você ainda não tiver um executável, leia runtime/doc/help.txt . Ele contém ponteiros para os outros arquivos de documentação. O Manual do Usuário parece um livro e é recomendado para aprender a usar o VIM. Veja :help user-manual .
Vim é Charityware. Você pode usá -lo e copiá -lo o quanto quiser, mas é incentivado a fazer uma doação para ajudar órfãos em Uganda. Leia o arquivo runtime/doc/uganda.txt para obter detalhes (faça :help uganda dentro do Vim).
Resumo da licença: não há restrições para usar ou distribuir uma cópia não modificada do VIM. Partes do VIM também podem ser distribuídas, mas o texto da licença deve sempre ser incluído. Para versões modificadas, algumas restrições se aplicam. A licença é compatível com GPL, você pode compilar o VIM com as bibliotecas GPL e distribuí -la.
Corrigir bugs e adicionar novos recursos leva muito tempo e esforço. Para mostrar seu apreço pelo trabalho e motivar Bram e outras pessoas a continuar trabalhando no VIM, envie uma doação.
Como Bram está de volta a um trabalho pago, o dinheiro agora será usado para ajudar as crianças em Uganda. Consulte runtime/doc/uganda.txt . Mas, ao mesmo tempo, as doações aumentam a motivação de Bram para continuar trabalhando no VIM!
Para obter as informações mais recentes sobre a aparência patrocinadora no site do VIM: http://www.vim.org/sponsor/
Se você deseja ajudar a melhorar o VIM, consulte o arquivo contribuindo.md.
As últimas notícias sobre Vim podem ser encontradas na página inicial do VIM: http://www.vim.org/
Se você tiver problemas, dê uma olhada na documentação ou dicas do VIM: http://www.vim.org/docs.php http://vim.wikia.com/wiki/vim_tips_wiki
Se você ainda tiver problemas ou outras perguntas, use uma das listas de discussão para discuti -las com usuários e desenvolvedores do VIM: http://www.vim.org/maillist.php
Se nada mais funcionar, relate os bugs diretamente: Bram moolenaar [email protected]
Envie quaisquer outros comentários, patches, flores e sugestões para: Bram moolenaar [email protected]
Este é README.md para a versão 8.2 do vim: vi melhorou.
coreano