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. Basic familiarity with vim is assumed.

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.

I consider this project mature enough for daily use. I will expand it as I see fit, which might include months of inactivity. I will respond to issues quickly, including requests for new features.

I will attempt to ship breaking changes to public interfaces in such a way that they are done "all/many at once". I consider this to be the best option for minimizing disruptions.

Some stats of current tasks

Some of the tags are currently inconsistent, this is under way to be fixed.

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.

<!-- s -->

All tasks

NameDescriptionTagsNotes
AppendCharInsert a char next to the cursor.append, insertion, change
BlockCommentLineChange the current line into a block comment.change, plugin, programming, commentThis assumes the use of a plugin, it is not tested with the buildin-commenting-feature.
ChangeWordChange multiple words.c, horizontal, w, word, change
CommentLineChange the current line into a single line comment.change, commenting, plugin, programmingNot available in vanilla-vim, needs plugin.
DeleteCharDelete the current char.change, char, deletion
DeleteFDelete with the F-motion.F, horizontal, deletion
DeletefDelete with the motion f.f, horizontal, deletion
DeleteInsideMatchDelete inside the current match.inside, match, deletion
DeleteLineDelete the current line.change, line, deletion
DeleteSentenceDelete the textobject inner sentence.sentence, deletion
DeletetDelete with the motion t.horizontal, t, deletion
DeleteTDelete with the movement T.T, horizontal, movement
DeleteWORDDelete multiple WORDs.WORD, deletion
DeleteWordDelete multiple words.word, deletion
IncrementIncrement the value at the cursor.change, char, increment
InsertCharInsert a char at the current position.char, insertion, change
JoinLinesJoin the current line with the line below.J, join, line, change
MoveAbsoluteLineMove to the absolute line.line, vertical, movement
MoveCharsLeftMove left charwise.char, h, horizontal, movement
MoveCharsRightMove right charwise.horizontal, l, movement
MoveEndOfFileMove to the end the file.end, file, vertical, movement
MoveEndOfLineMove to the end of the current line.end, horizontal, line, movement
MovefFind the next char.horizontal, f, movement
MoveFGo back to the last ocurrence of a char.F, horizontal, movement
MoveLinesDownMove down multiple lines.horizontal, k, lines, movement
MoveLinesUpMove multiple lines up.horizontal, k, lines, movement
MoveMatchMove to the current match.movement, match
MoveoEnter and leave insert mode below the current line.insert_mode, linewise, movement, o
MoveOEnter and leave insert mode above the current line.insert_mode, linewise, movement, O
MoveStartOfFileMove to the start of the file.file, vertical, start
MoveStartOfLineMove to the start of the current line.line, movement, start
MoveTGo back next to the last ocurrence of a char.horizontal, left, T, movement
MovetMove using t.horizontal, t, movement
MoveWORDMove multiple WORDS.W, WORD, movement
MoveWordMove multiple words.horizontal, w, word, movement
MoveWordEndMove to the end of words.end, vertical, word, movement
MoveWORDEndMove to the end of WORDs.end, vertical, word, movement
MoveWORDStartMove Back to the start of 'WORDS'.horizontal, word, movement
MoveWordStartMove back to the start of 'words'.horizontal, word, movement
PastePaste from a given register.register, Paste
pastePaste from a given register.register, paste
SearchBackwardSearch backwards.diagonal, movement, search
SearchForwardSearch forwards.forward, movement, search
SearchWordBackwardSearch backwards for the word at the cursor.backward, movement, search
SearchWordForwardSearch forwards for the word at the cursor.forward, movement, search
YankEndOfLineYank to the end of the current line.line, yank, end
YankfYank to the next char., f, horizontal, yank
YankFYank back to the previous char., F, horizontal, yank
YankInsideMatchYank inside the current match.inside, match, yank
YankIntoRegisterYank a line into a register.copy, line, vertical, register
YankTYank back next to the previous char.T, horizontal, yank
YanktYank to the next char., f, horizontal, yank
YankWORDYank multiple WORDS.counter, horizontal, w, word, yank
YankWordYank multiple words.counter, horizontal, w, word, yank
<!-- e -->

Task-Collections

The following table lists the available collections. Support for custom collections is included and described 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

NameDescriptionSupported Arguments
RandomSchedulerThe next task is chosen at random.-
RepeatUntilNSuccessSchedulerThe current task is repeated until n successes are reached.repetitions
RepeatNSchedulerA task is repeated n-times.repetitions

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/", -- The path used to store events.
	counter_bounds = { 1, 5 }, --The outer bounds for counters used in some tasks. WARNING: A high value may result in glitchy behaviour.
	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, -- Enables/Disables events.
	enable_highlights = true, --Enables/Disables highlights. Care is taken to ensure that tasks are possible without them.
	logging_args = {
		log_path = vim.fn.stdpath("log") .. "/nvim-training/" .. os.date("%Y-%M-%d") .. ".log",
		display_logs = false, --Enables/Disables wether messages with the level 'log' should be printed. WARNING: Enabling his produces a lot of noise, but might be usefull for developers.
		display_warnings = true, --Enables/Disables wether messages with the level 'warning' should be printed.
		skip_all = false, -- Enables/Disables logging entirely. Usefull if you are worried about saving disk space.
	},
	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.
	scheduler_args = { repetitions = 5 }, --These args are used to configure all the available schedulers
	task_alphabet = "ABCDEFGabddefg,.", -- The alphabet of targets used in tasks like f,t etc.
})

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.

Goals

Non-Goals

On Contributions

Contributions are welcome! Any input is appreciated, be it a bug report, a feature request, or a pull request. Just open a issue and we shall get cooking :)

License

GPL