├── .ignore ├── .gitattributes ├── .gitignore ├── test └── fnl │ └── snap │ └── main-test.fnl ├── fnl └── snap │ ├── select │ ├── cwd.fnl │ ├── insert.fnl │ ├── vim │ │ ├── currentbuffer.fnl │ │ └── mark.fnl │ ├── help.fnl │ ├── tmux │ │ └── switch.fnl │ ├── jumplist.fnl │ ├── lsp.fnl │ ├── file.fnl │ ├── vimgrep.fnl │ ├── common │ │ └── file.fnl │ └── git │ │ └── init.fnl │ ├── consumer │ ├── fzy │ │ ├── init.fnl │ │ ├── score.fnl │ │ ├── filter.fnl │ │ ├── positions.fnl │ │ └── all.fnl │ ├── combine.fnl │ ├── filter.fnl │ ├── limit.fnl │ ├── cache.fnl │ ├── try.fnl │ ├── chunk.fnl │ ├── positions.fnl │ └── fzf │ │ └── init.fnl │ ├── producer │ ├── luv │ │ ├── file.fnl │ │ ├── directory.fnl │ │ └── general.fnl │ ├── vim │ │ ├── oldfile.fnl │ │ ├── globalmarks.fnl │ │ ├── buffer.fnl │ │ ├── currentbuffer.fnl │ │ ├── jumplist.fnl │ │ ├── marks.fnl │ │ └── help.fnl │ ├── git │ │ ├── status.fnl │ │ ├── branch │ │ │ ├── local.fnl │ │ │ └── remote.fnl │ │ ├── general.fnl │ │ ├── file.fnl │ │ └── log.fnl │ ├── fd │ │ ├── general.fnl │ │ ├── file.fnl │ │ └── directory.fnl │ ├── tmux │ │ └── session.fnl │ ├── ripgrep │ │ ├── general.fnl │ │ ├── file.fnl │ │ └── vimgrep.fnl │ ├── request.fnl │ ├── create.fnl │ └── lsp │ │ └── init.fnl │ ├── preview │ ├── lsp.fnl │ ├── file.fnl │ ├── vim │ │ ├── currentbuffer.fnl │ │ └── mark.fnl │ ├── vimgrep.fnl │ ├── git │ │ └── log.fnl │ ├── help.fnl │ ├── jumplist.fnl │ └── common │ │ ├── syntax.fnl │ │ ├── read-file.fnl │ │ └── file.fnl │ ├── common │ ├── string.fnl │ ├── vimgrep │ │ └── parse.fnl │ ├── buffer.fnl │ ├── window.fnl │ ├── register.fnl │ ├── tbl.fnl │ └── io.fnl │ ├── view │ ├── size.fnl │ ├── results.fnl │ ├── view.fnl │ └── input.fnl │ ├── loading │ └── init.fnl │ ├── layout │ └── init.fnl │ ├── macros.fnl │ └── config │ └── init.fnl ├── lua └── snap │ ├── consumer │ ├── fzy │ │ ├── init.lua │ │ ├── filter.lua │ │ ├── score.lua │ │ ├── positions.lua │ │ └── all.lua │ ├── combine.lua │ ├── limit.lua │ ├── filter.lua │ ├── cache.lua │ ├── try.lua │ ├── chunk.lua │ ├── positions.lua │ └── fzf │ │ └── init.lua │ ├── producer │ ├── luv │ │ ├── file.lua │ │ ├── directory.lua │ │ └── general.lua │ ├── git │ │ ├── status.lua │ │ ├── branch │ │ │ ├── local.lua │ │ │ └── remote.lua │ │ ├── file.lua │ │ ├── general.lua │ │ └── log.lua │ ├── vim │ │ ├── oldfile.lua │ │ ├── globalmarks.lua │ │ ├── buffer.lua │ │ ├── jumplist.lua │ │ ├── marks.lua │ │ ├── currentbuffer.lua │ │ └── help.lua │ ├── fd │ │ ├── general.lua │ │ ├── file.lua │ │ └── directory.lua │ ├── tmux │ │ └── session.lua │ ├── ripgrep │ │ ├── file.lua │ │ ├── general.lua │ │ └── vimgrep.lua │ ├── request.lua │ ├── create.lua │ └── lsp │ │ └── init.lua │ ├── common │ ├── vimgrep │ │ └── parse.lua │ ├── string.lua │ ├── buffer.lua │ ├── register.lua │ ├── window.lua │ ├── tbl.lua │ └── io.lua │ ├── select │ ├── vim │ │ ├── currentbuffer.lua │ │ └── mark.lua │ ├── insert.lua │ ├── help.lua │ ├── file.lua │ ├── cwd.lua │ ├── tmux │ │ └── switch.lua │ ├── lsp.lua │ ├── vimgrep.lua │ ├── jumplist.lua │ ├── common │ │ └── file.lua │ └── git │ │ └── init.lua │ ├── preview │ ├── lsp.lua │ ├── file.lua │ ├── vim │ │ ├── currentbuffer.lua │ │ └── mark.lua │ ├── vimgrep.lua │ ├── jumplist.lua │ ├── help.lua │ ├── git │ │ └── log.lua │ └── common │ │ ├── syntax.lua │ │ ├── read-file.lua │ │ └── file.lua │ ├── view │ ├── size.lua │ ├── results.lua │ ├── view.lua │ └── input.lua │ ├── loading │ └── init.lua │ ├── layout │ └── init.lua │ ├── macros.fnl │ └── config │ └── init.lua ├── Makefile ├── scripts └── dep.sh ├── plugin └── snap.lua └── UNLICENSE /.ignore: -------------------------------------------------------------------------------- 1 | lua/snap/* 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | lua/**/*.lua linguist-generated 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /deps/ 2 | /test/lua/ 3 | /doc/tags 4 | 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /test/fnl/snap/main-test.fnl: -------------------------------------------------------------------------------- 1 | (module snap.main-test) 2 | 3 | (deftest something-simple 4 | (t.= 1 1 "1 should equal 1, I hope!")) 5 | -------------------------------------------------------------------------------- /fnl/snap/select/cwd.fnl: -------------------------------------------------------------------------------- 1 | (module snap.select.cwd) 2 | 3 | (defn select [selection winnr] 4 | (vim.schedule (partial vim.api.nvim_set_current_dir selection))) 5 | -------------------------------------------------------------------------------- /fnl/snap/select/insert.fnl: -------------------------------------------------------------------------------- 1 | (module snap.select.insert) 2 | 3 | (defn select [selection winnr] 4 | (vim.api.nvim_put [(tostring selection)] "c" true true)) 5 | -------------------------------------------------------------------------------- /fnl/snap/select/vim/currentbuffer.fnl: -------------------------------------------------------------------------------- 1 | (local file (require :snap.select.common.file)) 2 | 3 | {:select (file (fn [{: filename :row line}] {: filename : line}))} 4 | -------------------------------------------------------------------------------- /fnl/snap/select/help.fnl: -------------------------------------------------------------------------------- 1 | (module snap.select.help) 2 | 3 | (defn select [selection winnr] 4 | (vim.api.nvim_command (string.format "help %s" (tostring selection)))) 5 | -------------------------------------------------------------------------------- /fnl/snap/consumer/fzy/init.fnl: -------------------------------------------------------------------------------- 1 | (let [all (require :snap.consumer.fzy.all) 2 | cache (require :snap.consumer.cache)] 3 | (fn [producer] 4 | (all (cache producer)))) 5 | 6 | -------------------------------------------------------------------------------- /fnl/snap/producer/luv/file.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | general (snap.get :producer.luv.general)] 3 | (fn [request] 4 | (general {:file true} (snap.sync vim.fn.getcwd)))) 5 | -------------------------------------------------------------------------------- /fnl/snap/preview/lsp.fnl: -------------------------------------------------------------------------------- 1 | (local file (require :snap.preview.common.file)) 2 | 3 | (file 4 | (fn [{:filename path :col column :lnum line}] 5 | {: path 6 | : column 7 | : line})) 8 | -------------------------------------------------------------------------------- /fnl/snap/select/tmux/switch.fnl: -------------------------------------------------------------------------------- 1 | (module snap.select.tmux.switch {require {io snap.common.io}}) 2 | 3 | (defn select [selection winnr] 4 | (io.spawn :tmux [:switch-client "-t" selection] cwd)) 5 | -------------------------------------------------------------------------------- /fnl/snap/producer/luv/directory.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | general (snap.get :producer.luv.general)] 3 | (fn [request] 4 | (general {:directory true} (snap.sync vim.fn.getcwd)))) 5 | -------------------------------------------------------------------------------- /fnl/snap/common/string.fnl: -------------------------------------------------------------------------------- 1 | (module snap.common.string) 2 | 3 | (defn split [str] 4 | (icollect [_ line (ipairs (vim.split str "\n" true))] 5 | (let [trimmed (vim.trim line)] 6 | (if (not= trimmed "") trimmed)))) 7 | -------------------------------------------------------------------------------- /fnl/snap/producer/vim/oldfile.fnl: -------------------------------------------------------------------------------- 1 | (fn get-oldfiles [] 2 | (vim.tbl_filter #(= (vim.fn.empty (vim.fn.glob $1)) 0) vim.v.oldfiles)) 3 | 4 | (let [snap (require :snap)] 5 | (fn [] 6 | (snap.sync get-oldfiles))) 7 | 8 | -------------------------------------------------------------------------------- /fnl/snap/producer/git/status.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | general (snap.get :producer.git.general)] 3 | (fn [request] 4 | (let [cwd (snap.sync vim.fn.getcwd)] 5 | (general request {:args [:status :--porcelain] : cwd})))) 6 | -------------------------------------------------------------------------------- /fnl/snap/view/size.fnl: -------------------------------------------------------------------------------- 1 | (module snap.view.size) 2 | 3 | ;; Represents the bottom border 4 | (def border 1) 5 | 6 | ;; Padding between ui elements 7 | (def padding 1) 8 | 9 | ;; Percentage size that views should take up 10 | (def view-width 0.5) 11 | -------------------------------------------------------------------------------- /fnl/snap/preview/file.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local file (require :snap.preview.common.file)) 3 | 4 | (file 5 | (fn [selection] 6 | {:path (snap.sync (partial vim.fn.fnamemodify (tostring selection) ":p")) 7 | :line nil 8 | :column nil})) 9 | -------------------------------------------------------------------------------- /lua/snap/consumer/fzy/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/fzy/init.fnl" 2 | local all = require("snap.consumer.fzy.all") 3 | local cache = require("snap.consumer.cache") 4 | local function _1_(producer) 5 | return all(cache(producer)) 6 | end 7 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/common/vimgrep/parse.fnl: -------------------------------------------------------------------------------- 1 | (fn [line] 2 | "Parses a line in vimgrep format" 3 | (let [parts (vim.split (tostring line) ":")] 4 | {:filename (. parts 1) 5 | :lnum (tonumber (. parts 2)) 6 | :col (tonumber (. parts 3)) 7 | :text (. parts 4)})) 8 | -------------------------------------------------------------------------------- /fnl/snap/preview/vim/currentbuffer.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local file (require :snap.preview.common.file)) 3 | 4 | (file 5 | (fn [{: filename :row line}] 6 | {:path (snap.sync (partial vim.fn.fnamemodify filename ":p")) 7 | : line 8 | :column 1})) 9 | -------------------------------------------------------------------------------- /lua/snap/producer/luv/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/luv/file.fnl" 2 | local snap = require("snap") 3 | local general = snap.get("producer.luv.general") 4 | local function _1_(request) 5 | return general({file = true}, snap.sync(vim.fn.getcwd)) 6 | end 7 | return _1_ -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: deps compile test 2 | 3 | default: deps compile test 4 | 5 | deps: 6 | scripts/dep.sh Olical aniseed origin/develop 7 | 8 | compile: 9 | rm -rf lua 10 | deps/aniseed/scripts/compile.sh 11 | 12 | test: 13 | rm -rf test/lua 14 | deps/aniseed/scripts/test.sh 15 | -------------------------------------------------------------------------------- /fnl/snap/producer/git/branch/local.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | general (require :snap.producer.git.general)] 3 | (fn [request] 4 | (let [cwd (snap.sync vim.fn.getcwd)] 5 | (general request {:args [:branch :--sort :-committerdate :--format "%(refname:short)"] : cwd})))) 6 | -------------------------------------------------------------------------------- /lua/snap/common/vimgrep/parse.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/vimgrep/parse.fnl" 2 | local function _1_(line) 3 | local parts = vim.split(tostring(line), ":") 4 | return {filename = parts[1], lnum = tonumber(parts[2]), col = tonumber(parts[3]), text = parts[4]} 5 | end 6 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/preview/vim/mark.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local file (require :snap.preview.common.file)) 3 | 4 | (file 5 | (fn [selection] 6 | {:path (snap.sync (partial vim.fn.fnamemodify selection.file ":p")) 7 | :line (. selection.pos 2) 8 | :column (. selection.pos 3)})) 9 | -------------------------------------------------------------------------------- /fnl/snap/producer/git/branch/remote.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | general (require :snap.producer.git.general)] 3 | (fn [request] 4 | (let [cwd (snap.sync vim.fn.getcwd)] 5 | (general request {:args [:branch :-r :--sort :-committerdate :--format "%(refname:short)"] : cwd})))) 6 | -------------------------------------------------------------------------------- /lua/snap/producer/luv/directory.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/luv/directory.fnl" 2 | local snap = require("snap") 3 | local general = snap.get("producer.luv.general") 4 | local function _1_(request) 5 | return general({directory = true}, snap.sync(vim.fn.getcwd)) 6 | end 7 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/select/jumplist.fnl: -------------------------------------------------------------------------------- 1 | (module snap.select.jumplist) 2 | 3 | (defn select [selection winnr] 4 | (let [{: bufnr : lnum : col} selection] 5 | (vim.api.nvim_win_set_buf winnr bufnr) 6 | (vim.api.nvim_win_set_option winnr :relativenumber true) 7 | (vim.api.nvim_win_set_cursor winnr [lnum col]))) 8 | -------------------------------------------------------------------------------- /lua/snap/producer/git/status.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/git/status.fnl" 2 | local snap = require("snap") 3 | local general = snap.get("producer.git.general") 4 | local function _1_(request) 5 | local cwd = snap.sync(vim.fn.getcwd) 6 | return general(request, {args = {"status", "--porcelain"}, cwd = cwd}) 7 | end 8 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/select/lsp.fnl: -------------------------------------------------------------------------------- 1 | (local file (require :snap.select.common.file)) 2 | 3 | (local select (file (fn [{: filename :lnum line :col column}] {: filename : line : column}))) 4 | 5 | (fn autoselect [{: user_data : offset_encoding}] 6 | (vim.lsp.util.jump_to_location user_data offset_encoding true)) 7 | 8 | {: select 9 | : autoselect} 10 | -------------------------------------------------------------------------------- /lua/snap/select/vim/currentbuffer.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/vim/currentbuffer.fnl" 2 | local file = require("snap.select.common.file") 3 | local function _3_(_1_) 4 | local _arg_2_ = _1_ 5 | local filename = _arg_2_["filename"] 6 | local line = _arg_2_["row"] 7 | return {filename = filename, line = line} 8 | end 9 | return {select = file(_3_)} -------------------------------------------------------------------------------- /fnl/snap/producer/vim/globalmarks.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl)] 3 | 4 | (fn get-marks [] 5 | (vim.tbl_map 6 | (fn [mark] (snap.with_metas (string.format "%s = %s:%d:%d" mark.mark mark.file (. mark.pos 2) (. mark.pos 3)) mark)) 7 | (vim.fn.getmarklist))) 8 | 9 | (fn [] (snap.sync get-marks))) 10 | 11 | -------------------------------------------------------------------------------- /fnl/snap/select/file.fnl: -------------------------------------------------------------------------------- 1 | (local file (require :snap.select.common.file)) 2 | 3 | (local select (file (fn [selection] {:filename (tostring selection)}))) 4 | 5 | (fn multiselect [selections winnr] 6 | (each [index selection (ipairs selections)] 7 | (select selection (if (= (length selections) index) winnr false)))) 8 | 9 | {: multiselect 10 | : select} 11 | -------------------------------------------------------------------------------- /fnl/snap/consumer/combine.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl)] 3 | (fn [...] 4 | "Combines multiple producers" 5 | (let [producers [...]] 6 | (fn [request] 7 | (each [_ producer (ipairs producers)] 8 | (each [results (snap.consume producer request)] 9 | (coroutine.yield results))))))) 10 | 11 | -------------------------------------------------------------------------------- /lua/snap/preview/lsp.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/lsp.fnl" 2 | local file = require("snap.preview.common.file") 3 | local function _3_(_1_) 4 | local _arg_2_ = _1_ 5 | local path = _arg_2_["filename"] 6 | local column = _arg_2_["col"] 7 | local line = _arg_2_["lnum"] 8 | return {path = path, column = column, line = line} 9 | end 10 | return file(_3_) -------------------------------------------------------------------------------- /lua/snap/producer/vim/oldfile.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/oldfile.fnl" 2 | local function get_oldfiles() 3 | local function _1_(_241) 4 | return (vim.fn.empty(vim.fn.glob(_241)) == 0) 5 | end 6 | return vim.tbl_filter(_1_, vim.v.oldfiles) 7 | end 8 | local snap = require("snap") 9 | local function _2_() 10 | return snap.sync(get_oldfiles) 11 | end 12 | return _2_ -------------------------------------------------------------------------------- /fnl/snap/preview/vimgrep.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local file (require :snap.preview.common.file)) 3 | (local parse (require :snap.common.vimgrep.parse)) 4 | 5 | (file 6 | (fn [selection] 7 | (local {: filename :lnum line :col column} (parse (tostring selection))) 8 | {:path (snap.sync (partial vim.fn.fnamemodify filename ":p")) 9 | : line 10 | : column})) 11 | -------------------------------------------------------------------------------- /lua/snap/producer/git/branch/local.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/git/branch/local.fnl" 2 | local snap = require("snap") 3 | local general = require("snap.producer.git.general") 4 | local function _1_(request) 5 | local cwd = snap.sync(vim.fn.getcwd) 6 | return general(request, {args = {"branch", "--sort", "-committerdate", "--format", "%(refname:short)"}, cwd = cwd}) 7 | end 8 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/git/branch/remote.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/git/branch/remote.fnl" 2 | local snap = require("snap") 3 | local general = require("snap.producer.git.general") 4 | local function _1_(request) 5 | local cwd = snap.sync(vim.fn.getcwd) 6 | return general(request, {args = {"branch", "-r", "--sort", "-committerdate", "--format", "%(refname:short)"}, cwd = cwd}) 7 | end 8 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/consumer/filter.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap)] 2 | (fn [filter-fnc producer] 3 | "Filters values from producer" 4 | (fn [request] 5 | (each [results (snap.consume producer request)] 6 | (if 7 | (and (= (type results) :table) (> (length results) 0)) 8 | (coroutine.yield (vim.tbl_filter #(filter-fnc $1 request) results)) 9 | (coroutine.yield results)))))) 10 | -------------------------------------------------------------------------------- /fnl/snap/producer/git/general.fnl: -------------------------------------------------------------------------------- 1 | (let [io (require :snap.common.io) 2 | string (require :snap.common.string)] 3 | (fn [request {: args : cwd}] 4 | (each [data err cancel (io.spawn :git args cwd)] 5 | (if 6 | (request.canceled) (do (cancel) (coroutine.yield nil)) 7 | (not= err "") (coroutine.yield nil) 8 | (= data "") (coroutine.yield []) 9 | (coroutine.yield (string.split data)))))) 10 | -------------------------------------------------------------------------------- /fnl/snap/producer/vim/buffer.fnl: -------------------------------------------------------------------------------- 1 | (fn get-buffers [] 2 | (vim.tbl_map #(vim.fn.bufname $1) 3 | (vim.tbl_filter #(and (not= (vim.fn.bufname $1) "") 4 | (= (vim.fn.buflisted $1) 1) 5 | (= (vim.fn.bufexists $1) 1)) 6 | (vim.api.nvim_list_bufs)))) 7 | 8 | (let [snap (require :snap)] 9 | (fn [] 10 | (snap.sync get-buffers))) 11 | 12 | -------------------------------------------------------------------------------- /lua/snap/preview/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/file.fnl" 2 | local snap = require("snap") 3 | local file = require("snap.preview.common.file") 4 | local function _1_(selection) 5 | local function _3_() 6 | local _2_ = tostring(selection) 7 | local function _4_(...) 8 | return vim.fn.fnamemodify(_2_, ":p", ...) 9 | end 10 | return _4_ 11 | end 12 | return {path = snap.sync(_3_()), line = nil, column = nil} 13 | end 14 | return file(_1_) -------------------------------------------------------------------------------- /fnl/snap/producer/fd/general.fnl: -------------------------------------------------------------------------------- 1 | (let [io (require :snap.common.io) 2 | string (require :snap.common.string)] 3 | (fn [request {: args : cwd}] 4 | (each [data err kill (io.spawn :fd args cwd)] 5 | (if (request.canceled) (do 6 | (kill) 7 | (coroutine.yield nil)) 8 | (not= err "") (coroutine.yield nil) 9 | (= data "") (coroutine.yield []) 10 | (coroutine.yield (string.split data)))))) 11 | -------------------------------------------------------------------------------- /lua/snap/consumer/combine.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/combine.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local function _1_(...) 5 | local producers = {...} 6 | local function _2_(request) 7 | for _, producer in ipairs(producers) do 8 | for results in snap.consume(producer, request) do 9 | coroutine.yield(results) 10 | end 11 | end 12 | return nil 13 | end 14 | return _2_ 15 | end 16 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/consumer/limit.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap)] 2 | (fn [limit producer] 3 | "Limit" 4 | (fn [request] 5 | (var count 0) 6 | (each [results (snap.consume producer request)] 7 | ;; Collect the count of the results 8 | (when (= (type results) :table) (set count (+ count (length results)))) 9 | ;; When we have reached the limit signal to cancel 10 | (when (> count limit) (request.cancel)) 11 | (coroutine.yield results))))) 12 | 13 | -------------------------------------------------------------------------------- /lua/snap/preview/vim/currentbuffer.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/vim/currentbuffer.fnl" 2 | local snap = require("snap") 3 | local file = require("snap.preview.common.file") 4 | local function _3_(_1_) 5 | local _arg_2_ = _1_ 6 | local filename = _arg_2_["filename"] 7 | local line = _arg_2_["row"] 8 | local function _4_(...) 9 | return vim.fn.fnamemodify(filename, ":p", ...) 10 | end 11 | return {path = snap.sync(_4_), line = line, column = 1} 12 | end 13 | return file(_3_) -------------------------------------------------------------------------------- /lua/snap/producer/vim/globalmarks.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/globalmarks.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local function get_marks() 5 | local function _1_(mark) 6 | return snap.with_metas(string.format("%s = %s:%d:%d", mark.mark, mark.file, mark.pos[2], mark.pos[3]), mark) 7 | end 8 | return vim.tbl_map(_1_, vim.fn.getmarklist()) 9 | end 10 | local function _2_() 11 | return snap.sync(get_marks) 12 | end 13 | return _2_ -------------------------------------------------------------------------------- /lua/snap/preview/vim/mark.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/vim/mark.fnl" 2 | local snap = require("snap") 3 | local file = require("snap.preview.common.file") 4 | local function _1_(selection) 5 | local function _3_() 6 | local _2_ = selection.file 7 | local function _4_(...) 8 | return vim.fn.fnamemodify(_2_, ":p", ...) 9 | end 10 | return _4_ 11 | end 12 | return {path = snap.sync(_3_()), line = selection.pos[2], column = selection.pos[3]} 13 | end 14 | return file(_1_) -------------------------------------------------------------------------------- /fnl/snap/select/vimgrep.fnl: -------------------------------------------------------------------------------- 1 | (local parse (require :snap.common.vimgrep.parse)) 2 | (local file (require :snap.select.common.file)) 3 | 4 | (fn multiselect [selections winnr] 5 | (vim.fn.setqflist (vim.tbl_map parse selections)) 6 | (vim.api.nvim_command :copen) 7 | (vim.api.nvim_command :cfirst)) 8 | 9 | (local select 10 | (file (fn [selection] 11 | (local {: filename :lnum line :col column} (parse selection)) 12 | {: filename : line : column}))) 13 | 14 | {: select 15 | : multiselect} 16 | -------------------------------------------------------------------------------- /fnl/snap/producer/vim/currentbuffer.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap)] 2 | (fn [{: winnr}] 3 | (local bufnr (snap.sync (partial vim.api.nvim_win_get_buf winnr))) 4 | (local filename (snap.sync (partial vim.api.nvim_buf_get_name bufnr))) 5 | (local contents (snap.sync (partial vim.api.nvim_buf_get_lines bufnr 0 -1 false))) 6 | (local results []) 7 | (each [row line (ipairs contents)] 8 | (table.insert results (snap.with_metas line {: filename : row}))) 9 | (coroutine.yield results))) 10 | -------------------------------------------------------------------------------- /fnl/snap/producer/tmux/session.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | io (require :snap.common.io) 3 | string (require :snap.common.string)] 4 | (fn [request] 5 | (let [cwd (snap.sync vim.fn.getcwd)] 6 | (each [data err cancel (io.spawn :tmux [:list-sessions "-F" "#S"] cwd)] 7 | (if 8 | (request.canceled) (do (cancel) (coroutine.yield nil)) 9 | (not= err "") (coroutine.yield nil) 10 | (= data "") (coroutine.yield []) 11 | (coroutine.yield (string.split data))))))) 12 | -------------------------------------------------------------------------------- /scripts/dep.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Clones a GitHub repo into deps/{name} if it's not there already. 4 | # Will update the repository each time and ensure the right commit is checked out. 5 | # Args: GitHub user, repository name, checkout target. 6 | # Usage (after copying to your scripts directory): scripts/dep.sh Olical aniseed vX.Y.Z 7 | 8 | mkdir -p deps 9 | 10 | if [ ! -d "deps/$2" ]; then 11 | git clone "https://github.com/$1/$2.git" "deps/$2" 12 | fi 13 | 14 | cd "deps/$2" && git fetch && git checkout "$3" 15 | 16 | -------------------------------------------------------------------------------- /fnl/snap/producer/git/file.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl) 3 | general (snap.get :producer.git.general)] 4 | (local git {}) 5 | (local args [:ls-files]) 6 | (fn git.default [request] 7 | (let [cwd (snap.sync vim.fn.getcwd)] 8 | (general request {:args args : cwd}))) 9 | (fn git.args [new-args] 10 | (let [args (tbl.concat args new-args)] 11 | (fn [request] 12 | (let [cwd (or cwd (snap.sync vim.fn.getcwd))] 13 | (general request {: args : cwd}))))) 14 | git) 15 | -------------------------------------------------------------------------------- /lua/snap/producer/vim/buffer.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/buffer.fnl" 2 | local function get_buffers() 3 | local function _1_(_241) 4 | return vim.fn.bufname(_241) 5 | end 6 | local function _2_(_241) 7 | return ((vim.fn.bufname(_241) ~= "") and (vim.fn.buflisted(_241) == 1) and (vim.fn.bufexists(_241) == 1)) 8 | end 9 | return vim.tbl_map(_1_, vim.tbl_filter(_2_, vim.api.nvim_list_bufs())) 10 | end 11 | local snap = require("snap") 12 | local function _3_() 13 | return snap.sync(get_buffers) 14 | end 15 | return _3_ -------------------------------------------------------------------------------- /fnl/snap/consumer/cache.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl)] 3 | (fn [producer] 4 | "Provides a method to avoid running passed producer multiple times" 5 | (var cache []) 6 | (fn [request] 7 | (if (= (length cache) 0) 8 | (each [results (snap.consume producer request)] 9 | (if 10 | (> (length results) 0) 11 | (do 12 | (tbl.acc cache results) 13 | (coroutine.yield results)) 14 | (snap.continue))) 15 | cache)))) 16 | 17 | -------------------------------------------------------------------------------- /fnl/snap/consumer/fzy/score.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | fzy (require :fzy)] 3 | (fn [producer] 4 | "Scores the result set" 5 | (fn [request] 6 | (each [results (snap.consume producer request)] 7 | (match (type results) 8 | "table" (coroutine.yield 9 | (if 10 | (= request.filter "") 11 | results 12 | (vim.tbl_map #(snap.with_meta $1 :score (fzy.score request.filter (tostring $1))) results))) 13 | "nil" (coroutine.yield nil)))))) 14 | -------------------------------------------------------------------------------- /lua/snap/consumer/limit.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/limit.fnl" 2 | local snap = require("snap") 3 | local function _1_(limit, producer) 4 | local function _2_(request) 5 | local count = 0 6 | for results in snap.consume(producer, request) do 7 | if (type(results) == "table") then 8 | count = (count + #results) 9 | else 10 | end 11 | if (count > limit) then 12 | request.cancel() 13 | else 14 | end 15 | coroutine.yield(results) 16 | end 17 | return nil 18 | end 19 | return _2_ 20 | end 21 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/consumer/fzy/filter.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | fzy (require :fzy)] 3 | (fn [producer] 4 | "Filters each result from the producer using request.filter" 5 | (fn filter [filter results] 6 | (if 7 | (= filter "") 8 | results 9 | (vim.tbl_filter #(fzy.has_match filter (tostring $1)) results))) 10 | 11 | (fn [request] 12 | (each [results (snap.consume producer request)] 13 | (match (type results) 14 | "table" (coroutine.yield (filter request.filter results)) 15 | "nil" (coroutine.yield nil)))))) 16 | -------------------------------------------------------------------------------- /lua/snap/select/insert.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/insert.fnl" 2 | local _2amodule_name_2a = "snap.select.insert" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function select(selection, winnr) 14 | return vim.api.nvim_put({tostring(selection)}, "c", true, true) 15 | end 16 | _2amodule_2a["select"] = select 17 | return _2amodule_2a -------------------------------------------------------------------------------- /lua/snap/select/help.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/help.fnl" 2 | local _2amodule_name_2a = "snap.select.help" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function select(selection, winnr) 14 | return vim.api.nvim_command(string.format("help %s", tostring(selection))) 15 | end 16 | _2amodule_2a["select"] = select 17 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/preview/git/log.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local string (require :snap.common.string)) 3 | (local io (require :snap.common.io)) 4 | 5 | (fn [request] 6 | (local cwd (snap.sync vim.fn.getcwd)) 7 | 8 | (local (contents error) (snap.async (partial io.system :git [:diff-tree :-p request.selection.hash] cwd))) 9 | 10 | (snap.sync (fn [] 11 | (when 12 | (not (request.canceled)) 13 | (vim.api.nvim_buf_set_lines request.bufnr 0 -1 false (string.split contents)) 14 | (vim.api.nvim_buf_call request.bufnr (fn [] 15 | (vim.api.nvim_command "set filetype=git"))))))) 16 | -------------------------------------------------------------------------------- /fnl/snap/producer/vim/jumplist.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl)] 3 | 4 | (fn get-jumplist [] 5 | (vim.tbl_map 6 | (fn [item] 7 | (snap.with_metas 8 | (string.format "%s:%s:%s" (or item.filename (vim.api.nvim_buf_get_name item.bufnr)) item.lnum item.col) 9 | item)) 10 | (vim.tbl_filter 11 | #(and 12 | (vim.api.nvim_buf_is_valid $1.bufnr) 13 | (not= (vim.api.nvim_buf_get_name $1.bufnr) "")) 14 | (tbl.first (vim.fn.getjumplist))))) 15 | 16 | (fn [] 17 | (snap.sync get-jumplist))) 18 | 19 | -------------------------------------------------------------------------------- /lua/snap/preview/vimgrep.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/vimgrep.fnl" 2 | local snap = require("snap") 3 | local file = require("snap.preview.common.file") 4 | local parse = require("snap.common.vimgrep.parse") 5 | local function _1_(selection) 6 | local _local_2_ = parse(tostring(selection)) 7 | local filename = _local_2_["filename"] 8 | local line = _local_2_["lnum"] 9 | local column = _local_2_["col"] 10 | local function _3_(...) 11 | return vim.fn.fnamemodify(filename, ":p", ...) 12 | end 13 | return {path = snap.sync(_3_), line = line, column = column} 14 | end 15 | return file(_1_) -------------------------------------------------------------------------------- /lua/snap/view/size.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/view/size.fnl" 2 | local _2amodule_name_2a = "snap.view.size" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local border = 1 14 | _2amodule_2a["border"] = border 15 | local padding = 1 16 | _2amodule_2a["padding"] = padding 17 | local view_width = 0.5 18 | _2amodule_2a["view-width"] = view_width 19 | return _2amodule_2a -------------------------------------------------------------------------------- /lua/snap/consumer/filter.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/filter.fnl" 2 | local snap = require("snap") 3 | local function _1_(filter_fnc, producer) 4 | local function _2_(request) 5 | for results in snap.consume(producer, request) do 6 | if ((type(results) == "table") and (#results > 0)) then 7 | local function _3_(_241) 8 | return filter_fnc(_241, request) 9 | end 10 | coroutine.yield(vim.tbl_filter(_3_, results)) 11 | else 12 | coroutine.yield(results) 13 | end 14 | end 15 | return nil 16 | end 17 | return _2_ 18 | end 19 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/consumer/try.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl)] 3 | (fn [...] 4 | "Tries each subsequent producer, ending with the first producer that yields results" 5 | (let [producers [...]] 6 | (fn [request] 7 | (each [_ producer (ipairs producers)] 8 | (var had-values false) 9 | (each [results (snap.consume producer request)] 10 | (when (and (= (type results) :table) (> (length results) 0)) 11 | (set had-values true)) 12 | (coroutine.yield results)) 13 | (when had-values (coroutine.yield nil))))))) 14 | -------------------------------------------------------------------------------- /fnl/snap/preview/help.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | read-file (snap.get :preview.common.read-file) 3 | loading (snap.get :loading) 4 | syntax (snap.get :preview.common.syntax)] 5 | (fn [request] 6 | ;; Write the preview to the buffer. 7 | (snap.sync (fn [] 8 | (when (not (request.canceled)) 9 | (vim.api.nvim_buf_set_option request.bufnr :buftype :help) 10 | (vim.api.nvim_buf_call request.bufnr (fn [] 11 | (vim.api.nvim_command (string.format "noautocmd help %s" (tostring request.selection))) 12 | (vim.api.nvim_buf_set_option request.bufnr :syntax :help)))))))) 13 | -------------------------------------------------------------------------------- /lua/snap/consumer/cache.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/cache.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local function _1_(producer) 5 | local cache = {} 6 | local function _2_(request) 7 | if (#cache == 0) then 8 | for results in snap.consume(producer, request) do 9 | if (#results > 0) then 10 | tbl.acc(cache, results) 11 | coroutine.yield(results) 12 | else 13 | snap.continue() 14 | end 15 | end 16 | return nil 17 | else 18 | return cache 19 | end 20 | end 21 | return _2_ 22 | end 23 | return _1_ -------------------------------------------------------------------------------- /lua/snap/select/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/file.fnl" 2 | local file = require("snap.select.common.file") 3 | local select 4 | local function _1_(selection) 5 | return {filename = tostring(selection)} 6 | end 7 | select = file(_1_) 8 | local function multiselect(selections, winnr) 9 | for index, selection in ipairs(selections) do 10 | local function _2_() 11 | if (#selections == index) then 12 | return winnr 13 | else 14 | return false 15 | end 16 | end 17 | select(selection, _2_()) 18 | end 19 | return nil 20 | end 21 | return {multiselect = multiselect, select = select} -------------------------------------------------------------------------------- /lua/snap/select/cwd.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/cwd.fnl" 2 | local _2amodule_name_2a = "snap.select.cwd" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function select(selection, winnr) 14 | local function _1_(...) 15 | return vim.api.nvim_set_current_dir(selection, ...) 16 | end 17 | return vim.schedule(_1_) 18 | end 19 | _2amodule_2a["select"] = select 20 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/consumer/fzy/positions.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | fzy (require :fzy)] 3 | (fn [producer] 4 | "Adds positions to results" 5 | (fn [request] 6 | (each [results (snap.consume producer request)] 7 | (match (type results) 8 | "table" (coroutine.yield 9 | (if (= request.filter "") 10 | results 11 | (vim.tbl_map 12 | (fn [result] 13 | (snap.with_meta result :positions (fzy.positions request.filter (tostring result)))) 14 | results))) 15 | "nil" (coroutine.yield nil)))))) 16 | -------------------------------------------------------------------------------- /fnl/snap/producer/fd/file.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl) 3 | general (snap.get :producer.fd.general)] 4 | (local file {}) 5 | (local args [:--no-ignore-vcs :-t :f]) 6 | (fn file.default [request] 7 | (let [cwd (snap.sync vim.fn.getcwd)] 8 | (general request {: args : cwd}))) 9 | (fn file.hidden [request] 10 | (let [cwd (snap.sync vim.fn.getcwd)] 11 | (general request {:args [:--hidden (unpack args)] : cwd}))) 12 | (fn file.args [new-args] 13 | (fn [request] 14 | (let [cwd (snap.sync vim.fn.getcwd)] 15 | (general request {:args (tbl.concat args new-args) : cwd})))) 16 | file) 17 | -------------------------------------------------------------------------------- /lua/snap/producer/git/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/git/file.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local general = snap.get("producer.git.general") 5 | local git = {} 6 | local args = {"ls-files"} 7 | git.default = function(request) 8 | local cwd = snap.sync(vim.fn.getcwd) 9 | return general(request, {args = args, cwd = cwd}) 10 | end 11 | git.args = function(new_args) 12 | local args0 = tbl.concat(args, new_args) 13 | local function _1_(request) 14 | local cwd = (cwd or snap.sync(vim.fn.getcwd)) 15 | return general(request, {args = args0, cwd = cwd}) 16 | end 17 | return _1_ 18 | end 19 | return git -------------------------------------------------------------------------------- /fnl/snap/producer/ripgrep/general.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | io (snap.get :common.io) 3 | string (snap.get :common.string)] 4 | (fn [request {: args : cwd : absolute}] 5 | (each [data err cancel (io.spawn :rg args cwd)] 6 | (if 7 | (request.canceled) 8 | (do (cancel) (coroutine.yield nil)) 9 | (not= err "") 10 | (coroutine.yield nil) 11 | (= data "") 12 | (snap.continue) 13 | (do 14 | (var results (string.split data)) 15 | 16 | (when absolute 17 | (set results (vim.tbl_map #(string.format "%s/%s" cwd $1) results))) 18 | (coroutine.yield results)))))) 19 | -------------------------------------------------------------------------------- /fnl/snap/producer/vim/marks.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl)] 3 | 4 | (fn get-marks [winnr] 5 | (local bufnr (vim.api.nvim_win_get_buf winnr)) 6 | (vim.tbl_map 7 | (fn [mark] 8 | (local lnum (. mark.pos 2)) 9 | (local content (. (vim.api.nvim_buf_get_lines bufnr (- lnum 1) lnum false) 1)) 10 | ;; Modify the mark so that it is consistent with global marks 11 | (tset mark :file (vim.api.nvim_buf_get_name bufnr)) 12 | (snap.with_metas (string.format "%s : %s" mark.mark content) mark)) 13 | (vim.fn.getmarklist bufnr))) 14 | 15 | (fn [{: winnr}] (snap.sync (partial get-marks winnr)))) 16 | -------------------------------------------------------------------------------- /lua/snap/select/tmux/switch.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/tmux/switch.fnl" 2 | local _2amodule_name_2a = "snap.select.tmux.switch" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local io = require("snap.common.io") 14 | do end (_2amodule_locals_2a)["io"] = io 15 | local function select(selection, winnr) 16 | return io.spawn("tmux", {"switch-client", "-t", selection}, cwd) 17 | end 18 | _2amodule_2a["select"] = select 19 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/producer/fd/directory.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl) 3 | general (snap.get :producer.fd.general)] 4 | (local directory {}) 5 | (local args [:--no-ignore-vcs :-t :d]) 6 | (fn directory.default [request] 7 | (let [cwd (snap.sync vim.fn.getcwd)] 8 | (general request {: args : cwd}))) 9 | (fn directory.hidden [request] 10 | (let [cwd (snap.sync vim.fn.getcwd)] 11 | (general request {:args [:--hidden (unpack args)] : cwd}))) 12 | (fn directory.args [new-args] 13 | (fn [request] 14 | (let [cwd (snap.sync vim.fn.getcwd)] 15 | (general request {:args (tbl.concat args new-args) : cwd})))) 16 | directory) 17 | -------------------------------------------------------------------------------- /lua/snap/producer/fd/general.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/fd/general.fnl" 2 | local io = require("snap.common.io") 3 | local string = require("snap.common.string") 4 | local function _3_(request, _1_) 5 | local _arg_2_ = _1_ 6 | local args = _arg_2_["args"] 7 | local cwd = _arg_2_["cwd"] 8 | for data, err, kill in io.spawn("fd", args, cwd) do 9 | if request.canceled() then 10 | kill() 11 | coroutine.yield(nil) 12 | elseif (err ~= "") then 13 | coroutine.yield(nil) 14 | elseif (data == "") then 15 | coroutine.yield({}) 16 | else 17 | coroutine.yield(string.split(data)) 18 | end 19 | end 20 | return nil 21 | end 22 | return _3_ -------------------------------------------------------------------------------- /lua/snap/producer/vim/jumplist.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/jumplist.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local function get_jumplist() 5 | local function _1_(item) 6 | return snap.with_metas(string.format("%s:%s:%s", (item.filename or vim.api.nvim_buf_get_name(item.bufnr)), item.lnum, item.col), item) 7 | end 8 | local function _2_(_241) 9 | return (vim.api.nvim_buf_is_valid(_241.bufnr) and (vim.api.nvim_buf_get_name(_241.bufnr) ~= "")) 10 | end 11 | return vim.tbl_map(_1_, vim.tbl_filter(_2_, tbl.first(vim.fn.getjumplist()))) 12 | end 13 | local function _3_() 14 | return snap.sync(get_jumplist) 15 | end 16 | return _3_ -------------------------------------------------------------------------------- /lua/snap/producer/git/general.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/git/general.fnl" 2 | local io = require("snap.common.io") 3 | local string = require("snap.common.string") 4 | local function _3_(request, _1_) 5 | local _arg_2_ = _1_ 6 | local args = _arg_2_["args"] 7 | local cwd = _arg_2_["cwd"] 8 | for data, err, cancel in io.spawn("git", args, cwd) do 9 | if request.canceled() then 10 | cancel() 11 | coroutine.yield(nil) 12 | elseif (err ~= "") then 13 | coroutine.yield(nil) 14 | elseif (data == "") then 15 | coroutine.yield({}) 16 | else 17 | coroutine.yield(string.split(data)) 18 | end 19 | end 20 | return nil 21 | end 22 | return _3_ -------------------------------------------------------------------------------- /lua/snap/select/lsp.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/lsp.fnl" 2 | local file = require("snap.select.common.file") 3 | local select 4 | local function _3_(_1_) 5 | local _arg_2_ = _1_ 6 | local filename = _arg_2_["filename"] 7 | local line = _arg_2_["lnum"] 8 | local column = _arg_2_["col"] 9 | return {filename = filename, line = line, column = column} 10 | end 11 | select = file(_3_) 12 | local function autoselect(_4_) 13 | local _arg_5_ = _4_ 14 | local user_data = _arg_5_["user_data"] 15 | local offset_encoding = _arg_5_["offset_encoding"] 16 | return vim.lsp.util.jump_to_location(user_data, offset_encoding, true) 17 | end 18 | return {select = select, autoselect = autoselect} -------------------------------------------------------------------------------- /fnl/snap/producer/request.fnl: -------------------------------------------------------------------------------- 1 | (module snap.producer.request {require-macros [snap.macros]}) 2 | 3 | (defn create [config] 4 | "Creates a producer request" 5 | ;; Config validation 6 | (asserttable config.body "body must be a table") 7 | (assertfunction config.cancel "cancel must be a function") 8 | ;; Set up the request 9 | (local request {:is-canceled false}) 10 | ;; Copy each value 11 | (each [key value (pairs config.body)] 12 | (tset request key value)) 13 | ;; Cancels the request 14 | (fn request.cancel [] (tset request :is-canceled true)) 15 | ;; Checkes if request is canceled 16 | (fn request.canceled [] (or request.is-canceled (config.cancel request))) 17 | request) 18 | -------------------------------------------------------------------------------- /lua/snap/producer/tmux/session.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/tmux/session.fnl" 2 | local snap = require("snap") 3 | local io = require("snap.common.io") 4 | local string = require("snap.common.string") 5 | local function _1_(request) 6 | local cwd = snap.sync(vim.fn.getcwd) 7 | for data, err, cancel in io.spawn("tmux", {"list-sessions", "-F", "#S"}, cwd) do 8 | if request.canceled() then 9 | cancel() 10 | coroutine.yield(nil) 11 | elseif (err ~= "") then 12 | coroutine.yield(nil) 13 | elseif (data == "") then 14 | coroutine.yield({}) 15 | else 16 | coroutine.yield(string.split(data)) 17 | end 18 | end 19 | return nil 20 | end 21 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/producer/git/log.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | general (require :snap.producer.git.general)] 3 | (fn process-line [line] 4 | (local (end) (line:find " ")) 5 | (snap.with_metas 6 | ;; TODO: Required because fzy errors when each line is too long 7 | (line:sub 1 200) 8 | {:hash (line:sub 1 (- end 1)) 9 | :comment (line:sub (+ end 1) -1)})) 10 | 11 | (fn [request] 12 | (let [cwd (snap.sync vim.fn.getcwd)] 13 | (each [results (snap.consume #(general $1 {:args [:log :--oneline] : cwd}) request)] 14 | (match (type results) 15 | "table" (coroutine.yield (vim.tbl_map process-line results)) 16 | "nil" (coroutine.yield nil)))))) 17 | 18 | -------------------------------------------------------------------------------- /plugin/snap.lua: -------------------------------------------------------------------------------- 1 | if 1 ~= vim.fn.has("nvim-0.9.0") then 2 | vim.api.nvim_err_writeln("snap requires at least nvim-0.9.0.") 3 | return 4 | end 5 | 6 | if vim.g.loaded_snap == 1 then 7 | return 8 | end 9 | 10 | vim.g.loaded_snap = 1 11 | 12 | local highlights = { 13 | SnapSelect = { default = true, link = "Visual" }, 14 | SnapMultiSelect = { default = true, link = "Type" }, 15 | 16 | SnapNormal = { default = true, link = "Normal" }, 17 | SnapBorder = { default = true, link = "SnapNormal" }, 18 | 19 | SnapPosition = { default = true, link = "Identifier" }, 20 | SnapPrompt = { default = true, link = "Identifier" }, 21 | } 22 | 23 | for k, v in pairs(highlights) do 24 | vim.api.nvim_set_hl(0, k, v) 25 | end 26 | -------------------------------------------------------------------------------- /fnl/snap/preview/jumplist.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | parse (snap.get :common.vimgrep.parse)] 3 | (fn [request] 4 | ;; Write the preview to the buffer. 5 | (snap.sync (fn [] 6 | (when (not (request.canceled)) 7 | ;; Highlight using the cursor 8 | (vim.api.nvim_win_set_option request.winnr :cursorline true) 9 | (vim.api.nvim_win_set_option request.winnr :cursorcolumn true) 10 | (vim.api.nvim_win_set_buf request.winnr request.selection.bufnr) 11 | (local total-lines (length (vim.api.nvim_buf_get_lines request.selection.bufnr 0 -1 false))) 12 | (vim.api.nvim_win_set_cursor request.winnr [(math.min request.selection.lnum total-lines) 0])))))) 13 | 14 | -------------------------------------------------------------------------------- /fnl/snap/consumer/fzy/all.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | fzy (require :fzy)] 3 | (fn [producer] 4 | "All" 5 | (fn filter [filter results] 6 | (if 7 | (= filter "") 8 | results 9 | (let [processed []] 10 | (each [_ [index positions score] (ipairs (fzy.filter filter (vim.tbl_map #(tostring $1) results)))] 11 | (table.insert processed (snap.with_metas (. results index) {: positions : score}))) 12 | processed))) 13 | 14 | (fn [request] 15 | (each [results (snap.consume producer request)] 16 | (match (type results) 17 | "table" (coroutine.yield (filter request.filter results)) 18 | "nil" (coroutine.yield nil)))))) 19 | -------------------------------------------------------------------------------- /lua/snap/select/vimgrep.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/vimgrep.fnl" 2 | local parse = require("snap.common.vimgrep.parse") 3 | local file = require("snap.select.common.file") 4 | local function multiselect(selections, winnr) 5 | vim.fn.setqflist(vim.tbl_map(parse, selections)) 6 | vim.api.nvim_command("copen") 7 | return vim.api.nvim_command("cfirst") 8 | end 9 | local select 10 | local function _1_(selection) 11 | local _local_2_ = parse(selection) 12 | local filename = _local_2_["filename"] 13 | local line = _local_2_["lnum"] 14 | local column = _local_2_["col"] 15 | return {filename = filename, line = line, column = column} 16 | end 17 | select = file(_1_) 18 | return {select = select, multiselect = multiselect} -------------------------------------------------------------------------------- /fnl/snap/producer/vim/help.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl) 3 | read-file (snap.get :preview.common.read-file)] 4 | (fn [] 5 | (local tags-set {}) 6 | (local tag-files (snap.sync (partial vim.fn.globpath vim.o.runtimepath "doc/tags" 1 1))) 7 | (each [_ tag-file (ipairs tag-files)] 8 | (local tags []) 9 | (local contents (read-file tag-file)) 10 | (each [_ line (ipairs contents)] 11 | (when (not (line:match :^!_TAG_)) 12 | (local [name] (vim.split line (string.char 9) true)) 13 | (when (not (. tags-set name)) 14 | (tset tags-set name true) 15 | (table.insert tags name)))) 16 | (coroutine.yield tags)))) 17 | 18 | -------------------------------------------------------------------------------- /lua/snap/consumer/try.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/try.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local function _1_(...) 5 | local producers = {...} 6 | local function _2_(request) 7 | for _, producer in ipairs(producers) do 8 | local had_values = false 9 | for results in snap.consume(producer, request) do 10 | if ((type(results) == "table") and (#results > 0)) then 11 | had_values = true 12 | else 13 | end 14 | coroutine.yield(results) 15 | end 16 | if had_values then 17 | coroutine.yield(nil) 18 | else 19 | end 20 | end 21 | return nil 22 | end 23 | return _2_ 24 | end 25 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/producer/ripgrep/file.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl) 3 | general (snap.get :producer.ripgrep.general)] 4 | (local file {}) 5 | (local args [:--line-buffered :--files]) 6 | (fn file.default [request] 7 | (let [cwd (snap.sync vim.fn.getcwd)] 8 | (general request {: args : cwd}))) 9 | (fn file.hidden [request] 10 | (let [cwd (snap.sync vim.fn.getcwd)] 11 | (general request {:args [:--hidden (unpack args)] : cwd}))) 12 | (fn file.args [new-args cwd] 13 | (let [args (tbl.concat args new-args) 14 | absolute (not= cwd nil)] 15 | (fn [request] 16 | (let [cwd (or cwd (snap.sync vim.fn.getcwd))] 17 | (general request {: args : cwd : absolute}))))) 18 | file) 19 | -------------------------------------------------------------------------------- /lua/snap/preview/jumplist.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/jumplist.fnl" 2 | local snap = require("snap") 3 | local parse = snap.get("common.vimgrep.parse") 4 | local function _1_(request) 5 | local function _2_() 6 | if not request.canceled() then 7 | vim.api.nvim_win_set_option(request.winnr, "cursorline", true) 8 | vim.api.nvim_win_set_option(request.winnr, "cursorcolumn", true) 9 | vim.api.nvim_win_set_buf(request.winnr, request.selection.bufnr) 10 | local total_lines = #vim.api.nvim_buf_get_lines(request.selection.bufnr, 0, -1, false) 11 | return vim.api.nvim_win_set_cursor(request.winnr, {math.min(request.selection.lnum, total_lines), 0}) 12 | else 13 | return nil 14 | end 15 | end 16 | return snap.sync(_2_) 17 | end 18 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/producer/luv/general.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap)] 2 | (fn [types cwd] 3 | (local dirs [cwd]) 4 | (local relative-dir (snap.sync (partial vim.fn.fnamemodify cwd ":."))) 5 | (while (> (length dirs) 0) 6 | (local dir (table.remove dirs)) 7 | (local handle (vim.loop.fs_scandir dir)) 8 | (local results []) 9 | (while handle 10 | (local (name t) (vim.loop.fs_scandir_next handle)) 11 | (if name 12 | (do 13 | (local path (.. dir "/" name)) 14 | (local relative-path (snap.sync (partial vim.fn.fnamemodify path ":."))) 15 | (when (. types t) (table.insert results relative-path)) 16 | (when (= t :directory) (table.insert dirs path))) 17 | (lua "break"))) 18 | (coroutine.yield results)))) 19 | -------------------------------------------------------------------------------- /lua/snap/preview/help.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/help.fnl" 2 | local snap = require("snap") 3 | local read_file = snap.get("preview.common.read-file") 4 | local loading = snap.get("loading") 5 | local syntax = snap.get("preview.common.syntax") 6 | local function _1_(request) 7 | local function _2_() 8 | if not request.canceled() then 9 | vim.api.nvim_buf_set_option(request.bufnr, "buftype", "help") 10 | local function _3_() 11 | vim.api.nvim_command(string.format("noautocmd help %s", tostring(request.selection))) 12 | return vim.api.nvim_buf_set_option(request.bufnr, "syntax", "help") 13 | end 14 | return vim.api.nvim_buf_call(request.bufnr, _3_) 15 | else 16 | return nil 17 | end 18 | end 19 | return snap.sync(_2_) 20 | end 21 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/fd/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/fd/file.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local general = snap.get("producer.fd.general") 5 | local file = {} 6 | local args = {"--no-ignore-vcs", "-t", "f"} 7 | file.default = function(request) 8 | local cwd = snap.sync(vim.fn.getcwd) 9 | return general(request, {args = args, cwd = cwd}) 10 | end 11 | file.hidden = function(request) 12 | local cwd = snap.sync(vim.fn.getcwd) 13 | return general(request, {args = {"--hidden", unpack(args)}, cwd = cwd}) 14 | end 15 | file.args = function(new_args) 16 | local function _1_(request) 17 | local cwd = snap.sync(vim.fn.getcwd) 18 | return general(request, {args = tbl.concat(args, new_args), cwd = cwd}) 19 | end 20 | return _1_ 21 | end 22 | return file -------------------------------------------------------------------------------- /lua/snap/producer/vim/marks.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/marks.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local function get_marks(winnr) 5 | local bufnr = vim.api.nvim_win_get_buf(winnr) 6 | local function _1_(mark) 7 | local lnum = mark.pos[2] 8 | local content = (vim.api.nvim_buf_get_lines(bufnr, (lnum - 1), lnum, false))[1] 9 | mark["file"] = vim.api.nvim_buf_get_name(bufnr) 10 | return snap.with_metas(string.format("%s : %s", mark.mark, content), mark) 11 | end 12 | return vim.tbl_map(_1_, vim.fn.getmarklist(bufnr)) 13 | end 14 | local function _4_(_2_) 15 | local _arg_3_ = _2_ 16 | local winnr = _arg_3_["winnr"] 17 | local function _5_(...) 18 | return get_marks(winnr, ...) 19 | end 20 | return snap.sync(_5_) 21 | end 22 | return _4_ -------------------------------------------------------------------------------- /lua/snap/select/jumplist.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/jumplist.fnl" 2 | local _2amodule_name_2a = "snap.select.jumplist" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function select(selection, winnr) 14 | local _let_1_ = selection 15 | local bufnr = _let_1_["bufnr"] 16 | local lnum = _let_1_["lnum"] 17 | local col = _let_1_["col"] 18 | vim.api.nvim_win_set_buf(winnr, bufnr) 19 | vim.api.nvim_win_set_option(winnr, "relativenumber", true) 20 | return vim.api.nvim_win_set_cursor(winnr, {lnum, col}) 21 | end 22 | _2amodule_2a["select"] = select 23 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/consumer/chunk.fnl: -------------------------------------------------------------------------------- 1 | (fn chunk [size tbl] 2 | (var index 1) 3 | (var tbl-size (length tbl)) 4 | (fn [] 5 | (when (> index tbl-size) (lua "return nil")) 6 | (local chunk []) 7 | (while 8 | (and (<= index tbl-size) (< (length chunk) size)) 9 | (table.insert chunk (. tbl index)) 10 | (set index (+ index 1))) 11 | chunk)) 12 | 13 | (let [snap (require :snap)] 14 | (fn [chunk-size producer] 15 | "Chunks up a producer. Used instead of debouncing" 16 | (fn [request] 17 | (each [results (snap.consume producer request)] 18 | ;; Collect the count of the results 19 | (if 20 | (and (= (type results) :table) (> (length results) 0)) 21 | (each [part (chunk chunk-size results)] 22 | (coroutine.yield part)) 23 | (coroutine.yield results)))))) 24 | -------------------------------------------------------------------------------- /lua/snap/producer/fd/directory.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/fd/directory.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local general = snap.get("producer.fd.general") 5 | local directory = {} 6 | local args = {"--no-ignore-vcs", "-t", "d"} 7 | directory.default = function(request) 8 | local cwd = snap.sync(vim.fn.getcwd) 9 | return general(request, {args = args, cwd = cwd}) 10 | end 11 | directory.hidden = function(request) 12 | local cwd = snap.sync(vim.fn.getcwd) 13 | return general(request, {args = {"--hidden", unpack(args)}, cwd = cwd}) 14 | end 15 | directory.args = function(new_args) 16 | local function _1_(request) 17 | local cwd = snap.sync(vim.fn.getcwd) 18 | return general(request, {args = tbl.concat(args, new_args), cwd = cwd}) 19 | end 20 | return _1_ 21 | end 22 | return directory -------------------------------------------------------------------------------- /lua/snap/producer/git/log.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/git/log.fnl" 2 | local snap = require("snap") 3 | local general = require("snap.producer.git.general") 4 | local function process_line(line) 5 | local _end = line:find(" ") 6 | return snap.with_metas(line:sub(1, 200), {hash = line:sub(1, (_end - 1)), comment = line:sub((_end + 1), -1)}) 7 | end 8 | local function _1_(request) 9 | local cwd = snap.sync(vim.fn.getcwd) 10 | local function _2_(_241) 11 | return general(_241, {args = {"log", "--oneline"}, cwd = cwd}) 12 | end 13 | for results in snap.consume(_2_, request) do 14 | local _3_ = type(results) 15 | if (_3_ == "table") then 16 | coroutine.yield(vim.tbl_map(process_line, results)) 17 | elseif (_3_ == "nil") then 18 | coroutine.yield(nil) 19 | else 20 | end 21 | end 22 | return nil 23 | end 24 | return _1_ -------------------------------------------------------------------------------- /lua/snap/consumer/fzy/filter.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/fzy/filter.fnl" 2 | local snap = require("snap") 3 | local fzy = require("fzy") 4 | local function _1_(producer) 5 | local function filter(filter0, results) 6 | if (filter0 == "") then 7 | return results 8 | else 9 | local function _2_(_241) 10 | return fzy.has_match(filter0, tostring(_241)) 11 | end 12 | return vim.tbl_filter(_2_, results) 13 | end 14 | end 15 | local function _4_(request) 16 | for results in snap.consume(producer, request) do 17 | local _5_ = type(results) 18 | if (_5_ == "table") then 19 | coroutine.yield(filter(request.filter, results)) 20 | elseif (_5_ == "nil") then 21 | coroutine.yield(nil) 22 | else 23 | end 24 | end 25 | return nil 26 | end 27 | return _4_ 28 | end 29 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/vim/currentbuffer.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/currentbuffer.fnl" 2 | local snap = require("snap") 3 | local function _3_(_1_) 4 | local _arg_2_ = _1_ 5 | local winnr = _arg_2_["winnr"] 6 | local bufnr 7 | local function _4_(...) 8 | return vim.api.nvim_win_get_buf(winnr, ...) 9 | end 10 | bufnr = snap.sync(_4_) 11 | local filename 12 | local function _5_(...) 13 | return vim.api.nvim_buf_get_name(bufnr, ...) 14 | end 15 | filename = snap.sync(_5_) 16 | local contents 17 | local function _6_(...) 18 | return vim.api.nvim_buf_get_lines(bufnr, 0, -1, false, ...) 19 | end 20 | contents = snap.sync(_6_) 21 | local results = {} 22 | for row, line in ipairs(contents) do 23 | table.insert(results, snap.with_metas(line, {filename = filename, row = row})) 24 | end 25 | return coroutine.yield(results) 26 | end 27 | return _3_ -------------------------------------------------------------------------------- /lua/snap/consumer/fzy/score.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/fzy/score.fnl" 2 | local snap = require("snap") 3 | local fzy = require("fzy") 4 | local function _1_(producer) 5 | local function _2_(request) 6 | for results in snap.consume(producer, request) do 7 | local _3_ = type(results) 8 | if (_3_ == "table") then 9 | local function _5_() 10 | if (request.filter == "") then 11 | return results 12 | else 13 | local function _4_(_241) 14 | return snap.with_meta(_241, "score", fzy.score(request.filter, tostring(_241))) 15 | end 16 | return vim.tbl_map(_4_, results) 17 | end 18 | end 19 | coroutine.yield(_5_()) 20 | elseif (_3_ == "nil") then 21 | coroutine.yield(nil) 22 | else 23 | end 24 | end 25 | return nil 26 | end 27 | return _2_ 28 | end 29 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/ripgrep/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/ripgrep/file.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local general = snap.get("producer.ripgrep.general") 5 | local file = {} 6 | local args = {"--line-buffered", "--files"} 7 | file.default = function(request) 8 | local cwd = snap.sync(vim.fn.getcwd) 9 | return general(request, {args = args, cwd = cwd}) 10 | end 11 | file.hidden = function(request) 12 | local cwd = snap.sync(vim.fn.getcwd) 13 | return general(request, {args = {"--hidden", unpack(args)}, cwd = cwd}) 14 | end 15 | file.args = function(new_args, cwd) 16 | local args0 = tbl.concat(args, new_args) 17 | local absolute = (cwd ~= nil) 18 | local function _1_(request) 19 | local cwd0 = (cwd or snap.sync(vim.fn.getcwd)) 20 | return general(request, {args = args0, cwd = cwd0, absolute = absolute}) 21 | end 22 | return _1_ 23 | end 24 | return file -------------------------------------------------------------------------------- /lua/snap/consumer/fzy/positions.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/fzy/positions.fnl" 2 | local snap = require("snap") 3 | local fzy = require("fzy") 4 | local function _1_(producer) 5 | local function _2_(request) 6 | for results in snap.consume(producer, request) do 7 | local _3_ = type(results) 8 | if (_3_ == "table") then 9 | local function _5_() 10 | if (request.filter == "") then 11 | return results 12 | else 13 | local function _4_(result) 14 | return snap.with_meta(result, "positions", fzy.positions(request.filter, tostring(result))) 15 | end 16 | return vim.tbl_map(_4_, results) 17 | end 18 | end 19 | coroutine.yield(_5_()) 20 | elseif (_3_ == "nil") then 21 | coroutine.yield(nil) 22 | else 23 | end 24 | end 25 | return nil 26 | end 27 | return _2_ 28 | end 29 | return _1_ -------------------------------------------------------------------------------- /lua/snap/consumer/chunk.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/chunk.fnl" 2 | local function chunk(size, tbl) 3 | local index = 1 4 | local tbl_size = #tbl 5 | local function _1_() 6 | if (index > tbl_size) then 7 | return nil 8 | else 9 | end 10 | local chunk0 = {} 11 | while ((index <= tbl_size) and (#chunk0 < size)) do 12 | table.insert(chunk0, tbl[index]) 13 | index = (index + 1) 14 | end 15 | return chunk0 16 | end 17 | return _1_ 18 | end 19 | local snap = require("snap") 20 | local function _3_(chunk_size, producer) 21 | local function _4_(request) 22 | for results in snap.consume(producer, request) do 23 | if ((type(results) == "table") and (#results > 0)) then 24 | for part in chunk(chunk_size, results) do 25 | coroutine.yield(part) 26 | end 27 | else 28 | coroutine.yield(results) 29 | end 30 | end 31 | return nil 32 | end 33 | return _4_ 34 | end 35 | return _3_ -------------------------------------------------------------------------------- /fnl/snap/select/vim/mark.fnl: -------------------------------------------------------------------------------- 1 | (module snap.select.vim.mark) 2 | 3 | (defn select [selection winnr type] 4 | (var winnr winnr) 5 | (local path (vim.fn.fnamemodify selection.file ":p")) 6 | (let [buffer (vim.fn.bufnr path true)] 7 | (vim.api.nvim_buf_set_option buffer :buflisted true) 8 | (match type 9 | nil (when (not= winnr false) 10 | (vim.api.nvim_win_set_buf winnr buffer)) 11 | :vsplit (do 12 | (vim.api.nvim_command "vsplit") 13 | (vim.api.nvim_win_set_buf 0 buffer) 14 | (set winnr (vim.api.nvim_get_current_win))) 15 | :split (do 16 | (vim.api.nvim_command "split") 17 | (vim.api.nvim_win_set_buf 0 buffer) 18 | (set winnr (vim.api.nvim_get_current_win))) 19 | :tab (do 20 | (vim.api.nvim_command "tabnew") 21 | (vim.api.nvim_win_set_buf 0 buffer) 22 | (set winnr (vim.api.nvim_get_current_win)))) 23 | (vim.api.nvim_win_set_cursor winnr [(. selection.pos 2) (. selection.pos 3)]))) 24 | -------------------------------------------------------------------------------- /lua/snap/preview/git/log.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/git/log.fnl" 2 | local snap = require("snap") 3 | local string = require("snap.common.string") 4 | local io = require("snap.common.io") 5 | local function _1_(request) 6 | local cwd = snap.sync(vim.fn.getcwd) 7 | local contents, error = nil, nil 8 | local function _3_() 9 | local _2_ = {"diff-tree", "-p", request.selection.hash} 10 | local function _4_(...) 11 | return io.system("git", _2_, cwd, ...) 12 | end 13 | return _4_ 14 | end 15 | contents, error = snap.async(_3_()) 16 | local function _5_() 17 | if not request.canceled() then 18 | vim.api.nvim_buf_set_lines(request.bufnr, 0, -1, false, string.split(contents)) 19 | local function _6_() 20 | return vim.api.nvim_command("set filetype=git") 21 | end 22 | return vim.api.nvim_buf_call(request.bufnr, _6_) 23 | else 24 | return nil 25 | end 26 | end 27 | return snap.sync(_5_) 28 | end 29 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/ripgrep/general.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/ripgrep/general.fnl" 2 | local snap = require("snap") 3 | local io = snap.get("common.io") 4 | local string = snap.get("common.string") 5 | local function _3_(request, _1_) 6 | local _arg_2_ = _1_ 7 | local args = _arg_2_["args"] 8 | local cwd = _arg_2_["cwd"] 9 | local absolute = _arg_2_["absolute"] 10 | for data, err, cancel in io.spawn("rg", args, cwd) do 11 | if request.canceled() then 12 | cancel() 13 | coroutine.yield(nil) 14 | elseif (err ~= "") then 15 | coroutine.yield(nil) 16 | elseif (data == "") then 17 | snap.continue() 18 | else 19 | local results = string.split(data) 20 | if absolute then 21 | local function _4_(_241) 22 | return string.format("%s/%s", cwd, _241) 23 | end 24 | results = vim.tbl_map(_4_, results) 25 | else 26 | end 27 | coroutine.yield(results) 28 | end 29 | end 30 | return nil 31 | end 32 | return _3_ -------------------------------------------------------------------------------- /lua/snap/common/string.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/string.fnl" 2 | local _2amodule_name_2a = "snap.common.string" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function split(str) 14 | local tbl_17_auto = {} 15 | local i_18_auto = #tbl_17_auto 16 | for _, line in ipairs(vim.split(str, "\n", true)) do 17 | local val_19_auto 18 | do 19 | local trimmed = vim.trim(line) 20 | if (trimmed ~= "") then 21 | val_19_auto = trimmed 22 | else 23 | val_19_auto = nil 24 | end 25 | end 26 | if (nil ~= val_19_auto) then 27 | i_18_auto = (i_18_auto + 1) 28 | do end (tbl_17_auto)[i_18_auto] = val_19_auto 29 | else 30 | end 31 | end 32 | return tbl_17_auto 33 | end 34 | _2amodule_2a["split"] = split 35 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/loading/init.fnl: -------------------------------------------------------------------------------- 1 | (fn center-with-text-width [text text-width width] 2 | "Centers by using a text width" 3 | (let [space (string.rep " " (/ (- width text-width) 2))] 4 | (.. space text))) 5 | 6 | (fn center [text width] 7 | "Center text for loading screen" 8 | (center-with-text-width text (string.len text) width)) 9 | 10 | (fn [width height counter] 11 | "Create a basic loading screen" 12 | (local dots (string.rep "." (% counter 5))) 13 | (local space (string.rep " " (- 5 (string.len dots)))) 14 | (local loading-with-dots (.. "│" space dots " Loading " dots space "│")) 15 | (local text-width (string.len loading-with-dots)) 16 | (local loading []) 17 | 18 | (for [_ 1 (- (math.floor (/ height 2)) 1)] 19 | (table.insert loading "")) 20 | 21 | (table.insert loading 22 | (center-with-text-width (.. "╭" (string.rep "─" 19) "╮") text-width width)) 23 | (table.insert loading (center loading-with-dots width)) 24 | (table.insert loading 25 | (center-with-text-width (.. "╰" (string.rep "─" 19) "╯") text-width width)) 26 | loading) 27 | -------------------------------------------------------------------------------- /lua/snap/producer/request.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/request.fnl" 2 | local _2amodule_name_2a = "snap.producer.request" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local _ = nil 14 | _2amodule_locals_2a["_"] = _ 15 | local function create(config) 16 | assert((type(config.body) == "table"), "body must be a table") 17 | assert((type(config.cancel) == "function"), "cancel must be a function") 18 | local request = {["is-canceled"] = false} 19 | for key, value in pairs(config.body) do 20 | request[key] = value 21 | end 22 | request.cancel = function() 23 | request["is-canceled"] = true 24 | return nil 25 | end 26 | request.canceled = function() 27 | return (request["is-canceled"] or config.cancel(request)) 28 | end 29 | return request 30 | end 31 | _2amodule_2a["create"] = create 32 | return _2amodule_2a -------------------------------------------------------------------------------- /lua/snap/producer/vim/help.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/vim/help.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local read_file = snap.get("preview.common.read-file") 5 | local function _1_() 6 | local tags_set = {} 7 | local tag_files 8 | local function _3_() 9 | local _2_ = vim.o.runtimepath 10 | local function _4_(...) 11 | return vim.fn.globpath(_2_, "doc/tags", 1, 1, ...) 12 | end 13 | return _4_ 14 | end 15 | tag_files = snap.sync(_3_()) 16 | for _, tag_file in ipairs(tag_files) do 17 | local tags = {} 18 | local contents = read_file(tag_file) 19 | for _0, line in ipairs(contents) do 20 | if not line:match("^!_TAG_") then 21 | local _local_5_ = vim.split(line, string.char(9), true) 22 | local name = _local_5_[1] 23 | if not tags_set[name] then 24 | tags_set[name] = true 25 | table.insert(tags, name) 26 | else 27 | end 28 | else 29 | end 30 | end 31 | coroutine.yield(tags) 32 | end 33 | return nil 34 | end 35 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/select/common/file.fnl: -------------------------------------------------------------------------------- 1 | (fn [get-data] 2 | (fn [selection winnr type] 3 | (var winnr winnr) 4 | (let [{: filename : line : column} (get-data selection)] 5 | (local path (vim.fn.fnamemodify filename ":p")) 6 | (let [buffer (vim.fn.bufnr path true)] 7 | (vim.api.nvim_buf_set_option buffer :buflisted true) 8 | (match type 9 | nil (when (not= winnr false) 10 | (vim.api.nvim_win_set_buf winnr buffer)) 11 | :vsplit (do 12 | (vim.api.nvim_command "vsplit") 13 | (vim.api.nvim_win_set_buf 0 buffer) 14 | (set winnr (vim.api.nvim_get_current_win))) 15 | :split (do 16 | (vim.api.nvim_command "split") 17 | (vim.api.nvim_win_set_buf 0 buffer) 18 | (set winnr (vim.api.nvim_get_current_win))) 19 | :tab (do 20 | (vim.api.nvim_command "tabnew") 21 | (vim.api.nvim_win_set_buf 0 buffer) 22 | (set winnr (vim.api.nvim_get_current_win)))) 23 | (when (not= line nil) 24 | (vim.api.nvim_win_set_cursor winnr [line (if (= column nil) 0 column)])))))) 25 | -------------------------------------------------------------------------------- /lua/snap/loading/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/loading/init.fnl" 2 | local function center_with_text_width(text, text_width, width) 3 | local space = string.rep(" ", ((width - text_width) / 2)) 4 | return (space .. text) 5 | end 6 | local function center(text, width) 7 | return center_with_text_width(text, string.len(text), width) 8 | end 9 | local function _1_(width, height, counter) 10 | local dots = string.rep(".", (counter % 5)) 11 | local space = string.rep(" ", (5 - string.len(dots))) 12 | local loading_with_dots = ("\226\148\130" .. space .. dots .. " Loading " .. dots .. space .. "\226\148\130") 13 | local text_width = string.len(loading_with_dots) 14 | local loading = {} 15 | for _ = 1, (math.floor((height / 2)) - 1) do 16 | table.insert(loading, "") 17 | end 18 | table.insert(loading, center_with_text_width(("\226\149\173" .. string.rep("\226\148\128", 19) .. "\226\149\174"), text_width, width)) 19 | table.insert(loading, center(loading_with_dots, width)) 20 | table.insert(loading, center_with_text_width(("\226\149\176" .. string.rep("\226\148\128", 19) .. "\226\149\175"), text_width, width)) 21 | return loading 22 | end 23 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/luv/general.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/luv/general.fnl" 2 | local snap = require("snap") 3 | local function _1_(types, cwd) 4 | local dirs = {cwd} 5 | local relative_dir 6 | local function _2_(...) 7 | return vim.fn.fnamemodify(cwd, ":.", ...) 8 | end 9 | relative_dir = snap.sync(_2_) 10 | while (#dirs > 0) do 11 | local dir = table.remove(dirs) 12 | local handle = vim.loop.fs_scandir(dir) 13 | local results = {} 14 | while handle do 15 | local name, t = vim.loop.fs_scandir_next(handle) 16 | if name then 17 | local path = (dir .. "/" .. name) 18 | local relative_path 19 | local function _3_(...) 20 | return vim.fn.fnamemodify(path, ":.", ...) 21 | end 22 | relative_path = snap.sync(_3_) 23 | if types[t] then 24 | table.insert(results, relative_path) 25 | else 26 | end 27 | if (t == "directory") then 28 | table.insert(dirs, path) 29 | else 30 | end 31 | else 32 | break 33 | end 34 | end 35 | coroutine.yield(results) 36 | end 37 | return nil 38 | end 39 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/common/buffer.fnl: -------------------------------------------------------------------------------- 1 | (module snap.common.buffer) 2 | 3 | ;; Creates a namespace for highlighting 4 | (local namespace (vim.api.nvim_create_namespace :Snap)) 5 | 6 | (defn set-lines [bufnr start end lines] 7 | "Helper to set lines to results view" 8 | (vim.api.nvim_buf_set_lines bufnr start end false lines)) 9 | 10 | (defn add-highlight [bufnr hl row col-start col-end] 11 | "Helper function for adding highlighting" 12 | (vim.api.nvim_buf_add_highlight bufnr namespace hl row col-start col-end)) 13 | 14 | (defn add-selected-highlight [bufnr row] 15 | "Helper function for adding selected highlighting" 16 | (vim.api.nvim_buf_add_highlight bufnr namespace :SnapMultiSelect (- row 1) 0 -1)) 17 | 18 | (defn add-positions-highlight [bufnr row positions] 19 | "Helper function for adding positions highlights" 20 | (local line (- row 1)) 21 | (each [_ col (ipairs positions)] 22 | (add-highlight bufnr :SnapPosition line (- col 1) col))) 23 | 24 | (defn create [] 25 | "Creates a scratch buffer" 26 | (vim.api.nvim_create_buf false true)) 27 | 28 | (defn delete [bufnr] 29 | "Deletes a scratch buffer" 30 | (vim.api.nvim_buf_delete bufnr {:force true})) 31 | 32 | -------------------------------------------------------------------------------- /lua/snap/consumer/fzy/all.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/fzy/all.fnl" 2 | local snap = require("snap") 3 | local fzy = require("fzy") 4 | local function _1_(producer) 5 | local function filter(filter0, results) 6 | if (filter0 == "") then 7 | return results 8 | else 9 | local processed = {} 10 | local function _3_(_241) 11 | return tostring(_241) 12 | end 13 | for _, _2_ in ipairs(fzy.filter(filter0, vim.tbl_map(_3_, results))) do 14 | local _each_4_ = _2_ 15 | local index = _each_4_[1] 16 | local positions = _each_4_[2] 17 | local score = _each_4_[3] 18 | table.insert(processed, snap.with_metas(results[index], {positions = positions, score = score})) 19 | end 20 | return processed 21 | end 22 | end 23 | local function _6_(request) 24 | for results in snap.consume(producer, request) do 25 | local _7_ = type(results) 26 | if (_7_ == "table") then 27 | coroutine.yield(filter(request.filter, results)) 28 | elseif (_7_ == "nil") then 29 | coroutine.yield(nil) 30 | else 31 | end 32 | end 33 | return nil 34 | end 35 | return _6_ 36 | end 37 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/preview/common/syntax.fnl: -------------------------------------------------------------------------------- 1 | (let [snap-io (require :snap.common.io)] 2 | (fn [file-name bufnr] 3 | (local has-treesitter (pcall require :nvim-treesitter)) 4 | (local (_ highlight) (pcall require :nvim-treesitter.highlight)) 5 | (local (_ parsers) (pcall require :nvim-treesitter.parsers)) 6 | (local fake-path (.. (vim.fn.tempname) "/" file-name)) 7 | (vim.api.nvim_buf_set_name bufnr fake-path) 8 | (vim.api.nvim_buf_call bufnr (fn [] 9 | ;; Use the fake path to enable ftdetection 10 | (local eventignore (vim.api.nvim_get_option "eventignore")) 11 | (vim.api.nvim_set_option "eventignore" "FileType") 12 | (vim.api.nvim_command "filetype detect") 13 | (vim.api.nvim_set_option "eventignore" eventignore))) 14 | ;; Add syntax highlighting 15 | (local filetype (vim.api.nvim_buf_get_option bufnr "filetype")) 16 | (when 17 | (not= filetype "") 18 | (if 19 | has-treesitter 20 | (let [lang (parsers.ft_to_lang filetype)] 21 | (if 22 | (parsers.has_parser lang) 23 | (highlight.attach bufnr lang) 24 | (vim.api.nvim_buf_set_option bufnr "syntax" filetype))) 25 | (vim.api.nvim_buf_set_option bufnr "syntax" filetype))))) 26 | -------------------------------------------------------------------------------- /fnl/snap/consumer/positions.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap)] 2 | (fn get-positions [filter result] 3 | (if 4 | (= filter "") 5 | [] 6 | (do 7 | (local positions {}) 8 | (local filter (string.upper filter)) 9 | (local result (string.upper (tostring result))) 10 | (each [c (filter:gmatch ".")] 11 | (var last-index 1) 12 | (while true 13 | (local index (result:find c last-index true)) 14 | (if 15 | (not= index nil) 16 | (do 17 | (set last-index (+ index 1)) 18 | (tset positions index true)) 19 | (lua "break")))) 20 | (vim.tbl_keys positions)))) 21 | 22 | (fn [producer] 23 | (fn [request] 24 | (each [data (snap.consume producer request)] 25 | (match (type data) 26 | :table (if 27 | (= (length data) 0) 28 | (snap.continue) 29 | (fn positions [result] 30 | (get-positions request.filter result)) 31 | (coroutine.yield 32 | (vim.tbl_map 33 | #(snap.with_meta $1 :positions positions) 34 | data))) 35 | :nil (coroutine.yield nil)))))) 36 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /lua/snap/preview/common/syntax.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/common/syntax.fnl" 2 | local snap_io = require("snap.common.io") 3 | local function _1_(file_name, bufnr) 4 | local has_treesitter = pcall(require, "nvim-treesitter") 5 | local _, highlight = pcall(require, "nvim-treesitter.highlight") 6 | local _0, parsers = pcall(require, "nvim-treesitter.parsers") 7 | local fake_path = (vim.fn.tempname() .. "/" .. file_name) 8 | vim.api.nvim_buf_set_name(bufnr, fake_path) 9 | local function _2_() 10 | local eventignore = vim.api.nvim_get_option("eventignore") 11 | vim.api.nvim_set_option("eventignore", "FileType") 12 | vim.api.nvim_command("filetype detect") 13 | return vim.api.nvim_set_option("eventignore", eventignore) 14 | end 15 | vim.api.nvim_buf_call(bufnr, _2_) 16 | local filetype = vim.api.nvim_buf_get_option(bufnr, "filetype") 17 | if (filetype ~= "") then 18 | if has_treesitter then 19 | local lang = parsers.ft_to_lang(filetype) 20 | if parsers.has_parser(lang) then 21 | return highlight.attach(bufnr, lang) 22 | else 23 | return vim.api.nvim_buf_set_option(bufnr, "syntax", filetype) 24 | end 25 | else 26 | return vim.api.nvim_buf_set_option(bufnr, "syntax", filetype) 27 | end 28 | else 29 | return nil 30 | end 31 | end 32 | return _1_ -------------------------------------------------------------------------------- /fnl/snap/common/window.fnl: -------------------------------------------------------------------------------- 1 | (module snap.common.window) 2 | 3 | (defn create [bufnr {: width : height : row : col : focusable : enter : title}] 4 | "Creates a window with specified options" 5 | (vim.api.nvim_open_win bufnr (if (= enter nil) false enter) {: width 6 | : height 7 | : row 8 | : col 9 | : focusable 10 | :title_pos (if (not= title nil) :center nil) 11 | :title (if (not= title nil) (string.format " %s " title) nil) 12 | :noautocmd true 13 | :relative :editor 14 | :anchor :NW 15 | :style :minimal 16 | :border ["╭" "─" "╮" "│" "╯" "─" "╰" "│"]})) 17 | 18 | (defn update [winnr {: width : height : row : col : focusable}] 19 | "Updates a window with specified options" 20 | (when (vim.api.nvim_win_is_valid winnr) 21 | (vim.api.nvim_win_set_config winnr {: width 22 | : height 23 | : row 24 | : col 25 | : focusable 26 | :relative :editor}))) 27 | 28 | (defn close [winnr] 29 | (vim.api.nvim_win_close winnr true)) 30 | -------------------------------------------------------------------------------- /fnl/snap/common/register.fnl: -------------------------------------------------------------------------------- 1 | (module snap.common.register {require {tbl snap.common.tbl}}) 2 | 3 | ;; Prefill with commands key 4 | (local commands {}) 5 | 6 | (defn buf-map [bufnr modes keys fnc opts] 7 | "Creates a buffer mapping and creates callable signiture" 8 | (each [_ key (ipairs keys)] 9 | (each [_ mode (ipairs modes)] 10 | (vim.keymap.set mode key fnc (tbl.merge (or opts {:nowait true}) {:buffer bufnr}))))) 11 | 12 | (fn handle-string [tbl] 13 | "When a table is provided just return, if a string is provided wrap in the table" 14 | (match (type tbl) 15 | :table tbl 16 | :string [tbl])) 17 | 18 | (defn map [modes keys fnc opts] 19 | "Creates a global mapping" 20 | (each [_ key (ipairs (handle-string keys))] 21 | (each [_ mode (ipairs (handle-string modes))] 22 | (vim.keymap.set mode key fnc (or opts {}))))) 23 | 24 | ;; You should tend not to use this directly and instead just use snap.map with a command name 25 | (defn command [name fnc] 26 | "Adds a named function to the global :Snap command" 27 | ;; When the Snap command isn't registered add it 28 | (when 29 | (= (length commands) 0) 30 | (vim.api.nvim_create_user_command 31 | :Snap 32 | (fn [opts] 33 | (local name (. opts.fargs 1)) 34 | (when (?. commands name) 35 | ((. commands name)))) 36 | {:nargs 1 37 | :complete (fn [] (vim.tbl_keys commands))})) 38 | 39 | (tset commands name fnc)) 40 | -------------------------------------------------------------------------------- /fnl/snap/producer/ripgrep/vimgrep.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | tbl (snap.get :common.tbl) 3 | general (snap.get :producer.ripgrep.general)] 4 | (local vimgrep {}) 5 | (local args [:--line-buffered :-M 100 :--vimgrep]) 6 | (local line-args [:--line-buffered :-M 100 :--no-heading :--column]) 7 | (fn vimgrep.default [request] 8 | (let [cwd (snap.sync vim.fn.getcwd)] 9 | (general request {:args (tbl.concat args [request.filter]) : cwd}))) 10 | (fn vimgrep.hidden [request] 11 | (let [cwd (snap.sync vim.fn.getcwd)] 12 | (general request {:args (tbl.concat args [:--hidden request.filter]) : cwd}))) 13 | (fn vimgrep.line [new-args cwd] 14 | (let [args (tbl.concat line-args new-args) 15 | absolute (not= cwd nil)] 16 | (fn [request] 17 | (let [cmd (or cwd (snap.sync vim.fn.getcwd))] 18 | (general request {:args (tbl.concat args [request.filter]) : cwd : absolute}))))) 19 | (fn vimgrep.open_files [request] 20 | (local open_files (snap.sync #(vim.tbl_map #(vim.api.nvim_buf_get_name $1) (vim.api.nvim_list_bufs)))) 21 | (let [cwd (snap.sync vim.fn.getcwd)] 22 | (general request {:args (tbl.concat args (tbl.concat open_files [request.filter])) : cwd}))) 23 | (fn vimgrep.args [new-args cwd] 24 | (let [args (tbl.concat args new-args) 25 | absolute (not= cwd nil)] 26 | (fn [request] 27 | (let [cwd (or cwd (snap.sync vim.fn.getcwd))] 28 | (general request {:args (tbl.concat args [request.filter]) : cwd : absolute}))))) 29 | vimgrep) 30 | -------------------------------------------------------------------------------- /lua/snap/select/vim/mark.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/vim/mark.fnl" 2 | local _2amodule_name_2a = "snap.select.vim.mark" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function select(selection, winnr, type) 14 | local winnr0 = winnr 15 | local path = vim.fn.fnamemodify(selection.file, ":p") 16 | local buffer = vim.fn.bufnr(path, true) 17 | vim.api.nvim_buf_set_option(buffer, "buflisted", true) 18 | do 19 | local _1_ = type 20 | if (_1_ == nil) then 21 | if (winnr0 ~= false) then 22 | vim.api.nvim_win_set_buf(winnr0, buffer) 23 | else 24 | end 25 | elseif (_1_ == "vsplit") then 26 | vim.api.nvim_command("vsplit") 27 | vim.api.nvim_win_set_buf(0, buffer) 28 | winnr0 = vim.api.nvim_get_current_win() 29 | elseif (_1_ == "split") then 30 | vim.api.nvim_command("split") 31 | vim.api.nvim_win_set_buf(0, buffer) 32 | winnr0 = vim.api.nvim_get_current_win() 33 | elseif (_1_ == "tab") then 34 | vim.api.nvim_command("tabnew") 35 | vim.api.nvim_win_set_buf(0, buffer) 36 | winnr0 = vim.api.nvim_get_current_win() 37 | else 38 | end 39 | end 40 | return vim.api.nvim_win_set_cursor(winnr0, {selection.pos[2], selection.pos[3]}) 41 | end 42 | _2amodule_2a["select"] = select 43 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/preview/common/read-file.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | snap-io (snap.get :common.io)] 3 | (fn get-encoding [path] 4 | (local handle (io.popen (string.format "file -n -b --mime-encoding '%s'" path))) 5 | (local encoding (string.gsub (handle:read "*a") "^%s*(.-)%s*$" "%1") ) 6 | (handle:close) 7 | encoding) 8 | 9 | ;; Make file size for preview 10 | (local max-size (* 1024 500)) 11 | 12 | (fn [path on-resume] 13 | (var preview nil) 14 | (if 15 | (not (snap-io.exists path)) 16 | (set preview ["File does not exist"]) 17 | (= (get-encoding path) :binary) 18 | (set preview ["Binary file"]) 19 | (> (snap-io.size path) max-size) 20 | (set preview ["File too large to preview"]) 21 | (do 22 | (var databuffer "") 23 | (var reader (coroutine.create snap-io.read)) 24 | (fn free [cancel] 25 | (when cancel (cancel)) 26 | (set databuffer "") 27 | (set reader nil)) 28 | (while (not= (coroutine.status reader) :dead) 29 | (when on-resume (on-resume)) 30 | (local (_ cancel data) (coroutine.resume reader path)) 31 | (when 32 | (not= data nil) 33 | (set databuffer (.. databuffer data))) 34 | ;; yield to main thread and cancel if needed 35 | (snap.continue (partial free cancel))) 36 | (set preview []) 37 | (each [line (databuffer:gmatch "([^\r\n]*)(\r?\n?)")] 38 | (when (not (and (= line "") (= %2 ""))) 39 | (table.insert preview line))) 40 | (free))) 41 | preview)) 42 | -------------------------------------------------------------------------------- /lua/snap/consumer/positions.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/positions.fnl" 2 | local snap = require("snap") 3 | local function get_positions(filter, result) 4 | if (filter == "") then 5 | return {} 6 | else 7 | local positions = {} 8 | local filter0 = string.upper(filter) 9 | local result0 = string.upper(tostring(result)) 10 | for c in filter0:gmatch(".") do 11 | local last_index = 1 12 | while true do 13 | local index = result0:find(c, last_index, true) 14 | if (index ~= nil) then 15 | last_index = (index + 1) 16 | do end (positions)[index] = true 17 | else 18 | break 19 | end 20 | end 21 | end 22 | return vim.tbl_keys(positions) 23 | end 24 | end 25 | local function _3_(producer) 26 | local function _4_(request) 27 | for data in snap.consume(producer, request) do 28 | local _5_ = type(data) 29 | if (_5_ == "table") then 30 | if (#data == 0) then 31 | snap.continue() 32 | else 33 | local function positions(result) 34 | return get_positions(request.filter, result) 35 | end 36 | if positions then 37 | local function _6_(_241) 38 | return snap.with_meta(_241, "positions", positions) 39 | end 40 | coroutine.yield(vim.tbl_map(_6_, data)) 41 | else 42 | end 43 | end 44 | elseif (_5_ == "nil") then 45 | coroutine.yield(nil) 46 | else 47 | end 48 | end 49 | return nil 50 | end 51 | return _4_ 52 | end 53 | return _3_ -------------------------------------------------------------------------------- /lua/snap/select/common/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/common/file.fnl" 2 | local function _1_(get_data) 3 | local function _2_(selection, winnr, type) 4 | local winnr0 = winnr 5 | local _let_3_ = get_data(selection) 6 | local filename = _let_3_["filename"] 7 | local line = _let_3_["line"] 8 | local column = _let_3_["column"] 9 | local path = vim.fn.fnamemodify(filename, ":p") 10 | local buffer = vim.fn.bufnr(path, true) 11 | vim.api.nvim_buf_set_option(buffer, "buflisted", true) 12 | do 13 | local _4_ = type 14 | if (_4_ == nil) then 15 | if (winnr0 ~= false) then 16 | vim.api.nvim_win_set_buf(winnr0, buffer) 17 | else 18 | end 19 | elseif (_4_ == "vsplit") then 20 | vim.api.nvim_command("vsplit") 21 | vim.api.nvim_win_set_buf(0, buffer) 22 | winnr0 = vim.api.nvim_get_current_win() 23 | elseif (_4_ == "split") then 24 | vim.api.nvim_command("split") 25 | vim.api.nvim_win_set_buf(0, buffer) 26 | winnr0 = vim.api.nvim_get_current_win() 27 | elseif (_4_ == "tab") then 28 | vim.api.nvim_command("tabnew") 29 | vim.api.nvim_win_set_buf(0, buffer) 30 | winnr0 = vim.api.nvim_get_current_win() 31 | else 32 | end 33 | end 34 | if (line ~= nil) then 35 | local function _7_() 36 | if (column == nil) then 37 | return 0 38 | else 39 | return column 40 | end 41 | end 42 | return vim.api.nvim_win_set_cursor(winnr0, {line, _7_()}) 43 | else 44 | return nil 45 | end 46 | end 47 | return _2_ 48 | end 49 | return _1_ -------------------------------------------------------------------------------- /lua/snap/common/buffer.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/buffer.fnl" 2 | local _2amodule_name_2a = "snap.common.buffer" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local namespace = vim.api.nvim_create_namespace("Snap") 14 | local function set_lines(bufnr, start, _end, lines) 15 | return vim.api.nvim_buf_set_lines(bufnr, start, _end, false, lines) 16 | end 17 | _2amodule_2a["set-lines"] = set_lines 18 | local function add_highlight(bufnr, hl, row, col_start, col_end) 19 | return vim.api.nvim_buf_add_highlight(bufnr, namespace, hl, row, col_start, col_end) 20 | end 21 | _2amodule_2a["add-highlight"] = add_highlight 22 | local function add_selected_highlight(bufnr, row) 23 | return vim.api.nvim_buf_add_highlight(bufnr, namespace, "SnapMultiSelect", (row - 1), 0, -1) 24 | end 25 | _2amodule_2a["add-selected-highlight"] = add_selected_highlight 26 | local function add_positions_highlight(bufnr, row, positions) 27 | local line = (row - 1) 28 | for _, col in ipairs(positions) do 29 | add_highlight(bufnr, "SnapPosition", line, (col - 1), col) 30 | end 31 | return nil 32 | end 33 | _2amodule_2a["add-positions-highlight"] = add_positions_highlight 34 | local function create() 35 | return vim.api.nvim_create_buf(false, true) 36 | end 37 | _2amodule_2a["create"] = create 38 | local function delete(bufnr) 39 | return vim.api.nvim_buf_delete(bufnr, {force = true}) 40 | end 41 | _2amodule_2a["delete"] = delete 42 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/consumer/fzf/init.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | io (snap.get :common.io) 3 | cache (snap.get :consumer.cache) 4 | positions (snap.get :consumer.positions) 5 | tbl (snap.get :common.tbl) 6 | string (snap.get :common.string)] 7 | (fn [producer] 8 | (local cached-producer (cache producer)) 9 | (positions (fn [request] 10 | (local results []) 11 | (each [data (snap.consume cached-producer request)] 12 | (tbl.acc results data) 13 | (snap.continue)) 14 | (local results-string (table.concat (vim.tbl_map #(tostring $1) results) "\n")) 15 | (if 16 | (= request.filter "") 17 | (coroutine.yield results) 18 | (do 19 | (local cwd (snap.sync vim.fn.getcwd)) 20 | (local stdout (vim.loop.new_pipe false)) 21 | (local fzf (io.spawn :fzf [:-f request.filter] cwd stdout)) 22 | 23 | (stdout:write results-string) 24 | (stdout:shutdown) 25 | 26 | (each [data err kill fzf] 27 | (if 28 | (request.canceled) 29 | (do 30 | (kill) 31 | (coroutine.yield nil)) 32 | (not= err "") 33 | (coroutine.yield nil) 34 | (= data "") 35 | (snap.continue) 36 | (do 37 | (local results-indexed {}) 38 | (each [_ result (ipairs results)] 39 | (tset results-indexed (tostring result) result)) 40 | (local filtered-results (string.split data)) 41 | (coroutine.yield (vim.tbl_map #(. results-indexed $1) filtered-results))))) 42 | nil)))))) 43 | -------------------------------------------------------------------------------- /lua/snap/preview/common/read-file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/common/read-file.fnl" 2 | local snap = require("snap") 3 | local snap_io = snap.get("common.io") 4 | local function get_encoding(path) 5 | local handle = io.popen(string.format("file -n -b --mime-encoding '%s'", path)) 6 | local encoding = string.gsub(handle:read("*a"), "^%s*(.-)%s*$", "%1") 7 | handle:close() 8 | return encoding 9 | end 10 | local max_size = (1024 * 500) 11 | local function _1_(path, on_resume) 12 | local preview = nil 13 | if not snap_io.exists(path) then 14 | preview = {"File does not exist"} 15 | elseif (get_encoding(path) == "binary") then 16 | preview = {"Binary file"} 17 | elseif (snap_io.size(path) > max_size) then 18 | preview = {"File too large to preview"} 19 | else 20 | local databuffer = "" 21 | local reader = coroutine.create(snap_io.read) 22 | local function free(cancel) 23 | if cancel then 24 | cancel() 25 | else 26 | end 27 | databuffer = "" 28 | reader = nil 29 | return nil 30 | end 31 | while (coroutine.status(reader) ~= "dead") do 32 | if on_resume then 33 | on_resume() 34 | else 35 | end 36 | local _, cancel, data = coroutine.resume(reader, path) 37 | if (data ~= nil) then 38 | databuffer = (databuffer .. data) 39 | else 40 | end 41 | local function _5_(...) 42 | return free(cancel, ...) 43 | end 44 | snap.continue(_5_) 45 | end 46 | preview = {} 47 | for line in databuffer:gmatch("([^\13\n]*)(\13?\n?)") do 48 | if not ((line == "") and (__fnl_global___252 == "")) then 49 | table.insert(preview, line) 50 | else 51 | end 52 | end 53 | free() 54 | end 55 | return preview 56 | end 57 | return _1_ -------------------------------------------------------------------------------- /lua/snap/consumer/fzf/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/consumer/fzf/init.fnl" 2 | local snap = require("snap") 3 | local io = snap.get("common.io") 4 | local cache = snap.get("consumer.cache") 5 | local positions = snap.get("consumer.positions") 6 | local tbl = snap.get("common.tbl") 7 | local string = snap.get("common.string") 8 | local function _1_(producer) 9 | local cached_producer = cache(producer) 10 | local function _2_(request) 11 | local results = {} 12 | for data in snap.consume(cached_producer, request) do 13 | tbl.acc(results, data) 14 | snap.continue() 15 | end 16 | local results_string 17 | local function _3_(_241) 18 | return tostring(_241) 19 | end 20 | results_string = table.concat(vim.tbl_map(_3_, results), "\n") 21 | if (request.filter == "") then 22 | return coroutine.yield(results) 23 | else 24 | local cwd = snap.sync(vim.fn.getcwd) 25 | local stdout = vim.loop.new_pipe(false) 26 | local fzf = io.spawn("fzf", {"-f", request.filter}, cwd, stdout) 27 | stdout:write(results_string) 28 | stdout:shutdown() 29 | for data, err, kill in fzf do 30 | if request.canceled() then 31 | kill() 32 | coroutine.yield(nil) 33 | elseif (err ~= "") then 34 | coroutine.yield(nil) 35 | elseif (data == "") then 36 | snap.continue() 37 | else 38 | local results_indexed = {} 39 | for _, result in ipairs(results) do 40 | results_indexed[tostring(result)] = result 41 | end 42 | local filtered_results = string.split(data) 43 | local function _4_(_241) 44 | return results_indexed[_241] 45 | end 46 | coroutine.yield(vim.tbl_map(_4_, filtered_results)) 47 | end 48 | end 49 | return nil 50 | end 51 | end 52 | return positions(_2_) 53 | end 54 | return _1_ -------------------------------------------------------------------------------- /lua/snap/producer/ripgrep/vimgrep.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/ripgrep/vimgrep.fnl" 2 | local snap = require("snap") 3 | local tbl = snap.get("common.tbl") 4 | local general = snap.get("producer.ripgrep.general") 5 | local vimgrep = {} 6 | local args = {"--line-buffered", "-M", 100, "--vimgrep"} 7 | local line_args = {"--line-buffered", "-M", 100, "--no-heading", "--column"} 8 | vimgrep.default = function(request) 9 | local cwd = snap.sync(vim.fn.getcwd) 10 | return general(request, {args = tbl.concat(args, {request.filter}), cwd = cwd}) 11 | end 12 | vimgrep.hidden = function(request) 13 | local cwd = snap.sync(vim.fn.getcwd) 14 | return general(request, {args = tbl.concat(args, {"--hidden", request.filter}), cwd = cwd}) 15 | end 16 | vimgrep.line = function(new_args, cwd) 17 | local args0 = tbl.concat(line_args, new_args) 18 | local absolute = (cwd ~= nil) 19 | local function _1_(request) 20 | local cmd = (cwd or snap.sync(vim.fn.getcwd)) 21 | return general(request, {args = tbl.concat(args0, {request.filter}), cwd = cwd, absolute = absolute}) 22 | end 23 | return _1_ 24 | end 25 | vimgrep.open_files = function(request) 26 | local open_files 27 | local function _2_() 28 | local function _3_(_2410) 29 | return vim.api.nvim_buf_get_name(_2410) 30 | end 31 | return vim.tbl_map(_3_, vim.api.nvim_list_bufs()) 32 | end 33 | open_files = snap.sync(_2_) 34 | local cwd = snap.sync(vim.fn.getcwd) 35 | return general(request, {args = tbl.concat(args, tbl.concat(open_files, {request.filter})), cwd = cwd}) 36 | end 37 | vimgrep.args = function(new_args, cwd) 38 | local args0 = tbl.concat(args, new_args) 39 | local absolute = (cwd ~= nil) 40 | local function _4_(request) 41 | local cwd0 = (cwd or snap.sync(vim.fn.getcwd)) 42 | return general(request, {args = tbl.concat(args0, {request.filter}), cwd = cwd0, absolute = absolute}) 43 | end 44 | return _4_ 45 | end 46 | return vimgrep -------------------------------------------------------------------------------- /fnl/snap/layout/init.fnl: -------------------------------------------------------------------------------- 1 | (module snap.layout) 2 | 3 | ;; Global accessible layouts 4 | ;; Currently layouts always have the input placed below and therefore room 5 | ;; must be left available for it to fit 6 | 7 | ;; Helper to get lines 8 | (defn lines [] 9 | (vim.api.nvim_get_option :lines)) 10 | 11 | ;; Helper to get columns 12 | (defn columns [] 13 | (vim.api.nvim_get_option :columns)) 14 | 15 | (defn percent [size percent] 16 | (math.floor (* size percent))) 17 | 18 | (fn size [%width %height] 19 | {:width (math.floor (* (columns) %width)) 20 | :height (math.floor (* (lines) %height))}) 21 | 22 | (fn from-bottom [size offset] 23 | (- (lines) size offset)) 24 | 25 | ;; The middle for the height or width requested (from top or left) 26 | (defn middle [total size] 27 | (math.floor (/ (- total size) 2))) 28 | 29 | (defn %centered [%width %height] 30 | "Defines a centered layout based on percent" 31 | (let [{: width : height} (size %width %height)] 32 | {: width 33 | : height 34 | :row (middle (lines) height) 35 | :col (middle (columns) width)})) 36 | 37 | (defn %bottom [%width %height] 38 | "Defines a bottom layout based on percent" 39 | (let [{: width : height} (size %width %height)] 40 | {: width 41 | : height 42 | :row (from-bottom height 8) 43 | :col (middle (columns) width)})) 44 | 45 | (defn %top [%width %height] 46 | "Defines a top layout based on percent" 47 | (let [{: width : height} (size %width %height)] 48 | {: width : height :row 5 :col (middle (columns) width)})) 49 | 50 | ;; Primary available layouts: centered, bottom, top 51 | 52 | (defn centered [] 53 | (%centered 0.9 0.7)) 54 | 55 | (defn bottom [] 56 | (let [lines (vim.api.nvim_get_option :lines) 57 | height (math.floor (* lines 0.5)) 58 | width (vim.api.nvim_get_option :columns) 59 | col 0 60 | row (- lines height 4)] 61 | {: width : height : col : row })) 62 | 63 | (defn top [] 64 | (%top 0.9 0.7)) 65 | -------------------------------------------------------------------------------- /lua/snap/preview/common/file.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/preview/common/file.fnl" 2 | local snap = require("snap") 3 | local loading = snap.get("loading") 4 | local read_file = snap.get("preview.common.read-file") 5 | local parse = snap.get("common.vimgrep.parse") 6 | local syntax = snap.get("preview.common.syntax") 7 | local tbl = snap.get("common.tbl") 8 | local function _1_(get_file_data) 9 | local function _2_(request) 10 | local load_counter = 0 11 | local last_time = vim.loop.now() 12 | local max_length = 500 13 | local function render_loader() 14 | if ((vim.loop.now() - last_time) > 500) then 15 | local function _3_() 16 | if not request.canceled() then 17 | last_time = vim.loop.now() 18 | load_counter = (load_counter + 1) 19 | return vim.api.nvim_buf_set_lines(request.bufnr, 0, -1, false, loading(request.width, request.height, load_counter)) 20 | else 21 | return nil 22 | end 23 | end 24 | return snap.sync(_3_) 25 | else 26 | return nil 27 | end 28 | end 29 | local file_data = get_file_data(request.selection) 30 | local file_name = vim.fn.fnamemodify(file_data.path, ":t") 31 | local preview = read_file(file_data.path, render_loader) 32 | local preview_size = #preview 33 | local function _6_() 34 | if not request.canceled() then 35 | vim.api.nvim_win_set_option(request.winnr, "cursorline", true) 36 | vim.api.nvim_buf_set_lines(request.bufnr, 0, -1, false, preview) 37 | if ((file_data.line ~= nil) and (file_data.line <= preview_size)) then 38 | vim.api.nvim_win_set_cursor(request.winnr, {file_data.line, (file_data.column - 1)}) 39 | else 40 | end 41 | if (tbl["max-length"](preview) < max_length) then 42 | return syntax(file_name, request.bufnr) 43 | else 44 | return nil 45 | end 46 | else 47 | return nil 48 | end 49 | end 50 | snap.sync(_6_) 51 | preview = nil 52 | return nil 53 | end 54 | return _2_ 55 | end 56 | return _1_ -------------------------------------------------------------------------------- /lua/snap/common/register.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/register.fnl" 2 | local _2amodule_name_2a = "snap.common.register" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local tbl = require("snap.common.tbl") 14 | do end (_2amodule_locals_2a)["tbl"] = tbl 15 | local commands = {} 16 | local function buf_map(bufnr, modes, keys, fnc, opts) 17 | for _, key in ipairs(keys) do 18 | for _0, mode in ipairs(modes) do 19 | vim.keymap.set(mode, key, fnc, tbl.merge((opts or {nowait = true}), {buffer = bufnr})) 20 | end 21 | end 22 | return nil 23 | end 24 | _2amodule_2a["buf-map"] = buf_map 25 | local function handle_string(tbl0) 26 | local _1_ = type(tbl0) 27 | if (_1_ == "table") then 28 | return tbl0 29 | elseif (_1_ == "string") then 30 | return {tbl0} 31 | else 32 | return nil 33 | end 34 | end 35 | local function map(modes, keys, fnc, opts) 36 | for _, key in ipairs(handle_string(keys)) do 37 | for _0, mode in ipairs(handle_string(modes)) do 38 | vim.keymap.set(mode, key, fnc, (opts or {})) 39 | end 40 | end 41 | return nil 42 | end 43 | _2amodule_2a["map"] = map 44 | local function command(name, fnc) 45 | if (#commands == 0) then 46 | local function _3_(opts) 47 | local name0 = opts.fargs[1] 48 | local _5_ 49 | do 50 | local t_4_ = commands 51 | if (nil ~= t_4_) then 52 | t_4_ = (t_4_)[name0] 53 | else 54 | end 55 | _5_ = t_4_ 56 | end 57 | if _5_ then 58 | return commands[name0]() 59 | else 60 | return nil 61 | end 62 | end 63 | local function _8_() 64 | return vim.tbl_keys(commands) 65 | end 66 | vim.api.nvim_create_user_command("Snap", _3_, {nargs = 1, complete = _8_}) 67 | else 68 | end 69 | commands[name] = fnc 70 | return nil 71 | end 72 | _2amodule_2a["command"] = command 73 | return _2amodule_2a -------------------------------------------------------------------------------- /lua/snap/common/window.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/window.fnl" 2 | local _2amodule_name_2a = "snap.common.window" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function create(bufnr, _1_) 14 | local _arg_2_ = _1_ 15 | local width = _arg_2_["width"] 16 | local height = _arg_2_["height"] 17 | local row = _arg_2_["row"] 18 | local col = _arg_2_["col"] 19 | local focusable = _arg_2_["focusable"] 20 | local enter = _arg_2_["enter"] 21 | local title = _arg_2_["title"] 22 | local _3_ 23 | if (enter == nil) then 24 | _3_ = false 25 | else 26 | _3_ = enter 27 | end 28 | local _5_ 29 | if (title ~= nil) then 30 | _5_ = "center" 31 | else 32 | _5_ = nil 33 | end 34 | local _7_ 35 | if (title ~= nil) then 36 | _7_ = string.format(" %s ", title) 37 | else 38 | _7_ = nil 39 | end 40 | return vim.api.nvim_open_win(bufnr, _3_, {width = width, height = height, row = row, col = col, focusable = focusable, title_pos = _5_, title = _7_, noautocmd = true, relative = "editor", anchor = "NW", style = "minimal", border = {"\226\149\173", "\226\148\128", "\226\149\174", "\226\148\130", "\226\149\175", "\226\148\128", "\226\149\176", "\226\148\130"}}) 41 | end 42 | _2amodule_2a["create"] = create 43 | local function update(winnr, _9_) 44 | local _arg_10_ = _9_ 45 | local width = _arg_10_["width"] 46 | local height = _arg_10_["height"] 47 | local row = _arg_10_["row"] 48 | local col = _arg_10_["col"] 49 | local focusable = _arg_10_["focusable"] 50 | if vim.api.nvim_win_is_valid(winnr) then 51 | return vim.api.nvim_win_set_config(winnr, {width = width, height = height, row = row, col = col, focusable = focusable, relative = "editor"}) 52 | else 53 | return nil 54 | end 55 | end 56 | _2amodule_2a["update"] = update 57 | local function close(winnr) 58 | return vim.api.nvim_win_close(winnr, true) 59 | end 60 | _2amodule_2a["close"] = close 61 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/preview/common/file.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap) 2 | loading (snap.get :loading) 3 | read-file (snap.get :preview.common.read-file) 4 | parse (snap.get :common.vimgrep.parse) 5 | syntax (snap.get :preview.common.syntax) 6 | tbl (snap.get :common.tbl)] 7 | (fn [get-file-data] 8 | (fn [request] 9 | ;; Display loading 10 | (var load-counter 0) 11 | (var last-time (vim.loop.now)) 12 | (local max-length 500) 13 | 14 | ;; Progressively renders loader 15 | (fn render-loader [] 16 | ;; Don't always render 17 | (when 18 | (> (- (vim.loop.now) last-time) 500) 19 | (snap.sync (fn [] 20 | (when (not (request.canceled)) 21 | (set last-time (vim.loop.now)) 22 | (set load-counter (+ load-counter 1)) 23 | (vim.api.nvim_buf_set_lines 24 | request.bufnr 25 | 0 26 | -1 27 | false 28 | (loading request.width request.height load-counter))))))) 29 | 30 | (local file-data (get-file-data request.selection)) 31 | (local file-name (vim.fn.fnamemodify file-data.path ":t")) 32 | 33 | ;; Get the preview 34 | (var preview (read-file file-data.path render-loader)) 35 | (local preview-size (length preview)) 36 | ;; Write the preview to the buffer. 37 | (snap.sync (fn [] 38 | (when (not (request.canceled)) 39 | ;; Highlight using the cursor 40 | (vim.api.nvim_win_set_option request.winnr :cursorline true) 41 | ;; Set the preview 42 | (vim.api.nvim_buf_set_lines request.bufnr 0 -1 false preview) 43 | ;; Try to set cursor to appropriate line 44 | (when (and (not= file-data.line nil) (<= file-data.line preview-size)) 45 | ;; TODO Col highlighting isn't working 46 | (vim.api.nvim_win_set_cursor request.winnr [file-data.line (- file-data.column 1)])) 47 | ;; Add synxtax highlighting 48 | (when 49 | (< (tbl.max-length preview) max-length) 50 | (syntax file-name request.bufnr))))) 51 | 52 | (set preview nil)))) 53 | -------------------------------------------------------------------------------- /fnl/snap/view/results.fnl: -------------------------------------------------------------------------------- 1 | (module snap.view.results {require {size snap.view.size 2 | buffer snap.common.buffer 3 | window snap.common.window 4 | register snap.common.register}}) 5 | 6 | (local group (vim.api.nvim_create_augroup :SnapResults {:clear true})) 7 | 8 | (fn layout [config] 9 | "Creates the results layout" 10 | (let [{: width : height : row : col} (config.layout)] 11 | {:width (if (config.has-views) (- (math.floor (* width size.view-width)) size.padding size.padding) width) 12 | :height (- height size.border size.border size.padding) 13 | :title :Results 14 | :row (if config.reverse (+ row size.border size.padding size.padding) row) 15 | : col 16 | :focusable false})) 17 | 18 | (defn create [config] 19 | "Creates the results view" 20 | (let [bufnr (buffer.create) 21 | layout-config (layout config) 22 | winnr (window.create bufnr layout-config)] 23 | 24 | (vim.api.nvim_set_option_value :buftype :prompt {:buf bufnr}) 25 | (vim.api.nvim_set_option_value :textwidth 0 {:buf bufnr}) 26 | (vim.api.nvim_set_option_value :wrapmargin 0 {:buf bufnr}) 27 | (vim.api.nvim_set_option_value :wrap false {:win winnr}) 28 | (vim.api.nvim_set_option_value :cursorline true {:win winnr}) 29 | (vim.api.nvim_set_option_value :winhl "CursorLine:SnapSelect,Normal:SnapNormal,FloatBorder:SnapBorder" {:win winnr}) 30 | 31 | (fn delete [] 32 | (when (vim.api.nvim_win_is_valid winnr) 33 | (window.close winnr)) 34 | (when (vim.api.nvim_buf_is_valid bufnr) 35 | (buffer.delete bufnr))) 36 | 37 | (fn update [view] 38 | (when (vim.api.nvim_win_is_valid winnr) 39 | (let [layout-config (layout config)] 40 | (window.update winnr layout-config) 41 | (vim.api.nvim_set_option_value :cursorline true {:win winnr}) 42 | (tset view :height layout-config.height) 43 | (tset view :width layout-config.width)))) 44 | 45 | (local view {: update : delete : bufnr : winnr :width layout-config.width :height layout-config.height}) 46 | 47 | (vim.api.nvim_create_autocmd 48 | :VimResized 49 | { : group :callback (fn [] (view:update)) }) 50 | 51 | view)) 52 | 53 | -------------------------------------------------------------------------------- /fnl/snap/producer/create.fnl: -------------------------------------------------------------------------------- 1 | (let [snap (require :snap)] 2 | 3 | (fn create-slow-api [] 4 | "Creates an api for handling slow values" 5 | (local slow-api {:pending false :value nil}) 6 | (fn slow-api.schedule [fnc] 7 | (tset slow-api :pending true) 8 | (vim.schedule (fn [] 9 | (tset slow-api :value (fnc)) 10 | (tset slow-api :pending false)))) 11 | slow-api) 12 | 13 | (fn [{: producer 14 | : request 15 | : on-end 16 | : on-value 17 | : on-tick}] 18 | "Schedules a view for generation" 19 | ;; By the time the routine runs, we might be able to avoid it 20 | (when (not (request.canceled)) 21 | ;; Create the idle loop 22 | (var idle (vim.loop.new_idle)) 23 | ;; Create the producer 24 | (var thread (coroutine.create producer)) 25 | ;; Tracks the requests of slow nvim calls 26 | (var slow-api (create-slow-api)) 27 | ;; Handle ending the idle loop and optionally calling on end 28 | (fn stop [] 29 | (idle:stop) 30 | (set idle nil) 31 | (set thread nil) 32 | (set slow-api nil) 33 | (when on-end (on-end))) 34 | ;; This runs on each idle check 35 | (fn start [] 36 | (if 37 | ;; Only run when we aren't waiting for a slow-api call 38 | slow-api.pending 39 | ;; Return nil 40 | nil 41 | ;; When the thread is not dead 42 | (not= (coroutine.status thread) :dead) 43 | ;; Run the resume 44 | (do 45 | ;; Fetches results be also sends cancel signal 46 | (let [(_ value on-cancel) (coroutine.resume thread request slow-api.value)] 47 | ;; Match each type 48 | (match (type value) 49 | ;; We have a function so schedule it to be computed 50 | :function (slow-api.schedule value) 51 | :nil (stop) 52 | (where :table (= value snap.continue_value)) 53 | (if 54 | (request.canceled) 55 | (do 56 | (when on-cancel (on-cancel)) 57 | (stop))) 58 | _ (when on-value (on-value value))) 59 | (when on-tick (on-tick)))) 60 | ;; When the coroutine is dead then stop the loop 61 | (stop))) 62 | 63 | ;; Start the checker after each IO poll 64 | (idle:start start)))) 65 | -------------------------------------------------------------------------------- /fnl/snap/producer/lsp/init.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local tbl (require :snap.common.tbl)) 3 | 4 | (fn report-error [error] 5 | (vim.notify (.. "There was an error when calling LSP: " error.message) vim.log.levels.ERROR)) 6 | 7 | (fn lsp-buf-request [bufnr action params on-value on-error] 8 | (vim.lsp.buf_request bufnr action params 9 | (fn [error result context] 10 | (if error 11 | (on-error error) 12 | (let [client (vim.lsp.get_client_by_id context.client_id) 13 | results (if (vim.tbl_islist result) result [result])] 14 | (on-value {: bufnr : results :offset_encoding client.offset_encoding})))))) 15 | 16 | (fn lsp-producer [bufnr action params tranformer] 17 | (local (response error) (snap.async (partial lsp-buf-request bufnr action params))) 18 | (when error (snap.sync #(report-error error))) 19 | (snap.sync (partial tranformer (or response {})))) 20 | 21 | (fn get-bufnr [winnr] 22 | (snap.sync #(vim.api.nvim_win_get_buf winnr))) 23 | 24 | (fn get-params [winnr] 25 | (snap.sync #(vim.lsp.util.make_position_params winnr))) 26 | 27 | ;; Transformers take a response and return results 28 | ;; they are executed inside snap.sync 29 | (local transformers {}) 30 | 31 | (fn transformers.locations [{: offset_encoding : results}] 32 | (vim.tbl_map 33 | #(snap.with_metas $1.filename (tbl.merge $1 {: offset_encoding})) 34 | (vim.lsp.util.locations_to_items results offset_encoding))) 35 | 36 | (fn transformers.symbols [{: bufnr : results}] 37 | (vim.tbl_map 38 | #(snap.with_metas $1.text $1) 39 | (vim.lsp.util.symbols_to_items results bufnr))) 40 | 41 | (fn locations [action {: winnr}] 42 | (lsp-producer 43 | (get-bufnr winnr) 44 | action 45 | (get-params winnr) 46 | transformers.locations)) 47 | 48 | (local definitions #(locations "textDocument/definition" $1)) 49 | (local implementations #(locations "textDocument/implementation" $1)) 50 | (local type_definitions #(locations "textDocument/typeDefinition" $1)) 51 | 52 | (fn references [{: winnr}] 53 | (lsp-producer 54 | (get-bufnr winnr) 55 | "textDocument/references" 56 | (tbl.merge (get-params winnr) {:context {:includeDeclaration true}}) 57 | transformers.locations)) 58 | 59 | (fn symbols [{: winnr}] 60 | (lsp-producer 61 | (get-bufnr winnr) 62 | "textDocument/documentSymbol" 63 | (get-params winnr) 64 | transformers.symbols)) 65 | 66 | {: definitions 67 | : implementations 68 | : type_definitions 69 | : references 70 | : symbols} 71 | -------------------------------------------------------------------------------- /fnl/snap/view/view.fnl: -------------------------------------------------------------------------------- 1 | (module snap.view.view {require {size snap.view.size 2 | buffer snap.common.buffer 3 | window snap.common.window 4 | tbl snap.common.tbl 5 | register snap.common.register}}) 6 | 7 | (local group (vim.api.nvim_create_augroup :SnapView {:clear true})) 8 | 9 | (fn layout [config] 10 | "Creates a view layout" 11 | (let [{: width : height : row : col} (config.layout) 12 | index (- config.index 1) 13 | border (* index size.border) 14 | padding (* index size.padding) 15 | total-borders (* (- config.total-views 1) size.border) 16 | total-paddings (* (- config.total-views 1) size.padding) 17 | sizes (tbl.allocate (- height total-borders total-paddings) config.total-views) 18 | height (. sizes config.index) 19 | col-offset (math.floor (* width size.view-width))] 20 | {:width (- width col-offset size.padding size.padding size.border) 21 | : height 22 | :row (+ row (tbl.sum (tbl.take sizes index)) border padding) 23 | :col (+ col col-offset (* size.border 2) size.padding) 24 | :focusable false 25 | :title :Preview})) 26 | 27 | (defn create [config] 28 | "Creates a view" 29 | (let [bufnr (buffer.create) 30 | layout-config (layout config) 31 | winnr (window.create bufnr layout-config)] 32 | (vim.api.nvim_set_option_value :cursorline false {:win winnr}) 33 | (vim.api.nvim_set_option_value :cursorcolumn false {:win winnr}) 34 | (vim.api.nvim_set_option_value :wrap false {:win winnr}) 35 | (vim.api.nvim_set_option_value :winhl "Normal:SnapNormal,FloatBorder:SnapBorder" {:win winnr}) 36 | 37 | (fn delete [] 38 | (when (vim.api.nvim_win_is_valid winnr) 39 | (window.close winnr)) 40 | (when (vim.api.nvim_buf_is_valid bufnr) 41 | (buffer.delete bufnr))) 42 | 43 | (fn update [view] 44 | (when (vim.api.nvim_win_is_valid winnr) 45 | (let [layout-config (layout config)] 46 | (window.update winnr layout-config) 47 | (vim.api.nvim_win_set_option winnr :cursorline true) 48 | (tset view :height layout-config.height) 49 | (tset view :width layout-config.width)))) 50 | 51 | (local view {: update : delete : bufnr : winnr :width layout-config.width :height layout-config.height}) 52 | 53 | (vim.api.nvim_create_autocmd 54 | :VimResized 55 | { : group :callback (fn [] (view:update)) }) 56 | 57 | view)) 58 | 59 | -------------------------------------------------------------------------------- /lua/snap/producer/create.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/create.fnl" 2 | local snap = require("snap") 3 | local function create_slow_api() 4 | local slow_api = {value = nil, pending = false} 5 | slow_api.schedule = function(fnc) 6 | slow_api["pending"] = true 7 | local function _1_() 8 | slow_api["value"] = fnc() 9 | do end (slow_api)["pending"] = false 10 | return nil 11 | end 12 | return vim.schedule(_1_) 13 | end 14 | return slow_api 15 | end 16 | local function _4_(_2_) 17 | local _arg_3_ = _2_ 18 | local producer = _arg_3_["producer"] 19 | local request = _arg_3_["request"] 20 | local on_end = _arg_3_["on-end"] 21 | local on_value = _arg_3_["on-value"] 22 | local on_tick = _arg_3_["on-tick"] 23 | if not request.canceled() then 24 | local idle = vim.loop.new_idle() 25 | local thread = coroutine.create(producer) 26 | local slow_api = create_slow_api() 27 | local function stop() 28 | idle:stop() 29 | idle = nil 30 | thread = nil 31 | slow_api = nil 32 | if on_end then 33 | return on_end() 34 | else 35 | return nil 36 | end 37 | end 38 | local function start() 39 | if slow_api.pending then 40 | return nil 41 | elseif (coroutine.status(thread) ~= "dead") then 42 | local _, value, on_cancel = coroutine.resume(thread, request, slow_api.value) 43 | do 44 | local _6_ = type(value) 45 | if (_6_ == "function") then 46 | slow_api.schedule(value) 47 | elseif (_6_ == "nil") then 48 | stop() 49 | else 50 | local function _7_() 51 | return (value == snap.continue_value) 52 | end 53 | if ((_6_ == "table") and _7_()) then 54 | if request.canceled() then 55 | if on_cancel then 56 | on_cancel() 57 | else 58 | end 59 | stop() 60 | else 61 | end 62 | elseif true then 63 | local _0 = _6_ 64 | if on_value then 65 | on_value(value) 66 | else 67 | end 68 | else 69 | end 70 | end 71 | end 72 | if on_tick then 73 | return on_tick() 74 | else 75 | return nil 76 | end 77 | else 78 | return stop() 79 | end 80 | end 81 | return idle:start(start) 82 | else 83 | return nil 84 | end 85 | end 86 | return _4_ -------------------------------------------------------------------------------- /lua/snap/layout/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/layout/init.fnl" 2 | local _2amodule_name_2a = "snap.layout" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function lines() 14 | return vim.api.nvim_get_option("lines") 15 | end 16 | _2amodule_2a["lines"] = lines 17 | local function columns() 18 | return vim.api.nvim_get_option("columns") 19 | end 20 | _2amodule_2a["columns"] = columns 21 | local function percent(size, percent0) 22 | return math.floor((size * percent0)) 23 | end 24 | _2amodule_2a["percent"] = percent 25 | local function size(_25width, _25height) 26 | return {width = math.floor((columns() * _25width)), height = math.floor((lines() * _25height))} 27 | end 28 | local function from_bottom(size0, offset) 29 | return (lines() - size0 - offset) 30 | end 31 | local function middle(total, size0) 32 | return math.floor(((total - size0) / 2)) 33 | end 34 | _2amodule_2a["middle"] = middle 35 | local function _25centered(_25width, _25height) 36 | local _let_1_ = size(_25width, _25height) 37 | local width = _let_1_["width"] 38 | local height = _let_1_["height"] 39 | return {width = width, height = height, row = middle(lines(), height), col = middle(columns(), width)} 40 | end 41 | _2amodule_2a["%centered"] = _25centered 42 | local function _25bottom(_25width, _25height) 43 | local _let_2_ = size(_25width, _25height) 44 | local width = _let_2_["width"] 45 | local height = _let_2_["height"] 46 | return {width = width, height = height, row = from_bottom(height, 8), col = middle(columns(), width)} 47 | end 48 | _2amodule_2a["%bottom"] = _25bottom 49 | local function _25top(_25width, _25height) 50 | local _let_3_ = size(_25width, _25height) 51 | local width = _let_3_["width"] 52 | local height = _let_3_["height"] 53 | return {width = width, height = height, row = 5, col = middle(columns(), width)} 54 | end 55 | _2amodule_2a["%top"] = _25top 56 | local function centered() 57 | return _25centered(0.9, 0.7) 58 | end 59 | _2amodule_2a["centered"] = centered 60 | local function bottom() 61 | local lines0 = vim.api.nvim_get_option("lines") 62 | local height = math.floor((lines0 * 0.5)) 63 | local width = vim.api.nvim_get_option("columns") 64 | local col = 0 65 | local row = (lines0 - height - 4) 66 | return {width = width, height = height, col = col, row = row} 67 | end 68 | _2amodule_2a["bottom"] = bottom 69 | local function top() 70 | return _25top(0.9, 0.7) 71 | end 72 | _2amodule_2a["top"] = top 73 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/common/tbl.fnl: -------------------------------------------------------------------------------- 1 | (module snap.common.tbl) 2 | 3 | (defn max-length [tbl] 4 | "Returns max length of table values" 5 | (accumulate [max 0 _ line (ipairs tbl)] 6 | (let [len (length line)] 7 | (if (> len max) len max)))) 8 | 9 | (defn acc [tbl vals] 10 | "Accumulates non nil values" 11 | (when (not= vals nil) 12 | (each [_ value (ipairs vals)] 13 | (when (not= (tostring value) "") 14 | (table.insert tbl value))))) 15 | 16 | (defn merge [tbl1 tbl2] 17 | (let [result {}] 18 | (each [key val (pairs tbl1)] 19 | (tset result key val)) 20 | (each [key val (pairs tbl2)] 21 | (tset result key val)) 22 | result)) 23 | 24 | (defn concat [tbl-a tbl-b] 25 | "Concatenates tables" 26 | (let [tbl []] 27 | (each [_ value (ipairs tbl-a)] 28 | (table.insert tbl value)) 29 | (each [_ value (ipairs tbl-b)] 30 | (table.insert tbl value)) 31 | tbl)) 32 | 33 | (defn take [tbl num] 34 | "Takes the first n values from tbl" 35 | (local partial-tbl []) 36 | (each [_ value (ipairs tbl) :until (= num (length partial-tbl))] 37 | (table.insert partial-tbl value)) 38 | partial-tbl) 39 | 40 | (defn sum [tbl] 41 | "Sums table" 42 | (var count 0) 43 | (each [_ val (ipairs tbl)] 44 | (set count (+ count val))) 45 | count) 46 | 47 | (defn first [tbl] 48 | "Gets the first value from the table" 49 | (when tbl (. tbl 1))) 50 | 51 | (defn allocate [total divisor] 52 | "Divides by allocation, ensuing remainers are handled" 53 | (var remainder total) 54 | (local parts []) 55 | (local part (math.floor (/ total divisor))) 56 | (for [i 1 divisor] 57 | (if 58 | (= i divisor) 59 | (table.insert parts remainder) 60 | (do 61 | (table.insert parts part) 62 | (set remainder (- remainder part))))) 63 | parts) 64 | 65 | (fn partition [tbl p r comp] 66 | "Partitions a tbl" 67 | (let [x (. tbl r)] 68 | (var i (- p 1)) 69 | (for [j p (- r 1) 1] 70 | (when (comp (. tbl j) x) 71 | (set i (+ i 1)) 72 | (local temp (. tbl i)) 73 | (tset tbl i (. tbl j)) 74 | (tset tbl j temp))) 75 | (local temp (. tbl (+ i 1))) 76 | (tset tbl (+ i 1) (. tbl r)) 77 | (tset tbl r temp) 78 | (+ i 1))) 79 | 80 | (defn partial-quicksort [tbl p r m comp] 81 | "Partial quicksort for avoiding completely sorting tables when not needed" 82 | (when (< p r) 83 | (let [q (partition tbl p r comp)] 84 | (partial-quicksort tbl p (- q 1) m comp) 85 | (when (< p (- m 1)) 86 | (partial-quicksort tbl (+ q 1) r m comp))))) 87 | 88 | (defn max-length [tbl] 89 | "Finds the max length of value values" 90 | (accumulate [max 0 91 | _ val (ipairs tbl)] 92 | (let [len (length (tostring val))] 93 | (if (> len max) len max)))) 94 | -------------------------------------------------------------------------------- /fnl/snap/select/git/init.fnl: -------------------------------------------------------------------------------- 1 | (local snap (require :snap)) 2 | (local layout (require :snap.layout)) 3 | (local tbl (require :snap.common.tbl)) 4 | (local snap-string (require :snap.common.string)) 5 | 6 | (local filter (if (pcall require :fzy) 7 | (require :snap.consumer.fzy) 8 | (require :snap.consumer.fzf))) 9 | 10 | (fn action-layout [actions] 11 | (let [columns (layout.columns) 12 | lines (layout.lines) 13 | max-length (tbl.max-length actions) 14 | width (* max-length 3) 15 | height (+ (length actions) 3)] 16 | {: width 17 | : height 18 | :col (layout.middle columns width) 19 | :row (layout.middle lines height)})) 20 | 21 | (fn checkout [selection on-done] 22 | (vim.system 23 | [:git :checkout (tostring selection)] 24 | {:cwd (vim.fn.getcwd)} 25 | #(case $1.code 26 | 0 (do 27 | (when on-done (vim.schedule on-done)) 28 | (vim.notify 29 | (string.format "Checked out '%s'" (tostring selection)) 30 | vim.log.levels.INFO)) 31 | _ (vim.notify 32 | (string.format "Error when checking out '%s':\n%s" (tostring selection) $1.stderr) 33 | vim.log.levels.ERROR)))) 34 | 35 | (fn reset-soft [selection] 36 | (vim.system 37 | [:git :reset :--soft (tostring selection)] 38 | {:cwd (vim.fn.getcwd)} 39 | #(when 40 | (= $1.code 0) 41 | (vim.notify 42 | (string.format "Soft reset '%s'" (tostring selection)) 43 | vim.log.levels.INFO)))) 44 | 45 | (fn reset-hard [selection] 46 | (vim.system 47 | [:git :reset :--hard (tostring selection)] 48 | {:cwd (vim.fn.getcwd)} 49 | #(when 50 | (= $1.code 0) 51 | (vim.notify 52 | (string.format "Hard reset '%s'" (tostring selection)) 53 | vim.log.levels.INFO)))) 54 | 55 | (fn pull [branch remote] 56 | (checkout branch #(vim.system 57 | [:git :pull (tostring remote) (tostring branch)] 58 | {:cwd (vim.fn.getcwd)} 59 | #(when 60 | (= $1.code 0) 61 | (vim.notify 62 | (string.format "Pulled '%s/%s'" (tostring remote) (tostring branch)) 63 | vim.log.levels.INFO))))) 64 | 65 | (fn pull-list [branch] 66 | (vim.system 67 | [:git :remote] 68 | {:cwd (vim.fn.getcwd)} 69 | #(when 70 | (= $1.code 0) 71 | (local remotes (snap-string.split $1.stdout)) 72 | (vim.schedule #(snap.run {:prompt :Select> 73 | :producer (filter (fn [] remotes)) 74 | :select (partial (vim.schedule_wrap pull) branch) 75 | :layout (partial action-layout remotes)}))))) 76 | 77 | (local branch-actions (vim.tbl_map #(snap.with_metas $1.label $1) [ 78 | {:label "Checkout" :action checkout} 79 | {:label "Reset (soft)" :action reset-soft} 80 | {:label "Reset (hard)" :action reset-hard} 81 | {:label "Pull" :action pull-list}])) 82 | 83 | (fn branch [selection] 84 | (snap.run {:prompt :Select> 85 | :producer (filter (fn [] branch-actions)) 86 | :select #($1.action selection) 87 | :layout (partial action-layout branch-actions)})) 88 | 89 | {: branch} 90 | -------------------------------------------------------------------------------- /lua/snap/view/results.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/view/results.fnl" 2 | local _2amodule_name_2a = "snap.view.results" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local buffer, register, size, window = require("snap.common.buffer"), require("snap.common.register"), require("snap.view.size"), require("snap.common.window") 14 | do end (_2amodule_locals_2a)["buffer"] = buffer 15 | _2amodule_locals_2a["register"] = register 16 | _2amodule_locals_2a["size"] = size 17 | _2amodule_locals_2a["window"] = window 18 | local group = vim.api.nvim_create_augroup("SnapResults", {clear = true}) 19 | local function layout(config) 20 | local _let_1_ = config.layout() 21 | local width = _let_1_["width"] 22 | local height = _let_1_["height"] 23 | local row = _let_1_["row"] 24 | local col = _let_1_["col"] 25 | local _2_ 26 | if config["has-views"]() then 27 | _2_ = (math.floor((width * size["view-width"])) - size.padding - size.padding) 28 | else 29 | _2_ = width 30 | end 31 | local _4_ 32 | if config.reverse then 33 | _4_ = (row + size.border + size.padding + size.padding) 34 | else 35 | _4_ = row 36 | end 37 | return {width = _2_, height = (height - size.border - size.border - size.padding), title = "Results", row = _4_, col = col, focusable = false} 38 | end 39 | local function create(config) 40 | local bufnr = buffer.create() 41 | local layout_config = layout(config) 42 | local winnr = window.create(bufnr, layout_config) 43 | vim.api.nvim_set_option_value("buftype", "prompt", {buf = bufnr}) 44 | vim.api.nvim_set_option_value("textwidth", 0, {buf = bufnr}) 45 | vim.api.nvim_set_option_value("wrapmargin", 0, {buf = bufnr}) 46 | vim.api.nvim_set_option_value("wrap", false, {win = winnr}) 47 | vim.api.nvim_set_option_value("cursorline", true, {win = winnr}) 48 | vim.api.nvim_set_option_value("winhl", "CursorLine:SnapSelect,Normal:SnapNormal,FloatBorder:SnapBorder", {win = winnr}) 49 | local function delete() 50 | if vim.api.nvim_win_is_valid(winnr) then 51 | window.close(winnr) 52 | else 53 | end 54 | if vim.api.nvim_buf_is_valid(bufnr) then 55 | return buffer.delete(bufnr) 56 | else 57 | return nil 58 | end 59 | end 60 | local function update(view) 61 | if vim.api.nvim_win_is_valid(winnr) then 62 | local layout_config0 = layout(config) 63 | window.update(winnr, layout_config0) 64 | vim.api.nvim_set_option_value("cursorline", true, {win = winnr}) 65 | do end (view)["height"] = layout_config0.height 66 | view["width"] = layout_config0.width 67 | return nil 68 | else 69 | return nil 70 | end 71 | end 72 | local view = {update = update, delete = delete, bufnr = bufnr, winnr = winnr, width = layout_config.width, height = layout_config.height} 73 | local function _9_() 74 | return view:update() 75 | end 76 | vim.api.nvim_create_autocmd("VimResized", {group = group, callback = _9_}) 77 | return view 78 | end 79 | _2amodule_2a["create"] = create 80 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/macros.fnl: -------------------------------------------------------------------------------- 1 | ;; Defines a function that will safe schedule non-fast code 2 | (fn safefn [name ...] 3 | `(local ,name (vim.schedule_wrap (fn ,...)))) 4 | 5 | ;; Defines a metafunction 6 | (fn defmetafn [name tbl ...] 7 | `(def ,name (setmetatable ,tbl {:__call (fn [self# ...] ((fn ,...) ...))}))) 8 | 9 | ;; Calls a non-fast mode function safely 10 | (fn safecall [fnc ...] 11 | `((vim.schedule_wrap ,fnc) ,...)) 12 | 13 | ;; Defines a function that will safe schedule non-fast mode code 14 | ;; but when called again before the scheduled code is run, 15 | ;; it will just swap the arguments of the old call for the new call 16 | (fn safedebounced [name ...] 17 | `(local ,name 18 | (do 19 | (local body# (fn ,...)) 20 | (var args# nil) 21 | (fn [...] 22 | (if 23 | ;; when the args are nil we need to schedule 24 | (= args# nil) 25 | (do 26 | (set args# [...]) 27 | (vim.schedule (fn [] 28 | (let [actual-args# args#] 29 | ;; we reached the call to clear 30 | (set args# nil) 31 | (body# (unpack actual-args#)))))) 32 | ;; When the args are already set we have already scheduled 33 | ;; so just swap the args to be called with 34 | (set args# [...])))))) 35 | 36 | (fn asserttypes [types value msg] 37 | `(assert (vim.tbl_contains ,types (type ,value)) ,msg)) 38 | 39 | (fn asserttypes? [types value msg] 40 | `(when ,value (asserttypes ,types ,value ,msg))) 41 | 42 | (fn asserttype [typ value msg] 43 | `(assert (= (type ,value) ,typ) ,msg)) 44 | 45 | (fn asserttype? [typ value msg] 46 | `(when ,value (asserttype ,typ ,value ,msg))) 47 | 48 | (fn assertfunction [value msg] 49 | `(asserttype :function ,value ,msg)) 50 | 51 | (fn assertfunction? [value msg] 52 | `(asserttype? :function ,value ,msg)) 53 | 54 | (fn asserttable [value msg] 55 | `(asserttype :table ,value ,msg)) 56 | 57 | (fn asserttable? [value msg] 58 | `(asserttype? :table ,value ,msg)) 59 | 60 | (fn assertstring [value msg] 61 | `(asserttype :string ,value ,msg)) 62 | 63 | (fn assertstring? [value msg] 64 | `(asserttype? :string ,value ,msg)) 65 | 66 | (fn assertthread [value msg] 67 | `(asserttype :thread ,value ,msg)) 68 | 69 | (fn assertthread? [value msg] 70 | `(asserttype? :thread ,value ,msg)) 71 | 72 | (fn assertboolean [value msg] 73 | `(asserttype :boolean ,value ,msg)) 74 | 75 | (fn assertboolean? [value msg] 76 | `(asserttype? :boolean ,value ,msg)) 77 | 78 | (fn assertnumber [value msg] 79 | `(asserttype :number ,value ,msg)) 80 | 81 | (fn assertnumber? [value msg] 82 | `(asserttype? :number ,value ,msg)) 83 | 84 | (fn assertmetatable [value metatable msg] 85 | `(assert (= (getmetatable ,value) ,metatable) ,msg)) 86 | 87 | {: safefn 88 | : safecall 89 | : safedebounced 90 | : defmetafn 91 | : asserttypes 92 | : asserttypes? 93 | : asserttype 94 | : asserttype? 95 | : assertfunction 96 | : assertfunction? 97 | : asserttable 98 | : asserttable? 99 | : assertstring 100 | : assertstring? 101 | : assertthread 102 | : assertthread? 103 | : assertboolean 104 | : assertboolean? 105 | : assertnumber 106 | : assertnumber? 107 | : assertmetatable} 108 | -------------------------------------------------------------------------------- /lua/snap/macros.fnl: -------------------------------------------------------------------------------- 1 | ;; Defines a function that will safe schedule non-fast code 2 | (fn safefn [name ...] 3 | `(local ,name (vim.schedule_wrap (fn ,...)))) 4 | 5 | ;; Defines a metafunction 6 | (fn defmetafn [name tbl ...] 7 | `(def ,name (setmetatable ,tbl {:__call (fn [self# ...] ((fn ,...) ...))}))) 8 | 9 | ;; Calls a non-fast mode function safely 10 | (fn safecall [fnc ...] 11 | `((vim.schedule_wrap ,fnc) ,...)) 12 | 13 | ;; Defines a function that will safe schedule non-fast mode code 14 | ;; but when called again before the scheduled code is run, 15 | ;; it will just swap the arguments of the old call for the new call 16 | (fn safedebounced [name ...] 17 | `(local ,name 18 | (do 19 | (local body# (fn ,...)) 20 | (var args# nil) 21 | (fn [...] 22 | (if 23 | ;; when the args are nil we need to schedule 24 | (= args# nil) 25 | (do 26 | (set args# [...]) 27 | (vim.schedule (fn [] 28 | (let [actual-args# args#] 29 | ;; we reached the call to clear 30 | (set args# nil) 31 | (body# (unpack actual-args#)))))) 32 | ;; When the args are already set we have already scheduled 33 | ;; so just swap the args to be called with 34 | (set args# [...])))))) 35 | 36 | (fn asserttypes [types value msg] 37 | `(assert (vim.tbl_contains ,types (type ,value)) ,msg)) 38 | 39 | (fn asserttypes? [types value msg] 40 | `(when ,value (asserttypes ,types ,value ,msg))) 41 | 42 | (fn asserttype [typ value msg] 43 | `(assert (= (type ,value) ,typ) ,msg)) 44 | 45 | (fn asserttype? [typ value msg] 46 | `(when ,value (asserttype ,typ ,value ,msg))) 47 | 48 | (fn assertfunction [value msg] 49 | `(asserttype :function ,value ,msg)) 50 | 51 | (fn assertfunction? [value msg] 52 | `(asserttype? :function ,value ,msg)) 53 | 54 | (fn asserttable [value msg] 55 | `(asserttype :table ,value ,msg)) 56 | 57 | (fn asserttable? [value msg] 58 | `(asserttype? :table ,value ,msg)) 59 | 60 | (fn assertstring [value msg] 61 | `(asserttype :string ,value ,msg)) 62 | 63 | (fn assertstring? [value msg] 64 | `(asserttype? :string ,value ,msg)) 65 | 66 | (fn assertthread [value msg] 67 | `(asserttype :thread ,value ,msg)) 68 | 69 | (fn assertthread? [value msg] 70 | `(asserttype? :thread ,value ,msg)) 71 | 72 | (fn assertboolean [value msg] 73 | `(asserttype :boolean ,value ,msg)) 74 | 75 | (fn assertboolean? [value msg] 76 | `(asserttype? :boolean ,value ,msg)) 77 | 78 | (fn assertnumber [value msg] 79 | `(asserttype :number ,value ,msg)) 80 | 81 | (fn assertnumber? [value msg] 82 | `(asserttype? :number ,value ,msg)) 83 | 84 | (fn assertmetatable [value metatable msg] 85 | `(assert (= (getmetatable ,value) ,metatable) ,msg)) 86 | 87 | {: safefn 88 | : safecall 89 | : safedebounced 90 | : defmetafn 91 | : asserttypes 92 | : asserttypes? 93 | : asserttype 94 | : asserttype? 95 | : assertfunction 96 | : assertfunction? 97 | : asserttable 98 | : asserttable? 99 | : assertstring 100 | : assertstring? 101 | : assertthread 102 | : assertthread? 103 | : assertboolean 104 | : assertboolean? 105 | : assertnumber 106 | : assertnumber? 107 | : assertmetatable} 108 | -------------------------------------------------------------------------------- /lua/snap/view/view.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/view/view.fnl" 2 | local _2amodule_name_2a = "snap.view.view" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local buffer, register, size, tbl, window = require("snap.common.buffer"), require("snap.common.register"), require("snap.view.size"), require("snap.common.tbl"), require("snap.common.window") 14 | do end (_2amodule_locals_2a)["buffer"] = buffer 15 | _2amodule_locals_2a["register"] = register 16 | _2amodule_locals_2a["size"] = size 17 | _2amodule_locals_2a["tbl"] = tbl 18 | _2amodule_locals_2a["window"] = window 19 | local group = vim.api.nvim_create_augroup("SnapView", {clear = true}) 20 | local function layout(config) 21 | local _let_1_ = config.layout() 22 | local width = _let_1_["width"] 23 | local height = _let_1_["height"] 24 | local row = _let_1_["row"] 25 | local col = _let_1_["col"] 26 | local index = (config.index - 1) 27 | local border = (index * size.border) 28 | local padding = (index * size.padding) 29 | local total_borders = ((config["total-views"] - 1) * size.border) 30 | local total_paddings = ((config["total-views"] - 1) * size.padding) 31 | local sizes = tbl.allocate((height - total_borders - total_paddings), config["total-views"]) 32 | local height0 = sizes[config.index] 33 | local col_offset = math.floor((width * size["view-width"])) 34 | return {width = (width - col_offset - size.padding - size.padding - size.border), height = height0, row = (row + tbl.sum(tbl.take(sizes, index)) + border + padding), col = (col + col_offset + (size.border * 2) + size.padding), title = "Preview", focusable = false} 35 | end 36 | local function create(config) 37 | local bufnr = buffer.create() 38 | local layout_config = layout(config) 39 | local winnr = window.create(bufnr, layout_config) 40 | vim.api.nvim_set_option_value("cursorline", false, {win = winnr}) 41 | vim.api.nvim_set_option_value("cursorcolumn", false, {win = winnr}) 42 | vim.api.nvim_set_option_value("wrap", false, {win = winnr}) 43 | vim.api.nvim_set_option_value("winhl", "Normal:SnapNormal,FloatBorder:SnapBorder", {win = winnr}) 44 | local function delete() 45 | if vim.api.nvim_win_is_valid(winnr) then 46 | window.close(winnr) 47 | else 48 | end 49 | if vim.api.nvim_buf_is_valid(bufnr) then 50 | return buffer.delete(bufnr) 51 | else 52 | return nil 53 | end 54 | end 55 | local function update(view) 56 | if vim.api.nvim_win_is_valid(winnr) then 57 | local layout_config0 = layout(config) 58 | window.update(winnr, layout_config0) 59 | vim.api.nvim_win_set_option(winnr, "cursorline", true) 60 | do end (view)["height"] = layout_config0.height 61 | view["width"] = layout_config0.width 62 | return nil 63 | else 64 | return nil 65 | end 66 | end 67 | local view = {update = update, delete = delete, bufnr = bufnr, winnr = winnr, width = layout_config.width, height = layout_config.height} 68 | local function _5_() 69 | return view:update() 70 | end 71 | vim.api.nvim_create_autocmd("VimResized", {group = group, callback = _5_}) 72 | return view 73 | end 74 | _2amodule_2a["create"] = create 75 | return _2amodule_2a -------------------------------------------------------------------------------- /lua/snap/common/tbl.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/tbl.fnl" 2 | local _2amodule_name_2a = "snap.common.tbl" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local function max_length(tbl) 14 | local max = 0 15 | for _, line in ipairs(tbl) do 16 | local len = #line 17 | if (len > max) then 18 | max = len 19 | else 20 | max = max 21 | end 22 | end 23 | return max 24 | end 25 | _2amodule_2a["max-length"] = max_length 26 | local function acc(tbl, vals) 27 | if (vals ~= nil) then 28 | for _, value in ipairs(vals) do 29 | if (tostring(value) ~= "") then 30 | table.insert(tbl, value) 31 | else 32 | end 33 | end 34 | return nil 35 | else 36 | return nil 37 | end 38 | end 39 | _2amodule_2a["acc"] = acc 40 | local function merge(tbl1, tbl2) 41 | local result = {} 42 | for key, val in pairs(tbl1) do 43 | result[key] = val 44 | end 45 | for key, val in pairs(tbl2) do 46 | result[key] = val 47 | end 48 | return result 49 | end 50 | _2amodule_2a["merge"] = merge 51 | local function concat(tbl_a, tbl_b) 52 | local tbl = {} 53 | for _, value in ipairs(tbl_a) do 54 | table.insert(tbl, value) 55 | end 56 | for _, value in ipairs(tbl_b) do 57 | table.insert(tbl, value) 58 | end 59 | return tbl 60 | end 61 | _2amodule_2a["concat"] = concat 62 | local function take(tbl, num) 63 | local partial_tbl = {} 64 | for _, value in ipairs(tbl) do 65 | if (num == #partial_tbl) then break end 66 | table.insert(partial_tbl, value) 67 | end 68 | return partial_tbl 69 | end 70 | _2amodule_2a["take"] = take 71 | local function sum(tbl) 72 | local count = 0 73 | for _, val in ipairs(tbl) do 74 | count = (count + val) 75 | end 76 | return count 77 | end 78 | _2amodule_2a["sum"] = sum 79 | local function first(tbl) 80 | if tbl then 81 | return tbl[1] 82 | else 83 | return nil 84 | end 85 | end 86 | _2amodule_2a["first"] = first 87 | local function allocate(total, divisor) 88 | local remainder = total 89 | local parts = {} 90 | local part = math.floor((total / divisor)) 91 | for i = 1, divisor do 92 | if (i == divisor) then 93 | table.insert(parts, remainder) 94 | else 95 | table.insert(parts, part) 96 | remainder = (remainder - part) 97 | end 98 | end 99 | return parts 100 | end 101 | _2amodule_2a["allocate"] = allocate 102 | local function partition(tbl, p, r, comp) 103 | local x = tbl[r] 104 | local i = (p - 1) 105 | for j = p, (r - 1), 1 do 106 | if comp(tbl[j], x) then 107 | i = (i + 1) 108 | local temp = tbl[i] 109 | tbl[i] = tbl[j] 110 | tbl[j] = temp 111 | else 112 | end 113 | end 114 | local temp = tbl[(i + 1)] 115 | tbl[(i + 1)] = tbl[r] 116 | tbl[r] = temp 117 | return (i + 1) 118 | end 119 | local function partial_quicksort(tbl, p, r, m, comp) 120 | if (p < r) then 121 | local q = partition(tbl, p, r, comp) 122 | partial_quicksort(tbl, p, (q - 1), m, comp) 123 | if (p < (m - 1)) then 124 | return partial_quicksort(tbl, (q + 1), r, m, comp) 125 | else 126 | return nil 127 | end 128 | else 129 | return nil 130 | end 131 | end 132 | _2amodule_2a["partial-quicksort"] = partial_quicksort 133 | local function max_length0(tbl) 134 | local max = 0 135 | for _, val in ipairs(tbl) do 136 | local len = #tostring(val) 137 | if (len > max) then 138 | max = len 139 | else 140 | max = max 141 | end 142 | end 143 | return max 144 | end 145 | _2amodule_2a["max-length"] = max_length0 146 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/common/io.fnl: -------------------------------------------------------------------------------- 1 | (module snap.common.io {require {snap snap}}) 2 | 3 | (defn system [cmd args cwd on-value on-error] 4 | (fn on-exit [result] 5 | (if 6 | (= result.code 0) 7 | (on-value result.stdout) 8 | (on-error result.stderr))) 9 | (vim.system [cmd (unpack args)] {: cwd} on-exit)) 10 | 11 | (defn spawn [cmd args cwd stdin] 12 | "Spawns a command and returns a command iterator" 13 | (var stdoutbuffer "") 14 | (var stderrbuffer "") 15 | (let [stdout (vim.loop.new_pipe false) 16 | stderr (vim.loop.new_pipe false) 17 | handle (vim.loop.spawn cmd {: args :stdio [stdin stdout stderr] : cwd} 18 | (fn [code signal] 19 | (stdout:read_stop) 20 | (stderr:read_stop) 21 | (stdout:close) 22 | (stderr:close) 23 | (when stdin 24 | (stdin:read_stop) 25 | (stdin:close)) 26 | (handle:close)))] 27 | (stdout:read_start (fn [err data] 28 | (assert (not err)) 29 | (when data 30 | (set stdoutbuffer (.. stdoutbuffer data))))) 31 | (stderr:read_start (fn [err data] 32 | (assert (not err)) 33 | (when data 34 | (set stderrbuffer (.. stderrbuffer data))))) 35 | 36 | (fn kill [] 37 | (handle:kill vim.loop.constants.SIGTERM)) 38 | 39 | (fn [] 40 | (if 41 | (or (and handle (handle:is_active)) (not= stdoutbuffer "")) 42 | (let [stdout stdoutbuffer 43 | stderr stderrbuffer] 44 | (set stdoutbuffer "") 45 | (set stderrbuffer "") 46 | (values stdout stderr kill)) 47 | nil)))) 48 | 49 | (defn exists [path] 50 | "Check if file exists" 51 | (local fd (vim.loop.fs_open path "r" 438)) 52 | (when (~= fd nil) (vim.loop.fs_close fd)) 53 | (~= fd nil)) 54 | 55 | (defn size [path] 56 | (local fd (vim.loop.fs_open path "r" 438)) 57 | (local stat (vim.loop.fs_fstat fd)) 58 | (vim.loop.fs_close fd) 59 | stat.size) 60 | 61 | (local chunk-size 10000) 62 | 63 | (defn read [path] 64 | "Reads a file and yields contents" 65 | (var closed false) 66 | (var canceled false) 67 | (var reading true) 68 | (var databuffer "") 69 | (var fd nil) 70 | (var stat nil) 71 | (var current-offset 0) 72 | 73 | (fn on-close [err] 74 | (assert (not err) err) 75 | (set closed true)) 76 | 77 | (fn on-read [err data] 78 | (assert (not err) err) 79 | (set databuffer data)) 80 | 81 | (fn on-stat [err s] 82 | (assert (not err) err) 83 | (set stat s) 84 | (vim.loop.fs_read fd (math.min chunk-size stat.size) current-offset on-read)) 85 | 86 | (fn on-open [err f] 87 | (assert (not err) err) 88 | (set fd f) 89 | (vim.loop.fs_fstat fd on-stat)) 90 | 91 | (vim.loop.fs_open path "r" 438 on-open) 92 | 93 | (fn close [] (vim.loop.fs_close fd on-close)) 94 | 95 | (fn cancel [] (set canceled true)) 96 | 97 | (while 98 | (not closed) 99 | (if 100 | (or (not fd) (not stat) (= databuffer "")) 101 | (coroutine.yield cancel) 102 | (do 103 | (local data databuffer) 104 | (set databuffer "") 105 | (if 106 | canceled 107 | (close) 108 | reading 109 | (do 110 | (set current-offset (+ current-offset chunk-size)) 111 | (if 112 | (< current-offset stat.size) 113 | (vim.loop.fs_read fd chunk-size current-offset on-read) 114 | (do 115 | (set reading false) 116 | (close))))) 117 | 118 | (coroutine.yield cancel data))))) 119 | -------------------------------------------------------------------------------- /lua/snap/producer/lsp/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/producer/lsp/init.fnl" 2 | local snap = require("snap") 3 | local tbl = require("snap.common.tbl") 4 | local function report_error(error) 5 | return vim.notify(("There was an error when calling LSP: " .. error.message), vim.log.levels.ERROR) 6 | end 7 | local function lsp_buf_request(bufnr, action, params, on_value, on_error) 8 | local function _1_(error, result, context) 9 | if error then 10 | return on_error(error) 11 | else 12 | local client = vim.lsp.get_client_by_id(context.client_id) 13 | local results 14 | if vim.tbl_islist(result) then 15 | results = result 16 | else 17 | results = {result} 18 | end 19 | return on_value({bufnr = bufnr, results = results, offset_encoding = client.offset_encoding}) 20 | end 21 | end 22 | return vim.lsp.buf_request(bufnr, action, params, _1_) 23 | end 24 | local function lsp_producer(bufnr, action, params, tranformer) 25 | local response, error = nil, nil 26 | local function _4_(...) 27 | return lsp_buf_request(bufnr, action, params, ...) 28 | end 29 | response, error = snap.async(_4_) 30 | if error then 31 | local function _5_() 32 | return report_error(error) 33 | end 34 | snap.sync(_5_) 35 | else 36 | end 37 | local function _8_() 38 | local _7_ = (response or {}) 39 | local function _9_(...) 40 | return tranformer(_7_, ...) 41 | end 42 | return _9_ 43 | end 44 | return snap.sync(_8_()) 45 | end 46 | local function get_bufnr(winnr) 47 | local function _10_() 48 | return vim.api.nvim_win_get_buf(winnr) 49 | end 50 | return snap.sync(_10_) 51 | end 52 | local function get_params(winnr) 53 | local function _11_() 54 | return vim.lsp.util.make_position_params(winnr) 55 | end 56 | return snap.sync(_11_) 57 | end 58 | local transformers = {} 59 | transformers.locations = function(_12_) 60 | local _arg_13_ = _12_ 61 | local offset_encoding = _arg_13_["offset_encoding"] 62 | local results = _arg_13_["results"] 63 | local function _14_(_241) 64 | return snap.with_metas(_241.filename, tbl.merge(_241, {offset_encoding = offset_encoding})) 65 | end 66 | return vim.tbl_map(_14_, vim.lsp.util.locations_to_items(results, offset_encoding)) 67 | end 68 | transformers.symbols = function(_15_) 69 | local _arg_16_ = _15_ 70 | local bufnr = _arg_16_["bufnr"] 71 | local results = _arg_16_["results"] 72 | local function _17_(_241) 73 | return snap.with_metas(_241.text, _241) 74 | end 75 | return vim.tbl_map(_17_, vim.lsp.util.symbols_to_items(results, bufnr)) 76 | end 77 | local function locations(action, _18_) 78 | local _arg_19_ = _18_ 79 | local winnr = _arg_19_["winnr"] 80 | return lsp_producer(get_bufnr(winnr), action, get_params(winnr), transformers.locations) 81 | end 82 | local definitions 83 | local function _20_(_241) 84 | return locations("textDocument/definition", _241) 85 | end 86 | definitions = _20_ 87 | local implementations 88 | local function _21_(_241) 89 | return locations("textDocument/implementation", _241) 90 | end 91 | implementations = _21_ 92 | local type_definitions 93 | local function _22_(_241) 94 | return locations("textDocument/typeDefinition", _241) 95 | end 96 | type_definitions = _22_ 97 | local function references(_23_) 98 | local _arg_24_ = _23_ 99 | local winnr = _arg_24_["winnr"] 100 | return lsp_producer(get_bufnr(winnr), "textDocument/references", tbl.merge(get_params(winnr), {context = {includeDeclaration = true}}), transformers.locations) 101 | end 102 | local function symbols(_25_) 103 | local _arg_26_ = _25_ 104 | local winnr = _arg_26_["winnr"] 105 | return lsp_producer(get_bufnr(winnr), "textDocument/documentSymbol", get_params(winnr), transformers.symbols) 106 | end 107 | return {definitions = definitions, implementations = implementations, type_definitions = type_definitions, references = references, symbols = symbols} -------------------------------------------------------------------------------- /lua/snap/select/git/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/select/git/init.fnl" 2 | local snap = require("snap") 3 | local layout = require("snap.layout") 4 | local tbl = require("snap.common.tbl") 5 | local snap_string = require("snap.common.string") 6 | local filter 7 | if pcall(require, "fzy") then 8 | filter = require("snap.consumer.fzy") 9 | else 10 | filter = require("snap.consumer.fzf") 11 | end 12 | local function action_layout(actions) 13 | local columns = layout.columns() 14 | local lines = layout.lines() 15 | local max_length = tbl["max-length"](actions) 16 | local width = (max_length * 3) 17 | local height = (#actions + 3) 18 | return {width = width, height = height, col = layout.middle(columns, width), row = layout.middle(lines, height)} 19 | end 20 | local function checkout(selection, on_done) 21 | local function _2_(_241) 22 | local _3_ = _241.code 23 | if (_3_ == 0) then 24 | if on_done then 25 | vim.schedule(on_done) 26 | else 27 | end 28 | return vim.notify(string.format("Checked out '%s'", tostring(selection)), vim.log.levels.INFO) 29 | elseif true then 30 | local _ = _3_ 31 | return vim.notify(string.format("Error when checking out '%s':\n%s", tostring(selection), _241.stderr), vim.log.levels.ERROR) 32 | else 33 | return nil 34 | end 35 | end 36 | return vim.system({"git", "checkout", tostring(selection)}, {cwd = vim.fn.getcwd()}, _2_) 37 | end 38 | local function reset_soft(selection) 39 | local function _6_(_241) 40 | if (_241.code == 0) then 41 | return vim.notify(string.format("Soft reset '%s'", tostring(selection)), vim.log.levels.INFO) 42 | else 43 | return nil 44 | end 45 | end 46 | return vim.system({"git", "reset", "--soft", tostring(selection)}, {cwd = vim.fn.getcwd()}, _6_) 47 | end 48 | local function reset_hard(selection) 49 | local function _8_(_241) 50 | if (_241.code == 0) then 51 | return vim.notify(string.format("Hard reset '%s'", tostring(selection)), vim.log.levels.INFO) 52 | else 53 | return nil 54 | end 55 | end 56 | return vim.system({"git", "reset", "--hard", tostring(selection)}, {cwd = vim.fn.getcwd()}, _8_) 57 | end 58 | local function pull(branch, remote) 59 | local function _10_() 60 | local function _11_(_2410) 61 | if (_2410.code == 0) then 62 | return vim.notify(string.format("Pulled '%s/%s'", tostring(remote), tostring(branch)), vim.log.levels.INFO) 63 | else 64 | return nil 65 | end 66 | end 67 | return vim.system({"git", "pull", tostring(remote), tostring(branch)}, {cwd = vim.fn.getcwd()}, _11_) 68 | end 69 | return checkout(branch, _10_) 70 | end 71 | local function pull_list(branch) 72 | local function _13_(_241) 73 | if (_241.code == 0) then 74 | local remotes = snap_string.split(_241.stdout) 75 | local function _14_() 76 | local function _15_() 77 | return remotes 78 | end 79 | local function _16_(...) 80 | return vim.schedule_wrap(pull)(branch, ...) 81 | end 82 | local function _17_(...) 83 | return action_layout(remotes, ...) 84 | end 85 | return snap.run({prompt = "Select>", producer = filter(_15_), select = _16_, layout = _17_}) 86 | end 87 | return vim.schedule(_14_) 88 | else 89 | return nil 90 | end 91 | end 92 | return vim.system({"git", "remote"}, {cwd = vim.fn.getcwd()}, _13_) 93 | end 94 | local branch_actions 95 | local function _19_(_241) 96 | return snap.with_metas(_241.label, _241) 97 | end 98 | branch_actions = vim.tbl_map(_19_, {{label = "Checkout", action = checkout}, {label = "Reset (soft)", action = reset_soft}, {label = "Reset (hard)", action = reset_hard}, {label = "Pull", action = pull_list}}) 99 | local function branch(selection) 100 | local function _20_() 101 | return branch_actions 102 | end 103 | local function _21_(_241) 104 | return _241.action(selection) 105 | end 106 | local function _22_(...) 107 | return action_layout(branch_actions, ...) 108 | end 109 | return snap.run({prompt = "Select>", producer = filter(_20_), select = _21_, layout = _22_}) 110 | end 111 | return {branch = branch} -------------------------------------------------------------------------------- /lua/snap/common/io.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/common/io.fnl" 2 | local _2amodule_name_2a = "snap.common.io" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local snap = require("snap") 14 | do end (_2amodule_locals_2a)["snap"] = snap 15 | local function system(cmd, args, cwd, on_value, on_error) 16 | local function on_exit(result) 17 | if (result.code == 0) then 18 | return on_value(result.stdout) 19 | else 20 | return on_error(result.stderr) 21 | end 22 | end 23 | return vim.system({cmd, unpack(args)}, {cwd = cwd}, on_exit) 24 | end 25 | _2amodule_2a["system"] = system 26 | local function spawn(cmd, args, cwd, stdin) 27 | local stdoutbuffer = "" 28 | local stderrbuffer = "" 29 | local stdout = vim.loop.new_pipe(false) 30 | local stderr = vim.loop.new_pipe(false) 31 | local handle 32 | local function _2_(code, signal) 33 | stdout:read_stop() 34 | stderr:read_stop() 35 | stdout:close() 36 | stderr:close() 37 | if stdin then 38 | stdin:read_stop() 39 | stdin:close() 40 | else 41 | end 42 | return handle:close() 43 | end 44 | handle = vim.loop.spawn(cmd, {args = args, stdio = {stdin, stdout, stderr}, cwd = cwd}, _2_) 45 | local function _4_(err, data) 46 | assert(not err) 47 | if data then 48 | stdoutbuffer = (stdoutbuffer .. data) 49 | return nil 50 | else 51 | return nil 52 | end 53 | end 54 | stdout:read_start(_4_) 55 | local function _6_(err, data) 56 | assert(not err) 57 | if data then 58 | stderrbuffer = (stderrbuffer .. data) 59 | return nil 60 | else 61 | return nil 62 | end 63 | end 64 | stderr:read_start(_6_) 65 | local function kill() 66 | return handle:kill(vim.loop.constants.SIGTERM) 67 | end 68 | local function _8_() 69 | if ((handle and handle:is_active()) or (stdoutbuffer ~= "")) then 70 | local stdout0 = stdoutbuffer 71 | local stderr0 = stderrbuffer 72 | stdoutbuffer = "" 73 | stderrbuffer = "" 74 | return stdout0, stderr0, kill 75 | else 76 | return nil 77 | end 78 | end 79 | return _8_ 80 | end 81 | _2amodule_2a["spawn"] = spawn 82 | local function exists(path) 83 | local fd = vim.loop.fs_open(path, "r", 438) 84 | if (fd ~= nil) then 85 | vim.loop.fs_close(fd) 86 | else 87 | end 88 | return (fd ~= nil) 89 | end 90 | _2amodule_2a["exists"] = exists 91 | local function size(path) 92 | local fd = vim.loop.fs_open(path, "r", 438) 93 | local stat = vim.loop.fs_fstat(fd) 94 | vim.loop.fs_close(fd) 95 | return stat.size 96 | end 97 | _2amodule_2a["size"] = size 98 | local chunk_size = 10000 99 | local function read(path) 100 | local closed = false 101 | local canceled = false 102 | local reading = true 103 | local databuffer = "" 104 | local fd = nil 105 | local stat = nil 106 | local current_offset = 0 107 | local function on_close(err) 108 | assert(not err, err) 109 | closed = true 110 | return nil 111 | end 112 | local function on_read(err, data) 113 | assert(not err, err) 114 | databuffer = data 115 | return nil 116 | end 117 | local function on_stat(err, s) 118 | assert(not err, err) 119 | stat = s 120 | return vim.loop.fs_read(fd, math.min(chunk_size, stat.size), current_offset, on_read) 121 | end 122 | local function on_open(err, f) 123 | assert(not err, err) 124 | fd = f 125 | return vim.loop.fs_fstat(fd, on_stat) 126 | end 127 | vim.loop.fs_open(path, "r", 438, on_open) 128 | local function close() 129 | return vim.loop.fs_close(fd, on_close) 130 | end 131 | local function cancel() 132 | canceled = true 133 | return nil 134 | end 135 | while not closed do 136 | if (not fd or not stat or (databuffer == "")) then 137 | coroutine.yield(cancel) 138 | else 139 | local data = databuffer 140 | databuffer = "" 141 | if canceled then 142 | close() 143 | elseif reading then 144 | current_offset = (current_offset + chunk_size) 145 | if (current_offset < stat.size) then 146 | vim.loop.fs_read(fd, chunk_size, current_offset, on_read) 147 | else 148 | reading = false 149 | close() 150 | end 151 | else 152 | end 153 | coroutine.yield(cancel, data) 154 | end 155 | end 156 | return nil 157 | end 158 | _2amodule_2a["read"] = read 159 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/view/input.fnl: -------------------------------------------------------------------------------- 1 | (module snap.view.input {require {size snap.view.size 2 | tbl snap.common.tbl 3 | buffer snap.common.buffer 4 | window snap.common.window 5 | register snap.common.register}}) 6 | 7 | (fn layout [config] 8 | "Creates the input layout" 9 | (let [{: width : height : row : col} (config.layout)] 10 | {:width (if (config.has-views) (- (math.floor (* width size.view-width)) size.padding size.padding) width) 11 | :height 1 12 | :row (if config.reverse row (- (+ row height) size.padding)) 13 | : col 14 | :focusable true 15 | :title :Find 16 | :enter true})) 17 | 18 | (local mappings { 19 | :next [:] 20 | :enter [:] 21 | :enter-split [:] 22 | :enter-vsplit [:] 23 | :enter-tab [:] 24 | :exit [: :] 25 | :select [:] 26 | :unselect [:] 27 | :select-all [:] 28 | :prev-item [: : :] 29 | :next-item [: : :] 30 | :prev-page [: :] 31 | :next-page [: :] 32 | :view-page-down [:] 33 | :view-page-up [:] 34 | :view-toggle-hide [:] 35 | }) 36 | 37 | (local group (vim.api.nvim_create_augroup :SnapInput {:clear true})) 38 | 39 | (defn create [config] 40 | "Creates the input view" 41 | (let [bufnr (buffer.create) 42 | layout-config (layout config) 43 | winnr (window.create bufnr layout-config)] 44 | (vim.api.nvim_set_option_value :winhl "Search:None,Normal:SnapNormal,FloatBorder:SnapBorder" {:win winnr}) 45 | (vim.api.nvim_set_option_value :buftype :prompt {:buf bufnr}) 46 | (vim.api.nvim_set_option_value :bufhidden :wipe {:buf bufnr}) 47 | (buffer.add-highlight bufnr :SnapPrompt 0 0 (string.len config.prompt)) 48 | (vim.fn.prompt_setprompt bufnr config.prompt) 49 | (vim.api.nvim_command :startinsert) 50 | 51 | (local mappings (if config.mappings (tbl.merge mappings config.mappings) mappings)) 52 | 53 | (fn get-filter [] 54 | (let [contents (tbl.first (vim.api.nvim_buf_get_lines bufnr 0 1 false))] 55 | (if contents (contents:sub (+ (length config.prompt) 1)) ""))) 56 | 57 | ;; Track exit 58 | (var exited false) 59 | 60 | (fn on-exit [] 61 | (when (not exited) 62 | (set exited true) 63 | (config.on-exit))) 64 | 65 | (fn on-enter [type] 66 | (config.on-enter type) 67 | (on-exit)) 68 | 69 | (fn on-next [] 70 | (config.on-next) 71 | (on-exit)) 72 | 73 | (fn on-tab [] 74 | (config.on-select-toggle) 75 | (config.on-next-item)) 76 | 77 | (fn on-shifttab [] 78 | (config.on-select-toggle) 79 | (config.on-prev-item)) 80 | 81 | (fn on-ctrla [] 82 | (config.on-select-all-toggle)) 83 | 84 | (fn on_lines [] 85 | (config.on-update (get-filter)) 86 | nil) 87 | 88 | (fn on_detach [] nil) 89 | 90 | ;; Enter and exit 91 | ;; e.g. we want to support opening in splits etc 92 | (register.buf-map bufnr [:n :i] mappings.next on-next) 93 | (register.buf-map bufnr [:n :i] mappings.enter on-enter) 94 | (register.buf-map bufnr [:n :i] mappings.enter-split (partial on-enter "split")) 95 | (register.buf-map bufnr [:n :i] mappings.enter-vsplit (partial on-enter "vsplit")) 96 | (register.buf-map bufnr [:n :i] mappings.enter-tab (partial on-enter "tab")) 97 | (register.buf-map bufnr [:n :i] mappings.exit on-exit) 98 | 99 | ;; Selection 100 | (register.buf-map bufnr [:n :i] mappings.select on-tab) 101 | (register.buf-map bufnr [:n :i] mappings.unselect on-shifttab) 102 | (register.buf-map bufnr [:n :i] mappings.select-all on-ctrla) 103 | 104 | ;; Up & down are reversed when view is revered 105 | (register.buf-map bufnr [:n :i] mappings.prev-item config.on-prev-item) 106 | (register.buf-map bufnr [:n :i] mappings.next-item config.on-next-item) 107 | 108 | ;; Up & down are reversed when view is revered 109 | (register.buf-map bufnr [:n :i] mappings.prev-page config.on-prev-page) 110 | (register.buf-map bufnr [:n :i] mappings.next-page config.on-next-page) 111 | 112 | ;; Views 113 | (register.buf-map bufnr [:n :i] mappings.view-page-down config.on-viewpagedown) 114 | (register.buf-map bufnr [:n :i] mappings.view-page-up config.on-viewpageup) 115 | (register.buf-map bufnr [:n :i] mappings.view-toggle-hide config.on-view-toggle-hide) 116 | 117 | (vim.api.nvim_create_autocmd 118 | [:WinLeave :BufLeave :BufDelete] 119 | { : group :buffer bufnr :once true :callback on-exit }) 120 | 121 | (vim.api.nvim_buf_attach bufnr false {: on_lines : on_detach}) 122 | 123 | (fn delete [] 124 | (when (vim.api.nvim_win_is_valid winnr) 125 | (window.close winnr)) 126 | (when (vim.api.nvim_buf_is_valid bufnr) 127 | (buffer.delete bufnr))) 128 | 129 | (fn update [view] 130 | (when (vim.api.nvim_win_is_valid winnr) 131 | (let [layout-config (layout config)] 132 | (window.update winnr layout-config) 133 | (vim.api.nvim_set_option_value :cursorline true {:win winnr}) 134 | (tset view :height layout-config.height) 135 | (tset view :width layout-config.width)))) 136 | 137 | (local view {: update : delete : bufnr : winnr :width layout-config.width :height layout-config.height}) 138 | 139 | (vim.api.nvim_create_autocmd 140 | :VimResized 141 | { : group :callback (fn [] (view:update)) }) 142 | 143 | view)) 144 | -------------------------------------------------------------------------------- /lua/snap/view/input.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/view/input.fnl" 2 | local _2amodule_name_2a = "snap.view.input" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local buffer, register, size, tbl, window = require("snap.common.buffer"), require("snap.common.register"), require("snap.view.size"), require("snap.common.tbl"), require("snap.common.window") 14 | do end (_2amodule_locals_2a)["buffer"] = buffer 15 | _2amodule_locals_2a["register"] = register 16 | _2amodule_locals_2a["size"] = size 17 | _2amodule_locals_2a["tbl"] = tbl 18 | _2amodule_locals_2a["window"] = window 19 | local function layout(config) 20 | local _let_1_ = config.layout() 21 | local width = _let_1_["width"] 22 | local height = _let_1_["height"] 23 | local row = _let_1_["row"] 24 | local col = _let_1_["col"] 25 | local _2_ 26 | if config["has-views"]() then 27 | _2_ = (math.floor((width * size["view-width"])) - size.padding - size.padding) 28 | else 29 | _2_ = width 30 | end 31 | local _4_ 32 | if config.reverse then 33 | _4_ = row 34 | else 35 | _4_ = ((row + height) - size.padding) 36 | end 37 | return {width = _2_, height = 1, row = _4_, col = col, focusable = true, title = "Find", enter = true} 38 | end 39 | local mappings = {next = {""}, enter = {""}, ["enter-split"] = {""}, ["enter-vsplit"] = {""}, ["enter-tab"] = {""}, exit = {"", ""}, select = {""}, unselect = {""}, ["select-all"] = {""}, ["prev-item"] = {"", "", ""}, ["next-item"] = {"", "", ""}, ["prev-page"] = {"", ""}, ["next-page"] = {"", ""}, ["view-page-down"] = {""}, ["view-page-up"] = {""}, ["view-toggle-hide"] = {""}} 40 | local group = vim.api.nvim_create_augroup("SnapInput", {clear = true}) 41 | local function create(config) 42 | local bufnr = buffer.create() 43 | local layout_config = layout(config) 44 | local winnr = window.create(bufnr, layout_config) 45 | vim.api.nvim_set_option_value("winhl", "Search:None,Normal:SnapNormal,FloatBorder:SnapBorder", {win = winnr}) 46 | vim.api.nvim_set_option_value("buftype", "prompt", {buf = bufnr}) 47 | vim.api.nvim_set_option_value("bufhidden", "wipe", {buf = bufnr}) 48 | buffer["add-highlight"](bufnr, "SnapPrompt", 0, 0, string.len(config.prompt)) 49 | vim.fn.prompt_setprompt(bufnr, config.prompt) 50 | vim.api.nvim_command("startinsert") 51 | local mappings0 52 | if config.mappings then 53 | mappings0 = tbl.merge(mappings, config.mappings) 54 | else 55 | mappings0 = mappings 56 | end 57 | local function get_filter() 58 | local contents = tbl.first(vim.api.nvim_buf_get_lines(bufnr, 0, 1, false)) 59 | if contents then 60 | return contents:sub((#config.prompt + 1)) 61 | else 62 | return "" 63 | end 64 | end 65 | local exited = false 66 | local function on_exit() 67 | if not exited then 68 | exited = true 69 | return config["on-exit"]() 70 | else 71 | return nil 72 | end 73 | end 74 | local function on_enter(type) 75 | config["on-enter"](type) 76 | return on_exit() 77 | end 78 | local function on_next() 79 | config["on-next"]() 80 | return on_exit() 81 | end 82 | local function on_tab() 83 | config["on-select-toggle"]() 84 | return config["on-next-item"]() 85 | end 86 | local function on_shifttab() 87 | config["on-select-toggle"]() 88 | return config["on-prev-item"]() 89 | end 90 | local function on_ctrla() 91 | return config["on-select-all-toggle"]() 92 | end 93 | local function on_lines() 94 | config["on-update"](get_filter()) 95 | return nil 96 | end 97 | local function on_detach() 98 | return nil 99 | end 100 | register["buf-map"](bufnr, {"n", "i"}, mappings0.next, on_next) 101 | register["buf-map"](bufnr, {"n", "i"}, mappings0.enter, on_enter) 102 | local function _9_(...) 103 | return on_enter("split", ...) 104 | end 105 | register["buf-map"](bufnr, {"n", "i"}, mappings0["enter-split"], _9_) 106 | local function _10_(...) 107 | return on_enter("vsplit", ...) 108 | end 109 | register["buf-map"](bufnr, {"n", "i"}, mappings0["enter-vsplit"], _10_) 110 | local function _11_(...) 111 | return on_enter("tab", ...) 112 | end 113 | register["buf-map"](bufnr, {"n", "i"}, mappings0["enter-tab"], _11_) 114 | register["buf-map"](bufnr, {"n", "i"}, mappings0.exit, on_exit) 115 | register["buf-map"](bufnr, {"n", "i"}, mappings0.select, on_tab) 116 | register["buf-map"](bufnr, {"n", "i"}, mappings0.unselect, on_shifttab) 117 | register["buf-map"](bufnr, {"n", "i"}, mappings0["select-all"], on_ctrla) 118 | register["buf-map"](bufnr, {"n", "i"}, mappings0["prev-item"], config["on-prev-item"]) 119 | register["buf-map"](bufnr, {"n", "i"}, mappings0["next-item"], config["on-next-item"]) 120 | register["buf-map"](bufnr, {"n", "i"}, mappings0["prev-page"], config["on-prev-page"]) 121 | register["buf-map"](bufnr, {"n", "i"}, mappings0["next-page"], config["on-next-page"]) 122 | register["buf-map"](bufnr, {"n", "i"}, mappings0["view-page-down"], config["on-viewpagedown"]) 123 | register["buf-map"](bufnr, {"n", "i"}, mappings0["view-page-up"], config["on-viewpageup"]) 124 | register["buf-map"](bufnr, {"n", "i"}, mappings0["view-toggle-hide"], config["on-view-toggle-hide"]) 125 | vim.api.nvim_create_autocmd({"WinLeave", "BufLeave", "BufDelete"}, {group = group, buffer = bufnr, once = true, callback = on_exit}) 126 | vim.api.nvim_buf_attach(bufnr, false, {on_lines = on_lines, on_detach = on_detach}) 127 | local function delete() 128 | if vim.api.nvim_win_is_valid(winnr) then 129 | window.close(winnr) 130 | else 131 | end 132 | if vim.api.nvim_buf_is_valid(bufnr) then 133 | return buffer.delete(bufnr) 134 | else 135 | return nil 136 | end 137 | end 138 | local function update(view) 139 | if vim.api.nvim_win_is_valid(winnr) then 140 | local layout_config0 = layout(config) 141 | window.update(winnr, layout_config0) 142 | vim.api.nvim_set_option_value("cursorline", true, {win = winnr}) 143 | do end (view)["height"] = layout_config0.height 144 | view["width"] = layout_config0.width 145 | return nil 146 | else 147 | return nil 148 | end 149 | end 150 | local view = {update = update, delete = delete, bufnr = bufnr, winnr = winnr, width = layout_config.width, height = layout_config.height} 151 | local function _15_() 152 | return view:update() 153 | end 154 | vim.api.nvim_create_autocmd("VimResized", {group = group, callback = _15_}) 155 | return view 156 | end 157 | _2amodule_2a["create"] = create 158 | return _2amodule_2a -------------------------------------------------------------------------------- /fnl/snap/config/init.fnl: -------------------------------------------------------------------------------- 1 | (module snap.config {require {snap snap 2 | tbl snap.common.tbl} 3 | require-macros [snap.macros]}) 4 | 5 | ;; Based off the concept that you should have at least 80 cols for preview and results (when all real estate is available) 6 | (local default-min-width (* 80 2)) 7 | 8 | (fn preview-disabled [min-width] 9 | "Disables previews based on screen size" 10 | (<= (vim.api.nvim_get_option :columns) (or min-width default-min-width))) 11 | 12 | (fn hide-views [config] 13 | "Gives reasonable defaults for how previews should be display based on manual setting, custom function or display size 14 | 15 | if config.preview is nil or is true 16 | then determine if preview is disabled based on screen size 17 | if config.preview is set and is false 18 | then always hide 19 | if config.preview is a function 20 | then call the function and return the negation of the result" 21 | (match (type config.preview) 22 | :nil (preview-disabled config.preview_min_width) 23 | :boolean (or (= config.preview false) (preview-disabled config.preview_min_width)) 24 | :function (not (config.preview)))) 25 | 26 | (fn format-prompt [suffix prompt] 27 | "Formats a prompt" 28 | (string.format "%s%s" prompt (or suffix :>))) 29 | 30 | (fn with [fnc defaults] 31 | "Returns a new default with config pre-applied. 32 | 33 | If for example you prefer fzy over fzf, then: 34 | 35 | -- This creates a version of snap.defaults.file with fzy set as the default consumer: 36 | local file = file:with {consumer = 'fzy'} 37 | 38 | -- Adds a mapping to search buffers 39 | snap.map('n', 'b', file {producer = 'vim.buffer'})" 40 | (fn [config] (fnc (tbl.merge defaults config)))) 41 | 42 | (fn file-producer-by-kind [config kind] 43 | "Gets a producer from producer type strings and handle special configs like args and hidden" 44 | (var producer (match kind 45 | :ripgrep.file (snap.get :producer.ripgrep.file) 46 | :fd.file (snap.get :producer.fd.file) 47 | :vim.oldfile (snap.get :producer.vim.oldfile) 48 | :vim.buffer (snap.get :producer.vim.buffer) 49 | :git.file (snap.get :producer.git.file) 50 | (where p (= (type p) :function)) p 51 | _ (assert false "file.producer is invalid"))) 52 | 53 | ;; Config non-defaults 54 | (if 55 | (and 56 | config.args 57 | (or (= kind :ripgrep.file) 58 | (= kind :fd.file) 59 | (= kind :git.file))) 60 | (set producer (producer.args config.args)) 61 | (and 62 | config.hidden 63 | (or (= kind :ripgrep.file) 64 | (= kind :fd.file))) 65 | (set producer producer.hidden)) 66 | 67 | producer) 68 | 69 | (fn file-prompt-by-kind [kind] 70 | (match kind 71 | :ripgrep.file "Rg Files" 72 | :fd.file "Fd Files" 73 | :vim.oldfile "Old Files" 74 | :vim.buffer "Buffers" 75 | :git.file "Git Files" 76 | _ "Custom Files")) 77 | 78 | (fn current-word [] 79 | "Outputs the current word under cursor" 80 | (vim.fn.expand "")) 81 | 82 | (fn current-selection [] 83 | "Outputs the current selection" 84 | (local register (vim.fn.getreg "\"")) 85 | (vim.api.nvim_exec "normal! y" false) 86 | (local filter (vim.fn.trim (vim.fn.getreg "@"))) 87 | (vim.fn.setreg "\"" register) 88 | filter) 89 | 90 | (fn get-initial-filter [config] 91 | "Gets the initial filter" 92 | (if 93 | (not= config.filter_with nil) 94 | (match config.filter_with 95 | :cword (current-word) 96 | :selection (current-selection) 97 | _ (assert false "config.filter_with must be a string cword, or selection")) 98 | (not= config.filter nil) 99 | (match (type config.filter) 100 | :function (config.filter) 101 | :string config.filter 102 | _ (assert false "config.filter must be a string or function")) 103 | nil)) 104 | 105 | (defmetafn file {: with} [config] 106 | "Returns a functon which runs `snap.run` for searching files with common file producers and common consumers. 107 | 108 | Supported producers: 109 | 110 | - ripgrep.file 111 | - fd.file 112 | - vim.oldfile 113 | - vim.buffer 114 | - git.file 115 | - any producer function that returns files 116 | 117 | Supported consumers: 118 | 119 | - fzf 120 | - fzy 121 | 122 | Additional options: 123 | 124 | - hidden 125 | - args 126 | - layout 127 | - prompt 128 | - suffix 129 | - reverse 130 | - mappings 131 | - preview_min_width 132 | - preview 133 | 134 | Examples: 135 | 136 | -- Runs ripgrep.file producer with fzf 137 | file {producer = 'ripgrep.file'} 138 | 139 | -- Runs with fzy consumer 140 | file {producer = 'ripgrep.file', consumer = 'fzy'} 141 | 142 | -- Runs with vim.oldfile producer 143 | file {producer = 'vim.oldfile'} 144 | 145 | -- Runs with vim.buffer producer 146 | file {producer = 'vim.buffer'} 147 | 148 | -- Runs with git.file producer 149 | file {producer = 'git.file'} 150 | 151 | -- Runs with git.file producer with ripgrep.file fallback 152 | file {try = {'git.file', 'ripgrep.file'}} 153 | 154 | -- Customizes prompt 155 | file {prompt = 'My Prompt'} 156 | 157 | -- Customizes prompt suffix 158 | file {suffix = '>>'} 159 | 160 | -- When using propducer = 'ripgrep.file' sets the hidden flag 161 | file {hidden = true} 162 | 163 | -- When using propducer = 'ripgrep.file' customizes the arguments 164 | file {args = {'--hidden', '--iglob', '!.git/*'}} 165 | 166 | -- Provides a custom layout function 167 | file {layout = myCustomLayoutFunction}" 168 | 169 | (asserttable config) 170 | (assertstring? config.prompt "file.prompt must be a string") 171 | (assertstring? config.suffix "file.suffix must be a string") 172 | (assertfunction? config.layout "file.layout must be a function") 173 | (asserttable? config.args "file.args must be a table") 174 | (assertboolean? config.hidden "file.hidden must be a boolean") 175 | (asserttable? config.try "file.try must be a table") 176 | (asserttable? config.combine "file.combine must be a table") 177 | (assertboolean? config.reverse "file.reverse must be a boolean") 178 | (assertnumber? config.preview_min_width "file.preview-min-with must be a number") 179 | (asserttable? config.mappings "file.mappings must be a table") 180 | (asserttypes? [:function :boolean] config.preview "file.preview must be a boolean or a function") 181 | 182 | ;; Ensure at least one producer config is set 183 | (assert (or config.producer config.try config.combine) "one of file.producer, file.try or file.combine must be set") 184 | 185 | ;; Validate incompatible options 186 | (assert (not (and config.producer config.try)) "file.try and file.producer can not be used together") 187 | (assert (not (and config.producer config.combine)) "file.combine and file.producer can not be used together") 188 | (assert (not (and config.try config.combine)) "file.try and file.combine can not be used together") 189 | (assert (not (and config.hidden config.args)) "file.args and file.hidden can not be used together") 190 | 191 | ;; Helper function with config applied 192 | (local by-kind (partial file-producer-by-kind config)) 193 | 194 | ;; Consumer kind, default to fzy if config.consumer is not set and fzy exists 195 | (local consumer-kind 196 | (if 197 | (not= config.consumer nil) 198 | config.consumer 199 | (pcall require :fzy) 200 | :fzy 201 | :fzf)) 202 | 203 | ;; Get the initial producer module based on kind 204 | (local producer (if 205 | ;; If we are using try 206 | config.try 207 | ((snap.get :consumer.try) (unpack (vim.tbl_map by-kind config.try))) 208 | ;; If we are using combine 209 | config.combine 210 | ((snap.get :consumer.combine) (unpack (vim.tbl_map by-kind config.combine))) 211 | ;; Otherwise producer must be set 212 | (by-kind config.producer))) 213 | 214 | ;; Get the consumer module based on kind 215 | (local consumer (match consumer-kind 216 | :fzf (snap.get :consumer.fzf) 217 | :fzy (snap.get :consumer.fzy) 218 | (where c (= (type c) :function)) c 219 | _ (assert false "file.consumer is invalid"))) 220 | 221 | ;; Defaults in the user defined suffix 222 | (local add-prompt-suffix (partial format-prompt config.suffix)) 223 | 224 | ;; Create reasonable prompts based on kinds 225 | (local prompt (add-prompt-suffix (if 226 | config.prompt 227 | config.prompt 228 | config.producer 229 | (file-prompt-by-kind config.producer) 230 | config.try 231 | (table.concat (vim.tbl_map file-prompt-by-kind config.try) " or ") 232 | config.combine 233 | (table.concat (vim.tbl_map file-prompt-by-kind config.combine) " + ")))) 234 | 235 | ;; Get the selection module 236 | (local select-file (snap.get :select.file)) 237 | 238 | ;; Create a function to invoke snap 239 | (fn [] 240 | (let [hide_views (partial hide-views config) 241 | reverse (or config.reverse false) 242 | layout (or config.layout nil) 243 | mappings (or config.mappings nil) 244 | producer (consumer producer) 245 | select select-file.select 246 | multiselect select-file.multiselect 247 | initial_filter (get-initial-filter config) 248 | views [(snap.get :preview.file)]] 249 | (snap.run {: prompt 250 | : mappings 251 | : layout 252 | : reverse 253 | : producer 254 | : select 255 | : multiselect 256 | : views 257 | : hide_views 258 | : initial_filter})))) 259 | 260 | (fn vimgrep-prompt-by-kind [kind] 261 | (match kind 262 | :ripgrep.vimgrep "Rg Vimgrep" 263 | _ "Custom Vimgrep")) 264 | 265 | (defmetafn vimgrep {: with} [config] 266 | "Returns a functon which runs `snap.run` for grepping files. 267 | 268 | Supported producers: 269 | 270 | - ripgrep.vimgrep 271 | - any producer function that returns results in the vimgrep format 272 | 273 | Additional options: 274 | 275 | - hidden 276 | - args 277 | - layout 278 | - prompt 279 | - suffix 280 | - limit 281 | 282 | Examples: 283 | 284 | -- Runs with basic defaults, fzf and ripgrep.file 285 | vimgrep {} 286 | 287 | -- Customizes prompt 288 | vimgrep {prompt = 'My Prompt'} 289 | 290 | -- Customizes prompt suffix 291 | vimgrep {suffix = '>>'} 292 | 293 | -- When using propducer = 'ripgrep.vimgrep' sets the hidden flag 294 | vimgrep {hidden = true} 295 | 296 | -- When using propducer = 'ripgrep.vimgrep' customizes the arguments 297 | vimgrep {args = {'--hidden', '--iglob', '!.git/*'}} 298 | 299 | -- Provides a custom layout function 300 | vimgrep {layout = myCustomLayoutFunction}" 301 | 302 | (asserttable config) 303 | (assertstring? config.prompt "vimgrep.prompt must be a string") 304 | (assertnumber? config.limit "vimgrep.limit must be a number") 305 | (assertfunction? config.layout "vimgrep.layout must be a function") 306 | (asserttable? config.args "vimgrep.args must be a table") 307 | (assertboolean? config.hidden "vimgrep.hidden must be a boolean") 308 | (assertstring? config.suffix "vimgrep.suffix must be a string") 309 | (assertboolean? config.reverse "vimgrep.reverse must be a boolean") 310 | (assertboolean? config.preview "vimgrep.preview must be a boolean") 311 | (asserttable? config.mappings "vimgrep.mappings must be a table") 312 | 313 | ;; Get the producer type 314 | (local producer-kind (or config.producer :ripgrep.vimgrep)) 315 | 316 | ;; Gets the producer based on the producer type 317 | (var producer (match producer-kind 318 | :ripgrep.vimgrep (snap.get :producer.ripgrep.vimgrep) 319 | (where p (= (type p) :function)) p 320 | _ (assert false "vimgrep.producer is invalid"))) 321 | 322 | ;; Customize vimgrep 323 | (when 324 | (= producer-kind :ripgrep.vimgrep) 325 | (if 326 | config.args 327 | (set producer (producer.args config.args)) 328 | config.hidden 329 | (set producer producer.hidden))) 330 | 331 | ;; Gets a consumer based on options like limit 332 | (local consumer (if 333 | config.limit 334 | (partial (snap.get :consumer.limit) config.limit) 335 | (fn [producer] producer))) 336 | 337 | ;; Defaults in the user defined suffix 338 | (local format-prompt (partial format-prompt config.suffix)) 339 | 340 | ;; Get a reasonable default prompt based on kinds 341 | (local prompt (format-prompt (if 342 | config.prompt 343 | config.prompt 344 | producer-kind 345 | (vimgrep-prompt-by-kind producer-kind)))) 346 | 347 | (local vimgrep-select (snap.get :select.vimgrep)) 348 | 349 | (fn [] 350 | (let [hide_views (partial hide_views config) 351 | reverse (or config.reverse false) 352 | layout (or config.layout nil) 353 | mappings (or config.mappings nil) 354 | producer (consumer producer) 355 | select vimgrep-select.select 356 | multiselect vimgrep-select.multiselect 357 | initial_filter (get-initial-filter config) 358 | views [(snap.get :preview.vimgrep)]] 359 | (snap.run {: prompt 360 | : layout 361 | : reverse 362 | : mappings 363 | : producer 364 | : select 365 | : multiselect 366 | : views 367 | : hide_views 368 | : initial_filter})))) 369 | 370 | -------------------------------------------------------------------------------- /lua/snap/config/init.lua: -------------------------------------------------------------------------------- 1 | local _2afile_2a = "fnl/snap/config/init.fnl" 2 | local _2amodule_name_2a = "snap.config" 3 | local _2amodule_2a 4 | do 5 | package.loaded[_2amodule_name_2a] = {} 6 | _2amodule_2a = package.loaded[_2amodule_name_2a] 7 | end 8 | local _2amodule_locals_2a 9 | do 10 | _2amodule_2a["aniseed/locals"] = {} 11 | _2amodule_locals_2a = (_2amodule_2a)["aniseed/locals"] 12 | end 13 | local snap, tbl, _ = require("snap"), require("snap.common.tbl"), nil 14 | _2amodule_locals_2a["snap"] = snap 15 | _2amodule_locals_2a["tbl"] = tbl 16 | _2amodule_locals_2a["_"] = _ 17 | local default_min_width = (80 * 2) 18 | local function preview_disabled(min_width) 19 | return (vim.api.nvim_get_option("columns") <= (min_width or default_min_width)) 20 | end 21 | local function hide_views(config) 22 | local _1_ = type(config.preview) 23 | if (_1_ == "nil") then 24 | return preview_disabled(config.preview_min_width) 25 | elseif (_1_ == "boolean") then 26 | return ((config.preview == false) or preview_disabled(config.preview_min_width)) 27 | elseif (_1_ == "function") then 28 | return not config.preview() 29 | else 30 | return nil 31 | end 32 | end 33 | local function format_prompt(suffix, prompt) 34 | return string.format("%s%s", prompt, (suffix or ">")) 35 | end 36 | local function with(fnc, defaults) 37 | local function _3_(config) 38 | return fnc(tbl.merge(defaults, config)) 39 | end 40 | return _3_ 41 | end 42 | local function file_producer_by_kind(config, kind) 43 | local producer 44 | do 45 | local _4_ = kind 46 | if (_4_ == "ripgrep.file") then 47 | producer = snap.get("producer.ripgrep.file") 48 | elseif (_4_ == "fd.file") then 49 | producer = snap.get("producer.fd.file") 50 | elseif (_4_ == "vim.oldfile") then 51 | producer = snap.get("producer.vim.oldfile") 52 | elseif (_4_ == "vim.buffer") then 53 | producer = snap.get("producer.vim.buffer") 54 | elseif (_4_ == "git.file") then 55 | producer = snap.get("producer.git.file") 56 | else 57 | local function _5_() 58 | local p = _4_ 59 | return (type(p) == "function") 60 | end 61 | if ((nil ~= _4_) and _5_()) then 62 | local p = _4_ 63 | producer = p 64 | elseif true then 65 | local _0 = _4_ 66 | producer = assert(false, "file.producer is invalid") 67 | else 68 | producer = nil 69 | end 70 | end 71 | end 72 | if (config.args and ((kind == "ripgrep.file") or (kind == "fd.file") or (kind == "git.file"))) then 73 | producer = producer.args(config.args) 74 | elseif (config.hidden and ((kind == "ripgrep.file") or (kind == "fd.file"))) then 75 | producer = producer.hidden 76 | else 77 | end 78 | return producer 79 | end 80 | local function file_prompt_by_kind(kind) 81 | local _8_ = kind 82 | if (_8_ == "ripgrep.file") then 83 | return "Rg Files" 84 | elseif (_8_ == "fd.file") then 85 | return "Fd Files" 86 | elseif (_8_ == "vim.oldfile") then 87 | return "Old Files" 88 | elseif (_8_ == "vim.buffer") then 89 | return "Buffers" 90 | elseif (_8_ == "git.file") then 91 | return "Git Files" 92 | elseif true then 93 | local _0 = _8_ 94 | return "Custom Files" 95 | else 96 | return nil 97 | end 98 | end 99 | local function current_word() 100 | return vim.fn.expand("") 101 | end 102 | local function current_selection() 103 | local register = vim.fn.getreg("\"") 104 | vim.api.nvim_exec("normal! y", false) 105 | local filter = vim.fn.trim(vim.fn.getreg("@")) 106 | vim.fn.setreg("\"", register) 107 | return filter 108 | end 109 | local function get_initial_filter(config) 110 | if (config.filter_with ~= nil) then 111 | local _10_ = config.filter_with 112 | if (_10_ == "cword") then 113 | return current_word() 114 | elseif (_10_ == "selection") then 115 | return current_selection() 116 | elseif true then 117 | local _0 = _10_ 118 | return assert(false, "config.filter_with must be a string cword, or selection") 119 | else 120 | return nil 121 | end 122 | elseif (config.filter ~= nil) then 123 | local _12_ = type(config.filter) 124 | if (_12_ == "function") then 125 | return config.filter() 126 | elseif (_12_ == "string") then 127 | return config.filter 128 | elseif true then 129 | local _0 = _12_ 130 | return assert(false, "config.filter must be a string or function") 131 | else 132 | return nil 133 | end 134 | else 135 | return nil 136 | end 137 | end 138 | local file 139 | local function _15_(self_1_auto, ...) 140 | local function _16_(config) 141 | assert((type(config) == "table")) 142 | if config.prompt then 143 | assert((type(config.prompt) == "string"), "file.prompt must be a string") 144 | else 145 | end 146 | if config.suffix then 147 | assert((type(config.suffix) == "string"), "file.suffix must be a string") 148 | else 149 | end 150 | if config.layout then 151 | assert((type(config.layout) == "function"), "file.layout must be a function") 152 | else 153 | end 154 | if config.args then 155 | assert((type(config.args) == "table"), "file.args must be a table") 156 | else 157 | end 158 | if config.hidden then 159 | assert((type(config.hidden) == "boolean"), "file.hidden must be a boolean") 160 | else 161 | end 162 | if config.try then 163 | assert((type(config.try) == "table"), "file.try must be a table") 164 | else 165 | end 166 | if config.combine then 167 | assert((type(config.combine) == "table"), "file.combine must be a table") 168 | else 169 | end 170 | if config.reverse then 171 | assert((type(config.reverse) == "boolean"), "file.reverse must be a boolean") 172 | else 173 | end 174 | if config.preview_min_width then 175 | assert((type(config.preview_min_width) == "number"), "file.preview-min-with must be a number") 176 | else 177 | end 178 | if config.mappings then 179 | assert((type(config.mappings) == "table"), "file.mappings must be a table") 180 | else 181 | end 182 | if config.preview then 183 | assert(vim.tbl_contains({"function", "boolean"}, type(config.preview)), "file.preview must be a boolean or a function") 184 | else 185 | end 186 | assert((config.producer or config.try or config.combine), "one of file.producer, file.try or file.combine must be set") 187 | assert(not (config.producer and config.try), "file.try and file.producer can not be used together") 188 | assert(not (config.producer and config.combine), "file.combine and file.producer can not be used together") 189 | assert(not (config.try and config.combine), "file.try and file.combine can not be used together") 190 | assert(not (config.hidden and config.args), "file.args and file.hidden can not be used together") 191 | local by_kind 192 | local function _28_(...) 193 | return file_producer_by_kind(config, ...) 194 | end 195 | by_kind = _28_ 196 | local consumer_kind 197 | if (config.consumer ~= nil) then 198 | consumer_kind = config.consumer 199 | elseif pcall(require, "fzy") then 200 | consumer_kind = "fzy" 201 | else 202 | consumer_kind = "fzf" 203 | end 204 | local producer 205 | if config.try then 206 | producer = snap.get("consumer.try")(unpack(vim.tbl_map(by_kind, config.try))) 207 | elseif config.combine then 208 | producer = snap.get("consumer.combine")(unpack(vim.tbl_map(by_kind, config.combine))) 209 | else 210 | producer = by_kind(config.producer) 211 | end 212 | local consumer 213 | do 214 | local _31_ = consumer_kind 215 | if (_31_ == "fzf") then 216 | consumer = snap.get("consumer.fzf") 217 | elseif (_31_ == "fzy") then 218 | consumer = snap.get("consumer.fzy") 219 | else 220 | local function _32_() 221 | local c = _31_ 222 | return (type(c) == "function") 223 | end 224 | if ((nil ~= _31_) and _32_()) then 225 | local c = _31_ 226 | consumer = c 227 | elseif true then 228 | local _0 = _31_ 229 | consumer = assert(false, "file.consumer is invalid") 230 | else 231 | consumer = nil 232 | end 233 | end 234 | end 235 | local add_prompt_suffix 236 | do 237 | local _34_ = config.suffix 238 | local function _35_(...) 239 | return format_prompt(_34_, ...) 240 | end 241 | add_prompt_suffix = _35_ 242 | end 243 | local prompt 244 | local function _36_() 245 | if config.prompt then 246 | return config.prompt 247 | elseif config.producer then 248 | return file_prompt_by_kind(config.producer) 249 | elseif config.try then 250 | return table.concat(vim.tbl_map(file_prompt_by_kind, config.try), " or ") 251 | elseif config.combine then 252 | return table.concat(vim.tbl_map(file_prompt_by_kind, config.combine), " + ") 253 | else 254 | return nil 255 | end 256 | end 257 | prompt = add_prompt_suffix(_36_()) 258 | local select_file = snap.get("select.file") 259 | local function _37_() 260 | local hide_views0 261 | local function _38_(...) 262 | return hide_views(config, ...) 263 | end 264 | hide_views0 = _38_ 265 | local reverse = (config.reverse or false) 266 | local layout = (config.layout or nil) 267 | local mappings = (config.mappings or nil) 268 | local producer0 = consumer(producer) 269 | local select = select_file.select 270 | local multiselect = select_file.multiselect 271 | local initial_filter = get_initial_filter(config) 272 | local views = {snap.get("preview.file")} 273 | return snap.run({prompt = prompt, mappings = mappings, layout = layout, reverse = reverse, producer = producer0, select = select, multiselect = multiselect, views = views, hide_views = hide_views0, initial_filter = initial_filter}) 274 | end 275 | return _37_ 276 | end 277 | return _16_(...) 278 | end 279 | file = setmetatable({with = with}, {__call = _15_}) 280 | do end (_2amodule_2a)["file"] = file 281 | local function vimgrep_prompt_by_kind(kind) 282 | local _39_ = kind 283 | if (_39_ == "ripgrep.vimgrep") then 284 | return "Rg Vimgrep" 285 | elseif true then 286 | local _0 = _39_ 287 | return "Custom Vimgrep" 288 | else 289 | return nil 290 | end 291 | end 292 | local vimgrep 293 | local function _41_(self_1_auto, ...) 294 | local function _42_(config) 295 | assert((type(config) == "table")) 296 | if config.prompt then 297 | assert((type(config.prompt) == "string"), "vimgrep.prompt must be a string") 298 | else 299 | end 300 | if config.limit then 301 | assert((type(config.limit) == "number"), "vimgrep.limit must be a number") 302 | else 303 | end 304 | if config.layout then 305 | assert((type(config.layout) == "function"), "vimgrep.layout must be a function") 306 | else 307 | end 308 | if config.args then 309 | assert((type(config.args) == "table"), "vimgrep.args must be a table") 310 | else 311 | end 312 | if config.hidden then 313 | assert((type(config.hidden) == "boolean"), "vimgrep.hidden must be a boolean") 314 | else 315 | end 316 | if config.suffix then 317 | assert((type(config.suffix) == "string"), "vimgrep.suffix must be a string") 318 | else 319 | end 320 | if config.reverse then 321 | assert((type(config.reverse) == "boolean"), "vimgrep.reverse must be a boolean") 322 | else 323 | end 324 | if config.preview then 325 | assert((type(config.preview) == "boolean"), "vimgrep.preview must be a boolean") 326 | else 327 | end 328 | if config.mappings then 329 | assert((type(config.mappings) == "table"), "vimgrep.mappings must be a table") 330 | else 331 | end 332 | local producer_kind = (config.producer or "ripgrep.vimgrep") 333 | local producer 334 | do 335 | local _52_ = producer_kind 336 | if (_52_ == "ripgrep.vimgrep") then 337 | producer = snap.get("producer.ripgrep.vimgrep") 338 | else 339 | local function _53_() 340 | local p = _52_ 341 | return (type(p) == "function") 342 | end 343 | if ((nil ~= _52_) and _53_()) then 344 | local p = _52_ 345 | producer = p 346 | elseif true then 347 | local _0 = _52_ 348 | producer = assert(false, "vimgrep.producer is invalid") 349 | else 350 | producer = nil 351 | end 352 | end 353 | end 354 | if (producer_kind == "ripgrep.vimgrep") then 355 | if config.args then 356 | producer = producer.args(config.args) 357 | elseif config.hidden then 358 | producer = producer.hidden 359 | else 360 | end 361 | else 362 | end 363 | local consumer 364 | if config.limit then 365 | local _57_ = config.limit 366 | local function _58_(...) 367 | return snap.get("consumer.limit")(_57_, ...) 368 | end 369 | consumer = _58_ 370 | else 371 | local function _59_(producer0) 372 | return producer0 373 | end 374 | consumer = _59_ 375 | end 376 | local format_prompt0 377 | do 378 | local _61_ = config.suffix 379 | local function _62_(...) 380 | return format_prompt(_61_, ...) 381 | end 382 | format_prompt0 = _62_ 383 | end 384 | local prompt 385 | local function _63_() 386 | if config.prompt then 387 | return config.prompt 388 | elseif producer_kind then 389 | return vimgrep_prompt_by_kind(producer_kind) 390 | else 391 | return nil 392 | end 393 | end 394 | prompt = format_prompt0(_63_()) 395 | local vimgrep_select = snap.get("select.vimgrep") 396 | local function _64_() 397 | local hide_views0 398 | local function _65_(...) 399 | return hide_views(config, ...) 400 | end 401 | hide_views0 = _65_ 402 | local reverse = (config.reverse or false) 403 | local layout = (config.layout or nil) 404 | local mappings = (config.mappings or nil) 405 | local producer0 = consumer(producer) 406 | local select = vimgrep_select.select 407 | local multiselect = vimgrep_select.multiselect 408 | local initial_filter = get_initial_filter(config) 409 | local views = {snap.get("preview.vimgrep")} 410 | return snap.run({prompt = prompt, layout = layout, reverse = reverse, mappings = mappings, producer = producer0, select = select, multiselect = multiselect, views = views, hide_views = hide_views0, initial_filter = initial_filter}) 411 | end 412 | return _64_ 413 | end 414 | return _42_(...) 415 | end 416 | vimgrep = setmetatable({with = with}, {__call = _41_}) 417 | do end (_2amodule_2a)["vimgrep"] = vimgrep 418 | return _2amodule_2a --------------------------------------------------------------------------------