Utoljára aktív 1755161877

Revízió 3168a207ea0384aa7736502fb0f3e55dd441751b

glance.bash Eredeti
1# 函数:glance - 快速概览目录内容
2#
3# 作者: Gemini & anduin
4# 功能:
5# - 自动检测 Git 仓库,智能选择文件列表模式。
6# - 动态计算并调整 tree 的显示深度。
7# - 文件内容输出严格遵循 tree 的显示深度。
8# - 限制单个文件的最大输出行数。
9# - 支持按文件名模式筛选文件。
10#
11# 用法:
12# glance [目录] [选项...]
13#
14# 选项:
15# --max-files-preview <数量> : tree 显示的最大条目数 (默认: 100)
16# --max-file-lines <数量> : 单个文件的最大显示行数 (默认: 150)
17# --filter <模式> : 按扩展名筛选,逗号分隔 (例: '*.md,*.cs')
18#
19glance() {
20 local target_dir="."
21 local max_items_preview=100
22 local max_file_lines=150
23 local filter_patterns=""
24 local positional_args=()
25
26 # --- 内部辅助函数:处理单个文件的打印 (无改动) ---
27 _glance_process_file() {
28 local file="$1"
29 if [ ! -f "$file" ]; then return; fi
30 if file -b --mime-type "$file" | grep -q '^text/'; then
31 local total_lines; total_lines=$(wc -l < "$file")
32 local extension="${file##*.}"; local lang=""
33 case "$extension" in
34 js) lang="javascript" ;; py) lang="python" ;; rb) lang="ruby" ;;
35 sh) lang="bash" ;; css) lang="css" ;; html) lang="html" ;;
36 json) lang="json" ;; md) lang="markdown" ;; yml|yaml) lang="yaml" ;;
37 java) lang="java" ;; c) lang="c" ;; cpp) lang="cpp" ;; go) lang="go" ;;
38 *) lang="" ;;
39 esac
40 echo; echo "Content of file \"$file\":"; echo "\`\`\`$lang"
41 if [ "$total_lines" -gt "$max_file_lines" ]; then
42 head -n "$max_file_lines" "$file"; echo; echo "... (Only shown top $max_file_lines lines of $total_lines) ..."
43 else
44 cat "$file"
45 fi
46 echo; echo "\`\`\`"; echo "----------------------------------------------------------"
47 else
48 echo; echo "--> 已跳过二进制文件: \"$file\""; echo "----------------------------------------------------------"
49 fi
50 }
51
52 # --- 步骤 1: 解析参数 ---
53 while [[ $# -gt 0 ]]; do
54 case "$1" in
55 --max-files-preview)
56 if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then max_items_preview="$2"; shift 2;
57 else echo "错误: '--max-files-preview' 需要一个正整数参数。" >&2; return 1; fi ;;
58 --max-file-lines)
59 if [[ -n "$2" && "$2" =~ ^[0-9]+$ ]]; then max_file_lines="$2"; shift 2;
60 else echo "错误: '--max-file-lines' 需要一个正整数参数。" >&2; return 1; fi ;;
61 --filter)
62 if [[ -n "$2" && "$2" != -* ]]; then filter_patterns="$2"; shift 2;
63 else echo "错误: '--filter' 需要一个模式字符串参数。" >&2; return 1; fi ;;
64 -*) echo "错误: 未知选项 '$1'" >&2; return 1 ;;
65 *) positional_args+=("$1"); shift ;;
66 esac
67 done
68 [[ ${#positional_args[@]} -gt 0 ]] && target_dir="${positional_args[0]}"
69
70 # --- 步骤 2: 依赖和目录检查 ---
71 if ! command -v tree &>/dev/null; then echo "错误: 'tree' 命令未找到。" >&2; return 1; fi
72 if [ ! -d "$target_dir" ]; then echo "错误: 目录 '$target_dir' 不存在。" >&2; return 1; fi
73
74 echo "=========================================================="
75 echo "🔎 概览目录: $(realpath "$target_dir")"
76 echo "=========================================================="
77 echo
78
79 # --- 步骤 3: 动态计算 tree 的最佳深度 (基于未筛选的完整目录) ---
80 echo "🌳 目录结构:"
81 local best_depth=1; local max_depth_to_check=6; local prev_item_count=-1
82 for depth in $(seq 1 $max_depth_to_check); do
83 local current_item_count; current_item_count=$(tree -L "$depth" -a --noreport "$target_dir" | wc -l)
84 if [ "$depth" -gt 1 ] && [ "$current_item_count" -gt "$max_items_preview" ]; then
85 best_depth=$((depth - 1)); break;
86 fi
87 if [ "$depth" -gt 1 ] && [ "$current_item_count" -eq "$prev_item_count" ]; then
88 best_depth=$depth; break;
89 fi
90 best_depth=$depth; prev_item_count=$current_item_count
91 done
92
93 # --- 步骤 3.5: 应用筛选并打印 tree ---
94 local tree_args=(-L "$best_depth")
95 if [ -n "$filter_patterns" ]; then
96 local tree_pattern; tree_pattern=$(echo "$filter_patterns" | tr ',' '|')
97 tree_args+=(-P "$tree_pattern")
98 echo "(筛选模式: ${filter_patterns})"
99 fi
100 echo "(动态调整深度至 L${best_depth} 以适应预览数限制: ${max_items_preview})"
101 tree "${tree_args[@]}" "$target_dir"
102 echo
103
104 # --- 步骤 4: 遍历并打印文件内容 (应用筛选和深度限制) ---
105 local header_suffix=""
106 if [ -n "$filter_patterns" ]; then header_suffix=" (筛选: ${filter_patterns})"; fi
107 echo "📄 文件内容详情 (深度 L${best_depth} 以内, 单文件最多 ${max_file_lines}${header_suffix}):"
108 (
109 cd "$target_dir" || exit 1
110 echo "----------------------------------------------------------"
111
112 local filter_array=()
113 [ -n "$filter_patterns" ] && IFS=',' read -ra filter_array <<< "$filter_patterns"
114
115 if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
116 # Git 模式
117 local git_files
118 if [ ${#filter_array[@]} -gt 0 ]; then
119 git_files=$(git ls-files -- "${filter_array[@]}")
120 else
121 git_files=$(git ls-files)
122 fi
123 echo "$git_files" | awk -F'/' -v depth="$best_depth" 'NF <= depth' | while read -r file; do
124 _glance_process_file "$file"
125 done
126 else
127 # 普通模式
128 local find_args=(-maxdepth "$best_depth" -type f)
129 if [ ${#filter_array[@]} -gt 0 ]; then
130 find_args+=("(")
131 for i in "${!filter_array[@]}"; do
132 [ "$i" -ne 0 ] && find_args+=("-o")
133 find_args+=(-name "${filter_array[$i]}")
134 done
135 find_args+=(")")
136 fi
137 find . "${find_args[@]}" | while read -r file; do
138 _glance_process_file "${file#./}"
139 done
140 fi
141 )
142}