about summary refs log tree commit diff
path: root/fnl/nvrc/utils.fnl
blob: 6812c0cddc48cea295673cf2047efaa384738877 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
(fn tbl? [x]
  (= :table (type x)))

(fn count [xs]
  (if (tbl? xs) (table.maxn xs)
      (not xs) 0
      (length xs)))

(fn run! [f xs]
  "Execute the function (for side effects) for every xs."
  (when xs
    (let [nxs (count xs)]
      (when (> nxs 0)
        (for [i 1 nxs]
          (f (. xs i)))))))

(fn reduce [f init xs]
  "Reduce xs into a result by passing each subsequent value into the fn with
  the previous value as the first arg. Starting with init."
  (var result init)
  (run! (fn [x]
                (set result (f result x))) xs)
  result)

(fn merge! [base ...]
  (reduce (fn [acc m]
                  (when m
                    (each [k v (pairs m)]
                      (tset acc k v)))
                  acc) (or base {}) [...]))

(fn merge [...]
  (merge! {} ...))

(fn lsp_fidget []
  "Simple implementation of LSP fidget. Returns current LSP status with a spinner"
  (let [lsp (. (vim.lsp.util.get_progress_messages) 1)]
    (when lsp
      (let [msg (or lsp.message "")
          percentage (or lsp.percentage 0)
          title (or lsp.title "")
          spinners {1"⠋" 2 "⠙" 3 "⠹" 4 "⠸" 5 "⠼" 6 "⠴" 7 "⠦" 8 "⠧" 9 "⠇" 10 "⠏"}
          success-icon "^.^!"
          ms (/ (vim.loop.hrtime) 1000000)
          frame (% (math.floor (/ ms 120)) (length spinners))]
      (when (>= percentage 70)
        (let [ertn [(string.format " %%<%s %s %s (%s%%%%) "
                                   success-icon
                                   title msg
                                   percentage)]]
          (lua "return (table.unpack or _G.unpack)(ertn)")))
      (let [ertn [(string.format " %%<%s %s %s (%s%%%%) "
                                 (. spinners
                                    (+ frame 1))
                                 title msg
                                 percentage)]]
        (lua "return (table.unpack or _G.unpack)(ertn)"))))) "")

(fn will_it_fit [width winid]
  "Returns whether this module will fit in the given width"
  (> (vim.api.nvim_win_get_width (or (tonumber winid) 0)) width))

(fn close_buf [force]
  "ojroques/nvim-bufdel 'BSD-2'"
  (let [opts {:next :cycle :quit false}]
    (fn switch-buffer [windows buf]
      (let [cur-win (vim.fn.winnr)]
        (each [_ winid (ipairs windows)]
          (set-forcibly! winid (or (tonumber winid) 0))
          (vim.cmd (string.format "%d wincmd w" (vim.fn.win_id2win winid)))
          (vim.cmd (string.format "buffer %d" buf)))
        (vim.cmd (string.format "%d wincmd w" cur-win))))

    (fn get-next-buf [buf]
      (var next (vim.fn.bufnr "#"))
      (when (and (= opts.next :alternate) (= (vim.fn.buflisted next) 1))
        (lua "return next"))
      (for [i 0 (- (vim.fn.bufnr "$") 1) 1]
        (set next (+ (% (+ buf i) (vim.fn.bufnr "$")) 1))
        (when (= (vim.fn.buflisted next) 1)
          (lua "return next"))))

    (local buf (vim.fn.bufnr))
    (when (= (vim.fn.buflisted buf) 0)
      (vim.cmd :close)
      (lua "return "))
    (when (< (length (vim.fn.getbufinfo {:buflisted 1})) 2)
      (when opts.quit
        (if force (vim.cmd :qall!) (vim.cmd "confirm qall"))
        (lua "return "))
      (local (term _)
             (pcall (fn []
                      (vim.api.nvim_buf_get_var buf :term_type))))
      (when term
        (vim.cmd (string.format "setlocal nobl" buf))
        (vim.cmd :enew)
        (lua "return "))
      (vim.cmd :enew)
      (vim.cmd :bp))
    (local next-buf (get-next-buf buf))
    (local windows (. (. (vim.fn.getbufinfo buf) 1) :windows))
    (if (or force (= (vim.fn.getbufvar buf :&buftype) :terminal))
        (let [(term type) (pcall (fn []
                                   (vim.api.nvim_buf_get_var buf :term_type)))]
          (if term
              (if (= type :wind)
                  (do
                    (vim.cmd (string.format "%d bufdo setlocal nobl" buf))
                    (vim.cmd :BufferLineCycleNext))
                  (let [cur-win (vim.fn.winnr)]
                    (vim.cmd (string.format "%d wincmd c" cur-win))
                    (lua "return ")))
              (do
                (switch-buffer windows next-buf)
                (vim.cmd (string.format "bd! %d" buf)))))
        (do
          (switch-buffer windows next-buf)
          (vim.cmd (string.format "silent! confirm bd %d" buf))))
    (when (= (vim.fn.buflisted buf) 1)
      (switch-buffer windows buf))))

(fn defer_unpack [pack after]
  (when pack
    (set-forcibly! after (or after 0))
    (vim.defer_fn (fn [] ((. (require :packer) :loader) pack)) after)))

{: merge : lsp_fidget : will_it_fit : close_buf : defer_unpack}