Class: Pindo::PindoContext

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/pindo/base/pindocontext.rb

Defined Under Namespace

Modules: SelectionKey

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePindoContext

Returns a new instance of PindoContext.



12
13
14
15
16
17
18
19
20
21
# File 'lib/pindo/base/pindocontext.rb', line 12

def initialize
  @current_command = nil      # 根命令(第一个设置的命令)
  @current_directory = nil    # 项目路径
  @memory_selections = {}      # 三级结构的内存缓存
  @file_cache_loaded = false   # 标记文件缓存是否已加载
  @cache_enabled = false       # 默认禁用缓存
  @command_group = nil         # 命令组名称
  @verbose = false             # 是否输出详细日志
  ensure_cache_dir
end

Instance Attribute Details

#current_commandObject (readonly)

Returns the value of attribute current_command.



10
11
12
# File 'lib/pindo/base/pindocontext.rb', line 10

def current_command
  @current_command
end

#current_directoryObject (readonly)

Returns the value of attribute current_directory.



10
11
12
# File 'lib/pindo/base/pindocontext.rb', line 10

def current_directory
  @current_directory
end

Instance Method Details

#cache_enabled?Boolean

检查缓存是否启用

Returns:

  • (Boolean)


152
153
154
# File 'lib/pindo/base/pindocontext.rb', line 152

def cache_enabled?
  @cache_enabled
end

#clear_current_cacheObject

清除当前上下文的缓存



195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/pindo/base/pindocontext.rb', line 195

def clear_current_cache
  return unless @cache_enabled

  proj_path = get_project_path
  cmd = root_command
  return unless proj_path && cmd

  if @memory_selections[proj_path] && @memory_selections[proj_path][cmd]
    @memory_selections[proj_path].delete(cmd)
    @memory_selections.delete(proj_path) if @memory_selections[proj_path].empty?
    save_file_cache
    puts "[PindoContext] 清除缓存: [#{proj_path}][#{cmd}]" if verbose?
  end
end

#debug_infoObject

调试信息



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# File 'lib/pindo/base/pindocontext.rb', line 466

def debug_info
  puts "\n=== PindoContext Debug Info ==="
  puts "当前命令: #{@current_command || ''}"
  puts "命令组: #{@command_group || ''}"
  puts "设置的目录: #{@current_directory || '未设置'}"
  puts "实际项目路径: #{get_project_path}"
  puts "缓存启用: #{@cache_enabled}"

  proj_path = get_project_path
  root_cmd = @command_group || @current_command

  if root_cmd && @memory_selections.dig(proj_path, root_cmd)
    puts "当前缓存的选择:"
    @memory_selections[proj_path][root_cmd].each do |k, v|
      next if k.to_s.start_with?('__')  # 跳过内部字段
      puts "  #{k}: #{v.inspect}"
    end
  end
  puts "================================\n"
end

#enable_cache(enabled = true) ⇒ Object

启用/禁用缓存



143
144
145
146
147
148
149
# File 'lib/pindo/base/pindocontext.rb', line 143

def enable_cache(enabled = true)
  @cache_enabled = enabled
  if enabled && !@file_cache_loaded && @current_command
    load_file_cache_with_confirmation
    @file_cache_loaded = true
  end
end

#get_project_pathObject

内部使用的项目路径获取方法优先使用已设置的目录,如果没有则尝试获取Git仓库根目录



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/pindo/base/pindocontext.rb', line 178

def get_project_path
  # 如果已经设置了目录,直接返回
  return @current_directory if @current_directory

  # 尝试获取Git仓库根目录
  begin
    git_root = `git rev-parse --show-toplevel 2>/dev/null`.strip
    return git_root if $?.success? && !git_root.empty?
  rescue
    # git命令失败
  end

  # 最后的后备:使用当前目录
  Dir.pwd
end

#get_selection(key) ⇒ Object

获取用户选择(三级结构访问)



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/pindo/base/pindocontext.rb', line 117

def get_selection(key)
  # 使用统一的项目路径获取方法
  project_path = get_project_path
  root_command = @command_group || @current_command

  return nil unless project_path && root_command

  # 从三级结构中获取值(总是从内存获取,不管是否启用缓存)
  value = @memory_selections.dig(project_path, root_command, key)

  if value
    puts "[PindoContext] 从内存获取: [#{project_path}][#{root_command}][#{key}] = #{value.inspect}" if verbose?
  else
    puts "[PindoContext] 内存中未找到: [#{project_path}][#{root_command}][#{key}]" if verbose?
  end

  value
end

#has_selection?(key) ⇒ Boolean

检查是否有缓存的选择

Returns:

  • (Boolean)


137
138
139
140
# File 'lib/pindo/base/pindocontext.rb', line 137

def has_selection?(key)
  # 总是检查内存中是否有值,不管是否启用缓存
  !get_selection(key).nil?
end

#nested_call?Boolean

是否是嵌套调用

Returns:

  • (Boolean)


157
158
159
# File 'lib/pindo/base/pindocontext.rb', line 157

def nested_call?
  !@current_command.nil?
end

#project_pathObject

获取当前项目路径(统一的获取方法,确保一致性)



172
173
174
# File 'lib/pindo/base/pindocontext.rb', line 172

def project_path
  get_project_path
end

#reset_contextObject

重置上下文(顶层命令结束时调用)



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/pindo/base/pindocontext.rb', line 73

def reset_context
  # 仅在启用缓存时保存文件缓存
  save_file_cache if @cache_enabled && @current_command

  @current_command = nil
  @current_directory = nil
  @file_cache_loaded = false
  @cache_enabled = false
  @command_group = nil
  # 暂不清理内存缓存,让同一进程内可以复用
end

#root_commandObject

获取当前根命令



167
168
169
# File 'lib/pindo/base/pindocontext.rb', line 167

def root_command
  @command_group || @current_command
end

#set_context(command, directory = nil, options = {}) ⇒ Object

设置当前上下文



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/pindo/base/pindocontext.rb', line 29

def set_context(command, directory = nil, options = {})
  # 如果已有命令在执行,这是嵌套调用,不需要做任何事
  unless @current_command.nil?
    puts "[PindoContext] 嵌套调用 #{command},使用已有上下文 (根命令: #{@current_command},命令组: #{@command_group})" if verbose?
    return
  end

  # 第一次设置,是顶层命令
  @current_command = command  # 保持原始命令名称
  @current_directory = directory || Dir.pwd  # 固定项目目录

  # 从选项中获取缓存配置
  @cache_enabled = options[:cache_enabled] || false
  @verbose = options[:verbose] || false
  # 使用 get_command_group 来确定缓存组
  @command_group = get_command_group(command)

  if verbose?
    puts "\n[PindoContext] ========== 设置顶层命令上下文 =========="
    puts "[PindoContext] 命令: #{command}"
    puts "[PindoContext] 目录: #{@current_directory}"
    puts "[PindoContext] 缓存启用: #{@cache_enabled}"
    puts "[PindoContext] 命令组: #{@command_group}"
    puts "[PindoContext] options: #{options.inspect}"
  end

  # 仅在启用缓存时加载文件缓存
  if @cache_enabled && !@file_cache_loaded
    puts "[PindoContext] 准备加载文件缓存..." if verbose?
    load_file_cache_with_confirmation
    @file_cache_loaded = true
  else
    if verbose?
      if !@cache_enabled
        puts "[PindoContext] 缓存未启用,跳过文件缓存加载"
      elsif @file_cache_loaded
        puts "[PindoContext] 文件缓存已加载,跳过重复加载"
      end
    end
  end
  puts "[PindoContext] ======================================\n" if verbose?
end

#set_selection(key, value) ⇒ Object

设置用户选择(三级结构:项目路径 -> 根命令 -> 键值)



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/pindo/base/pindocontext.rb', line 86

def set_selection(key, value)
  # 构建三级键 - 使用统一的项目路径获取方法
  project_path = get_project_path
  root_command = @command_group || @current_command

  # 如果没有有效的项目路径或命令,不保存
  unless project_path && root_command
    puts "[PindoContext] 警告: 无法保存选择,缺少项目路径或命令上下文"
    return
  end

  # 初始化三级结构(总是保存到内存,不管是否启用缓存)
  @memory_selections[project_path] ||= {}
  @memory_selections[project_path][root_command] ||= {}
  @memory_selections[project_path][root_command][key] = value

  # 更新该命令组的最后修改时间
  @memory_selections[project_path][root_command]['__last_modified__'] = Time.now.to_i

  puts "[PindoContext] 保存到内存: [#{project_path}][#{root_command}][#{key}] = #{value.inspect}" if verbose?

  # 仅在启用缓存时保存到文件
  if @cache_enabled
    save_file_cache
    puts "[PindoContext] 已保存到文件缓存" if verbose?
  else
    puts "[PindoContext] 缓存未启用,仅保存到内存" if verbose?
  end
end

#top_level_command?Boolean

是否是顶层命令(非嵌套)

Returns:

  • (Boolean)


162
163
164
# File 'lib/pindo/base/pindocontext.rb', line 162

def top_level_command?
  @current_command.nil?
end

#verbose?Boolean

判断是否处于 verbose 模式

Returns:

  • (Boolean)


24
25
26
# File 'lib/pindo/base/pindocontext.rb', line 24

def verbose?
  @verbose || ENV['PINDO_VERBOSE'] == '1' || ENV['PINDO_DEBUG'] == '1'
end