norbsidian

norbsidian

  1. Created: 
  2. Updated: 
  3. Reading Time: 4 minutes
  4. 📥 Download

This Is some expert tier exporting

So one thing I had a problem with is getting my neorg notes to export to obsidian without manually having to specify the directory that it will be exported to. So here is a recipe for a script that I wrote for my neovim config that does just that.

Pragma

We start offcreate some tables and load in some libraries

local norbsidian = {}
local builtins = require("telescope.builtin")
local pickers = require("telescope.pickers")

I am now going to define this here class and function

Now the NorbOptions class is a secret mousekatool to use later more on that later, but the norbsidian_export_template function just takes the inputs and gives us a pure function that will always generate the proper export.

---@class NorbOptions
---@field name string
---@field dir string must be the absolute path, no trailing slash | default: $HOME
-- make this next on optional
---@field env string nil must be a env_var that points to the directory, no trailing slash | default: $HOME
---

--- @param loc string
--- @return filename string
local function norbsidian_export_template(loc, filename)

 filename = loc .. filename .. ".md"
 return "Neorg export to-file " .. filename .. " markdown"
end

Telescope 🥰

Alright so now this is another function that will give a nice gui to choose a Norb to export our neorg file. dont worry we are getting there

norbsidian.telescope = function(selections, callback)
 assert(#selections > 0, "No selections provided") -- Ensure there are selections

 local pickers = require('telescope.pickers')
 local finders = require('telescope.finders')
 local conf = require('telescope.config').values
 local actions = require('telescope.actions')
 local action_state = require('telescope.actions.state')

 local opts = {}
 pickers.new(opts, {
  prompt_title = "Select a Export local",
  finder = finders.new_table {
   results = selections,
   entry_maker = function(entry)
	   return {
		   value = entry,                                  -- <-- -----------------\
		   display = entry.name,                           -- SAME THING            |
		   ordinal = entry.name,                           -- /--------------------/
	   }                                                   -- |
   end                                                     -- |
  },                                                          -- |
  sorter = conf.generic_sorter(opts),                         -- |
  attach_mappings = function(prompt_bufnr, _map)              -- |
   actions.select_default:replace(function()               -- |
	   local selection = action_state.get_selected_entry() -- |
	   actions.close(prompt_bufnr)                         -- |
	   callback(selection.value)
	   --               ^\____________________________________/
   end)
   return true
  end,
 }):find()
end

NORBS 👹

this is where you can add any amount of locations for you to export to. Give the name something recognizable and the directory the absolute path.

---@field Norbs table
norbsidian.Norbs = {
 {
  name = "Blog Posts",
  dir = "/home/adamkali/git/blog.kalilarosa.xyz/content/posts/",
 },
 {
  name = "Blog Configs",
  dir = "/home/adamkali/git/blog.kalilarosa.xyz/content/configs/"
 },
 {
  name = "Dailies",
  dir = "/mnt/c/Users/adam/Documents/notes/My_Second_Mind/05-Dailies/",
 },
 {
  name = "Work",
  dir = "/mnt/c/Users/adam/Documents/notes/My_Second_Mind/09-Work/",
 },
 {
  name = "Mindspace Docs"
 },
 {
  name = "Egg Cli Docs",
  dir = "/home/adamkali/projects/egg_cli/docs/"
 },
 {
  name = "Dotnvim Docs",
  dir = "/home/adamkali/git/dotnvim/docs/"
 }
}

The Export Function

Now we are going to define the export function that will call our pure norbsidian_export_template function. Right now i have it configurable to have either a directory or an env variable. However, I am sure you can see if you are using multiple computers you can define env variables on each computer and just point to the right location. This excersise is left to the reader ;) Or if neither are defined, just export the norg file to home. We use the secret mousekatool: NorbOptions, to get some intellisence when writing out the function.

---@param selection NorbOptions
norbsidian.export = function(selection)
 local filename = vim.api.nvim_buf_get_name(0)
 filename = string.sub(filename, 1, string.len(filename) - 5)
 local filename_path = vim.split(filename, "/")
 filename =  filename_path[#filename_path]
 -- vim.notify("Selected: "..vim.json.encode(filename_path) , vim.log.levels.TRACE, { title = "Norbsidian", timeout = 1000 })
 if selection.dir then
  norbsidian.export_loc = norbsidian_export_template(selection.dir, filename)
 elseif selection.env then
  norbsidian.export_loc = norbsidian_export_template(os.getenv(selection.env), filename)
 else
  vim.notify("No dir or env provided: Defaulting to $HOME", vim.log.levels.WARN, { title = "Norbsidian", timeout = 1000 })
  norbsidian.export_loc = norbsidian_export_template(os.getenv("HOME"), filename)
 end
 if norbsidian.export_loc then
  vim.cmd(norbsidian.export_loc)
 end
end

The Thing you call from a keybind

Okay so this is the function that will be called from a keybind, and then those other functions and one we have not met yet will be called. Get the selections an then the function callback will do the exporting!

norbsidian.get_selections = function()
 norbsidian.telescope(norbsidian.Norbs, function(selection)
  norbsidian.export(selection)
 end)
end
return norbsidian

Where do we put this file?

If you use the current standard for neovim configuration, you should have some form of this directory structure in you neovim config. You can just put it in the lua folder so that you can load the functions in a keymaps.lua in the after folder.

  after/
   plugin/
        󰣙 keymaps.lua 
  lua/
      plugins/
    󰣙 norbsidian.lua # Put here
󰂺  README.md
󰣙  init.lua

And here is an example of how you would call the function from a keybind.

local wk = require('which-key').add
local neorg_leader = "<space>n"
-- ... 
wk {
 { neorg_leader, expr = false, group = "[N]eorg", nowait = false, remap = false, icon = { icon = "", "@constructor.tsx" } },
 -- ...
 { neorg_leader .. 'e', require('norbsidian').get_selections, desc = "neorg configured export" },
}
-- ...

Try it out and let me know what you think! email me, or make an issue on this repo if you have any questions!