(import-macros {: set!} :nvrc.macro.set)
(local {: setup
        : mapping
        :config {: compare : disable}
        : ConfirmBehavior
        : visible
        : select_next_item
        : select_prev_item} (require :cmp))
(local under-compare (require :cmp-under-comparator))
(local clangd-score (require :clangd_extensions.cmp_scores))

(set! completeopt "menuone,noselect")

(local icons {:Text "(t)"
              :Method "(m)"
              :Function "(f)"
              :Constructor "(C)"
              :Field "(s)"
              :Variable "(v)"
              :Class "(C)"
              :Interface "(i)"
              :Module "(m)"
              :Property "(p)"
              :Unit "(u)"
              :Value "(v)"
              :Enum "(e)"
              :EnumMember "(e)"
              :Keyword "(k)"
              :Snippet "(S)"
              :Color "(R)"
              :Reference "(r)"
              :Constant "(c)"
              :Struct "(s)"
              :Event "(e)"
              :Operator "(o)"
              :TypeParameter "(T)"
              :File "(F)"
              :Folder "(F)"
              })

(setup {:snippet {:expand (fn [args]
                                (vim.snippet.expand args.body))}
            :formatting {:format (fn [entry vim-item]
                                   (set vim-item.kind
                                        (string.format "%s %s"
                                                       (. icons vim-item.kind)
                                                       vim-item.kind))
                                   (set vim-item.menu
                                        (. {:nvim_lsp "[LSP]"}
                                           entry.source.name))
                                   vim-item)}
            :mapping {:<C-p> (mapping.select_prev_item)
                      :<C-n> (mapping.select_next_item)
                      :<C-d> (mapping.scroll_docs (- 4))
                      :<C-f> (mapping.scroll_docs 4)
                      :<C-Space> (mapping.complete)
                      :<C-e> (mapping.close)
                      :<up> disable
                      :<down> disable
                      :<CR> (mapping (mapping.confirm {:behavior ConfirmBehavior.Replace
                                                               :select false}) [:i :c])
                      :<Tab> (mapping {:i (fn [fallback]
                                              (if (visible) (select_next_item)
                                              (vim.snippet.active {:direction 1}) (vim.snippet.jump 1)
                                              (fallback)))})
                      :<S-Tab> (mapping {:i (fn [fallback]
                                                  (if (visible) (select_next_item)
                                                  (vim.snippet.active {:direction -1}) (vim.snippet.jump -1)
                                                  (fallback)))})}
            :sources [{:name :nvim_lsp}]
            :sorting {:comparators [compare.offset
                                    compare.exact
                                    clangd-score
                                    compare.score
                                    under-compare.under
                                    compare.kind
                                    compare.sort_text
                                    compare.length
                                    compare.order]}})