diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index e69f8fc..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Changelog
-
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
-and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
-
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a89ec6d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+SHELL:=/usr/bin/env bash
+
+LOG_INFO=$(shell date +"%H:%M:%S") \e[0;34mINFO\e[0m
+LOG_ERROR=$(shell date +"%H:%M:%S") \e[1;31mERROR\e[0m
+LOG_WARNING=$(shell date +"%H:%M:%S") \e[0;33mWARNING\e[0m
+LOG_SUCCESS=$(shell date +"%H:%M:%S") \e[0;32mSUCCESS\e[0m
+GIT_ROOT=$(shell git rev-parse --show-toplevel)
+
+.DEFAULT_GOAL := load
+
+load:
+ @echo -e "$(LOG_INFO) Loading dev env..."
+ @echo -e "$(LOG_WARNING) Opening $(GIT_ROOT)"
+ nvim --cmd "set rtp+=$(GIT_ROOT)"
diff --git a/README.md b/README.md
index 3d9007f..b6fa486 100644
--- a/README.md
+++ b/README.md
@@ -1,306 +1,132 @@
-
๐ฆด AutoSave.nvim
-
- A NeoVim plugin for saving your work before the world collapses or you type :qa!
+
๐งถ auto-save.nvim
-
-
- 
-
-
+ Automatically save your changes in NeoVim
-
- Demo
-
+
+
+
+
+
+
+
+
-# TL;DR
+### ๐ Features
-
- AutoSave.nvim is a NeoVim plugin written in Lua that aims to provide the simple functionality of automatically saving your work whenever you make changes to it. You can filter under which conditions which files are saved and when the auto-save functionality should be triggered (events). To get started simply install the plugin with your favorite plugin manager!
-
+- automatically save your changes so the world doesn't collapse
+- highly customizable:
+ - conditionals to assert whether to save or not
+ - execution message (it can be dimmed and personalized)
+ - events that trigger auto-save
+- debounce the save with a delay
+- multiple callbacks
+- automatically clean the message area
-# ๐ฒ Table of Contents
+
-* [Features](#-features)
-* [Notices](#-notices)
-* [Installation](#-installation)
- * [Prerequisites](#prerequisites)
- * [Adding the plugin](#adding-the-plugin)
- * [Setup Configuration](#setup-configuration)
- * [For init.lua](#for-initlua)
- * [For init.vim](#for-initvim)
- * [Updating](#updating)
-* [Usage](#-usage)
- * [Commands](#commands)
- * [Default](#default)
- * [Extra](#extra)
- * [General](#general)
-* [Configuration](#-configuration)
- * [General](#general)
- * [Conditions](#conditions)
- * [Hooks](#hooks)
- * [Recommendations](#recommendations)
-* [Contribute](#-contribute)
-* [Inspirations](#-inspirations)
-* [License](#-license)
-* [FAQ](#-faq)
-* [To-Do](#-to-do)
+### ๐ Requirements
-# ๐ Features
-+ Automatically save current file(s).
-+ Set conditions that files must meet to be saved (e.g. filetype, existence, ...).
-+ Set events that will trigger the plugin.
-+ Add custom hooks (e.g. print a message when the plugin is turned off).
-+ Toggle the plugin on and off.
+- Neovim >= 0.5.0
-# ๐บ Notices
-Checkout the [CHANGELOG.md](https://github.com/Pocco81/AutoSave.nvim/blob/main/CHANGELOG.md) file for more information on the notices below:
+
-+ **15-07-21**: Implemented debounce_delay setting thanks to #7 and "Preserve cursor marks" feature when saving thanks to #8.
-+ **04-07-21**: Fixed #1.
-+ **01-07-21**: Just released!
+### ๐ฆ Installation
-# ๐ฆ Installation
-
-## Prerequisites
-
-- [NeoVim nightly](https://github.com/neovim/neovim/releases/tag/nightly) (>=v0.5.0)
-
-## Adding the plugin
-You can use your favorite plugin manager for this. Here are some examples with the most popular ones:
-
-### Vim-plug
-
-```lua
-Plug 'Pocco81/AutoSave.nvim'
-```
-### Packer.nvim
-
-```lua
-use "Pocco81/AutoSave.nvim"
-```
-
-### Vundle
-
-```lua
-Plugin 'Pocco81/AutoSave.nvim'
-```
-
-### NeoBundle
-```lua
-NeoBundleFetch 'Pocco81/AutoSave.nvim'
-```
-
-## Setup (configuration)
-As it's stated in the TL;DR, there are already some sane defaults that you may like, however you can change them to match your taste. These are the defaults:
-```lua
-enabled = true,
-execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
-events = {"InsertLeave", "TextChanged"},
-conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true,
-},
-write_all_buffers = false,
-on_off_commands = false,
-clean_command_line_interval = 0,
-debounce_delay = 135
-```
-
-The way you setup the settings on your config varies on whether you are using vimL for this or Lua.
+Install the plugin with your favourite package manager:
- For init.lua
-
+ Packer.nvim
```lua
-local autosave = require("autosave")
-
-autosave.setup(
- {
- enabled = true,
- execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
- events = {"InsertLeave", "TextChanged"},
- conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true
- },
- write_all_buffers = false,
- on_off_commands = true,
- clean_command_line_interval = 0,
- debounce_delay = 135
- }
-)
+use({
+ "Pocco81/auto-save.nvim",
+ config = function()
+ require("auto-save").setup {
+ -- your config goes here
+ -- or just leave it empty :)
+ }
+ end,
+})
```
-
+
-
- For init.vim
-
+ vim-plug
-```lua
+```vim
+Plug 'Pocco81/auto-save.nvim'
lua << EOF
-local autosave = require("autosave")
-
-autosave.setup(
- {
- enabled = true,
- execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
- events = {"InsertLeave", "TextChanged"},
- conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true
- },
- write_all_buffers = false,
- on_off_commands = true,
- clean_command_line_interval = 0,
- debounce_delay = 135
- }
-)
+ require("auto-save").setup {
+ -- your config goes here
+ -- or just leave it empty :)
+ }
EOF
```
-
+
-For instructions on how to configure the plugin, check out the [configuration](#configuration) section.
+
-## Updating
-This depends on your plugin manager. If, for example, you are using Packer.nvim, you can update it with this command:
-```lua
-:PackerUpdate
-```
+### โ๏ธ Configuration
-# ๐ค Usage
-
-## Commands
-All the commands follow the *camel casing* naming convention and have the `AS` prefix so that it's easy to remember that they are part of this plugin. These are all of them:
-
-### Default
-+ `:ASToggle`: toggles AutoSave.nvim on and off.
-
-### Extra
-+ `:ASOn`: turns AutoSave.nvim on.
-+ `:ASOff`: turns AutoSave.nvim off.
-
-## General
-+ `vim.g.autosave_state`: use this to check whether AutoSave is on (`true`) or off (`false`).
-
-# ๐ฌ Configuration
-Although settings already have self-explanatory names, here is where you can find info about each one of them and their classifications!
-
-## General
-+ `enabled:`: (Boolean) if true, enables AutoSave.nvim at startup (Note: this is not for loading the plugin it self but rather the "auto-save" functionality. This is like running `:ASOn`).
-+ `execution_message`: (String) message to be displayed when saving [a] file[s].
-+ `events`: (Table): events that will trigger the plugin.
-+ `write_all_buffers`: (Boolean) if true, writes to all modifiable buffers that meet the `conditions`.
-+ `on_off_commands`: (Boolean) if true, enables extra commands for toggling the plugin on and off (`:ASOn` and `:ASOff`).
-+ `clean_command_line_interval` (Integer) if greater than 0, cleans the command line after *x* amount of milliseconds after printing the `execution_message`.
-+ `debounce_delay` (Integer) if greater than 0, saves the file at most every `debounce_delay` milliseconds, vastly improving editing performance. If 0 then saves are performed immediately after `events` occur. It's recommend to leave the default value (`135`), which is just long enough to reduce unnecessary saves, but short enough that you don't notice the delay.
-
-## Conditions
-These are the conditions that every file must meet so that it can be saved. If every file to be auto-saved doesn't meet all of the conditions it won't be saved.
-+ `exists`: (Boolean) if true, enables this condition. If the file doesn't exist it won't save it (e.g. if you `nvim stuff.txt` and don't save the file then this condition won't be met)
-+ `modifiable`: (Boolean) if true, enables this condition. If the file isn't modifiable, then this condition isn't met.
-+ `filename_is_not`: (Table, Strings) if there is one or more filenames (should be strings) in the table, it enables this condition. Use this to exclude filenames that you don't want to automatically save.
-+ `filetype_is_not`: (Table, Strings) if there is one or more filetypes (should be strings) in the table, it enables this condition. Use this to exclude filetypes that you don't want to automatically save.
-
-## Hooks
-Use them to execute code at certain events [described by their names]. These are the ones available:
-
-| Function | Description |
-|----------------------|--------------------------------------------------------------------|
-| hook_before_on() | Before toggling the plugin on |
-| hook_after_on() | After toggling the plugin on |
-| hook_before_off() | Before toggling the plugin off |
-| hook_after_off() | After toggling the plugin off |
-| hook_before_saving() | Before its even checked if the current file(s) meet the conditions |
-| hook_after_saving | After saving the file(s) |
-
-They can be used like so:
+**auto-save** comes with the following defaults:
```lua
-local autosave = require("autosave")
+{
+ enabled = true, -- start auto-save when the plugin is loaded (i.e. when your package manager loads it)
+ execution_message = {
+ message = function() -- message to print on save
+ return ("AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"))
+ end,
+ dim = 0.18, -- dim the color of `message`
+ cleaning_interval = 4000, -- (milliseconds) automatically clean MsgArea after displaying `message`. See :h MsgArea
+ },
+ trigger_events = {"InsertLeave", "TextChanged"}, -- vim events that trigger auto-save. See :h events
+ -- function that determines whether to save the current buffer or not
+ -- return true: if buffer is ok to be saved
+ -- return false: if it's not ok to be saved
+ condition = function(buf)
+ local fn = vim.fn
+ local utils = require("auto-save.utils.data")
-autosave.hook_after_off = function ()
- print("I was toggled off!")
-end
+ if
+ fn.getbufvar(buf, "&modifiable") == 1 or
+ utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then
+ return true -- met condition(s), can save
+ end
+ return false -- can't save
+ end,
+ write_all_buffers = false, -- write all buffers when the current one meets `condition`
+ debounce_delay = 135, -- saves the file at most every `debounce_delay` milliseconds
+ callbacks = { -- functions to be executed at different intervals
+ enabling = nil, -- ran when enabling auto-save
+ disabling = nil, -- ran when disabling auto-save
+ before_asserting_save = nil, -- ran before checking `condition`
+ before_saving = nil, -- ran before doing the actual save
+ after_saving = nil -- ran after doing the actual save
+ }
+}
```
-## Recommendations
-+ Many other plugins/stuff that you may use rely on using the same events as the ones AutoSave uses by default or may need to interact with the buffer before it's saved. Mainly being plugins for snippets support. If this is your case, consider increasing the `debounce_delay` setting to your needs.
+Additionally you may want to set up a key mapping to toggle auto-save:
-# ๐ FAQ
+```lua
+vim.api.nvim_set_keymap("n", "n", ":ASToggle", {})
+```
-- Q: ***"How can I view the doc from NeoVim?"***
-- A: Use `:help AutoSave.nvim`
+
-# ๐ซ Contribute
+### ๐ชด Usage
-Pull Requests are welcomed as long as they are properly justified and there are no conflicts. If your PR has something to do with the README or in general related with the documentation, I'll gladly merge it! Also, when writing code for the project **you must** use the [.editorconfig](https://github.com/Pocco81/AutoSave.nvim/blob/main/.editorconfig) file on your editor so as to "maintain consistent coding styles". For instructions on how to use this file refer to [EditorConfig's website](https://editorconfig.org/).
+Besides running auto-save at startup (if you have `enabled = true` in your config), you may as well:
-# ๐ญ Inspirations
+- `ASToggle`: toggle auto-save
-The following projects inspired the creation of AutoSave.nvim. If possible, go check them out to see why they are so amazing :]
-- [907th/vim-auto-save](https://github.com/907th/vim-auto-save): Automatically save changes to disk in Vim.
-
-# ๐ License
-
-AutoSave.nvim is released under the GPL v3.0 license. It grants open-source permissions for users including:
-
-- The right to download and run the software freely
-- The right to make changes to the software as desired
-- The right to redistribute copies of the software
-- The right to modify and distribute copies of new versions of the software
-
-For more convoluted language, see the [LICENSE file](https://github.com/Pocco81/AutoSave.nvim/blob/main/LICENSE.md).
-
-# ๐ TO-DO
-
-**High Priority**
-+ None
-
-**Low Priority**
-+ None
-
-
-
- Enjoy!
-
+
diff --git a/doc/autosave.txt b/doc/autosave.txt
deleted file mode 100644
index 12f52f5..0000000
--- a/doc/autosave.txt
+++ /dev/null
@@ -1,201 +0,0 @@
-*AutoSave.nvim* *AutoSave-help* A NeoVim plugin for saving your work before the world collapses or you type :qa!
-
-Author: Pocco81
-License: GPL-3.0 License
-
-CONTENTS *truezen-contents*
-
-TL;DR |autosave-tldr|
-Installation |autosave-installation|
- Prerequisites |autosave-prerequisites|
- Adding the plugin |autosave-adding-the-plugin|
- Setup Configuration |autosave-setup-configuration|
- For init.lua |autosave-for-initlua|
- For init.vim |autosave-for-initvim|
- Updating |autosave-updating|
-Features |autosave-features|
-Usage (commands) |autosave-usage-commands|
- Default |autosave-default|
- Extra |autosave-extra|
-Configuration |autosave-configuration|
- General |autosave-general|
- Conditions |autosave-conditions|
- Hooks |autosave-hooks|
-
-==============================================================================
-
-# TL;DR *autosave-tldr*
-AutoSave.nvim is a NeoVim plugin written in Lua that aims to provide the simple functionality of automatically saving your work whenever you make changes to it. You can filter under which conditions which files are saved and when the auto-save functionality should triggered (events). To get started simply install the plugin with your favorite plugin manager!
-
-# Installation *autosave-installation*
-
-## Prerequisites *autosave-prerequisites*
-
-- [NeoVim nightly](https://github.com/neovim/neovim/releases/tag/nightly) (>=v0.5.0)
-
-## Adding the plugin *AutoSave-adding-the-plugin*
-You can use your favorite plugin manager for this. Here are some examples with the most popular ones:
-
-### Vim-plug
-
-```lua
-Plug 'Pocco81/AutoSave.nvim'
-```
-### Packer.nvim
-
-```lua
-use "Pocco81/AutoSave.nvim"
-```
-
-### Vundle
-
-```lua
-Plugin 'Pocco81/AutoSave.nvim'
-```
-
-### NeoBundle
-```lua
-NeoBundleFetch 'Pocco81/AutoSave.nvim'
-```
-
-## Setup (configuration) *AutoSave-setup-configuration*
-As it's stated in the TL;DR, there are already some sane defaults that you may like, however you can change them to match your taste. These are the defaults:
-```lua
-enabled = true,
-execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
-events = {"InsertLeave", "TextChanged"},
-conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true,
-},
-write_all_buffers = false,
-on_off_commands = false,
-clean_command_line_interval = 0
-debounce_delay = 135
-```
-
-The way you setup the settings on your config varies on whether you are using vimL for this or Lua.
-
-For init.lua *AutoSave-for-initlua*
-
-```lua
-local autosave = require("autosave")
-
-autosave.setup(
- {
- enabled = true,
- execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
- events = {"InsertLeave", "TextChanged"},
- conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true
- },
- write_all_buffers = false,
- on_off_commands = true,
- clean_command_line_interval = 0
- debounce_delay = 135
- }
-)
-```
-
-For init.vim *AutoSave-for-initvim*
-
-```lua
-lua << EOF
-local autosave = require("autosave")
-
-autosave.setup(
- {
- enabled = true,
- execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
- events = {"InsertLeave", "TextChanged"},
- conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true
- },
- write_all_buffers = false,
- on_off_commands = true,
- clean_command_line_interval = 0
- debounce_delay = 135
- }
-)
-EOF
-```
-
-
-
-For instructions on how to configure the plugin, check out the [configuration](#configuration) section.
-
-## Updating *autosave-updating*
-This depends on your plugin manager. If, for example, you are using Packer.nvim, you can update it with this command:
-```lua
-:PackerUpdate
-```
-
-# Usage (commands) *autosave-usage-commands*
-All the commands follow the *camel casing* naming convention and have the `AS` prefix so that it's easy to remember that they are part of this plugin. These are all of them:
-
-## Default
-+ `:ASToggle`: toggles AutoSave.nvim on and off.
-
-## Extra
-+ `:ASOn`: turns AutoSave.nvim on.
-+ `:ASOff`: turns AutoSave.nvim off.
-
-# Configuration *autosave-configuration*
-Although settings already have self-explanatory names, here is where you can find info about each one of them and their classifications!
-
-## General
-+ `enabled:`: (Boolean) if true, enables AutoSave.nvim at startup (Note: this is not for loading the plugin it self but rather the "auto-save" functionality. This is like running `:ASOn`).
-+ `execution_message`: (String) message to be displayed when saving [a] file[s]. If the string is empty, no message will be displayed.
-+ `events`: (Table): events that will trigger the plugin.
-+ `write_all_buffers`: (Boolean) if true, writes to all modifiable buffers that meet the `conditions`.
-+ `on_off_commands`: (Boolean) if true, enables extra commands for toggling the plugin on and off (`:ASOn` and `:ASOff`).
-+ `clean_command_line_interval` (Integer) if greater than 0, cleans the command line after *x* amount of milliseconds after printing the `execution_message`.
-+ `debounce_delay` (Integer) if greater than 0, saves the file at most every `debounce_delay` milliseconds, vastly improving editing performance. If 0 then saves are performed immediately after `events` occur. It's recommend to leave the default value (`135`), which is just long enough to reduce unnecessary saves, but short enough that you don't notice the delay.
-
-## Conditions
-These are the conditions that every file must meet so that it can be saved. If every file to be auto-saved doesn't meet all of the conditions it won't be saved.
-+ `exists`: (Boolean) if true, enables this condition. If the file doesn't exist it won't save it (e.g. if you `nvim stuff.txt` and don't save the file then this condition won't be met)
-+ `modifiable`: (Boolean) if true, enables this condition. If the file isn't modifiable, then this condition isn't met.
-+ `filename_is_not`: (Table, Strings) if there is one or more filenames (should be strings) in the table, it enables this condition. Use this to exclude filenames that you don't want to automatically save.
-+ `filetype_is_not`: (Table, Strings) if there is one or more filetypes (should be strings) in the table, it enables this condition. Use this to exclude filetypes that you don't want to automatically save.
-
-## Hooks
-Use them to execute code at certain events [described by their names]. These are the ones available:
-
-| Function | Description |
-|----------------------|----------------------------------------------------------------------|
-| hook_before_on() | Before toggling the plugin on |
-| hook_after_on() | After toggling the plugin on |
-| hook_before_off() | Before toggling the plugin off |
-| hook_after_off() | After toggling the plugin off |
-| hook_before_saving() | Before its even checked if the file meets the conditions to be saved |
-| hook_after_saving | After successfully saving the file or not |
-
-They can be used like so:
-
-```lua
-local autosave = require("autosave")
-
-autosave.hook_after_off = function ()
- print("I was toggled off!")
-end
-```
-
-# License *AutoSave-license*
-
-AutoSave.nvim is released under the GPL v3.0 license. It grants open-source permissions for users including:
-
-- The right to download and run the software freely
-- The right to make changes to the software as desired
-- The right to redistribute copies of the software
-- The right to modify and distribute copies of new versions of the software
-
-For more convoluted language, see the [LICENSE file](https://github.com/Pocco81/AutoSave.nvim/blob/main/README.md).
diff --git a/lua/auto-save/config.lua b/lua/auto-save/config.lua
new file mode 100644
index 0000000..53b296f
--- /dev/null
+++ b/lua/auto-save/config.lua
@@ -0,0 +1,43 @@
+local config = {}
+
+config.options = {
+ enabled = true, -- start auto-save when the plugin is loaded (i.e. when your package manager loads it)
+ execution_message = {
+ message = function() -- message to print on save
+ return ("AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"))
+ end,
+ dim = 0.18, -- dim the color of `message`
+ cleaning_interval = 4000, -- (milliseconds) automatically clean MsgArea after displaying `message`. See :h MsgArea
+ },
+ trigger_events = {"InsertLeave", "TextChanged"}, -- vim events that trigger auto-save. See :h events
+ -- function that determines whether to save the current buffer or not
+ -- return true: if buffer is ok to be saved
+ -- return false: if it's not ok to be saved
+ condition = function(buf)
+ local fn = vim.fn
+ local utils = require("auto-save.utils.data")
+
+ if
+ fn.getbufvar(buf, "&modifiable") == 1 or
+ utils.not_in(fn.getbufvar(buf, "&filetype"), {}) then
+ return true -- met condition(s), can save
+ end
+ return false -- can't save
+ end,
+ write_all_buffers = false, -- write all buffers when the current one meets `condition`
+ debounce_delay = 135, -- saves the file at most every `debounce_delay` milliseconds
+ callbacks = { -- functions to be executed at different intervals
+ enabling = nil, -- ran when enabling auto-save
+ disabling = nil, -- ran when disabling auto-save
+ before_asserting_save = nil, -- ran before checking `condition`
+ before_saving = nil, -- ran before doing the actual save
+ after_saving = nil -- ran after doing the actual save
+ }
+}
+
+function config.set_options(opts)
+ opts = opts or {}
+ config.options = vim.tbl_deep_extend("keep", opts, config.options)
+end
+
+return config
diff --git a/lua/auto-save/init.lua b/lua/auto-save/init.lua
new file mode 100644
index 0000000..295131b
--- /dev/null
+++ b/lua/auto-save/init.lua
@@ -0,0 +1,149 @@
+local M = {}
+
+local cnf = require("auto-save.config").options
+local callback = require("auto-save.utils.data").do_callback
+local colors = require("auto-save.utils.colors")
+local echo = require("auto-save.utils.echo")
+local autosave_running
+local api = vim.api
+local g = vim.g
+local fn = vim.fn
+local cmd = vim.cmd
+local o = vim.o
+
+api.nvim_create_augroup("AutoSave", {
+ clear = true,
+})
+
+local global_vars = {}
+
+local function set_buf_var(buf, name, value)
+ if buf == nil then
+ global_vars[name] = value
+ else
+ api.nvim_buf_set_var(buf, 'autosave_' .. name, value)
+ end
+end
+
+local function get_buf_var(buf, name)
+ if buf == nil then
+ return global_vars[name]
+ end
+ local success, mod = pcall(api.nvim_buf_get_var, buf, 'autosave_' .. name)
+ return success and mod or nil
+end
+
+local function debounce(lfn, duration)
+ local function inner_debounce()
+ local buf = api.nvim_get_current_buf()
+ if not get_buf_var(buf, 'queued') then
+ vim.defer_fn(function()
+ set_buf_var(buf, 'queued', false)
+ lfn(buf)
+ end, duration)
+ set_buf_var(buf, 'queued', true)
+ end
+ end
+
+ return inner_debounce
+end
+
+function M.save(buf)
+ buf = buf or api.nvim_get_current_buf()
+
+ callback("before_asserting_save")
+
+ if cnf.condition(buf) == false then
+ return
+ end
+
+ if not api.nvim_buf_get_option(buf, 'modified') then
+ return
+ end
+
+ callback("before_saving")
+
+ if g.auto_save_abort == true then
+ return
+ end
+
+ if cnf.write_all_buffers then
+ cmd("silent! wall")
+ else
+ api.nvim_buf_call(buf, function () cmd("silent! write") end)
+ end
+
+ callback("after_saving")
+
+ api.nvim_echo({ { (type(cnf.execution_message.message) == "function" and cnf.execution_message.message() or cnf.execution_message.message), 'AutoSaveText' } }, true, {})
+ if cnf.execution_message.cleaning_interval > 0 then
+ fn.timer_start(
+ cnf.execution_message.cleaning_interval,
+ function()
+ cmd([[echon '']])
+ end
+ )
+ end
+end
+
+local save_func = (cnf.debounce_delay > 0 and debounce(M.save, cnf.debounce_delay) or M.save)
+
+local function perform_save()
+ g.auto_save_abort = false
+ save_func()
+end
+
+function M.on()
+ api.nvim_create_autocmd(cnf.trigger_events, {
+ callback = function()
+ perform_save()
+ end,
+ pattern = "*",
+ group = "AutoSave",
+ })
+
+ api.nvim_create_autocmd("VimEnter", {
+ callback = function()
+ if cnf.execution_message.dim > 0 then
+ MSG_AREA = colors.get_hl("MsgArea")
+ MSG_AREA.background = (MSG_AREA.background or colors.get_hl("Normal")["background"])
+ local foreground = (
+ o.background == "dark" and
+ colors.darken((MSG_AREA.background or "#000000"), cnf.execution_message.dim, MSG_AREA.foreground) or
+ colors.lighten((MSG_AREA.background or "#ffffff"), cnf.execution_message.dim, MSG_AREA.foreground)
+ )
+
+ colors.highlight("AutoSaveText", { fg = foreground })
+ end
+ end,
+ once = true,
+ group = "AutoSave",
+ })
+
+ callback("enabling")
+ autosave_running = true
+end
+
+function M.off()
+
+ api.nvim_create_augroup("AutoSave", {
+ clear = true,
+ })
+
+ callback("disabling")
+ autosave_running = false
+end
+
+function M.toggle()
+ if autosave_running then
+ M.off()
+ else
+ M.on()
+ end
+end
+
+function M.setup(custom_opts)
+ require("auto-save.config").set_options(custom_opts)
+end
+
+return M
diff --git a/lua/auto-save/utils/colors.lua b/lua/auto-save/utils/colors.lua
new file mode 100644
index 0000000..d73c30c
--- /dev/null
+++ b/lua/auto-save/utils/colors.lua
@@ -0,0 +1,70 @@
+local M = {}
+---@param hex_str string hexadecimal value of a color
+local hex_to_rgb = function(hex_str)
+ local hex = "[abcdef0-9][abcdef0-9]"
+ local pat = "^#(" .. hex .. ")(" .. hex .. ")(" .. hex .. ")$"
+ hex_str = string.lower(hex_str)
+
+ assert(string.find(hex_str, pat) ~= nil, "hex_to_rgb: invalid hex_str: " .. tostring(hex_str))
+
+ local red, green, blue = string.match(hex_str, pat)
+ return { tonumber(red, 16), tonumber(green, 16), tonumber(blue, 16) }
+end
+
+function M.highlight(group, color, force)
+ if color.link then
+ vim.api.nvim_set_hl(0, group, {
+ link = color.link,
+ })
+ else
+ if color.style then
+ for _, style in ipairs(color.style) do
+ color[style] = true
+ end
+ end
+ color.style = nil
+ if force then
+ vim.cmd("hi " .. group .. " guifg=" .. (color.fg or "NONE") .. " guibg=" .. (color.bg or "NONE"))
+ return
+ end
+ vim.api.nvim_set_hl(0, group, color)
+ end
+end
+
+function M.get_hl(name)
+ local ok, hl = pcall(vim.api.nvim_get_hl_by_name, name, true)
+ if not ok then
+ return
+ end
+ for _, key in pairs({ "foreground", "background", "special" }) do
+ if hl[key] then
+ hl[key] = string.format("#%06x", hl[key])
+ end
+ end
+ return hl
+end
+
+---@param fg string forecrust color
+---@param bg string background color
+---@param alpha number number between 0 and 1. 0 results in bg, 1 results in fg
+function M.blend(fg, bg, alpha)
+ bg = hex_to_rgb(bg)
+ fg = hex_to_rgb(fg)
+
+ local blendChannel = function(i)
+ local ret = (alpha * fg[i] + ((1 - alpha) * bg[i]))
+ return math.floor(math.min(math.max(0, ret), 255) + 0.5)
+ end
+
+ return string.format("#%02X%02X%02X", blendChannel(1), blendChannel(2), blendChannel(3))
+end
+
+function M.darken(hex, amount, bg)
+ return M.blend(hex, bg or M.bg, math.abs(amount))
+end
+
+function M.lighten(hex, amount, fg)
+ return M.blend(hex, fg or M.fg, math.abs(amount))
+end
+
+return M
diff --git a/lua/auto-save/utils/data.lua b/lua/auto-save/utils/data.lua
new file mode 100644
index 0000000..0e91e4e
--- /dev/null
+++ b/lua/auto-save/utils/data.lua
@@ -0,0 +1,25 @@
+local M = {}
+
+local cnf = require("auto-save.config").options
+
+function M.set_of(list)
+ local set = {}
+ for i = 1, #list do
+ set[list[i]] = true
+ end
+ return set
+end
+
+function M.not_in(var, arr)
+ if M.set_of(arr)[var] == nil then
+ return true
+ end
+end
+
+function M.do_callback(callback_name)
+ if type(cnf.callbacks[callback_name]) == "function" then
+ cnf.callbacks[callback_name]()
+ end
+end
+
+return M
diff --git a/lua/auto-save/utils/echo.lua b/lua/auto-save/utils/echo.lua
new file mode 100644
index 0000000..dbb0d5d
--- /dev/null
+++ b/lua/auto-save/utils/echo.lua
@@ -0,0 +1,25 @@
+local TITLE = "auto-save"
+
+return function(msg, kind)
+ local has_notify_plugin = pcall(require, "notify")
+ local level = {}
+
+ if kind == "error" then
+ level.log = vim.log.levels.ERROR
+ level.type = "error"
+ elseif kind == "warn" then
+ level.log = vim.log.levels.WARN
+ level.type = "error"
+ else
+ level.log = kind or vim.log.levels.INFO
+ level.type = "info"
+ end
+
+ if has_notify_plugin then
+ vim.notify(msg, level.log, {
+ title = TITLE,
+ })
+ else
+ vim.notify(("%s (%s): %s"):format(TITLE, level.type, msg), level.log)
+ end
+end
diff --git a/lua/autosave/config.lua b/lua/autosave/config.lua
deleted file mode 100644
index ea017f6..0000000
--- a/lua/autosave/config.lua
+++ /dev/null
@@ -1,29 +0,0 @@
-local config = {}
-
-config.options = {
- enabled = true,
- execution_message = "AutoSave: saved at " .. vim.fn.strftime("%H:%M:%S"),
- events = {"InsertLeave", "TextChanged"},
- conditions = {
- exists = true,
- filename_is_not = {},
- filetype_is_not = {},
- modifiable = true,
- },
- write_all_buffers = false,
- on_off_commands = false,
- clean_command_line_interval = 0,
- debounce_delay = 135
-}
-
-function config.set_options(opts)
- opts = opts or {}
-
- for opt, _ in pairs(opts) do
- if (config.options[opt] ~= nil) then -- not nil
- config.options[opt] = opts[opt]
- end
- end
-end
-
-return config
diff --git a/lua/autosave/init.lua b/lua/autosave/init.lua
deleted file mode 100644
index d1a3b95..0000000
--- a/lua/autosave/init.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-local opts = require("autosave.config").options
-local cmd = vim.cmd
-
-local M = {}
-
-local function setup_load()
- if opts["enabled"] == true then
- vim.g.autosave_state = true
- require("autosave.main").main("on")
- else
- vim.g.autosave_state = false
- end
-end
-
-local function setup_commands()
- if opts["on_off_commands"] == true then
- cmd([[command! ASOn lua require'autosave.main'.main('on')]])
- cmd([[command! ASOff lua require'autosave.main'.main('off')]])
- end
-end
-
-function M.setup(custom_opts)
- require("autosave.config").set_options(custom_opts)
- setup_load()
- setup_commands()
-end
-
-return M
diff --git a/lua/autosave/main.lua b/lua/autosave/main.lua
deleted file mode 100644
index 1d75c75..0000000
--- a/lua/autosave/main.lua
+++ /dev/null
@@ -1,51 +0,0 @@
-local autocmds = require("autosave.modules.autocmds")
-local autosave = require("autosave")
-local g = vim.g
-local M = {}
-require("autosave.utils.viml_funcs")
-
-local function on()
-
- if (autosave.hook_before_on ~= nil) then
- autosave.hook_before_on()
- end
-
- autocmds.load_autocommands()
- g.autosave_state = true
-
- if (autosave.hook_after_on ~= nil) then
- autosave.hook_after_on()
- end
-end
-
-local function off()
-
- if (autosave.hook_before_off ~= nil) then
- autosave.hook_before_off()
- end
-
- autocmds.unload_autocommands()
- g.autosave_state = false
-
- if (autosave.hook_after_off ~= nil) then
- autosave.hook_after_off()
- end
-end
-
-function M.main(option)
- option = option or 'load'
-
- if (option == 'toggle') then
- if (g.autosave_state == true) then
- off()
- else
- on()
- end
- elseif (option == 'on') then
- on()
- elseif (option == 'off') then
- off()
- end
-end
-
-return M
diff --git a/lua/autosave/modules/autocmds.lua b/lua/autosave/modules/autocmds.lua
deleted file mode 100644
index 3179ab1..0000000
--- a/lua/autosave/modules/autocmds.lua
+++ /dev/null
@@ -1,192 +0,0 @@
-local api = vim.api
-local fn = vim.fn
-local cmd = vim.cmd
-
-local opts = require("autosave.config").options
-local autosave = require("autosave")
-local default_events = { "InsertLeave", "TextChanged" }
-
-local modified
-
-local M = {}
-
-local function table_has_value(tbl, value)
- for key, _ in pairs(tbl) do
- if tbl[key] == value then
- return true
- end
- end
-
- return false
-end
-
-local function set_modified(value)
- modified = value
-end
-
-local function get_modified()
- return modified
-end
-
-local function actual_save()
- -- might use update, but in that case it can't be checked if a file was modified and so it will always
- -- print opts["execution_message"]
- if api.nvim_eval([[&modified]]) == 1 then
- local first_char_pos = fn.getpos("'[")
- local last_char_pos = fn.getpos("']")
-
- if opts["write_all_buffers"] then
- cmd("silent! wall")
- else
- cmd("silent! write")
- end
-
- fn.setpos("'[", first_char_pos)
- fn.setpos("']", last_char_pos)
-
- if get_modified() == nil or get_modified() == false then
- set_modified(true)
- end
-
- M.message_and_interval()
- end
-end
-
-local function assert_user_conditions()
- local sc_exists, sc_filename, sc_filetype, sc_modifiable = true, true, true, true
-
- for condition, value in pairs(opts["conditions"]) do
- if condition == "exists" then
- if value == true then
- if fn.filereadable(fn.expand("%:p")) == 0 then
- sc_exists = false
- break
- end
- end
- elseif condition == "modifiable" then
- if value == true then
- if api.nvim_eval([[&modifiable]]) == 0 then
- sc_modifiable = false
- break
- end
- end
- elseif condition == "filename_is_not" then
- if not (next(opts["conditions"]["filename_is_not"]) == nil) then
- if table_has_value(opts["conditions"]["filename_is_not"], vim.fn.expand('%:t')) == true then
- sc_filename = false
- break
- end
- end
- elseif condition == "filetype_is_not" then
- if not (next(opts["conditions"]["filetype_is_not"]) == nil) then
- if table_has_value(opts["conditions"]["filetype_is_not"], api.nvim_eval([[&filetype]])) == true then
- sc_filetype = false
- break
- end
- end
- end
- end
-
- return { sc_exists, sc_filename, sc_filetype, sc_modifiable }
-end
-
-local function assert_return(values, expected)
- for key, value in pairs(values) do
- if value ~= expected then
- return false
- end
- end
-
- return true
-end
-
-function M.message_and_interval()
- if get_modified() == true then
- set_modified(false)
- if opts["execution_message"] ~= "" then
- print(opts["execution_message"])
- end
-
- if opts["clean_command_line_interval"] > 0 then
- cmd(
- [[call timer_start(]]
- .. opts["clean_command_line_interval"]
- .. [[, funcref('g:AutoSaveClearCommandLine'))]]
- )
- end
- end
-end
-
-local function debounce(lfn, duration)
- local queued = false
-
- local function inner_debounce()
- if not queued then
- vim.defer_fn(function()
- queued = false
- lfn()
- end, duration)
- queued = true
- end
- end
-
- return inner_debounce
-end
-
-function M.do_save()
- if assert_return(assert_user_conditions(), true) then
- M.debounced_save()
- end
-end
-
-function M.save()
- if autosave.hook_before_saving ~= nil then
- autosave.hook_before_saving()
- end
-
- M.do_save()
-
- if autosave.hook_after_saving ~= nil then
- autosave.hook_after_saving()
- end
-end
-
-local function get_events()
- if next(opts["events"]) == nil or opts["events"] == nil then
- return default_events
- else
- return opts["events"]
- end
-end
-
-local function parse_events()
- return table.concat(get_events(), ",")
-end
-
-function M.load_autocommands()
- if opts["debounce_delay"] == 0 then
- M.debounced_save = actual_save
- else
- M.debounced_save = debounce(actual_save, opts["debounce_delay"])
- end
-
- api.nvim_exec([[
- aug autosave_save
- au!
- au ]] .. parse_events() .. [[ * execute "lua require'autosave.modules.autocmds'.save()"
- aug END
- ]], false)
-end
-
-function M.unload_autocommands()
- api.nvim_exec(
- [[
- aug autosave_save
- au!
- aug END
- ]],
- false
- )
-end
-
-return M
diff --git a/lua/autosave/utils/viml_funcs.lua b/lua/autosave/utils/viml_funcs.lua
deleted file mode 100644
index 80ee7f1..0000000
--- a/lua/autosave/utils/viml_funcs.lua
+++ /dev/null
@@ -1,12 +0,0 @@
-local api = vim.api
-
-api.nvim_exec(
- [[
- function! g:AutoSaveClearCommandLine(timer)
- if mode() != 'c'
- echon ''
- endif
- endfunction
-]],
- false
-)
diff --git a/plugin/ascmds.vim b/plugin/ascmds.vim
deleted file mode 100644
index 7fe2e80..0000000
--- a/plugin/ascmds.vim
+++ /dev/null
@@ -1,19 +0,0 @@
-" GPL-3.0 License
-
-" prevent the plugin from loading twice
-if exists('g:loaded_autosave') | finish | endif
-
-let s:save_cpo = &cpo " save user coptions
-set cpo&vim " reset them to defaults
-
-
-" Interface {{{
-command! ASToggle lua require'autosave.main'.main('toggle')
-" }}}
-
-
-let &cpo = s:save_cpo " restore after
-unlet s:save_cpo
-
-" set to true the var that controls the plugin's loading
-let g:loaded_autosave = 1
diff --git a/plugin/auto-save.lua b/plugin/auto-save.lua
new file mode 100644
index 0000000..fcc9a2f
--- /dev/null
+++ b/plugin/auto-save.lua
@@ -0,0 +1,15 @@
+if vim.g.loaded_auto_save then
+ return
+end
+vim.g.loaded_auto_save = true
+
+local command = vim.api.nvim_create_user_command
+local cnf = require("auto-save.config").options
+
+command("AToggle", function()
+ require("auto-save").toggle()
+end, {})
+
+if cnf.enabled then
+ require("auto-save").on()
+end
diff --git a/research.txt b/research.txt
deleted file mode 100644
index 06ecedb..0000000
--- a/research.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This plugin is for automatically saving files.
-
-
-it should only write if:
- 1. buffer has been modified
diff --git a/resources/demo.gif b/resources/demo.gif
deleted file mode 100644
index 51e40b8..0000000
Binary files a/resources/demo.gif and /dev/null differ