作者cuello (cuello)
看板Editor
标题[vim ] 把游标位置上的「字」写出去给外部程式?
时间Thu Jul 22 19:25:52 2021
Hi,
我在 .vimrc 里这麽做
map <C-j> :.,/^[ \t]*$/ w !<外部程式><CR><CR>
就是定义 [Ctrl]-[J] 把 buffer 游标所在那一行开始往後
把整段(直到碰到空行),写出去给外部的程式,
这个程式则由 stdin 读入,接手处里这几行。
但是,我有进一步的需求,就是以上的方式是以行为单位,
问题是,可不可能只写出去游标所在的「那一个字」
「那一个字」可以是 "W/B" 或是 "w/b" 的「大字」或「小字」
我想过,例如,再编辑模式: B"ayW
可以把那个我要的「字」存到 named register a 去
但是,我不晓得要怎样才能在 .vimrc 把 "a 像上面那样
写出去给一个外部程式
请问这可以办到吗?
感谢指点迷津!
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 59.115.193.195 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Editor/M.1626953154.A.AC5.html
※ 编辑: cuello (59.115.193.195 台湾), 07/22/2021 19:26:37
1F:推 as23041248: 你要的是 <cword>?07/22 22:34
2F:推 ssd860505da: 用* register? 可是某些情况会出bug,快被烦死了07/23 01:08
3F:→ ssd860505da: 我後来用这两个plugins07/23 01:08
4F:→ ssd860505da: tmux-plugins/vim-tmux-focus-events07/23 01:08
5F:→ ssd860505da: roxma/vim-tmux-clipboard07/23 01:08
6F:→ ssd860505da: 目前没出什麽问题07/23 01:08
7F:推 as23041248: exe "normal! viw" | exe "'<,'>write !{cmd}"07/23 04:14
8F:推 bootleq: map 里可以用 <C-R>=expand('<cword>') 插字进去07/23 08:40
9F:推 as23041248: 楼上 要写到外部程式好像无法这样使用07/23 13:12
感谢!你们说得我心痒痒的,感觉充满希望
但是,试了再试, 发现我的 :echo has('clipboard') 是 0
而且我的 :reg 只有 " 0 1 ... a b ... - % /
抱歉! 是我的错! 没有说明我这边的环境: 我在 Debian Linux 上,
是阳春的 vim 跟 X11 (没 desktop)
我循着大家给的线索, 觉得就是卡在
1. <cword> 写不出去
2. register 就是写不出去... :( :(
※ 编辑: cuello (59.115.193.195 台湾), 07/23/2021 16:22:42
喔对了,为了方便检查 vim 到底写出来什麽东西,
还写了个短短的 script xless(1) 来充当 <外部程式>
所以都用
:甚麽东西 w !xless hd
dump 出16进位码来 debug...
--------xless -----------
#!/bin/sh
RECEPTOR="cat"
if [ "$1" ] ; then
[ -f "$1" ] || { RECEPTOR="$1" && shift ; }
fi
#$RECEPTOR $1 | (
# ^^^^^ 这样档案不能有空白
$RECEPTOR ${1+"$1"} | (
exec 6<&0
xterm -e sh -c 'exec 0<&6 less -r'
)
exit $?
-------------------------
※ 编辑: cuello (59.115.193.195 台湾), 07/23/2021 16:36:00
※ 编辑: cuello (59.115.193.195 台湾), 07/23/2021 16:36:51
我刚刚改了一行上面那个 xless 程式.
对不起,我先前没看懂,as23041248 最後一行用手打真的写得出去
:exe "normal! viw" | exe "'<,'>write !xless hd"
但出去的是一整行, 它往前越过了 "inner-word", 跑到前一个「字」去
而且好像是进了 visual mode,还是怎样?(我几乎没用过 visual mode)
而且那一行写不进 .vimrc, 老是在 "E?? mark not set"
不晓得那些符号该 escape...
我想上网把 exe 搞清楚,结果... 资料好难找...
刚刚还误会这搞不好是 windows-specific... 真不好意思...
※ 编辑: cuello (59.115.193.195 台湾), 07/23/2021 19:44:22
※ 编辑: cuello (59.115.193.195 台湾), 07/23/2021 19:45:33
10F:推 as23041248: 写进vimrc? 你想弄成key mapping07/23 21:57
11F:→ as23041248: 越过inner word是什麽意思07/23 21:58
是的, 就像一开始提起的那样,或是用<leader>
两种情形似乎都有一些东西需要 escape...
我的意思是,它把整行都写出去了,然後落入 visual mode
我游标在第2个字,它往前超出第2字范围
连同第一个字,说 inner-word 是我看了之後赶紧上网恶补
看到他们把 yiw 叫做 yank inner word :)
因为以前不懂得 yiw 的奥妙跟好处,真是感谢!
12F:推 siuoly: 你另外写一个脚本测试也太辛苦了07/23 22:13
13F:→ siuoly: 好奇是什麽情况要用stdin?我目前只用到cmd argument的情形07/23 22:19
14F:→ siuoly: 测试<cword> 可用 :!echo <cword> 查看结果07/23 22:20
※ 编辑: cuello (59.115.193.195 台湾), 07/24/2021 00:24:13
刚刚初步测试 :!echo <cWORD> | xless 真的可以耶!
所以,用外面的 echo 它会 expand! (这算是「外面的」吗?)
我稍後,或明天再继续把它弄清楚
事情是这样的, 我平常私下很紧凑地在用纯文字档作流水帐
每行的开头自动插入一个 epoch time, 例如现在是 1627058355
然後,不管做了什麽事,就丢进去就是了,事後想追查就 grep
那麽里边不免会夹杂一些影音档案,或 http, 或本地档案
後来就有上我在一开头描述的做法. 一直不满意的地方就是
每个影音档必须占用单独的一行, 而不能跟文字混在一起.
所以, 这是个迟早要去解决的事...
例如, 我放了
aaa.jpg
bbb.jpg
ccc.jpg
只要我游标在 bbb.jpg 那一行, [Ctrl]-[J] 就会叫出我的 image viewer,
例如, 从 stdin, 经由 xargs 同塞给它 bbb.jpg 跟 ccc.jpg
然後我可以在 bbb.jpg 跟 ccc.jpg 快速来回跳动比较. 还算顺利.
但是,有一天,不管怎麽弄,我那个 image viewer 都只给我错误讯息!
快气疯! 本来事情够多了,突然又多了件事要解决,情急之下.... 当然没解决
为甚麽?因为没有好用的,用得顺手的工具!
所以,待改天心平气和了之後,就坐下来,把 xless 先弄对
让它可以接受 $1 而且也可以接受 stdin, 而且还可以插入个 hd(1).
然後,就看到了, 我所编辑的那个纯文字档里,含有古早时代留下来的
0d 0a (i.e. CR LF i.e. \r \n) 所以,工具还是很重要啊~ (叹气~)
但是,後来我并没有去移除那些 0x0d,而是在<外部程式>的前端过滤 0d.
※ 编辑: cuello (59.115.193.195 台湾), 07/24/2021 01:04:15
15F:推 siuoly: vim内建echo用法 :echo expand("<cWORD>") 07/24 10:18
16F:→ siuoly: 外部shell命令就会自己展开,我以前也踩过这坑= ="... 07/24 10:19
17F:→ siuoly: 可能你已经知道了 提醒下 map 命令里 | 符号要改成<bar> 07/24 10:21
我~并~不~知~道! 还好你大声讲了出来!不然我又要在那边.... you know.... :)
18F:→ siuoly: 否则vim 把 | 看成是map之後接续 新的命令 07/24 10:23
19F:→ siuoly: 我也常常弄小东西花很多时间,我常怀疑这样时间真的有赚吗 07/24 10:32
20F:→ siuoly: 弄出来是很爽没错,但可以我都尽量找现成工具来做事 07/24 10:33
21F:→ siuoly: 你辛苦哩 07/24 10:34
※ 编辑: cuello (59.115.168.28 台湾), 07/24/2021 13:06:48