litlua

package module
v0.0.0-...-713e2d3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 8, 2025 License: MIT Imports: 12 Imported by: 0

README

LitLua v0.0.2

LitLua is a literate programming tool inspired by Emacs designed to support better formating of lua based configuration. It enables you to write and maintain well-documented Lua configurations by transforming literate Markdown docs into executable Lua code.

🚨 This is a very early work in progress, so there may be edge cases and bugs not found yet - until V1 its recommend to use a VCS to ensure your config is not overwritten :) 🚨

Features

  • 📝 Markdown-Based: Write your configurations in familiar Markdown format
  • 🔍 Code Block Extraction: Automatically extracts and processes Lua code blocks
  • 💾 Redundancy Precautions: Automatically creates backups of configuration files before overwriting
  • 🛠 Simple CLI Interface: Easy to use optional command-line tooling
  • 📦 LSP Support!: Powered by LuaLS, LitLua provides built-in LSP support for your Markdown->Lua configurations

Here is a small demo of Litlua handling nvim configuration. You can find the Nvim configuration repo using Litlua here: https://github.com/jwtly10/config.nvim

https://github.com/user-attachments/assets/f928c89b-c42f-45da-8e7c-8c428b162882

Why?

After spending some time with Emacs, I could see the value of having litterate configurations for more than just the emacs ecosystem - configurations being just a readable, documentation first markdown file, that will be 'transpiled' into the expected format!

Check out Examples for a small showcase of what LitLua is about.

I've re-written some of kickstart.nvim in markdown and used LitLua to generate the lua files, you can see the same for an example wezterm config - .wezterm.lua is the transpiled file, *.litlua.md is the markdown source.

If you have the LitLua LSP installed, you will also get LSP support for the markdown files, so you can hover over functions and go to definitions etc.

Roadmap

  • Basic Markdown to Lua conversion to SFO
  • Built in LitLua LSP support
  • Live file compilations (via LSP)
  • Support compiling litlua.md files on Neovim startup
  • Single file to multiple file output (master file, into multiple configuration .lua files)
  • 'Tagging' of code blocks for easy reference and linking
  • Hot swapping configuration management - switch between versions of configurations

Generally the idea is this should seamlessly integrate into existing lua based configuration setups, such as Neovim, and work alongside existing lua files. With as much work done via the LSP as possible, to create a seamless experience and be editor agnostic.

Installation

These installation instructions assume you have go installed - https://go.dev/doc/install

There are 2 installations available, the LSP and the CLI.

The LSP is editor agnostic and will try to take care of all compilation while the LSP is running. On save/exit, the lua file will be generated, given output pragma options are set (see below FileFormat).

The CLI contains a subset of the LSP features, and is more suited directory or one off conversions, or for CI/Scripting support

It is recommend you read here before installing and getting started: LSP.md

You can install both with:

go install github.com/jwtly10/litlua/cmd/...@latest
LSP Installation
go install github.com/jwtly10/litlua/cmd/litlua-ls@latest
CLI Installation
go install github.com/jwtly10/litlua/cmd/litlua@latest
Build from source
# Clone the repo
git clone https://github.com/jwtly10/litlua.git
cd litlua

# Installing the LSP from source
go build -o litlua-ls cmd/litlua-ls/main.go
# Move the LSP binary to your PATH  
mv litlua-ls /usr/local/bin  

# Installed the CLI
go build -o litlua cmd/litlua/main.go
# Move the CLI binary to your PATH  
mv litlua /usr/local/bin  

More installation options will be available in the future.

File Format

LitLua processes custom Markdown files (.litlua.md) containing Lua code blocks. Here's an example:

<!-- @pragma output: init.lua -->

# Neovim Telescope Configuration

Our telescope setup with detailed explanations.

```lua
require('telescope').setup({
    defaults = {
        mappings = {
            i = {
                ['<C-u>'] = false,
                ['<C-d>'] = false,
            },
        },
    },
})
```

This configures the basic telescope behavior. Let's add some keymaps:

```lua
-- File browsing
vim.keymap.set('n', '<leader>ff', 
    require('telescope.builtin').find_files)

-- Live grep
vim.keymap.set('n', '<leader>fg', 
    require('telescope.builtin').live_grep)
```

LitLua will:

  1. Parse the Markdown document
  2. Extract pragma directives at the top of the file, such as output:init.lua
  3. Extract Lua code blocks
  4. Generate a clean Lua file with all the code to the output file init.litlua.lua
  5. Create a backup of any existing output file

Note: The output file will be init.litlua.lua for safety reason - please see Configuration for details

Usage

LSP

See LSP.md for more information on the LSP support and usage.

CLI
Basic usage:

Converts .litlua.md markdown document to lua file (based on the output pragma) else defaults to original file name with .litlua.lua extension:

litlua <your_configuration_file_with_lua_src.litlua.md>

Enable debug logging during conversion:

litlua -debug <your_configuration_file_with_lua_src.litlua.md>

Converts a directory, looking for.litlua.md markdown documents to transform to lua files as above.

litlua  ./path/to/config/files

Example Output:

~/Projects/litlua ❯ litlua ./examples/                                                                                 22.11.0  1.23.3

🚀 Compilation is running:
  📄 Path     : ./examples/

Compilation Results:
Source                                                                 Output
--------------------------------------------------------------------------------------------------------------
lsp_example.litlua.md                                                  compiled.litlua.lua
wezterm/wezterm_configuration.litlua.md                                wezterm/.wezterm.lua
kickstart.nvim/kickstart_configuration.litlua.md                       kickstart.nvim/output.litlua.lua
--------------------------------------------------------------------------------------------------------------

✨ Compilation complete! Processed 3 files

Output

LitLua generates a single Lua file containing all the extracted code blocks, maintaining their original order as specified in the Markdown source.

Configuration

Litlua will always default to outputing files with a .litlua.lua extension. Even if you have specified something.lua. This is done as a safety precaution to prevent the case of accidently updating a file you did not back up.

For most usecases, this is not a problem, as .*.lua will ensure the filetype still has all usual properties of a lua file.

In order to FORCE the output path you can use:

<!-- @pragma output: init.lua -->
<!-- @pragma force: true -->

Which WILL output a file init.lua. Please use this at your own risk.

By default, LitLua will generate the output file in the same directory as the input file, with a .litlua.lua extension. You can customize the output path using pragmas at the start your document:

NOTE: The file path will ALWAYS be relative to the input file

<!-- @pragma output: init.lua -->

# My Neovim Configuration
...

Development

Setup locally
git clone https://github.com/jwtly10/litlua
go test ./... -v

Contributing

Contributions are welcome! Please feel free to submit a Pull Request or Issue.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

View Source
const VERSION = "v0.0.2"

Variables

This section is empty.

Functions

This section is empty.

Types

type BackupManager

type BackupManager struct {
}

BackupManager is a helper struct to manage backups of output files

This is a short term solution to ensuring that the output file is not overwritten by accident.

func NewBackupManager

func NewBackupManager() *BackupManager

func (*BackupManager) CreateBackupOf

func (bm *BackupManager) CreateBackupOf(absFilePath string) (absBackedUpFile string, err error)

CreateBackupOf creates a backup of an absolute file path if it already exists

Returns the abs path to the backup file, or an empty string if no backup was created

type CodeBlock

type CodeBlock struct {
	// The code that was parsed from the markdown source
	Code string
	// The original markdown source code file where the code block extracted from
	Source string
	// The position of the code block in the source file
	Position Position
}

type Document

type Document struct {
	// Metadata about the source file
	Metadata MetaData
	// Document-level pragmas controlling extraction options
	Pragmas Pragma
	// The extracted code blocks
	Blocks []CodeBlock
}

Document represents a parsed markdown document containing pragmas and code blocks, and any other required metadata about the source file

type MetaData

type MetaData struct {
	// The absolute file path of the markdown source file
	AbsSource string
}

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

func NewParser

func NewParser() *Parser

func (*Parser) ParseMarkdownDoc

func (p *Parser) ParseMarkdownDoc(r io.Reader, md MetaData) (*Document, error)

ParseMarkdownDoc parses Markdown content into a document

It pulls out compilation pragmas and lua code blocks from the content and returns a Document

type Position

type Position struct {
	StartLine int
	// Note the end line always contains the “` of the code block
	EndLine int
}

Position represents the start and end line numbers of a code block in the source file

type Pragma

type Pragma struct {
	// The lua file output directory, relative to the source markdown file
	Output string
	// Force the output file type directly (to not convert to .litlua.lua)
	Force bool
	// Internal flag for additional debugging output
	Debug bool
}

type PragmaKey

type PragmaKey string
const (
	PragmaOutput PragmaKey = "output"
	PragmaForce  PragmaKey = "force"
	PragmaDebug  PragmaKey = "debug"
)

type WriteMode

type WriteMode int
const (
	// ModePretty Writes with headers and formatting
	ModePretty WriteMode = iota
	// ModeShadow Writes preserving line positions for LSP
	ModeShadow
)

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer writes a parsed Markdown Document to the configured output writer

func NewWriter

func NewWriter(mode WriteMode) *Writer

NewWriter creates a new Writer with the specified write mode WriteMode

func (*Writer) WriteContent

func (w *Writer) WriteContent(doc *Document, out io.Writer) error

func (*Writer) WriteHeader

func (w *Writer) WriteHeader(out io.Writer, metadata WriterMetadata) error

type WriterMetadata

type WriterMetadata struct {
	Version   string
	AbsSource string
	Generated string // Pre-formatted timestamp string
}

WriterMetadata contains metadata for file generation

Directories

Path Synopsis
cmd
litlua command
litlua-ls command
internal
cli
lsp

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL