udayvir-singh/hibiscus.nvim

github github
fennel
star 28
stars
alert-circle 0
open issues
users 1
subscribers
git-branch 1
forks
CREATED

2022-03-31

UPDATED

4 days ago


Hibiscus.nvim

:hibiscus: Highly opinionated macros to elegantly write your neovim config.

Companion library for tangerine, but it can also be used standalone.

Neovim version

Rational

  • :candy: Syntactic eye candy over hellscape of lua api
  • :tanabata_tree: Provides missing features in both fennel and nvim api

Installation

  • Create file plugin/1-tangerine.lua to bootstrap hibiscus: ```lua
    • ~/.config/nvim/plugin/tangerine.lua

-- pick your plugin manager, default [standalone] local pack = "tangerine" or "packer" or "paq"

local function bootstrap (url) local name = url:gsub(".*/", "") local path = vim.fn.stdpath [[data]] .. "/site/pack/".. pack .. "/start/" .. name

if vim.fn.isdirectory(path) == 0 then
    print(name .. ": installing in data dir...")

    vim.fn.system {"git", "clone", "--depth", "1", url, path}

    vim.cmd [[redraw]]
    print(name .. ": finished installing")
end

end

bootstrap "https://github.com/udayvir-singh/hibiscus.nvim"


- Require a macro library at top of your modules:
```fennel
; require all macros
(require-macros :hibiscus.core)
(require-macros :hibiscus.vim)

; require selected macros
(import-macros {: fstring} :hibiscus.core)
(import-macros {: map!}    :hibiscus.vim)

:tada: now start using these macros in your config


Packer

You can use packer to manage hibiscus afterwards:

(require-macros :hibiscus.packer)

(packer-setup)

(packer
  (use! :udayvir-singh/hibiscus.nvim))

Paq

(local paq (require :paq))

(paq {
  :udayvir-singh/hibiscus.nvim
})

Packer Macros

(require-macros :hibiscus.packer)

packer-setup

Bootstraps packer and calls packer.init function with {opts?}.

packer

Wrapper around packer.startup function, automatically adds packer to plugin list and syncs it.

use!

Much more lisp friendly wrapper over packer.use function.

Examples:
(packer
  (use! :udayvir-singh/tangerine.nvim)

  (use! :udayvir-singh/hibiscus.nvim
        :requires ["udayvir-singh/tangerine.nvim"])

  (use! :some-plugin
        :module "path/module" ; automatically requires that module
        ...))

Neovim Macros

(require-macros :hibiscus.vim)
; or
(import-macros {: augroup!} :hibiscus.vim)

keymaps

map!

Defines vim keymap for the given modes from {lhs} to {rhs}

Arguments:

{args} can contain the following values:

; modes |                   options                           |
[ nivcx  :remap :verbose :buffer :nowait :expr :unique :script ]
  • verbose: opposite to silent
  • remap: opposite to noremap
Examples:
;; -------------------- ;;
;;      VIMSCRIPT       ;;
;; -------------------- ;;
(map! [n :buffer] :R "echo &rtp")
(map! [n :remap]  :P "<Plug>(some-function)")


