创建一个简单的行编辑器


19

输入:不带换行符的字符串*
允许用户编辑和提交换行符
修改后的字符串(可选带尾随的换行符)

行编辑器至少必须允许用户:

  1. 左右移动可见光标

  2. 在光标位置插入和/或覆盖字符

  3. 删除光标位置的字符

  4. 提交新的字符串,即停止编辑会使修改后的字符串返回/打印/显示/保存(没有其他文本)

赞赏,但不是必需的:

  • 您的代码的解释。

  • 链接到可以演示您的程序/功能的在线测试站点

  • 演示用法的动画图像(例如,TIO不允许交互)

注意:

  • 键绑定仅是建议

  • 不需要GUI或视觉样式

例子

在下面,用表示光标_

进入: Just some text
允许用户编辑:
Just some text_  用户按下九次(向左箭头键)
Just ̲some text  用户按下Del四次
Just ̲ text  用户按下 用户按下Out:any
Just any_text Enter
Just any text

入: Remove me
允许用户编辑:
Remove me_  用户按Backspace九次
_  用户按出:(空字符串)Enter
 


*为了避免琐碎的编辑器解决方案,必须通过与编辑命令不同的输入法来提供此解决方案,或者必须使用换行符或类似的命令将它们与它们分开。


我们是否必须将这些确切的按键用于I / O?另外,我们可以创建一个文件来保存文本吗?
Rɪᴋᴇʀ

1
@Riker 键绑定仅是建议。输入和输出方法遵循PPCG的默认设置
亚当

字符串可以包含换行符吗?换行符可以用来“提交”吗?
Conor O'Brien

@ ConorO'Brien否;简单的编辑器。是; 编辑必须至少允许用户:(......)4.提交新的字符串
亚当

1
如果您在问题的实际正文中指定了,将是很好的,因为此站点上的标题并不完全是规范...
Conor O'Brien

Answers:



8

JavaScript(ES6),15个 14字节

我不明白为什么这么多的赞!

s=>prompt(s,s)

由于Adám建议我将原始输入显示在中,因此节省了一个字节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

(上面的第二行是交互式编辑,第三行是结果文本的输出。)


1
对我来说不行-bash: read: -i: invalid option吗?man说只ers允许标志。
Rɪᴋᴇʀ

是啊,我正要询问-ei
亚当

-i是在Bash 4.0(2009年2月发布)中引入的–“ -i text使用TEXT作为Readline的初始文本”。
manatwork '17

我想知道猫会工作吗?
马修·卢

cat只是等待传入的流,shell将不提供任何编辑功能。至少不是默认情况下。
manatwork '17

3

Bash + Vi / Vim,14个字节

echo $1>a;vi a

vivimmacOS 上的别名,我不了解其他操作系统。


也许我遗漏了一些东西,但这是否满足输出修改后的字符串的要求?
格雷森·肯特

1
@GraysonKent您可以通过单击:wq!或保存并退出:x,所以我认为是。OP在什么条件上尚不清楚。
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;

感谢JörgHülsermann,节省了10个字节;感谢Luke,节省了2个字节。

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

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


2
您可以删除input元素的类型attribut
约尔格Hülsermann

您可能应该使用oninput代替。
马修·罗

@SIGSEGV我认为按下oninput时不会触发Enter
汤姆(Tom)

1
e.which==13?alert(t.value):0-> e.which-13||alert(t.value)保存两个字节。
路加福音

3

Python 2275个 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的例子

进入: Just some text
Just some text>
Just some> text  用户按Ctrl+C五次
Just > text  用户按Backspace四次
Just any> text  用户按 用户按出: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

enter image description here

enter image description here

  • 按九次向左箭头按钮。

enter image description here

  • 按下删除按钮四次。

enter image description here

  • 按下a然后ny

enter image description here

  • Enter终止。

enter image description here

详细

#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 demo


2

Ruby,9 19 22 84字节

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

这将创建一个Readline预输入钩子,该钩子将插入文本s,然后重新显示。在此之后,irb陷入混乱,因此请确保从文件中运行它。作为lambda运行,它将输入字符串作为参数并返回输出字符串。

puts Readline.readline

这将使用Readline库执行行编辑。我以前的回答只允许使用退格键。

puts gets

这是真的,真的是自我解释。

编辑:我被要求提供解释。等同于puts(gets)gets用行编辑器输入一个字符串。puts输出它。


链接方法调用:r.insert_text(s).redisplay并删除以下内容;。顺便说一句,据我了解我们的政策,您应该提到您的代码在中运行irb,因为否则您将需要Readline在代码中进行要求。
manatwork '17

1

PHP + HTML,26字节

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

浏览器会自动添加结束标记

$ _GET使用类似http://example.com?0=input输入的URL 在HTML中创建<input value=input

这是字符串输入的输出

<input value=input


我应该认为这可行吗?也许您可以添加说明,链接或动画?
亚当

@Adám是的,您可以假设可能会有所改善,并设置属性autofocus以使其光标位于开始位置。如果设置了属性,您还可以编辑其他HTML元素contenteditable
约尔格Hülsermann

输入=test></input><script>alert("Hi");//some malicious code\n</script>
RomanGräf17年

@RomanGräf坏男孩。是的,它是更好的过滤器的Javascript
约尔格Hülsermann

1

Tcl,17

puts [gets stdin]

在线解释器只是想演示一下,然后我展示了Windows命令外壳中的一些图像:

测试用例1

enter image description hereenter image description hereenter image description hereenter image description hereenter image description here

测试案例2

enter image description hereenter image description here enter image description here


你能解释一下吗?
亚当

1
我可以添加在Windows命令行上运行的图像。
sergiol

@Adám:您是否仍要我解释代码的作用或图像是否足够?
sergiol

这就够了。
亚当

1

AHK,32字节

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

InputBox存储键入的任何内容作为变量,s并给出该变量的启动提示,1这是第一个传递的参数。
Send将击键发送到当前窗口。在这种情况下,它将是的内容s
MsgBox是一个选项,但是对于高尔夫来说,Send短2个字节。

Animation


@Adám我误读了那部分。我已经更新了答案。
Engineer Toast

现在很好。
亚当

1

Excel VBA立即窗口命令-22字节

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

enter image description here


2
这只是部分解决方案,因为您的初始值(“ Hi”)是硬编码的。初始值必须从某个位置(单元格,提示或文件...)读取,最终值必须置于某个位置(单元格,消息框,文件等)。
亚当

inputbox(0,,"Hi")保存一个字节
Felipe Nardi Batista

@Adám谢谢。现在已修复,它正在从单元格A1中读取
Rohan

我认为您需要[a1]=inputbox(0,,[a1])什么,否则,哪里a去了?存储在变量中不是有效的输出方法
亚当

它从单元格A1到达的地方
Rohan

0

ZX Spectrum BASIC,7个字节

平凡的,为了完整性INPUT而包含(PRINT每个都是一个字节的令牌)。

INPUT a$: PRINT a$

1
它如何获得的初始值a$
亚当

@Adám a$通过键盘输入获取的初始值;a$将被INPUT关键字覆盖。
Shaun Bebbers

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个字符。

Simple type-em-up simulator

Simple type-em-up simulator in action

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.