Como escrever na vertical?

22

Digamos que eu queira produzir o seguinte texto no meu documento:

%
%            Not Important
%    O ------------------------->
%    |
%  S |
%  o |
%  m |
%  e |
%    |
%  M |
%  s |
%  g |
%    |
%    V

Existe alguma maneira fácil de escrever verticalmente "Some Msg" como acima, sem precisar inserir manualmente cada caractere em cada linha?

Allan Hasegawa
fonte
5
Você poderia escrever seu texto normalmente, e depois :s/./% \0\r/adicionar as %novas linhas ... Mas não é uma ótima solução ...
Martin Tournoij
Solução agradável, meio que funciona. Vai usá-lo por enquanto, obrigado.
Allan Hasegawa

Respostas:

16

Uma solução realmente boa provavelmente exigiria mais trabalho, mas "não é ruim" não é muito difícil de alcançar.

Idéia

Tudo o que precisamos é mover uma linha para baixo após cada caractere, então vamos fazer isso via InsertCharPrecomando automático!

Código

Coloque-o .vimrcou, melhor ainda, em algum arquivo no plugin/diretório

" enters insert mode to write vertically
function! VertStart()
    augroup Vert
        autocmd!
        " handles each entered character and moves cursor down
        autocmd InsertCharPre * call feedkeys("\<left>\<down>", 'n')
        autocmd InsertLeave * call VertEnd()
    augroup END

    inoremap <BS> <Up><Del>
    startinsert
endfunction

" cleans up on leaving insert mode
function! VertEnd()
    iunmap <BS>
    augroup Vert
        autocmd!
    augroup END
endfunction

" command to start writing vertically
command! Vert call VertStart()

Uso

Digite o :Vertcomando para começar a escrever verticalmente. Sair do modo de inserção desativa automaticamente esse "modo". Obviamente, você pode mapeá-lo para um atalho se precisar usar esse comando com frequência.

Problemas conhecidos

  1. A gravação vertical não será desativada se você sair do modo de inserção via Ctrl-C(isso é resultado de Ctrl-Cser implementado de uma maneira um pouco estranha em relação ao InsertLeaveevento, que não é acionado; portanto, usar a chave exige que você tenha cuidado).
xaizek
fonte
1
Uma refutação ao Problema conhecido nº 1: você não deve sair do modo Inserir <C-C>.
tommcdo
@ Tommcdo, eu não, mas se estiver lá, alguém usa. Na verdade, é útil evitar a expansão da abreviação, estou me perguntando por que InsertLeavenão é acionado para essa chave.
xaizek
1
Suponho que pretendo promover uma tendência de rejeição <C-C>como uma boa maneira de sair do modo Inserir. A maneira como você mencionou isso pode significar que às vezes é um bom método. É como dizer "Advertência: seu documento não será salvo se você fechar o Microsoft Word desconectando o computador".
tommcdo
@ tommcdo Não achou que poderia soar assim. Foi adicionada uma observação sobre <C-C>o motivo do problema. Não conheço outro método para deixar o modo de inserção suprimindo a expansão da abreviação, como <C-C>acontece, se não houver, é útil pelo menos como parte de um mapeamento inoremap <silent> <c-c> <c-c>:doautocmd InsertLeave<cr>.
precisa saber é
Eu não tinha considerado abreviações, esse é um bom ponto. Até encontrei alguns lugares na ajuda que descrevem <C-C>como sair do modo Inserir sem expandir abreviações, e não há menção de como ele não aciona InsertLeaveeventos. Agora estou curioso para saber se existe uma maneira integrada de fazer isso, mas por enquanto seu mapeamento é uma ótima idéia.
tommcdo
4

Você pode digitar como de costume e depois converter o texto horizontal atual em vertical usando a substituição no Vim da seguinte forma (aplica-se à linha atual):

:s/\(.\)/\1\r/g

O método mais fácil de lembrar é executar um dos seguintes comandos (para todas as linhas):

:%!fold -w1
:%!grep -o .

Para aplicar apenas para a linha atual ou mais linhas, anteceda com V, expanda a área para mais linhas, se necessário, e execute acima (mas sem %).

Para o PowerShell no Windows, verifique a substituição para fold .

Para definir o mapeamento de teclas simples (por exemplo F2), tente o seguinte:

:nnoremap <F2> V:!fold -w1<CR>

