/neorg

Modernity meets insane extensibility. The future of organizing your life in Neovim.

Primary LanguageLuaGNU General Public License v3.0GPL-3.0

Neorg - An Organized Future

Requires Discord Paypal BuyMeACoffee Patreon

License Status


Life Organization Tool Written in Lua

IntroductionInstallationUsageKeybindsWiki

GIFS

Credits: Logo by Binx


The pain... it won't stop. After so much oppression from other text editors, it's time we fight back. With the introduction of lua, we will fight back.


Manage Your Life with Neovim-inspired Keybinds

Keybinds that make logical sense. Simply think, don't remember.


Jump To The Most Important Directories with Workspaces

Teleport to your favourite locations right away.


Configure Everything - Literally

Experience the power and configurability of Neorg's backend through modules and events.
Select only the code you want - throw everything else away.


TreeSitter Powered Editing

Feel more accurate edits thanks to Neorg's deeper understanding of your documents with Treesitter

(CURRENTLY WIP)

🌟 Introduction

Neorg is a tool designed to reimagine organization as you know it. Neo - new, org - organization. Grab some coffee, start writing some notes, let your editor handle the rest.

Why do we need Neorg? There are currently projects designed to clone org-mode from emacs, what is the goal of this project? Whilst those projects are amazing, it's simply not enough. We need our own, better solution - one that will surpass every other text editor. One that will give you all the bragging rights for using Neovim. Here's how we'll do it:

  • Revise the org format - Simple, very extensible, unambiguous. Will make you feel right at home. Org and markdown have several flaws, but the most notable one is the requirement for complex parsers. I really advise educating yourself on just how bad markdown can get at times; what if we told you it's possible to eliminate those problems completely, all whilst keeping that familiar markdown feel?

    Enter the .norg file format, whose base spec is almost complete. The cross between all the best things from org and the best things from markdown, revised and merged into one.

  • Keybinds that make sense - vim's keybind philosophy is unlike any other, and we want to keep that vibe. Keys form a "language", one that you can speak, not one that you need to learn off by heart.

  • Infinite extensibility - no, that isn't a hyperbole. We mean it. Neorg is built upon an insanely modular and configurable backend - keep what you need, throw away what you don't care about. Use the defaults or change 'em. You are in control of what code runs and what code doesn't run.

  • Logic. Everything has a reason, everything has logical meaning. If there's a feature, it's there because it's necessary, not because two people asked for it.

🔧 Installation

