Home

Awesome

nvim-training

License: GPL

This code implements a Neovim Plugin for training your muscle memory.

This plugin fills a gap I have noticed during interaction with vim: Knowing is half the battle, executing another entirely. This plugin aims to help with the latter.

A training session consists of a series of tasks, each of which is small and easily repeatable. The plugin will recognize when a task is completed and automatically start the next one. This helps to work on a lot of tasks in a short amount of time.

The list of tasks is growing all the time, if you miss a particular one you may open a feature request :)

Some stats of current tasks

In Action

GIF

Installation

Install it using the plugin manager of your choice. Lazy is tested, if any other fails, please open an issue. Pinning your local installation to a fixed version is encouraged. In Lazy, a possible setup might be:

local lazy = require("lazy")
local plugin_list = {
    -- Your various other plugins ..
    {"https://github.com/Weyaaron/nvim-training", pin= true, opts = {}} -- Support for configuration with opts is included, see below for the options
}
lazy.setup(plugin_list)

Commands

This plugin uses subcommands of Training to activate certain functions. All of these commands support completion, just use Tab and you will be fine. Currently, these are the available options:

NameSyntaxDescription
Start:Training Start [Scheduler] [Task-Collection A] [Task Collection B] ...Starts a session with the choosen scheduler and the choosen task collections. Both arguments are optional.
Stop:Training StopStops a session.
Analyze:Training AnalyzePrints some statistics about your progress.

Some care is taken to avoid overwritting your files, but just to be safe you may start in an empty buffer/directory.

Currently supported tasks

NameDescriptionTagsNotes
AppendCharInsert a char next to the cursor.append, insertion, change
ChangeWordChange text using w,c.horizontal, w, word, c, change
DeleteCharDelete the current char.change, char, deletion
DeleteInsideMatchDelete inside the current match.change, inside, match, deletion
DeleteLineDelete the current line.change, line, deletion
DeleteWORDDelete using 'W'.movement, word, deletion
DeleteWordDelete using 'w'.movement, word, deletion
Delete_fMove using f.f, horizontal, movement
IncrementIncrement the value at the cursor.change, char, increment
InsertCharInsert a char at the current position.char, insertion, change
MoveAbsoluteLineMove to the absolute line.line, vertical, movement
MoveEndOfFileMove to the end the file.end, file, vertical, movement
MoveEndOfLineMove to the end of the current line.end, horizontal, line, movement
MoveFMove using F.F, horizontal, movement
MoveMatchMove to the current match.movement, match
MoveStartOfFileMove to the start of the file.file, vertical, start
MoveStartOfLineMove to the start of the current line.line, movement, start
MoveTMove using T.T, horizontal, movement
MoveWORDMove using W.W, WORD, movement
MoveWordMove using w.horizontal, w, word, movement
MoveWordEndMove to the end of the current 'word'.end, vertical, word, movement
Move_OEnter and leave insert mode above the current line.insert_mode, linewise, movement, O
Move_oEnter and leave insert mode below the current line.insert_mode, linewise, movement, o
MovefMove using f.f, horizontal, movement
MovetMove using t.horizontal, t, movement
PastePaste from a given register.register, paste
SearchForwardSearch forwards for a target-string.diagonal, movement, search
YankEndOfLineYank to the end of the current line.line, yank, end
YankInsideMatchYank inside the current match.inside, match, yank
YankIntoRegisterYank a line into a register.copy, line, vertical, register
YankWORDYank using w.counter, horizontal, w, word, yank
YankWordYank using w.counter, horizontal, w, word, yank

Task-Collections

The following table lists the available collections. They will grow over time, for support for custom collections see below.

NameDescriptionLink
AllAll supported tasks. Does involve tasks that are designed with plugins in mind!All
ChangeTasks involving some change to the buffer.Change
MovementsTasks involving movement.Movements
NonMovementsTasks not involving movement.NonMovements
YankingTasks involving yankingYanking

Schedulers

NameDescription
RandomSchedulerThe next task is chosen at random.
RepeatUntilNSuccessThe current task is repeated until n successes are reached.

Configuration

A interface for configuration is provided. These are the default values if you do not change anything yourself.

local training = require("nvim-training")
training.configure({ -- All of these options work for 'opts' of lazy as well.
	audio_feedback = true, -- Enables/Disables audio feedback, if enabled, requires the 'sox' package providing the 'play' command.
	base_path = vim.fn.stdpath("data") .. "/nvim-training/",
	counter_bounds = { 1, 5 },
	custom_collections = {}, -- A table of tables containing names of tasks, for details read on.
	enable_counters = true, -- Enables/Disables counters in tasks that support counters.
	enable_events = true, -- If the plugin should save events. These are used for the subcommand analyze.
	possible_marks_list = { "a", "b", "c", "r", "s", "t", "d", "n", "e" }, -- A list of possible marks.
	possible_register_list = { "a", "b", "c", "r", "s", "t", "d", "n", "e" }, -- A list of possible registers.
	task_alphabet = "ABCDEFGabddefg,.",
})

Custom Collections

To add a custom collection, please use its name as a key for a list of task names in the config, for example like this:

local training = require("nvim-training")
training.configure({
    -- .. your other configs ...
	custom_collections = { MyCollection = { "MoveWord", "MoveWORD"}}
})

You may provide as many collections as you wish, they will be available in autocompletion.

For beginners

Hi, welcome. Since this plugin is aimed at beginners, I will help out with any issues about getting started. Just message me over on aaronwey@posteo.de and I will help you out. Depending on the issue, your feedback may be used to improve the setup for everyone :)

Goals

Non-Goals

How to get started with contributing

Contributions are welcome! Any input is appreciated, be it a bug report, a feature request, or a pull request. This is my first project in lua, therefore, some junk and bad practices are to be expected. Any feedback/suggestions are appreciated.

Best Practices for contributing

License

GPL