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.

Adão
fonte
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.

Kritixi Lithos
fonte
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 ..."))

Shaggy
fonte
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.)

homem a trabalhar
fonte
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.

Rɪᴋᴇʀ
fonte
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>

Tom
fonte
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',
Felipe Nardi Batista
fonte
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;
}
Khaled.K
fonte
Você não pode substituir KEY_*pelos respectivos números inteiros para salvar alguns bytes?
sergiol
2

VBScript, 23 40 bytes

MsgBox InputBox("",,Wscript.Arguments(0))

insira a descrição da imagem aqui

Johan du Toit
fonte
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

aloisdg diz Restabelecer Monica
fonte
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.

dkudriavtsev
fonte
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

Jörg Hülsermann
fonte
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

sergiol
fonte
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

Engenheiro Toast
fonte
@ 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

Rohan
fonte
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$
Radovan Garabík
fonte
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)
12Me21
fonte
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".

UMA
fonte
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

Shaun Bebbers
fonte