Installation may seem a bit daunting, however it's nothing you can't understand. If you really like to be in control, you can read exactly what the below code snippets do in the wiki. You can install through any plugin manager (it can even be vimscript plugin managers, as long as you're running Neovim version 0.5 or higher).

❗ NOTE: Neorg requires plenary.nvim to operate, so be sure to install it alongside Neorg!

  • Packer:

    use { 
        "vhyrro/neorg",
        config = function()
            require('neorg').setup {
                -- Tell Neorg what modules to load
                load = {
                    ["core.defaults"] = {}, -- Load all the default modules
                    ["core.norg.concealer"] = {}, -- Allows for use of icons
                    ["core.norg.dirman"] = { -- Manage your directories with Neorg
                        config = {
                            workspaces = {
                                my_workspace = "~/neorg"
                            }
                        }
                    }
                },
            }
        end,
        requires = "nvim-lua/plenary.nvim"
    }

    You can put the configuration directly in packer's config table (as shown above) or in a separate location within your config (make sure the configuration code runs after Neorg is loaded!):

    require('neorg').setup {
        -- Tell Neorg what modules to load
        load = {
            ["core.defaults"] = {}, -- Load all the default modules
            ["core.norg.concealer"] = {}, -- Allows for use of icons
            ["core.norg.dirman"] = { -- Manage your directories with Neorg
                config = {
                    workspaces = {
                        my_workspace = "~/neorg"
                    }
                }
            }
        },
    }

    Want to lazy load? Turns out that can be rather problematic. You can use the ft key to load Neorg only upon entering a .norg file. Here's an example:

    use { "vhyrro/neorg", ft = "norg", config = ... }

    However don't expect everything to work. TreeSitter highlights are known to fail, amongst other things. Neorg practically lazy loads itself - only a few lines of code are run on startup, these lines check whether the current extension is .norg, if it's not then nothing else loads. You shouldn't have to worry about performance issues.

    After all of that resource the current file and :PackerSync:

    PackerSync GIF

  • vim-plug:

    Plug 'vhyrro/neorg' | Plug 'nvim-lua/plenary.nvim'

    Afterwards resource the current file and to install plugins run :PlugInstall.

    You can put this initial configuration in your init.vim file:

    lua << EOF
        require('neorg').setup {
            -- Tell Neorg what modules to load
            load = {
                ["core.defaults"] = {}, -- Load all the default modules
                ["core.norg.concealer"] = {}, -- Allows for use of icons
                ["core.norg.dirman"] = { -- Manage your directories with Neorg
                    config = {
                        workspaces = {
                            my_workspace = "~/neorg"
                        }
                    }
                }
            },
        }
    EOF
🤖 For the latest and greatest check out the unstable branch

Setting up TreeSitter

As of right now, the TreeSitter parser is in its early stage. To install it, you want to run this code snippet before you invoke require('nvim-treesitter.configs').setup():

local parser_configs = require('nvim-treesitter.parsers').get_parser_configs()

parser_configs.norg = {
    install_info = {
        url = "https://github.com/vhyrro/tree-sitter-norg",
        files = { "src/parser.c" },
        branch = "main"
    },
}

Then run :TSInstall norg. If you want the parser to be more persistent across different installations of your config make sure to set norg as a parser in the ensure_installed table, then run :TSUpdate. Here's an example config, yours will probably be different:

require('nvim-treesitter.configs').setup {
	ensure_installed = { "norg", "haskell", "cpp", "c", "javascript", "markdown" },
}

Having a rare occurence where the parser doesn't work instantly? Try running :e. You'll only need to run it once in your lifetime, for some reason TS doesn't have issues after that.

Still not working? Uh oh, you're stepping on muddy territory. There are several reasons why a parser may not work right off the bat, however most commonly it's because of plugin loading order. Neorg needs nvim-treesitter to be up and running before it starts adding colours to highlight groups. With packer this can be achieved with an after = "nvim-treesitter" flag in your use call to Neorg. Not using packer? Make sure that Neorg's setup() gets called after nvim-treesitter's setup. If nothing else works then try creating an after/ftplugin/norg.lua file and paste your Neorg configuration there.

It's a bit hacky - it will unfortunately stay this way until we get first-class support in the nvim-treesitter repository. Sorry!

Setting up Compe

Neorg comes with a completion source that you can enable. Make sure to set neorg to true in the source table for nvim-compe:

source = {
    path = true,
    buffer = true,
    <etc.>,
    neorg = true
}

❓ Usage

Simply drop into a .norg file and start typing!

Usage Showcase

You may realize that we don't have an insane amount of frontend features just yet. This doesn't mean the plugin isn't capable of those things, it just means we're working on them! We tried focusing heavily on the backend first, but now that that is almost done we are actually starting work on features just for you:

  • Telescope.nvim integration for several things
  • TreeSitter parser (can be found here)
    • AST Generation
    • Custom highlight support
    • Custom folds (done, but not pushed yet)
    • Language injection (for code blocks)
    • Indentation engine based on the treesitter parser
    • Smarter todo item toggling with the TreeSitter AST

Everything you see above will be coming soon! Here's the things we do currently support:

  • Indentation (a tad too predictive, will be fixed with TreeSitter)
  • Toggling of TODO items with keybinds
  • Very configurable workspaces
  • nvim-compe completion source

It's all about the patience! We're gonna deliver all the juicy features ASAP. In the meantime you might be interested in reading the spec and familiarizing yourself with the new format :D

⌨️ Keybinds

Neorg comes with no keys bound by default. If you want to use all the default keys, you may want to modify the core.keybinds's configuration to generate them for you, here's how you would do it (note that this code snippet is an extension of the installation snippet):

use {
    "vhyrro/neorg",
    config = function()
        require('neorg').setup {
            -- Tell Neorg what modules to load
            load = {
                ["core.defaults"] = {}, -- Load all the default modules
                ["core.keybinds"] = { -- Configure core.keybinds
                    config = {
                        default_keybinds = true, -- Generate the default keybinds
                        neorg_leader = "<Leader>o" -- This is the default if unspecified
                    }
                },
                ["core.norg.concealer"] = {}, -- Allows for use of icons
                ["core.norg.dirman"] = { -- Manage your directories with Neorg
                    config = {
                        workspaces = {
                            my_workspace = "~/neorg"
                        }
                    }
                }
            },
        }
    end,
    requires = "nvim-lua/plenary.nvim"
}

You may actually want to change your keybinds though! Changing keybinds is a rather trivial task. The wiki entry for keybinds can be found here. It'll tell you the ins and outs of what you need to do :)

📓 Consult The Wiki

The wiki is the go-to place if you need answers to anything Neorg-related. Usage, Keybinds, User Callbacks, Modules, Events? It's all there, so we recommend you seriously go read it!

💻 Contributing

Contributions are always welcome and will always be welcome. You can check CONTRIBUTING.md if you wanna find out more. Have a cool idea? Want to implement something, but don't know where to start? I'm always here to help! You can always create an issue or join the discord and chat there.

📷 Extra GIFs

Language Injection

Get syntax highlighting for any language that's supported by treesitter.

Injection

Smort Syntax

Thanks to TreeSitter we can achieve a surprising amount of precision.

Trailing Modifier Showcas Comments

Completion

Neorg uses both TreeSitter and nvim-compe in unison to provide contextual completion based on your position in the syntax tree.

Completion Code Tag Completion

💜 Support

Love what I do? Want to see more get done faster? Want to support future projects of mine? Any sort of support is always heartwarming and fuels the urge to keep going ❤️. You can support me here:

💚 Credits

Massive shoutouts to the people who supported the project! These are: