Better Hovers

Luwu's hovers target luwu-lsp, the language server we maintain alongside the language, and the Luwu VSCode/Code-OSS extension. Every hover on this page was copied unedited from luwu-lsp: point at a dotted underline to see one, or tap it on a touch screen.

What's improved

Classes at a glance

Hover a class's name to see how to build one and what it holds, private members included. Hover an object of the class and you see only what you can use from outside.

--- A cat that can be fed.
class Cat(public const name: string, private hunger = 3)
    --- Feeds the cat, so it's less hungry.
    public function feed(self, amount: number = 1): Cat
        self.hunger = math.max(self.hunger - amount, 0)
        return self
    end
end

const nyla = Cat("Nyla")
nyla:feed(2)

Access specifiers like public and private explain the rules they bring.

Traits

A class's hover marks the members it gets from a trait, like -- from Health. A trait method returning Self shows the class you called it on: ada is a Player, not just Health.

--- Something that takes damage and can run out of health.
trait Health
    expect max_health: number
    health = 100

    --- Takes `amount` off [Health], never going below zero, like [math.max] would.
    function damage(self, amount: number): Self
        self.health = math.max(self.health - amount, 0)
        return self
    end
end

--- A player in the arena.
class Player(public const name: string) implements Health
    public max_health = 150
end

const ada = Player("Ada"):damage(30)
print(ada.health)

Doc comments link what they mention. [Health] jumps to the trait, and [math.max] links to the library docs.

Keywords explain themselves

Every keyword has a hover, Luwu's keywords included: do expressions, give and when. The same word gets a different hover when it means something else, like if as an expression.

const prices: { [string]: number? } = { apple = 1.25, pear = 0.8 }

const total = do
    local sum = 0
    for _, fruit in { "apple", "kiwi", "pear" } when const price = prices[fruit] do
        sum += price
    end
    give sum

print(if total > 2 then "pricey" else "cheap")

Refinements

A function that narrows a type says so. Hover class.implements to see what it refines, then hover the refined value to see what it became.

trait Named
    expect name: string
end

class Cat(name: string) implements Named end

--- The name of anything that has one.
const function name_of(thing: unknown): string?
    if class.implements(thing, Named) then
        return thing.name
    end
    return nil
end

const function tag(name: literal<string>): string
    return `<{name}>`
end

print(name_of(Cat("Nyla")), tag("main"))

literal<T> and the other type functions explain themselves too.

More or less detail

In your editor, a hover can show more or less. These commands change it for the rest of the session:

The luwu.hover.verbosity setting picks where each session starts.