Crie um editor de linhas simples


19

In: uma string sem quebras de linha *
Permite ao usuário editar e enviar a linha
Out: a string modificada (opcionalmente com uma quebra de linha à direita)

O editor de linha deve, no mínimo, permitir ao usuário:

  1. mover um cursor visível para a esquerda e direita

  2. insira e / ou substitua caracteres na posição do cursor

  3. remover caracteres na posição do cursor

  4. envie a nova string, ou seja, interrompa a edição para que a string modificada seja retornada / impressa / exibida / salva ... (sem nenhum outro texto)

Apreciado, mas não obrigatório:

  • explicação do seu código.

  • link para um site de testes on-line que pode demonstrar seu programa / função

  • uma imagem animada demonstrando uso (o TIO, por exemplo, não permite interatividade)

Nota:

  • ligações de teclas são apenas sugestões

  • GUI ou estilo visual não é necessário

Exemplos

A seguir, o cursor é ilustrado com _.

In: Just some text
permite que o usuário edite: O
Just some text_  usuário pressiona (tecla de seta esquerda) nove vezes O
Just ̲some text  usuário pressiona Delquatro vezes O
Just ̲ text  usuário pressiona O  usuário pressiona Out:any
Just any_text Enter
Just any text

In: Remove me
permite que o usuário edite: O
Remove me_  usuário pressiona Backspacenove vezes O
_  usuário pressiona Out: (string vazia)Enter
 


* Para evitar soluções triviais de editor, isso deve ser fornecido por um método de entrada diferente dos comandos de edição ou deve ser separado deles por uma nova linha ou similar.


Temos que usar essas teclas pressionadas exatamente para E / S? Além disso, podemos criar um arquivo para salvar o texto?
Rɪᴋᴇʀ

11
As combinações de teclas do @Riker são apenas sugestões . Os métodos de entrada e saída seguem os padrões do PPCG .
Adám 24/04/19

A sequência pode conter novas linhas? E uma nova linha pode ser usada para "enviar"?
Conor O'Brien

@ ConorO'Brien Não; Editor de linha simples . Sim; O editor deve, no mínimo, permitir que o usuário: (...) 4. envie a nova string
Adám 24/04/19

11
Seria bom se você especificou linha no próprio corpo da pergunta, como títulos neste site não são exatamente as especificações ...
Conor O'Brien

Respostas:


3

APL (Dyalog) , 5 bytes

⍞←⍞⋄⍞

Este é um tradfn, então, para usá-lo, faça

a
⍞←⍞⋄⍞

E, em seguida, chame-o usando a, após o qual você fornecerá a sequência inicial e poderá editar a sequência.


8

JavaScript (ES6), 15 14 bytes

Não entendo por que isso está recebendo tantos votos positivos!

s=>prompt(s,s)

Salvei um byte graças à sugestão de Adám de exibir a entrada original no prompt.


Tente

f=
s=>prompt(s,s)
console.log(f("Edit this ..."))


11
Salve um byte substituindo ""por 0ou mesmo s(para que o usuário ainda possa ver o texto original durante a edição - um recurso interessante).
Adám 24/04/19

5

Bash 4.x, 25 caracteres

read -ei "$*" t
echo "$t"

Exemplo de execução:

bash-4.3$ bash interactive.sh hello world
hello golfing world
hello golfing world

(A linha 2 acima foi a edição interativa, a linha 3 a saída do texto resultante.)


11
Não funciona para mim -bash: read: -i: invalid option? mandiz apenas que erssão permitidos sinalizadores.
Rɪᴋᴇʀ

Sim, eu estava prestes a perguntar sobre-ei
Adám

-ifoi introduzido no Bash 4.0 (lançado em fevereiro de 2009) - “-i texto Use TEXT como o texto inicial do Readline”.
manatwork

Eu estou pensando, o gato funcionaria?
Matthew Roh

cataguarda apenas o fluxo de entrada, para o qual o shell não fornecerá funcionalidade de edição. Pelo menos não por padrão.
manatwork

3

Bash + Vi / Vim, 14 bytes

echo $1>a;vi a

vié alias vimno macOS, não conheço outros sistemas operacionais.


Talvez esteja faltando alguma coisa, mas isso atende ao requisito de saída da string modificada?
Grayson Kent

11
@GraysonKent, você pode salvar e sair pressionando :wq!ou :x, então acho que sim. OP é um pouco claro sobre o que se qualifica como isso.
Rɪᴋᴇʀ

