tmux 有类似 vim 的标记吗?

tmux 有类似 vim 的标记吗?

假设我正在tail查看正在运行的应用程序的一些日志,我预计很快就会出现一些长输出,我希望在完成后滚动到顶部。tmux 有什么可以帮助我的东西吗?我在想像 vim 的分数,我可以按ma做一个名为 的标记a,然后按'a跳转到该行。

理想的工作流程:

  1. tail -f一些东西
  2. <prefix> m a树立一个标记a
  3. 做一些事情,导致大量的输出被记录下来
  4. <prefix> ' a跳转到a定义的位置

答案1

虽然 Tmux 确实具有“标记”功能,但我认为它并不适合您的用例。

在复制模式下,按下Shiftx(又称“X”)会设置一个标记,然后Metax在当前位置和该标记之间切换。问题是,当你退出复制模式时,标记会丢失。所以你不能运行随后的 tail -f并回到该点。

我个人的建议是使用分页器进行输出,该分页器支持 (a) 跟踪不断增长的文件,以及 (b) 标记/跳转功能。这可以在命令中轻松找到less。您的工作流程将非常接近您所描述的:

  1. less +F一些东西
  2. Ctrl+c暂时退出跟随模式
  3. ma设置一个名为“a”的标记
  4. F重新启动跟随模式
  5. 做一些事情,导致大量的输出被记录下来
  6. Ctrl+c暂时退出跟随模式(无论如何,您都不希望它在分析输出时滚动)。
  7. 'a跳到你的目标
  8. F如果需要,重新启动跟随模式

编辑/更新

如果你真的想要一个“标记”和“转到标记”功能,那么可能的, 但非常在我看来,这太 hacky 了。我发布这篇文章的原因其实只是因为 (a) 我终于让它 (大部分) 工作了,以及 (b) 我想把它从我的配置中移除,但又不想失去工作成果。

首先,创建两个单独的附加文件:

.tmux-set_mark.tmux

# Must use "run-shell" since it can run the
# command immediately.  The #() syntax always 
# uses the *previous* results.
# The capture-pane is hackery to get the current 
# line number we are on (starting from the 
# beginning of the history.
run "tmux set-environment TMUX_CUR_LINE $(tmux capture-pane -S - -E - -p | tac | awk 'NF {p=1} p' | wc -l)"

# Store it in a user-option on the current 
# pane.  This allows marks in multiple panes 
# to work.
set-option -F -p @TMUX_MARK "#{TMUX_CUR_LINE}"

display-message "Mark set at line #{@TMUX_MARK}"

.tmux-goto_mark.tmux

# Must use "run-shell" since it can run 
# the command immediately.  The #() 
# syntax always uses the *previous* 
# results.
run-shell "tmux set-environment TMUX_CUR_LINE $(tmux capture-pane -S - -E - -p | tac | awk 'NF {p=1} p' | wc -l)"

# Set a user option on the pane with 
# the line number we need to goto.
# This is calculated, of course, by 
# subtracting the marked-line-number
# from the current-line-number
set-option -F -p @TMUX_GOTO "#{e|-:#{TMUX_CUR_LINE},#{@TMUX_MARK}}"

copy-mode

# Goto the line.  Again `run-shell` is needed
# here since send-keys can't expand the FORMAT 
# string, but run-shell can.

run-shell 'tmux display-message #{@TMUX_GOTO}'
run-shell 'tmux send-keys -X goto-line #{@TMUX_GOTO}'

# The next two lines are just additional
# hackery to use the built-in TMux marking
# ability so that the marked line is highlighted
# and at the top of the screen
send-keys -X set-mark
send-keys -X jump-to-mark

然后,在您的中.tmux.conf设置键绑定以获取这些文件:

unbind x
bind x source-file "$HOME/.tmux-set_mark.tmux"
unbind X
bind X source-file "$HOME/.tmux-goto_mark.tmux"

在我看来,这太可怕了。更简单的方法失败了:

  • 如果有更好的方法来获取缓冲区中当前所在的行号,那就简单多了,但似乎没有一个变量可以做到这一点。我能找到的最接近的方法是history_size,但直到您开始滚动窗格时,历史记录才会开始。
  • 如果采用绝对行号会更容易goto-line,而不是采用相对行号底部复制模式下的缓冲区,而不是顶部。

此代码还有一个额外的警告/错误。如果您在 Tmux 窗格的第一个“页面”上执行此操作(在开始滚动之前),它突出显示的行将不是您标记的行。另一种方法是不使用:

send-keys -X set-mark
send-keys -X jump-to-mark

但随后,他们goto-line总会把期望的标记放在底部窗格,这意味着您始终需要向下滚动窗格。

答案2

鉴于@NotTheDr01ds 对我在 OP 下方的评论的评论,您可以在开始步骤 3 中的进程之前,向您正在跟踪的文件中附加一个唯一的行(如果您具有写权限,并且附加这一行不会干扰该日志文件将来的任何使用),方法是:

echo '# mymark' >> file.log && tail -f file.log

tail -f或者如果这不是首选,并且如果你要拖放的文件在你开始第 3 步的过程之前没有快速增长,你可以直接在终端中输入显示的输出

$ tail -f file.log
 > some line from the log
 > another line from the log
 # mymark!
 > line generated by step3
 > and there will be many more lines generated by step3...
 > .           .           .           .           .           
 > .           .           .           .           .           
 > .           .           .           .           .           

# mymark然后在这两种情况下,您都可以在 tmux 的复制模式(使用)中向后搜索字符串?^# mymark

相关内容