An interactive learning platform for mastering CLI tools directly in Neovim. Practice commands with guided exercises, track your progress, and build muscle memory through spaced repetition.
- ✨ Features
- 📦 Installation
- [Using lazy.nvim](#using-lazynvimhttpsgithubcomfolkelazynvim)
- [Using packer.nvim](#using-packernvimhttpsgithubcomwbthomasonpackernvim)
- 🚀 Quick Start
- ⚙️ Configuration
- 🎮 Usage
- 📚 Creating Custom Exercises
- 🔄 Creating Cycles
- 📊 Scoring System
- 🎯 Difficulty Progression
- 🧠 Learning Principles
- 🔍 Built-in Exercises
- 🤝 Contributing
- 📝 License
- 🙏 Acknowledgments
- 📮 Support
- 🎯 Structured Learning Paths: Organized exercises in progressive cycles
- 📊 Progress Tracking: Detailed statistics, scores, and mastery levels
- ⏱️ Adaptive Difficulty: Target times adjust based on your performance
- 💡 Progressive Hints: Get help when stuck (with minimal score penalty)
- 🏆 Score & Ranking: Performance-based scoring with best time/score tracking
- 📁 Exercise Files: Practice with real files attached to each exercise
- 📚 References: Built-in documentation and learning resources
- 💾 State Persistence: Your progress is automatically saved
- 🔧 Fully Customizable: Add your own exercises, cycles, and configurations
Using lazy.nvim
{
'StefanBartl/learn-cli.nvim',
config = function()
require('learn_cli').setup({
-- Your configuration here
})
end,
}Using packer.nvim
use {
'StefanBartl/learn-cli.nvim',
config = function()
require('learn_cli').setup()
end
}- Install the plugin
- Run
:LearnClito open the dashboard - Select a cycle or exercise to begin
- Practice in the integrated terminal
- Track your progress over time
require('learn_cli').setup({
-- Data storage location
data_dir = vim.fn.stdpath("data") .. "/learn_cli",
-- Auto-save progress
auto_save = true,
auto_save_interval_ms = 30000, -- 30 seconds
-- UI settings
ui = {
dashboard = {
width = "85%",
height = "85%",
border = "rounded", -- "single", "double", "rounded", "none"
show_stats = true,
show_recent = true,
recent_count = 10,
},
exercise_view = {
width = "90%",
height = "90%",
border = "rounded",
show_timer = true,
show_hints_count = true,
terminal_height = 15,
},
show_progress_bar = true,
use_icons = true,
},
-- Scoring algorithm
scoring = {
base_score = 100,
hint_penalty = 10,
time_bonus_threshold = 0.8, -- Bonus if < 80% of target time
time_penalty_threshold = 1.5, -- Penalty if > 150% of target time
completion_bonus = 10,
},
-- Timer settings
timer = {
show_warnings = true,
warning_at_percent = 0.75, -- Warn at 75% of target time
adaptive_target = true, -- Adjust target based on performance
adaptive_factor = 0.9, -- 10% adjustment
},
-- Keymaps
keymaps = {
prefix = "<leader>lc",
dashboard = "d",
next_exercise = "n",
prev_exercise = "p",
show_hint = "h",
complete_exercise = "<CR>",
quit = "q",
},
})| Command | Description |
|---|---|
:LearnCli |
Open the main dashboard |
:LearnCliStart <id> |
Start a specific exercise by ID |
:LearnCliStats |
Show detailed statistics |
:LearnCliExport <file> |
Export progress to a file |
:LearnCliImport <file> |
Import progress from a file |
:LearnCliBackup |
Create a backup of current progress |
:LearnCliReset! |
Reset all progress (with confirmation) |
Global (configurable prefix: <leader>lc):
<leader>lcd- Open dashboard<leader>lcs- Show statistics<leader>lcb- Backup progress
In Exercise View:
n- Next exercisep- Previous exerciseh- Show next hint<CR>- Mark exercise completeq- Quit exercise view
Create a Lua file in your exercises directory:
-- ~/.config/nvim/learn_cli_exercises/my_exercises.lua
return {
{
id = "sed_basic_replace",
program = "sed",
title = "Basic Text Replacement",
description = "Learn to replace text using sed",
difficulty = "beginner",
target_time_seconds = 180,
task = [[
You have a file 'data.txt' with various lines.
Task:
1. Replace all occurrences of "foo" with "bar"
2. Save the result to 'output.txt'
Expected command: sed 's/foo/bar/g' data.txt > output.txt
]],
hints = {
"Use sed with the 's' command for substitution",
"The syntax is: s/pattern/replacement/flags",
"The 'g' flag means 'global' (all occurrences)",
},
files = {
["data.txt"] = [[
foo is here
more foo there
foo foo everywhere
not here though
]],
},
references = {
"man sed",
"https://www.gnu.org/software/sed/manual/sed.html",
},
tags = { "sed", "text", "replace" },
prerequisites = {},
},
}Then configure the exercises directory:
require('learn_cli').setup({
exercises_dir = vim.fn.stdpath("config") .. "/learn_cli_exercises",
})Cycles group related exercises into learning paths:
-- In your custom exercises file or separate cycle file
local cycles = {
{
id = "grep_fundamentals",
name = "Grep Fundamentals",
description = "Master the grep command",
exercise_ids = {
"grep_basic_search",
"grep_case_insensitive",
"grep_regex_basics",
"grep_inverted_match",
},
estimated_duration_minutes = 20,
difficulty = "beginner",
},
}
-- Register cycles
for _, cycle in ipairs(cycles) do
require('learn_cli.state').register_cycle(cycle)
endYour score for each exercise is calculated based on:
- Base Score: 100 points (default)
- Hint Penalties: -10 points per hint used
- Time Bonuses: Up to +20 points for fast completion
- Time Penalties: Up to -10 points for slow completion
- Completion Bonus: +10 points for finishing
Mastery Level is calculated from your recent performance (last 5 attempts) and improves with:
- High scores
- Consistency (completing all recent attempts)
- Experience (total attempts)
Exercises are tagged with difficulty levels:
- 🟢 Beginner: Basic commands and simple flags
- 🟡 Intermediate: Combined flags and pipes
- 🟠 Advanced: Complex scenarios and edge cases
- 🔴 Expert: Optimization and advanced patterns
The plugin suggests difficulty progression based on your mastery level:
- ≥80% mastery → Suggested to move up
- <40% mastery → Suggested to review easier exercises
This plugin incorporates proven learning techniques:
- Revisit exercises after intervals
- Reinforces memory through practice
- Tracks time since last attempt
- Start with basics, build to advanced
- Prerequisites ensure proper foundation
- Adaptive timing adjusts to your pace
- Practice in real terminal environment
- No passive reading - hands-on learning
- Immediate feedback on attempts
- Focused exercises on specific skills
- Measurable progress tracking
- Challenging but achievable targets
The plugin comes with exercises for:
- grep: Text search and pattern matching
- sed: Stream editing and text transformation
- (More coming soon!)
Contributions are welcome! Please check out the Developer README for guidelines on:
- Adding new exercises
- Improving the scoring algorithm
- Extending the UI
- Writing tests
MIT License - see LICENSE for details
- Inspired by command-line learning tools and spaced repetition systems
- Built with Neovim's powerful Lua API
- Thanks to the Neovim community for feedback and contributions
Happy Learning! 🚀