Skip to content

Latest commit

 

History

History
157 lines (87 loc) · 10.6 KB

faq.md

File metadata and controls

157 lines (87 loc) · 10.6 KB
title description author categories created version
FAQ
Frequently asked questions about Nyoom
shaunsingh
docs
2022-12-09
0.1.0

General

This is the section for questions on how Nyoom works, is it for you, how does it compare to other configurations, and how can you get started.

Is Nyoom for me?

If you don't mind tinkering with lisps, and don't want to start entirely from scratch, then of course! However, if you prefer something that is truly yours, don't mind a little boilerplate here and there, or don't like fennel, checkout some other configurations!

How does nyoom compare to (insert premade configuration)

  • Unlike quite a few premade configurations, Nyoom allows for a high degree of extensibility and customizability, while remaining performant.
  • Nyoom puts a focus on integration. This means that enabled modules will enable new features and optimizations in other modules (e.g. enabling tools.tree-sitter will enable tree-sitter based folding with nvim-ufo )
  • Nyoom enhances rather than replaces Neovim's features and ideals.

How does Nyoom work?

At its core Nyoom is just plain fennel with a few niceties. Everything within core/ is quite standard. It provides a set of opinionated defaults along with optimizations to speed up startup and it provides a standard library to simplify your code.

Nyoom takes heavy advantage of fennel's compile-time macro functionality, which builds the core of Nyoom's module system and package management system. Nyoom's module system allows for clever interactions between sets of plugins defined into modules, a concept familiar to users of doom emacs. However, emacs-lisp isn't fennel and thats where Nyoom's magic starts

A list of modules is defined in modules.fnl using the nyoom! macro. The purpose of the nyoom! macro is to take the list of modules, formatted similar to doom's plist, and turn it into something neovim can read. It does at compile-time by

  1. loading all of the enabled modules into a registry
  2. including (inline require) all of the enabled modules into packages.fnl. This allows Nyoom's package management system to module dependencies, and allows for more advanced macros that can pre-compute code determined across multiple modules.
  3. compiling all of the enabled modules. As we loaded the list of modules and several macros in our include pass, we can use this information to conditionally compile code using macros (nyoom-module-p!), compile warnings (nyoom-ensure-module!) and more.

To aid with the module system, Nyoom also wraps packer.nvim with a few macros with similar syntax to use-package. This wrapper adds additional keys (such as :nyoom-module) that aid in the definition and creation of modules.

All of these and a bit more comes together to create the nyoom cli. Once again utilizing that compile time magic, nyoom sync can precompute your enabled plugins, modules, and integrations, and compile that into a single file with lazy loaded definitions

Why is startuptime important?

Why go so far to ensure Nyoom starts up quickly? After all, some of you keep the same nvim instance open for weeks at a time.

Startuptime gets a disproportional amount of attention because it’s the first thing Nyoom’s users notice

In most configurations, It’s left to the user to know or care about optimal lazy loads, autocommads, and to implement them, but that’s a lot to ask when the problem domain is so vast, esoteric, and a moving target (with a high cost-to-benefit). Who has the time to inspect, much less fix, all their packages? And maintain that effort across Emacs or package updates? It’s easier to just install all your plugins and leave it be, which is what people do.

However, when a user first opens up nyoom, the startuptime is the first thing they're greated with. Startuptime adds up quickly. With one or two plugins sure, it only adds a few milliseconds here or there, but add support for debugging, profiling, language servers, and several languages and neovim can easily take multiple seconds to get going.

Users shouldn't be scared of enabling modules. I shouldn't be scared of affecting users by adding more. By ensuring that the core modules and base of Nyoom are loaded and compiled optimally, everything is left in the hands of the user. It’s left to the user to know or care about lazy loading, auto commands, autoloading, and how to implement them in their own configurations, and by all means use the use-package! macro to configure your plugins as well, even if its a bit slower than doing it yourself.

By making it easy to properly manage packages, I hope users will have more incentive to keep neatly loaded neovim configurations

Rather than startuptime, runtime performance is a bigger priority, though the two rarely stray far from each other. Each release of Nyoom is heavily profiled to ensure all modules and core code aren't bogging down your workflow

Why fennel?

Fennel is a programming language that brings together the speed, simplicity, and reach of Lua with the flexibility of a lisp syntax and macro system. Macros are how lisps accomplish metaprogramming. You’ll see a lot of people treat lisp macros with a kind of mystical reverence. While several other languages have macro systems, the power of macros in lisps stem from allowance of lisps to you to write programs using the same notation you use for data structures. Remember: code is data, and we just need to manipulate data.

While people largely exaggerate the usefulness of macros, there are a few places where macros shine, and configurations are one of them. Utilizing macros, we can essentially create our own syntax at compile-time. For example, lets take a look at the set! macro I've used. set! is used for vim.opt options. For example, (set! mouse :a) expands to vim.opt["mouse"]="a". If a string or number isn't passed to set!, it will assume true. e.g. (set! list) will expand to vim.opt["list"]=true. Similarly if the option starts with no, it will assume false e.g. (set! noru) will expand to vim.opt["ru"]=false. Of course, this is a very simple example and macros can get very, very complex but you get the idea.

Fennel also fixes quite a few of the quirks of lua:

  • the paren-first syntax is more regular
  • being a lisp, lua's issues of statements and issues of operator precedence are solved
  • fennel makes it super difficult to use lua globals on accident.
  • seperates syntax sequential and key/value tables, while lua uses curly braces for both. Plus a lot of nice syntax for dealing with variables and data in general

With the macros provided, you can configure neovim just as easily, or dare I say easier than you can with Lua or vimscript, while retaining the performance benefits of LuaJIT.

Learning fennel

For most people, chances are you haven't even heard of fennel before. So where should you start?

  1. Read through the Documentation
  2. Install fennel yourself! (Skip the part where it goes over adding fennel support to your editor, that's what this project is for :p). A copy of fennel is provided within neovim through hotpot.nvim
  3. Learn lua first. I recommend reading through the Neovim lua guide as well.
  4. Learn fennel
  5. Go over the Style guide.
  6. Learn macros.

If you have trouble configuring neovim to your needs, check out Antifennel to see how lua code compiles back to fennel! However, the generated code isn't always the cleanest, so its recommend you use it as a last resort. If you need any help, feel free to join the Nyoom discord server!

Fiddling with Fennel code

Feel free to open the Scratch buffer (:Scratch) to get a nice working eviornment to start with

While fiddling with the config, you can check if the things are not broken yet:

  1. evaluate form you just written (<localleader>er, by default <space>mer)
  2. evaluate buffer (<localleader>eb, by default <space>meb)
  3. live-compile (reflect) your changes with <leader>hr
  4. In reflect mode, live-evaluate your code with <leader>hx

Take a look at :h conjure for more

Why is the project named Nyoom?

For fun, no major reason really. Also somewhat goes well with the mantras Nyoom lives by.

How do I ...

This is the section for learning the basics of how to get the most out of Nyoom.

Update my plugins/modules?

As you've probably noticed, all the main Packer commands such as :PackerSync don't work in Nyoom. Instead, its recommend to use the nyoom cli command, a small shell script that lives in bin/.

Nyoom ships with a lockfile containing pinned commits for all of the plugins it uses. You can run nyoom sync to syncronize your plugins with the provided lockfile.lua, and to install/remove plugins depending on what modules you have enabled.

If you'd like to live life on he edge, you can run nyoom lock to update the lockfile, then run nyoom sync to update your plugins to their latest respective commits.

Find out what version of Nyoom I'm running?

nyoom sync will also spit out the commit of Nyoom you're using. As Nyoom uses git under the hood, any and all git commands will works just as well. You can use nyoom upgrade to git pull to the latest version of Nyoom.

Turn Nyoom into an "IDE" ?

Enabling a language module (e.g. lang.rust) will do the following:

  1. Install its tree-sitter parser with tools.tree-sitter
  2. Install its language server with tools.lsp
  3. Set it up for debugging with tools.debugger if available
  4. Register its tooling under mason to auto-install with tools.mason
  5. Set up a minor GUI with ui.hydra if available
  6. Set up recomended formatters and linters if available
  7. Install any language-specific plugins (e.g rust-tools and crates.nvim).

If you find support for a language lacking, or want to add a plugin/integration to a module, feel free to pull-request or open an issue about it!

Update nyoom?

You can use the nyoom upgrade command if you'd like a fancy prompt with a nice diff. As Nyoom uses git under the hood, you can also simply git pull.

Add packages?

Refer to the getting_started guide for instructions on how to add packages.

Add configuration?

Refer to the getting_started guide for instructions on how to add configuration. You can also take a look at examples.md to check out examples of configurations others have done

Contributing

Refer to contributing.md for information on how to contribute