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.
Keybinds that make logical sense. Simply think, don't remember.
Teleport to your favourite locations right away.
Experience the power and configurability of Neorg's backend through modules and events.
Select only the code you want - throw everything else away.
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.
IMPORTANT: Neorg is alpha software. We consider it stable however be prepared for changes and potentially outdated documentation. We are advancing fast and keeping docs up-to-date would be very painful.
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!
-
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
: -
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
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", "src/scanner.cc" },
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!
Neorg comes with its own API for completion. Users can then write integration modules to allow different plugins like nvim-compe
and nvim-cmp
to communicate with the Neorg core. By default no engine is specified. To specify one, make sure to configure core.norg.completion
:
["core.norg.completion"] = {
config = {
engine = "nvim-compe" | "nvim-cmp" -- We current support nvim-compe and nvim-cmp only
}
}
Make sure to set neorg
to true
in the source
table for nvim-compe:
source = {
path = true,
buffer = true,
<etc.>,
neorg = true
}
Make sure to enable the neorg
completion source in the cmp sources table:
sources = {
...
{ name = "neorg" }
}
And that's it!
Simply drop into a .norg file and start typing!
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 (see https://github.com/vhyrro/neorg-telescope)
- TreeSitter parser (can be found here)
- AST Generation
- Custom highlight support
- Custom folds
- Language injection (for code blocks)
- Smarter todo item toggling with the TreeSitter AST
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
Here are some things we are working on:
- Fully fledged GTD workflow (with @Danymat)
- Dynamically displaying and interacting with a Table of Contents (with @mrossinek)
- Better parsing of markup (bold, italic etc.)
- Overhauled indentation engine
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 :)
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!
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.
Get syntax highlighting for any language that's supported by treesitter.
Thanks to TreeSitter we can achieve a surprising amount of precision.
Neorg uses both TreeSitter and nvim-compe in unison to provide contextual completion based on your position in the syntax tree.
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:
Massive shoutouts to the people who supported the project! These are: