Создайте простой редактор строк


19

In: строка без разрывов строки *
Разрешить пользователю редактировать и отправлять строку
Out: измененную строку (опционально с завершающим переводом строки)

Редактор строк должен как минимум позволить пользователю:

  1. переместить видимый курсор влево и вправо

  2. вставлять и / или перезаписывать символы в позиции курсора

  3. удалить символы в позиции курсора

  4. отправить новую строку, т.е. прекратить редактирование, заставить измененную строку вернуть / распечатать / отобразить / сохранить… (без другого текста)

Ценится, но не обязательно:

  • объяснение вашего кода.

  • ссылка на сайт онлайн-тестирования, который может продемонстрировать вашу программу / функцию

  • анимированное изображение, демонстрирующее использование (например, TIO не допускает интерактивность)

Замечания:

  • привязки клавиш только предложения

  • GUI или визуальный стиль не требуется

Примеры

Далее курсор обозначен с помощью _.

In: Just some text
разрешить пользователю редактировать:
 Just some text_  пользователь нажимает ←(левая клавиша со стрелкой) девять раз
 Just ̲some text  пользователь нажимает Delчетыре раза
 Just ̲ text  пользователь нажимает  пользователь нажимает Out:any
 Just any_text Enter
Just any text

In: Remove me
разрешить пользователю редактирование:
 Remove me_  пользователь нажимает Backspaceдевять раз.
 _  Пользователь нажимает Out: (пустая строка)Enter
 


* Чтобы избежать тривиальных решений редактора, это должно быть либо предоставлено с помощью другого метода ввода, чем команды редактирования, или должно быть отделено от них новой строкой или аналогичным.


Нужно ли использовать эти точные нажатия клавиш для ввода-вывода? Кроме того, мы можем создать файл для сохранения текста?
— R '24

1
Привязка клавиш @Riker - это только предложения . Методы ввода и вывода соответствуют настройкам PPCG по умолчанию .
— Адам

Может ли строка содержать символы новой строки? И можно ли использовать новую строку для «отправки»?
— Конор О'Брайен

@ ConorO'Brien Нет; Простой редактор строк . Да; Редактор должен как минимум разрешить пользователю: (...) 4. отправить новую строку
— Adám

1
Было бы неплохо, если бы вы указали строку в фактической части вопроса, так как заголовки на этом сайте не совсем
— Конор О'Брайен,

Ответы:


3

APL (Dyalog) , 5 байтов

⍞←⍞⋄⍞

Это tradfn, поэтому, чтобы использовать его, сделайте

∇a
⍞←⍞⋄⍞
∇

И затем вызвать его с помощью a, после чего вы вводите начальную строку, а затем вы можете редактировать строку.


8

JavaScript (ES6), 15 14 байт

Я не понимаю, почему так много голосов!

s=>prompt(s,s)

Сохраненный байт благодаря предложению Адама , чтобы я отобразил исходный ввод в prompt.


Попытайся

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


1
Сохранить байт, заменяя ""с 0или даже s(так что пользователь все еще может увидеть оригинальный текст , а редактирование - аккуратный функция).
— Адам

5

Bash 4.x, 25 символов

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

Образец прогона:

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

(Строка 2 выше - интерактивное редактирование, строка 3 - вывод полученного текста.)


1
У меня не работает -bash: read: -i: invalid option? manговорит только ersразрешенные флаги.
— R '24

Да, я собирался спросить об этом-ei
— Адам

-iбыл представлен в Bash 4.0 (выпущен в феврале 2009 г.) - «-i text Использовать TEXT в качестве исходного текста для Readline».
— manatwork

Мне интересно, сработает ли кошка?
— Мэтью Ро,

catпросто ожидает входящий поток, для которого оболочка не будет предоставлять никаких функций редактирования. По крайней мере, не по умолчанию.
— manatwork

3

Bash + Vi / Vim, 14 байтов

echo $1>a;vi a

vivimна MacOS есть псевдоним , я не знаю о других ОС.


Может быть, я что-то упустил, но соответствует ли это требованию вывода измененной строки?
— Грейсон Кент

1
@GraysonKent вы можете сохранить и выйти, нажав :wq!или :x, так что я так думаю. ОП немного неясно, что можно отнести к этому.
— Rɪᴋᴇʀ

3

HTML + JavaScript (ES6), 77 66 64 байта

HTML

<input id=t

JavaScript

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

Сэкономили 10 байт благодаря Йоргу Хюльсерманну и 2 байта благодаря Люку.

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

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


2
Вы можете удалить атрибут типа для входного элемента
— Йорг Хюльсерманн

Вы, вероятно, должны использовать oninputвместо этого.
— Мэтью Ро

@SIGSEGV Я не думаю, что oninputсрабатывает при Enterнажатии
— Том

1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)сохраняет два байта.
— Лука

3

Python 2 , 275 200 байт

Не победитель, но вот он:

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)

Объяснение:

Он работает путем реверсирования ввода (с помощью [::-1]), исключения и вставки символов в этот инвертированный ввод, чтобы курсор не перемещался. Снова переворачивает при печати.

Использование:

Клавиша [Tab] для перемещения вправо
[Ctrl + C] для перемещения влево
[Backspace] для стирания
[Return] для завершения редактирования
Любая другая клавиша, будет вставлена ​​в текст

Пример:

Используя пример OP

In: Just some text
 Just some text>
 Just some> text  пользователь нажимает Ctrl+Cпять раз
 Just > text  пользователь нажимает Backspaceчетыре раза
 Just any> text  пользователь нажимает  пользователь нажимает Out:any
 Just any> text Enter
Just any text

Версия встроенного редактора:

Если вы хотите, чтобы текст редактировался внутри строки, добавьте ,'\r',в конце printоператора:

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

6
+1 Очень мило. Первый ответ, который на самом деле реализует настоящий редактор, а не полагается на уже существующую функциональность. Я подумывал опубликовать еще одну задачу, чтобы сделать именно это.
— Адам

Вы не можете сохранить байты, используя другие клавиши для левой и правой?
— Адам

Я мог бы принимать символы как -и +для этого, но редактор не смог бы принять эти символы тогда
— Фелипе Нарди Батиста

Как насчет \tа \v?
— Адам

1
Это проблема пользователя, нет? Control + K, может быть?
— Адам

3

C + NCURSES, 573 байта

#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;}

Тестовое задание

  • Скомпилируйте и запустите с вводом Just some text.

введите описание изображения здесь

введите описание изображения здесь

  • Нажмите кнопку со стрелкой влево девять раз.

введите описание изображения здесь

  • Нажмите кнопку Удалить четыре раза.

введите описание изображения здесь

  • Нажмите aзатем, nзатем y.

введите описание изображения здесь

  • Нажмите, Enterчтобы прекратить.

введите описание изображения здесь

Детальнее

#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;
}

Вы не можете заменить KEY_*на соответствующие целые числа, чтобы сохранить несколько байтов?
— sergiol


2

C #, 53 байта

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

Где sстрока, которую нужно изменить, и вывод нового значения.

SendKeys.SendWait : отправляет данные ключи активному приложению, а затем ожидает обработки сообщений.

или 74 байта, если мы не в контексте Windows Forms:

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

GIF демо


2

Рубин, 9 19 22 84 байта

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

Это создает хук предварительного ввода Readline, который вставляет текст s, а затем снова отображается. После этого irb испортится, поэтому обязательно запустите его из файла. Запускается как лямбда, он принимает входную строку в качестве аргумента и возвращает выходную строку.

puts Readline.readline

Это использует библиотеку Readline для выполнения редактирования строки. Мой предыдущий ответ позволял только пробелы.

puts gets

Это действительно очень понятно.

Изменить: меня попросили объяснить. Это эквивалентно puts(gets). getsвводит строку с помощью редактора строк. putsвыводит это.


Цепочка вызовов метода: r.insert_text(s).redisplayи удалите следующее ;. Кстати, как я понимаю нашу политику, вы должны упомянуть, что ваш код работает irb, потому что в противном случае вам потребуется его использование Readline.
— manatwork

1

PHP + HTML, 26 байт

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

Браузер автоматически добавляет закрывающий тег

$ _GET Использование URL-адреса, подобного тому, http://example.com?0=inputкак Input создает в HTML<input value=input

И это выход для ввода строки

<input value=input


Должен ли я считать, что это работает? Может быть, вы можете добавить объяснение, или ссылку, или анимацию?
— Адам

@ Adám Да, вы можете предположить, что это может быть, вы улучшите его и установите атрибут, autofocusчтобы курсор находился в начале. Другие элементы HTML, которые вы также можете редактировать, если установите атрибутcontenteditable
— Jörg Hülsermann,

Вход =test></input><script>alert("Hi");//some malicious code\n</script>
— Роман Грэф

@ RomanGräf Bad Boy. Да, лучше отфильтровать Javascript
— Йорг Хюльсерманн

1

Tcl, 17

puts [gets stdin]

Онлайн-переводчики просто отстой, чтобы продемонстрировать это, а затем я демонстрирую некоторые изображения из командной оболочки Windows:

Тестовый пример 1

введите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесьвведите описание изображения здесь

Контрольный пример 2

введите описание изображения здесьвведите описание изображения здесь введите описание изображения здесь


Вы можете объяснить это?
— Адам

1
Я могу добавить образы, запущенные в командной строке Windows.
— sergiol

@ Adám: Вы все еще хотите, чтобы я объяснил, что делает код, или изображений достаточно?
— sergiol

Достаточно.
— Адам

1

AHK , 32 байта

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

InputBoxсохраняет все, что введено в качестве переменной, sи выдает начальную подсказку для переменной, 1которая является первым переданным параметром.
Sendотправляет нажатия клавиш в текущее окно. В этом случае это будет содержимое s.
MsgBoxбыл вариант, но для игры в гольф на Send2 байта короче.

Анимация


@ Adám Я неправильно понял эту часть. Я обновил ответ.
— Тост инженера

Теперь это хорошо.
— адам

1

Команда непосредственного окна Excel VBA - 22 байта

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

введите описание изображения здесь


2
Это только частичное решение, поскольку ваше начальное значение («Привет») жестко запрограммировано. Начальное значение должно быть прочитано откуда-то (ячейка, приглашение или файл ...), а конечное значение должно быть где-то помещено (ячейка, окно сообщения, файл, ...).
— Адам

inputbox(0,,"Hi")сохраняет байт
— Фелипе Нарди Батиста,

@ Adám Спасибо. Исправлено: теперь он читает из ячейки A1
— Рохан,

Я думаю, что вам нужно [a1]=inputbox(0,,[a1])или что-то, в противном случае, куда aидти? Хранение в переменной не является допустимым методом вывода .
— адам

Он идет туда, откуда пришел из камеры А1
— Рохан,

0

ZX Spectrum BASIC, 7 байтов

Тривиально, включено для полноты ( INPUTи PRINTкаждый токен по одному байту).

INPUT a$: PRINT a$

1
Как это получить начальное значение a$?
— Адам

@ Adám получает начальное значение a$с клавиатуры; a$будет INPUTперезаписано ключевым словом.
— Шон Бебберс

0

SmileBASIC, 138 байт

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

Создает функцию E с 1 аргументом и 0 выходами. (Вывод отображается в консоли)

Экранированные символы должны быть реальными символами, но они не будут отображаться здесь.

Управление:

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.

Вставка / удаление символов - это задом наперед, поэтому это очень раздражает в использовании (но все равно должно соответствовать требованиям).

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

Интерпретатор команд Windows, 16 байт

set/pa=
echo %a%

Это очень тривиально; интерпретатор команд - это тривиальный редактор строк.


0

Commodore BASIC (C64Mini, C64 / 128, VIC-20 и т. Д.) 179 токенов BASIC

Это должно быть набрано в бизнес-режиме (прописные / строчные буквы)

 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

Позволяет базовое редактирование текста + удаление + новая строка. Максимальный размер a$как и всех строк в Commodore BASIC составляет 255 символов, так что больше, чем это может привести к сбою программы. Я найду способ сделать> 255 символов, если это необходимо.

Простой симулятор

Простой симулятор типа в действии

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.