3

HTML + JavaScript (ES6), 77 66 64 bytes

HTML

<input id=t

Javascript

onkeyup=e=>e.which-13||alert(t.value);f=a=>t.value=a;

Economizou 10 bytes graças a Jörg Hülsermann e 2 bytes graças a Luke.

onkeyup=e=>e.which-13||alert(t.value);f=a=>t.value=a;

f("Remove Me");
<input id=t>


2
você pode remover o attribut tipo para a entrada Elemento
Jörg Hülsermann

Você provavelmente deveria usar oninput.
Matthew Roh

@SIGSEGV Eu não acho que oninputé acionado quando Enteré pressionado
Tom

11
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)salva dois bytes.
Luke

3

Python 2 , 275 200 bytes

Não é um vencedor, mas aqui está:

from msvcrt import*
s=list(input())[::-1]
c=i=0
def p(a):print''.join(a)[::-1]
while'\r'!=c:p(s[:i]+['<']+s[i:]);c=getch();x=c!='\b';exec["s[i:i+1-x]=c*x","i=(i-1+2*(c<'\\t'))%-~len(s)"][x*' '>c]
p(s)

Explicação:

Ele funciona revertendo a entrada (com [::-1]) e excluindo e inserindo caracteres nessa entrada revertida para que o cursor não precise se mover. Reverte novamente ao imprimir.

Uso:

Tecla [Tab] para mover para a direita
[Ctrl + C] para mover para a esquerda
[Backspace] para apagar
[Return] para concluir a edição.
Qualquer outra tecla será inserida no texto

Exemplo:

Usando o exemplo do OP

In: O Just some text
Just some text>
Just some> text  usuário pressiona Ctrl+Ccinco vezes O
Just > text  usuário pressiona Backspacequatro vezes O
Just any> text  usuário pressiona O  usuário pressiona Out:any
Just any> text Enter
Just any text

Versão do editor embutido:

Se você deseja que o texto seja editado em linha, acrescente ,'\r',no final da printdeclaração:

def p(a):print''.join(a)[::-1],'\r',

6
+1 Muito bom. Primeira resposta que realmente implementa um editor real, em vez de depender de funcionalidades pré-existentes. Eu estava pensando em postar outro desafio para fazer exatamente isso.
Adám 25/04

Você não pode salvar bytes usando outras teclas para esquerda e direita?
Adám 25/04/19

Eu poderia assumir como personagens -e +a fazê-lo, mas o editor não seria capaz de aceitar esses personagens, em seguida
Felipe Nardi Batista

Que tal \te \v?
Adám 25/04/19

11
Esse é o problema do usuário, não? Control + K, talvez?
Adám

3

C + NCURSES, 573 bytes

#include <curses.h>
i;j;k;s;c;p;int main(a,b)char**b;{char*q;char t[999];if(a&&(q=b[1]))while(*q)t[s++]=*q++;i=s;initscr();noecho();keypad(stdscr,1);do{for(j=0;j<i;j++)addch(t[j]);addch('|');for(j=i;t[j];j++)addch(t[j]);c=getch();switch(c){case KEY_LEFT:if(i)i--;break;case KEY_RIGHT:if(i<s)i++;break;case 8:case 127:case KEY_BACKSPACE:if(i){for(k=i-1;k<s;k++)t[k]=t[k+1];i--;s--;}break;case KEY_DC:if(i<s){for(k=i;k<s;k++)t[k]=t[k+1];s--;}break;default:if(c>31&c<127){for(k=s;k>i;k--)t[k]=t[k-1];t[i]=c;i++;s++;}}clear();}while(c!=10);printw(t);getch();endwin();return 0;}

Teste

  • Compilar e executar com entrada Just some text.

insira a descrição da imagem aqui

insira a descrição da imagem aqui

  • Pressione o botão Seta para a esquerda nove vezes.

insira a descrição da imagem aqui

  • Pressione o botão Excluir quatro vezes.

insira a descrição da imagem aqui

  • Pressione aentão nentão y.

insira a descrição da imagem aqui

  • Pressione Enterpara finalizar.

insira a descrição da imagem aqui

Detalhado

#include <curses.h>

int main(int argc, char ** argv)
{
    char*q = 0;
    char t[999] = {0};
    int j = 0, k = 0;
    int i = 0; // cursor before first char
    int s = 0; // current size
    int c = 0; // current input
    int p = 0;

    // copy first command-line argument
    if(argc>0 && (q=argv[1]))while(*q)t[s++]=*q++; i=s;

    initscr(); // initiate NCURSES
    noecho(); // input does not echo on entry
    keypad(stdscr,TRUE); // handle all input

    do
    {
        // print current content with cursor
        for(j=0;j<i;j++) addch(t[j]);
        addch('|'); for(j=i;t[j];j++) addch(t[j]);

//      printw("\n\n> key %d pressed",c); // debug

        c = getch(); // read next char

        switch(c)
        {
            case KEY_LEFT: // left arrow; cursor left
            if(i > 0) i--;
            break;

            case KEY_RIGHT: // right arrow; cursor right
            if(i < s) i++;
            break;

            case 8: // backspace; remove previous char
            case 127:
            case KEY_BACKSPACE:
            if(i > 0)
            {
                for(k=i-1; k<s; k++) t[k]=t[k+1];
                i--;s--;
            }
            break;

            case KEY_DC: // delete; remove next char
            if(i < s)
            {
                for(k=i; k<s; k++) t[k]=t[k+1];
                s--;
            }
            break;

            default: // none of the above

            if(c > 31 && c < 127) // printable char
            {
                for(k=s; k>i; k--) t[k]=t[k-1];
                t[i] = c;i++;s++;
            }
        }

        clear(); // clear screen
        if(c == 10) break;
    }
    while(c);

    addch('\n');
    printw(t); // print final result
    getch(); // wait for any input
    endwin();
    return 0;
}

Você não pode substituir KEY_*pelos respectivos números inteiros para salvar alguns bytes?
sergiol


2

C #, 53 bytes

s=>{SendKeys.SendWait(s);return Console.ReadLine();};

Onde sestá uma string para modificar e a saída é o novo valor.

SendKeys.SendWait : envia as chaves fornecidas para o aplicativo ativo e aguarda o processamento das mensagens.

ou 74 bytes se não estivermos em um contexto do Windows Forms:

s=>{System.Windows.Forms.SendKeys.SendWait(s);return Console.ReadLine();};

demonstração gif


2

Ruby, 9 19 22 84 bytes

->s{r=Readline;r.pre_input_hook=->{r.insert_text s;r.redisplay};r.readline}

Isso cria um gancho de pré-entrada Readline que insere o texto e, em seguida, é exibido novamente. Depois disso, o irb fica bagunçado, portanto, execute-o em um arquivo. Executar como um lambda, pega a sequência de entrada como argumento e retorna a sequência de saída.

puts Readline.readline

Isso usa a biblioteca Readline para executar a edição de linha. Minha resposta anterior permitia apenas backspaces.

puts gets

Isso é realmente, realmente auto-explicativo.

Edit: me pediram uma explicação. Isso é equivalente a puts(gets). getsinsere uma string com um editor de linha. putsgera isso.


Encadear as chamadas de método: r.insert_text(s).redisplaye remova o seguinte ;. BTW, como eu entendo nossa política, você deve mencionar que seu código é executado irb, porque, caso contrário, você precisaria fazê Readline-lo.
manatwork

1

PHP + HTML, 26 bytes

<input value=<?=$_GET[0]?>

O navegador adiciona automaticamente a tag de fechamento

$ _GET Usando um URL como http://example.com?0=inputEntrada Cria em um HTML<input value=input

E esta é a saída para a entrada de string

<input value=input


Devo assumir que isso funciona? Talvez você possa adicionar uma explicação, link ou animação?
Adám

@ Adám Sim, você pode assumir isso Talvez você melhore e defina o atributo autofocuspara ter o cursor no início. Outros elementos HTML você também pode editar se você definir o atributocontenteditable
Jörg Hülsermann

Entrada =test></input><script>alert("Hi");//some malicious code\n</script>
Roman Gräf

@ RomanGräf Bad Boy. Sim, é melhor filtrar Javascript
Jörg Hülsermann

1

Tcl, 17

puts [gets stdin]

Intérpretes on-line são péssimos para demonstrá-lo, então mostro algumas imagens de um shell de comando do Windows:

Caso de teste 1

insira a descrição da imagem aquiinsira a descrição da imagem aquiinsira a descrição da imagem aquiinsira a descrição da imagem aquiinsira a descrição da imagem aqui

Caso de teste 2

insira a descrição da imagem aquiinsira a descrição da imagem aqui insira a descrição da imagem aqui


Você pode explicar este?
Adám 24/04/19

11
Eu posso adicionar imagens dele em execução em uma linha de comando do Windows.
Sergiol # 24/17

@ Adám: Você ainda quer que eu explique o que o código está fazendo ou as imagens são suficientes?
Sergiol # 25/17

Isto é suficiente.
Adám

1

AHK , 32 bytes

InputBox,s,,,,,,,,,,%1%
Send,%s%

InputBoxarmazena o que for digitado como a variável se fornece um prompt inicial da variável, 1que é o primeiro parâmetro passado.
Sendenvia pressionamentos de tecla para a janela atual. Nesse caso, será o conteúdo de s.
MsgBoxera uma opção, mas, para o golfe, Sendé 2 bytes mais curto.

Animação


@ Adám eu interpretei mal essa parte. Eu atualizei a resposta.
Engineer Toast

Agora está bom.
Adám 25/04/19

1

Comando da janela imediata do VBA do Excel - 22 bytes

[a1]=inputbox(0,,[a1])

insira a descrição da imagem aqui


2
Esta é apenas uma solução parcial, pois seu valor inicial ("Oi") é codificado. O valor inicial deve ser lido de algum lugar (uma célula ou prompt ou arquivo ...) e o valor final deve ser colocado em algum lugar (uma célula, uma caixa de mensagens, um arquivo, ...).
Adám 26/04/19

inputbox(0,,"Hi")salva um byte
Felipe Nardi Batista

@ Adám Obrigado. Corrigido agora está lendo a célula A1
Rohan

Eu acho que você precisa [a1]=inputbox(0,,[a1])ou algo assim, para onde avai? Armazenar em uma variável não é um método de saída válido .
Adám

Ele é de onde veio a célula A1
Rohan

0

ZX Spectrum BASIC, 7 bytes

Trivial, incluído para ser completo ( INPUTe PRINTpossui tokens de um byte cada).

INPUT a$: PRINT a$

11
Como ele obtém o valor inicial de a$?
Adám 25/04/19

@ Adám obtém o valor inicial de a$pela entrada do teclado; a$será sobrescrito com a INPUTpalavra - chave.
Shaun Bebbers

0

SmileBASIC, 138 bytes

DEF E S@L
WAIT
B=BUTTON(1)C=C-(B==4&&C)+(B>7&&C<LEN(S))I$=INKEY$()IF"\u0008"<I$THEN B=I$<"\u000E"S=SUBST$(S,C,B,I$*!B)?S?" "*C;1IF"\u0008"!=I$GOTO@L
END

Cria uma função Ecom 1 argumento e 0 saídas. (A saída é exibida no console)

Os caracteres de escape devem ser os símbolos reais, mas não apareceriam aqui.

Controles:

Normal keys: Insert a character before the cursor.
Enter: Delete the character at the cursor.
Backspace: Submit.
D-pad left: Move cursor left.
All buttons except up, down, and left on the d-pad: Move cursor right.

A inserção / exclusão de caracteres é invertida, portanto, é muito chato de usar (mas ainda deve atender aos requisitos).

Just some text
1             
'(press right 5 times)
Just some text
     1
'(press enter 4 times)
Just  text
     1
'(press a)
Just a text
     1
'(press right)
Just a text
      1
'(...)
Just any text
       1
'(press backspace)

0

Intérprete de comando do Windows, 16 bytes

set/pa=
echo %a%

Isso é muito trivial; o intérprete de comando é trivialmente um "editor de linha".


0

Commodore BASIC (C64Mini, C64 / 128, VIC-20 etc ...) 179 bytes BASIC tokenizados

Isso deve ser digitado no modo comercial (caracteres maiúsculos / minúsculos)

 0a$="Just some text":?"{SHIFT+CLR/HOME}"a$"_":fOi=0to1step0:getk$:on-(k$<>"")goS2:goS1:nE
 1?"{CTRL+N}{CLR/HOME}"a$"_  ";:return
 2ifasc(k$)<>20thena$=a$+k$:on-(asc(k$)=13)goS4:return
 3if-(len(a$))thena$=leF(a$,len(a$)-1):goS4:return
 4?"{ARROW LEFT}{ARROW LEFT}{ARROW LEFT}  ":return

Permite edição básica de texto + excluir + nova linha. O tamanho máximo de a$todas as seqüências de caracteres no Commodore BASIC é de 255 caracteres; portanto, mais do que isso, travará o programa. Vou encontrar uma maneira de fazer> 255 caracteres, se necessário.

Simulador simples de digitação

Simulador simples de digitação em ação

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.