Em seguida, digite algo e pressione F2para tornar o texto vertical, simples assim.


Outra alternativa é definir a quebra automática de linha, por exemplo

:set tw=1 " textwidth
:set formatoptions+=t

Isso envolverá automaticamente o texto o mais próximo de 1 caractere, conforme o espaço em branco permitir. A desvantagem é que cada letra precisa ser seguida por espaço (então é quase o mesmo que você pressionariaEnter

kenorb
fonte
1
Em vez disso :s/\(.\)/\1\r/g, você pode simplesmente usar o :s/./\0\r/gque é funcionalmente idêntico.
Curinga
1

Acho que as macros são uma maneira incrível de fazer coisas incomuns se você estiver interessado em fazer isso mais de uma vez na lua azul. Digamos que você tenha a seguinte tabela:

%
%            Not Important
%    O ------------------------->
%    | Stuff in side the table
%  S |
%  o | So you can't just write your
%  m |
%  e | text and transform it into
%    |
%  M | the shape that you want
%  s |
%  g | Macros help here
%    |
%    V

E digamos que você deseja substituir Some Msgcom Other Message. Primeiro, vamos estender a tabela para o caractere extra (linha antes do último yy5p:

%
%            Not Important
%    O ------------------------->
%    | Stuff in side the table
%  S |
%  o | So you can't just write your
%  m |
%  e | text and transform it into
%    |
%  M | the shape that you want
%  s |
%  g | Macros help here
%    |
%    |
%    |
%    |
%    |
%    |
%    V

A macro que eu vou criar cuidará da conversão do texto de horizontal para vertical enquanto substitui o texto antigo. Comece digitando o texto no primeiro local (o cursor está no final de Other Message):

%
%            Not Important
%    O ------------------------->
%    | Stuff in side the table
%  SOther Message |
%  o | So you can't just write your
%  m |
%  e | text and transform it into
%    |
%  M | the shape that you want
%  s |
%  g | Macros help here
%    |
%    |
%    |
%    |
%    |
%    |
%    V

Registre a seguinte macro:

  • qq: inicia a gravação da macro denominada q
  • ^: ir para o início da linha
  • 3l: mova para a coluna onde o texto será colocado
  • x: excluir o caractere antigo
  • l: mova para a direita, deixando um caractere da mensagem no lugar do caractere antigo:
  • v: vá para o modo visual
  • f|: pule para |
  • 2h: retroceder dois caracteres
  • d: seleção de corte
  • j: descer
  • P: colar antes do cursor
  • q: encerra a gravação da macro

Neste ponto, você tem:

%
%            Not Important
%    O ------------------------->
%    | Stuff in side the table
%  O |
%  other Message | So you can't just write your
%  m |
%  e | text and transform it into
%    |
%  M | the shape that you want
%  s |
%  g | Macros help here
%    |
%    |
%    |
%    |
%    |
%    |
%    V

Repita a macro o número suficiente de vezes (ou seja, o número de caracteres, mas você não precisa conhecê-la com antecedência. Apenas subestime e continue depois de ver o quão perto sua estimativa estava). Então vamos com 10@q. Você obtém:

%
%            Not Important
%    O ------------------------->
%    | Stuff in side the table
%  O |
%  t | So you can't just write your
%  h |
%  e | text and transform it into
%  r |
%    | the shape that you want
%  M |
%  e | Macros help here
%  s |
%  s |
%  a |
%   ge |
%    |
%    |
%    V

Ok, mais um ( @q):

%
%            Not Important
%    O ------------------------->
%    | Stuff in side the table
%  O |
%  t | So you can't just write your
%  h |
%  e | text and transform it into
%  r |
%    | the shape that you want
%  M |
%  e | Macros help here
%  s |
%  s |
%  a |
%  g |
%   e |
%    |
%    V

Seu cursor está agora no último e. A macro não funciona bem com a última letra (você pode tentar @qe udesfazer) para obter resultados insatisfatórios. Simplesmente ajuste você mesmo ( Xpara backspace).

Shahbaz
fonte
Muito agradável. Macros são o caminho a seguir no vim. Minha rápida tentativa foi essencialmente a mesma que a sua; qq03lxldt|i ^[jPxq@q
Wildcard
@Wildcard, posso haz upvote?
Shahbaz #
1
Ha! Fugiu da minha mente; Eu pensei que tinha. :)
Curinga