使用源突出显示与 less 结合使用工作得很好,但我很难知道如何使用它,git show
因为没有文件扩展名来线索source-highlight
git 输出中使用的语言......
less somefile.rb # result is syntax colourised
git show master:somefile.rb | less # no colouring
使用调用git show master:somefile.rb | less
实际上与调用相同less somefile
(即不.rb
);因为没有扩展名,所以源突出显示无法猜测语法。
是否有一种非扩展方式可以让源突出显示进行猜测,或者我可以以某种方式将--lang-def
选项传递给LESSOPEN
变量吗?
编辑1 啊,所以看起来像source-highlight可以使用其他方法推断语言,但我的源文件中没有任何这些。
答案1
我最终修改了 gnu source-highlight 的 src-hilite-lesspipe.sh ,以便它可以与管道文件一起使用:https://gist.github.com/jaygooby/9494858d3d481a64819d227a9318f6c7
这意味着也以常规方式调用:
less code.py
您还可以对没有任何扩展名的无扩展名文件进行源代码突出显示语言推理特征源突出显示使用:
less /tmp/mycode
以及(这样做的最初动机)管道文件:
cat /tmp/file.rb | less
git show master:obfusicated.perl # implicit pipe to less via git's pager
如果您知道您的代码使用的语法 source-highlight 没有任何定义文件,您可以通过设置类似的语言来覆盖猜测。 c 通常是一个很好的后备:
SRCLANG=c git show master:app/views/layouts/application.html.erb
这是其要点的原始副本:https://gist.github.com/jaygooby/9494858d3d481a64819d227a9318f6c7
#! /bin/bash
#
# Based on http://git.savannah.gnu.org/cgit/src-highlite.git/tree/src/src-hilite-lesspipe.sh.in
# by Lorenzo Bettini
#
# Modified by Jay Caines-Gooby to support piped files
# [email protected]
# @jaygooby
#
# Typically called by setting:
#
# export LESSOPEN="|-/path/to/src-hilite-lesspipe.sh %s"
# export LESS=-R
#
# If we're less-ing a file, %s will be replaced by the name of the file. If
# there's no file and we're reading from a pipe, then %s is set to -
#
# This script differs from the original src-hilite-lesspipe.sh
# in that it can handle pipes and files with no extensions and will
# attempt to guess their language using the file command.
#
# So as well as invoking on regular files:
#
# less some.rb
# less some.py
#
# It will should be able to work on:
#
# less no-extension-but-contains-perl
#
# and even with more complex examples (my original motivation
# https://unix.stackexchange.com/questions/469982/how-can-i-use-source-highlight-with-git-show)
#
# git show master:some.rb
#
# It uses bashisms to do this, so is no longer a pure POSIX sh script.
set -eu
# Users can override the guessed language by setting SRCLANG:
# SRCLANG=c git show master:app/views/layouts/application.html.erb
SRCLANG=${SRCLANG:-}
guess_language() {
lang=$(echo -e ${1:-} | file - | cut -d" " -f2)
echo $(tr [A-Z] [a-z] <<< "$lang")
}
# check if the language passed as $1 is known to source-highlight
# In an earlier version of this script I set a fallback (c.lang)
# but this causes issues with paging man pages etc
check_language_is_known() {
fallback=""
lang=$(source-highlight --lang-list | cut -d' ' -f1 | grep "${1:-}" || true)
lang=${lang:-$fallback}
echo $lang
}
for source in "$@"; do
case $source in
*ChangeLog|*changelog)
source-highlight --failsafe -f esc --lang-def=changelog.lang --style-file=esc.style -i "$source" ;;
*Makefile|*makefile)
source-highlight --failsafe -f esc --lang-def=makefile.lang --style-file=esc.style -i "$source" ;;
*.tar|*.tgz|*.gz|*.bz2|*.xz)
lesspipe "$source" ;;
*)
# naive check for a file extension; let source-highlight infer language
# but only when source isn't - (ie. from a piped file)
if [[ "$source" != "-" && $(basename "$source") =~ \. ]]; then
source-highlight --failsafe --infer-lang -f esc --style-file=esc.style -i "$source"
else
# We're being piped to, or the filename doesn't have an extension
# so guess the language.
# When we're being piped to, we cat stdin, but when it's a file
# without an extension, we cat the file instead.
# unset IFS so line breaks are preserved and capture the file's contents
# (will only work for files up to bash's available memory). There should
# be a better way to replicate this with tee or process substitution...
IFS= file=$([ "source" = "-" ] && cat || cat "$source")
lang=$(guess_language $file)
lang=$(check_language_is_known $lang)
# Don't call if source-highlight doesn't know the language
# BUT also let users override the guessed lang if the environment
# variable SRCLANG is set. This can help where you know e.g. your
# source code is c-like, but source-highlight has no specific syntax
# definition for your code
[ -n "$SRCLANG" ] && lang="$SRCLANG"
if [ -n "$lang" ]; then
echo $file | source-highlight --failsafe -f esc --src-lang=$lang --style-file=esc.style
else
echo $file
fi
fi
;;
esac
done
答案2
source-highlight
无需使用扩展名即可猜测语言。看6.1 如何发现输入语言。
不幸的是,该功能要求输入是常规文件。当我尝试使用它来识别标准输入时,出现以下错误:
source-highlight: missing feature: language inference requires input file
因此它在管道中间不可用,这是在格式化git
输出时调用它的方式。
git
确实有一些配置其寻呼机的选项 - 请参阅文档核心寻呼机和寻呼机。<cmd>。但是没有任何机制可以将附加信息(例如文件名)传递给分页器 - git-show
仅在显示提交时有格式化选项。您指定的“寻呼机命令”必须是一个附加的包装器脚本,它执行以下步骤:
- 读取整个输入并将其保存在临时文件中
- 调用
source-highlight ...
该文件 - 将输出传送到实际的寻呼机
对于没有适当的“sha-bang”来识别它们的文件,这仍然会失败。