;; -------------------- ;;
;;        FENNEL        ;;
;; -------------------- ;;
(map! [nv :expr] :j
      '(if (> vim.v.count 0) "j" "gj"))

(local greet #(print "Hello World!"))

(map! [n] :gH 'greet) ; optionally quote to explicitly indicate a function

autocmds

augroup!

Defines autocmd group of {name} with {cmds} containing [args pattern cmd] chunks

Arguments:

{args} can contain the following values:

[ :nested :once BufRead Filetype ...etc ]
Examples:
;; -------------------- ;;
;;      VIMSCRIPT       ;;
;; -------------------- ;;
(augroup! :spell
  [[FileType] [markdown gitcommit] "setlocal spell"])

(augroup! :MkView
  [[BufWinLeave
    BufLeave
    BufWritePost
    BufHidden
    QuitPre :nested] ?* "silent! mkview!"]
  [[BufWinEnter] ?* "silent! loadview"])


;; -------------------- ;;
;;        FENNEL        ;;
;; -------------------- ;;
(augroup! :highlight-yank
  [[TextYankPost] * #(vim.highlight.on_yank {:timeout 80})])

(local greet #(print "Hello World!"))

(augroup! :greet
  [[BufRead] *.sh '(print :HOLLA)]
  [[BufRead] *    'hello] ; remember to quote functions to indicate they are callbacks

commands

command!

Defines user command {lhs} to {rhs}

Arguments:

{args} can contain the same opts as nvim_create_user_command:

[
  :bar      <boolean>
  :bang     <boolean>
  :buffer   <boolean>
  :register <boolean>
  :range    (or <boolean> <string>)
  :addr     <string>
  :count    <string>
  :nargs    <string>
  :complete (or <string> <function>)
]
Examples:
;; -------------------- ;;
;;      VIMSCRIPT       ;;
;; -------------------- ;;
(command! [:range "%"] :Strip "<line1>,<line2>s: \\+$::e")


;; -------------------- ;;
;;        FENNEL        ;;
;; -------------------- ;;
(fn greet [opts]
  (print :hello opts.args))

(command! [:nargs 1 :complete #["world"]] :Greet 'greet) ; quoting is optional

(command! [:bang true] :Lhs #(print $.bang))

misc

exec

Converts [cmd] chunks in {cmds} to valid vim.cmd call

Example:
(exec [
  [:set "nowrap"]
  [:echo "hello" "world"]
])

concat

Concats strings in {list} with {sep} at compile time

Examples:
(concat ["hello" "foo"] " ") ; -> "hello foo"

(concat ["hello" "foo" var] " ") ; -> "hello foo" .. " " .. var

vim options

set!

Works like command :set, sets vim option {name} to {val}

(set! nobackup)
(set! tabstop 4)

(each [_ opt (ipairs ["number" "rnu"])]
      (set! opt true))

set+

Appends {val} to string-style option {name}

(set+ wildignore "*.foo")

set^

Prepends {val} to string-style option {name}

(set^ wildignore ["*.foo" "*.baz"])

rem!

Removes {val} from string-style option {name}

(rem! wildignore "*.baz")

color!

Sets vim colorscheme to {name}

(color! desert)

variables

g!

Sets global variable {name} to {val}.

(g! mapleader " ")

b!

Sets buffer scoped variable {name} to {val}.

(b! gretting "Hello World!")

Core Macros

(require-macros :hibiscus.core)
; or
(import-macros {: fstring} :hibiscus.core)

fstring

(fstring {str})

wrapper around string.format, works like javascript's template literates

  • ${...} is parsed as variable
  • $(...) is parsed as fennel code
Examples:
(local name "foo")
(fstring "hello ${name}")

(fstring "${name}: two + four is $(+ 2 4).")

pretty print

(dump {...})

pretty prints {...} into human readable form

general

(or= {x} ...)

checks if {x} is equal to any one of {...}

checking

(nil? {x})

checks if value of {x} is nil

(boolean? {x})

checks if {x} is of boolean type

(string? {x})

checks if {x} is of string type

(number? {x})

checks if {x} is of number type

(odd? {int})

checks if {int} is of odd parity

(even? {int})

checks if {int} is of even parity

(function? {x})

checks if {x} is of function type

(table? {x})

checks if {x} is of table type

(list? {tbl})

checks if {tbl} is valid list / array

(empty? {tbl})

checks if {tbl} has length of 0

unary operators

(inc {int})

increments {int} by 1 and returns its value

(++ {var})

increments variable {var} by 1 and returns its value

(dec {int})

decrements {int} by 1 and returns its value

(-- {var})

decrements variable {var} by 1 and returns its value

string concat

(append {var} {str})

appends {str} to variable {var}

(tappend {tbl} {key} {str})

appends {str} to {key} of table {tbl}

(prepend {var} {str})

prepends {str} to variable {var}

(tprepend {tbl} {key} {str})

prepends {str} to {key} of table {tbl}

table merging

(merge-list {list1} {list2})

merges all values of {list1} and {list2} together

(merge {tbl1} {tbl2})

merges {tbl1} and {tbl2}, correctly appending lists

(merge! {var} {tbl})

merges values of {tbl} onto variable {var}

End Credits

  • aniseed: for introducing me to fennel
  • zest: for inspiring hibiscus.vim macros