Last active
April 24, 2025 15:16
-
-
Save sandrods/e238f5563d6f7ec1a5f0def1f3ed7d21 to your computer and use it in GitHub Desktop.
Revisions
-
sandrods revised this gist
Apr 24, 2025 . 1 changed file with 7 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -39,10 +39,16 @@ Define your focus areas in `.focus/config.yml`: ```yaml invoices: - app/assets/stylesheets/components.css - app/components/invoices - app/components/ui/picker - app/controllers/invoices_controller.rb - app/controllers/invoices - app/controllers/picker - app/models/invoice.rb - app/models/invoice_item.rb - app/views/invoices - app/views/picker ``` ### Basic Commands -
sandrods revised this gist
Apr 24, 2025 . 2 changed files with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes.File renamed without changes. -
sandrods revised this gist
Apr 24, 2025 . 1 changed file with 0 additions and 8 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -31,14 +31,6 @@ When you update your configuration, you can refresh your focus area without losi bin/focus invoices --refresh ``` ## Usage ### Configuration -
sandrods revised this gist
Apr 24, 2025 . 1 changed file with 87 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,87 @@ # Focus: A Developer's Context Switcher When working on large codebases, developers often need to switch between different features or areas of the application. The `focus` script helps manage this cognitive load by creating organized workspaces for different contexts. ## The Problem Working on features that span multiple directories (controllers, models, views, specs) requires constant navigation and context switching. This leads to keeping multiple editor windows open, maintaining mental lists of relevant files, and repeatedly searching through deep directory structures. ## The Solution The `focus` script creates virtual workspaces using symlinks. It maintains a configuration file where you define groups of related files and directories. When you switch to a focus area, the script creates a dedicated directory with symlinks to all relevant files, preserving their original structure while making them easily accessible in one place. ## Features ### 1. Easy Setup - First-time run creates an example configuration - Opens the config file in your editor for immediate customization ### 2. Smart Symlink Management - Creates directory structure as needed - Handles both files and directories - Maintains original file structure within the focus directory ### 3. Refresh Mode When you update your configuration, you can refresh your focus area without losing existing symlinks: ```bash bin/focus invoices --refresh ``` ### 4. Clear Feedback The script provides clear status messages: - ✅ Successfully linked files - ❌ Missing source files - ℹ️ Already existing links (in refresh mode) ## Usage ### Configuration Define your focus areas in `.focus/config.yml`: ```yaml invoices: - app/controllers/invoices_controller.rb - app/models/invoice.rb - app/views/invoices - spec/models/invoice_spec.rb ``` ### Basic Commands ```bash # First time setup bin/focus # Switch to a focus area bin/focus invoices # Update after config changes bin/focus invoices --refresh ``` ## Benefits 1. **Reduced Cognitive Load**: All relevant files for a feature are in one place 2. **Faster Navigation**: No need to dig through deep directory structures 3. **Non-Destructive**: Uses symlinks, so original files remain unchanged 4. **Flexible**: Easy to update and modify focus areas as needed ## Installation 1. Copy the `focus` script to your project's `bin` directory 2. Make it executable: `chmod +x bin/focus` ## Tips - Include both implementation and test files in your focus areas - Use directories when you need all files in a folder - Use `--refresh` when you want to preserve existing links The `focus` script is a simple tool that can significantly improve your development workflow by reducing the friction of context switching and keeping related files easily accessible. -
sandrods revised this gist
Apr 24, 2025 . No changes.There are no files selected for viewing
-
sandrods revised this gist
Apr 24, 2025 . 1 changed file with 21 additions and 8 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -56,32 +56,45 @@ rescue Psych::SyntaxError => e end if ARGV.empty? puts "Usage: bin/focus [section_name] [--refresh]" list_available_sets(sets) exit 0 end refresh_mode = ARGV.include?("--refresh") section = ARGV.find { |arg| !arg.start_with?("--") } unless section puts "❌ Please provide a section name" list_available_sets(sets) exit 1 end unless sets.key?(section) puts "❌ Section '#{section}' not found in #{FOCUS_FILE}." list_available_sets(sets) exit 1 end target_dir = File.join(FOCUS_ROOT, section) puts "🔄 #{refresh_mode ? "Refreshing" : "Creating"} symlinks in #{target_dir}/ ..." # Only remove existing symlinks if not in refresh mode FileUtils.rm_rf(target_dir) unless refresh_mode sets[section].each do |relative_path| source_path = File.expand_path(relative_path) dest_path = File.join(target_dir, relative_path) if File.exist?(source_path) begin FileUtils.mkdir_p(File.dirname(dest_path)) FileUtils.ln_s(source_path, dest_path) unless File.exist?(dest_path) puts "✅ Linked: #{relative_path}" rescue Errno::EEXIST puts "ℹ️ Already exists: #{relative_path}" end else puts "❌ Missing: #{relative_path}" end -
sandrods created this gist
Apr 24, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,93 @@ #!/usr/bin/env ruby require "fileutils" require "yaml" FOCUS_FILE = ".focus/config.yml" FOCUS_ROOT = ".focus" EDITOR_COMMAND = "cursor" # Change to "code" or whatever def list_available_sets(sets) puts "ℹ️ Available focus sets:" sets.keys.each { |key| puts " - #{key}" } end def create_example_focus_file example = { "invoices" => [ "app/controllers/invoices_controller.rb", "app/models/invoice.rb", "app/views/invoices", "spec/models/invoice_spec.rb" ], "auth" => [ "app/controllers/sessions_controller.rb", "app/models/user.rb", "app/views/sessions", "spec/requests/login_spec.rb" ] } FileUtils.mkdir_p(File.dirname(FOCUS_FILE)) File.write(FOCUS_FILE, example.to_yaml) puts "✅ Created #{FOCUS_FILE} with example sections." end unless File.exist?(FOCUS_FILE) puts "⚠️ #{FOCUS_FILE} not found." print "Would you like to create a sample one? (Y/n): " answer = $stdin.gets.strip.downcase if answer.empty? || answer == "y" || answer == "yes" create_example_focus_file system(EDITOR_COMMAND, FOCUS_FILE) exit 0 else puts "🚫 Aborted. Please create #{FOCUS_FILE} manually." exit 1 end end begin sets = YAML.load_file(FOCUS_FILE) rescue Psych::SyntaxError => e puts "❌ YAML parsing error in #{FOCUS_FILE}:\n#{e.message}" exit 1 end if ARGV.empty? puts "Usage: bin/focus [section_name]" list_available_sets(sets) exit 0 end section = ARGV.first target_dir = File.join(FOCUS_ROOT, section) unless sets.key?(section) puts "❌ Section '#{section}' not found in #{FOCUS_FILE}." list_available_sets(sets) exit 1 end puts "🔄 Creating symlinks in #{target_dir}/ ..." FileUtils.rm_rf(target_dir) sets[section].each do |relative_path| source_path = File.expand_path(relative_path) dest_path = File.join(target_dir, relative_path) if File.exist?(source_path) FileUtils.mkdir_p(File.dirname(dest_path)) FileUtils.ln_s(source_path, dest_path) puts "✅ Linked: #{relative_path}" else puts "❌ Missing: #{relative_path}" end end puts "\n📂 Focus folder ready: #{target_dir}" puts "🚀 Opening with: #{EDITOR_COMMAND} #{target_dir}/" system(EDITOR_COMMAND, target_dir)