如何在linux下通过管道输入到sublimetext?

d6kp6zgx  于 2023-01-16  发布在  Linux
关注(0)|答案(8)|浏览(126)

如何从stdin接收文本到sublimetext编辑器中?使用vim,它是这样工作的:

echo "potato potato potato" | vim -

gedit也是如此,用这些内容创建一个新文档。
Sublimetext似乎刚开始在一个新的标签页中编辑一个名为“-”的文件,有没有其他的shell技巧可以工作?

kknvjkwl

kknvjkwl1#

假设Sublime仍然不支持打开STDIN,一个直接的解决方案是将输出转储到一个临时文件,在Sublime中打开该文件,然后删除该文件。假设您在bin目录中创建了一个名为tosubl的脚本,如下所示:

#!/bin/bash

TMPDIR=${TMPDIR:-/tmp}  # default to /tmp if TMPDIR isn't set
F=$(mktemp $TMPDIR/tosubl-XXXXXXXX)
cat >| $F  # use >| instead of > if you set noclobber in bash
subl $F
sleep .3  # give subl a little time to open the file
rm -f $F  # file will be deleted as soon as subl closes it

然后你可以这样使用它:

$ ps | tosubl

但是如果你的shell支持Process Substitution(很可能支持),一个更有效和可靠的解决方案是使用Process Substitution,这样就不用临时文件了。

tosubl() {
    subl <(cat)
}

echo "foo" | tosubl
  • 我非常肯定您可以在该函数中删除cat的使用,因为它将冗余的位从stdin铲到stdout,但在该上下文中这样做的语法目前还不清楚。*
p5fdfcr1

p5fdfcr12#

我不知道Sublime Text,但你的问题应该是通用的,因为它适用于任何接受文件名作为参数,但拒绝从stdin读取的程序。
幸运的是,Bash允许您通过管道将stdout从一个进程传输到某种临时文件中,然后将该文件的名称传递给另一个进程。
man bash开始:
支持命名管道的系统支持进程替换(FIFO)或命名打开文件的/dev/fd方法。它采用〈(列表)或〉(list)。进程列表的输入或输出连接到FIFO或/dev/fd中的某个文件。该文件的名称作为扩展的结果作为参数传递给当前命令。如果〉如果使用〈(list)形式,则应读取作为参数传递的文件以获得list的输出。
假设 SomeProcess 生成您希望在编辑器中捕获的输出:

sublimetext <(SomeProcess)

或:

SomeProcess | sublimetext <(cat)

如果您认为自己将经常手工输入该代码,那么您可能希望将sublimetext <(cat)放入shell脚本或别名中。
万一你的操作系统不支持进程替换,你可以自己指定一个临时文件:

SomeProcess > /tmp/myoutput
sublimetext /tmp/myoutput
9rbhqvlz

9rbhqvlz3#

您可能会发现vipe from moreutils非常有用。如果您已经设置了EDITOR='subl --wait',您可以简单地:

echo 'potato potato potato' | vipe
nx7onnlm

nx7onnlm4#

从版本4开始,SublimeText支持从标准输入管道输入。
From the changelog
构建版本4063
命令行:subl -现在可用于从所有平台上的stdin读取

    • 仅在MacOS上更新!**:自构建版本4109起

现在可以使用subl编辑标准输入,例如:回波试验|苏伯尔|猫

ycggw6v2

ycggw6v25#

稍微借用一下https://stackoverflow.com/a/31035834/2429912,因为对我来说,它完成了90%,但不是全部:
使用临时文件是一种几乎可以在任何编辑器中使用的方法。如果编辑器支持等待文件关闭(sublime -w表示Sublime Text),则更好的是,您可以实时编辑它,这使它更加通用。为此,您需要更改提供的script @tylerl-在您的PATH中名为tosubl的script:

#!/bin/bash

TMPDIR=${TMPDIR:-/tmp} # default to /tmp if TMPDIR isn't set
F=$(mktemp $TMPDIR/tosubl-XXXXXXXX)
cat >| $F # use >| instead of > if you set noclobber in bash
subl -w $F # waits until the file is closed
cat $F # prints out the contents of the file to stdout
rm -f $F # clean up the file

现在运行echo "hello" | tosubl > local.file将打开Sublime中第一个脚本的输出,一旦关闭它,将其保存到local.file

6bc51xsx

6bc51xsx6#

如果你想显示带有ANSI转义序列的彩色文本(例如终端缓冲区),你可以安装包ANSIescape并使用下面的命令:
F=$(mktemp); cat > $F; subl $F; subl --command ansi; sleep .5; rm -f $F

nwwlzxa7

nwwlzxa77#

现在是2020年,sublime仍然不能(不会?)从stdin中读取数据,由于我让sublime传递输入的程序,这个线程中的答案对我来说都不令人满意。
在我的例子中,我想利用kitty terminal emulator的"将当前选择粘贴到程序"功能。当你按下键盘快捷键时,该功能会将终端中的当前选择输入到程序中。出于某种原因,* kitty * 的开发人员决定将选择作为一个 * 参数 * 而不是通过stdin传递。
为了解决这个问题,我写了一个小的C脚本来处理这两种情况。为了运行这个脚本,你需要安装TCC。你可能需要先检查一下你的repo。我知道在debian上你可以用apt来安装它:sudo apt install tcc。或者,您可以使用GCC编译以下代码,只需删除第一行。

#!/usr/bin/tcc -run

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    uint64_t randVal = 0;
    FILE *fp = fopen("/dev/urandom", "rb");
    fread((char *) &randVal, 8, 1, fp);
    fclose(fp);
    
    char tmpfile[512] = {0};
    sprintf(tmpfile, "/tmp/piped_input_%llu.txt", randVal);
    
    fp = fopen(tmpfile, "wb");
    
    if(!fp)
    {
        fprintf(stderr, "Could not open temporary file: '%s'\n", tmpfile);
        return -1;
    }
    
    if(argc == 2)
        fprintf(fp, "%s", argv[1]);
        
    if(argc == 1)
    {
        uint8_t tmpBuf[4096] = {0};
        memset(tmpBuf, 0, 4096); // Old habit... ¯\_(ツ)_/¯
        
        while(!feof(stdin))
        {
            int32_t numRead = fread((char *) tmpBuf, 1, 4096, stdin);
            
            if(numRead > 0)
                fwrite((char *) tmpBuf, numRead, 1, fp);
            else
                break;
        }
    }
    
    fflush(fp);
    fclose(fp);
    
    char cmdStr[512] = {0};
    sprintf(cmdStr, "subl %s", tmpfile);
    system(cmdStr);
    
    // Give sublime some time to open the file
    usleep(1000 * 250);
    unlink(tmpfile);
    
    return 0;
}

上述脚本将从stdin读取,除非向程序传递参数。在任何情况下,它都只是将输入(stdinargv[1])读入一个临时文件,用sublime打开文件,等待约250ms让sublime有时间打开文件,然后删除临时文件。
您可以将上述代码复制到路径中的某个位置(例如/usr/local/bin/subl_pipe)。chmod 755 /usr/local/bin/subl_pipe.
不管怎样,我希望这最终对其他人有用......^_^

相关问题