Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d21d203
Fix base64url codec, refactor/cleanup
MisanthropicBit Jul 24, 2025
bdce628
Bump all action versions
MisanthropicBit Jul 24, 2025
95e869d
Drop support for 0.7.2
MisanthropicBit Jul 25, 2025
7a340e2
Use valid utf-8 in test cases to make stylua happy
MisanthropicBit Jul 25, 2025
ea840b1
Add 0.11.0 to test workflow
MisanthropicBit Jul 25, 2025
c8377fc
Move zbase32 and crockford into separate files
MisanthropicBit Jul 25, 2025
988dcdf
Temporarily fix end column discrepancy
MisanthropicBit Jul 27, 2025
21c0734
Fix only for motions
MisanthropicBit Jul 27, 2025
c2cd9f6
Account for eol
MisanthropicBit Jul 27, 2025
054524f
Ignore parameter type mismatch
MisanthropicBit Jul 27, 2025
2eeb158
Sort codecs
MisanthropicBit Jul 27, 2025
39b11c2
Remove mention of active_codecs from docs
MisanthropicBit Jul 27, 2025
ae41a08
Fixes/cleanup
MisanthropicBit Jul 27, 2025
84a0a63
Properly account for recent fix to vim.fn.getpos
MisanthropicBit Jul 28, 2025
f5d520e
Styling
MisanthropicBit Jul 28, 2025
4c2c5df
Fix tests + skipped tests
MisanthropicBit Jul 28, 2025
793c78a
Fix deprecated function, health check reporting
MisanthropicBit Jul 28, 2025
efde64d
Support writeback from floating window [skip ci]
MisanthropicBit Aug 1, 2025
e06fa27
Merge branch 'master' into support-writeback
MisanthropicBit Oct 6, 2025
a49c879
Refactor + fixes
MisanthropicBit Oct 6, 2025
032d67d
Styling
MisanthropicBit Oct 6, 2025
cb07a97
Add compat.validate
MisanthropicBit Oct 6, 2025
4d33ad8
Fix comparison
MisanthropicBit Oct 6, 2025
496a449
Fix compat.validate, add Page spec
MisanthropicBit Oct 7, 2025
2dde9f5
Big refactor
MisanthropicBit Oct 12, 2025
a649538
Fix tests
MisanthropicBit Oct 12, 2025
6b2b766
Add zindex, rename options to win_options, remove json_auto_open
MisanthropicBit Oct 13, 2025
4f6b8b4
Floating window fixes
MisanthropicBit Oct 13, 2025
05c13f9
Fix applying with newlines
MisanthropicBit Oct 13, 2025
425a6f0
Fix override mappings test
MisanthropicBit Oct 13, 2025
125847d
Merge branch 'master' into support-writeback
MisanthropicBit Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,21 @@ require("decipher").setup({
float = { -- Floating window options
padding = 0, -- Zero padding (does not apply to title if any)
border = { -- Floating window border
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "", "FloatBorder" },
{ "╭", "FloatBorder" },
{ "─", "FloatBorder" },
{ "╮", "FloatBorder" },
{ "│", "FloatBorder" },
{ "╯", "FloatBorder" },
{ "─", "FloatBorder" },
{ "╰", "FloatBorder" },
{ "│", "FloatBorder" },
},
mappings = {
close = "q", -- Key to press to close the floating window
apply = "a", -- Key to press to apply the encoding/decoding
jsonpp = "J", -- Key to prettily format contents as json if possbile
help = "?", -- Toggle help
close = "q", -- Close the floating window
apply = "<leader>a", -- Apply the encoded/decoded preview in the original buffer
update = "<leader>u", -- Update the original buffer with changes made in the encoded/decoded preview
jsonpp = "<leader>j", -- Prettily format contents as json if possible (view is immutable)
help = "g?", -- Toggle help
},
title = true, -- Display a title with the codec name
title_pos = "left", -- Position of the title
Expand Down
36 changes: 32 additions & 4 deletions lua/decipher/compat.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
local compat = {}

---@param tbl table
---@return boolean
function compat.tbl_islist(tbl)
if vim.fn.has("nvim-0.10.0") == 1 then
return vim.islist(tbl)
Expand All @@ -15,10 +13,40 @@ end
function compat.get_report_funcs()
if vim.fn.has("nvim-0.10") == 1 then
return vim.health.start, vim.health.ok, vim.health.error
else
---@diagnostic disable-next-line: deprecated
return vim.health.report_start, vim.health.report_ok, vim.health.report_error
end
end

---@diagnostic disable-next-line: deprecated
return vim.health.report_start, vim.health.report_ok, vim.health.report_error
---@param name string
---@param value unknown
---@param options { scope: "local" | "global", win: integer?, buf: integer? }
function compat.set_option(name, value, options)
if vim.fn.has("nvim-0.10.0") == 1 then
vim.api.nvim_set_option_value(name, value, options)
else
if options.win then
---@diagnostic disable-next-line: deprecated
vim.api.nvim_win_set_option(options.win, name, value)
elseif options.buf then
---@diagnostic disable-next-line: deprecated
vim.api.nvim_buf_set_option(options.buf, name, value)
end
end
end

---@param name string
---@param value any
---@param validator vim.validate.Validator
---@param optional boolean?
---@param message string?
function compat.validate(name, value, validator, optional, message)
if vim.fn.has("nvim-0.11.0") == 1 then
vim.validate(name, value, validator, optional, message)
else
vim.validate({ [name] = { value, validator, optional or message } })
end
end

return compat
22 changes: 14 additions & 8 deletions lua/decipher/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ local config = {}
---@class decipher.WindowMappings
---@field close? string
---@field apply? string
---@field jsonpp? string
---@field update? string
---@field json? string
---@field help? string

---@class decipher.WindowConfig
Expand All @@ -14,7 +15,8 @@ local config = {}
---@field title_pos? 'left' | 'center' | 'right'
---@field autoclose? boolean
---@field enter? boolean
---@field options? table<string, any>
---@field win_options? table<string, any>
---@field zindex integer?

---@class decipher.Config
---@field float? decipher.WindowConfig
Expand All @@ -35,15 +37,17 @@ local default_config = {
},
mappings = {
close = "q",
apply = "a",
jsonpp = "J",
help = "?",
apply = "<leader>a",
update = "<leader>u",
json = "<leader>j",
help = "g?",
},
title = true,
title_pos = "left",
autoclose = true,
enter = false,
options = {},
win_options = {},
zindex = 50,
},
}

Expand All @@ -70,13 +74,15 @@ local function validate_config(_config)
["float.mappings"] = { _config.float.mappings, "table" },
["float.mappings.close"] = { _config.float.mappings.close, "string" },
["float.mappings.apply"] = { _config.float.mappings.apply, "string" },
["float.mappings.jsonpp"] = { _config.float.mappings.jsonpp, "string" },
["float.mappings.update"] = { _config.float.mappings.update, "string" },
["float.mappings.json"] = { _config.float.mappings.json, "string" },
["float.mappings.help"] = { _config.float.mappings.help, "string" },
["float.title"] = { _config.float.title, "boolean" },
["float.title_pos"] = { _config.float.title_pos, "string" },
["float.autoclose"] = { _config.float.autoclose, "boolean" },
["float.enter"] = { _config.float.enter, "boolean" },
["float.options"] = { _config.float.options, "table" },
["float.win_options"] = { _config.float.win_options, "table" },
["float.zindex"] = { _config.float.zindex, "number" },
})
end

Expand Down
45 changes: 0 additions & 45 deletions lua/decipher/errors.lua

This file was deleted.

66 changes: 42 additions & 24 deletions lua/decipher/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local decipher_version = "2.1.0"

local codecs = require("decipher.codecs")
local config = require("decipher.config")
local errors = require("decipher.errors")
local notifications = require("decipher.notifications")
local motion = require("decipher.motion")
local selection = require("decipher.selection")
local str_utils = require("decipher.util.string")
Expand All @@ -15,6 +15,10 @@ decipher.codec = codecs.codec
---@class decipher.Options
---@field public preview boolean if a preview should be shown or not

---@class decipher.ProcessCodecOptions
---@field selection_type decipher.SelectionType
---@field codec_type "encode" | "decode"

---@alias decipher.CodecArg string | decipher.Codecs

---@return string
Expand Down Expand Up @@ -63,18 +67,32 @@ end

---@param codec_name string
---@param status boolean
---@param value string?
---@param value string
---@param selection_type decipher.SelectionType
local function open_float_handler(codec_name, status, value, selection_type)
---@param codec_type "encode" | "decode"
local function open_float_handler(codec_name, status, value, selection_type, codec_type)
if status and value == nil then
value = "Codec not found"
end

if not status then
notifications.error(("%s: %s"):format(codec_name, value))
return
end

-- We need the selection in order to apply the codec operation from the
-- preview window later on
local _selection = selection.get_selection(selection_type)

ui.float.open(codec_name, { value }, config.float, selection_type, _selection)
ui.float.open({
title = codec_name,
contents = vim.fn.split(value, [[\r\?\n]]),
config = config.float,
selection_type = selection_type,
codec_name = codec_name,
codec_type = codec_type,
selection = _selection,
})
end

--- Handler for setting a text region to a value
Expand All @@ -85,12 +103,12 @@ end
---@diagnostic disable-next-line:unused-local
local function set_text_region_handler(codec_name, status, value, selection_type)
if not status then
errors.error_message(("%s: %s"):format(codec_name, value), true)
notifications.error(("%s: %s"):format(codec_name, value))
return
end

if value == nil then
errors.error_message_codec(codec_name)
notifications.codec_not_found("Codec not found: " .. codec_name)
return
end

Expand All @@ -102,8 +120,9 @@ end
---@param codec_name decipher.CodecArg
---@param codec_func fun(string): string
---@param selection_type decipher.SelectionType
---@param codec_type "encode" | "decode"
---@param options decipher.Options
local function process_codec(codec_name, codec_func, selection_type, options)
local function process_codec(codec_name, codec_func, selection_type, codec_type, options)
local lines = selection.get_text(0, selection_type)
local joined = table.concat(lines, "\n")
local status, value = pcall(codec_func, codec_name, joined)
Expand All @@ -113,74 +132,75 @@ local function process_codec(codec_name, codec_func, selection_type, options)
local _codec_name = ("%s"):format(codec_name)

if do_preview then
open_float_handler(_codec_name, status, value, selection_type)
open_float_handler(_codec_name, status, value, selection_type, codec_type)
else
set_text_region_handler(_codec_name, status, value, selection_type)
end
end

---@param codec_func fun(string): string
---@param selection_type decipher.SelectionType
---@param codec_type "encode" | "decode"
---@param options decipher.Options
local function process_codec_prompt(codec_func, selection_type, options)
local function process_codec_prompt(codec_func, selection_type, codec_type, options)
vim.ui.select(codecs.supported(), { prompt = "Codec?: " }, function(codec_name)
if codec_name == nil then
return
end

process_codec(codec_name, codec_func, selection_type, options)
process_codec(codec_name, codec_func, selection_type, codec_type, options)
end)
end

---@param codec_name decipher.CodecArg
---@param options decipher.Options
function decipher.encode_selection(codec_name, options)
process_codec(codec_name, decipher.encode, "visual", options)
process_codec(codec_name, decipher.encode, "visual", "encode", options)
end

---@param codec_name decipher.CodecArg
---@param options decipher.Options
function decipher.decode_selection(codec_name, options)
process_codec(codec_name, decipher.decode, "visual", options)
process_codec(codec_name, decipher.decode, "visual", "decode", options)
end

---@param codec_name decipher.CodecArg
---@param options decipher.Options
function decipher.encode_motion(codec_name, options)
motion.start_motion(function()
process_codec(codec_name, decipher.encode, "motion", options)
process_codec(codec_name, decipher.encode, "motion", "encode", options)
end)
end

---@param codec_name decipher.CodecArg
---@param options decipher.Options
function decipher.decode_motion(codec_name, options)
motion.start_motion(function()
process_codec(codec_name, decipher.decode, "motion", options)
process_codec(codec_name, decipher.decode, "motion", "decode", options)
end)
end

---@param options decipher.Options
function decipher.encode_selection_prompt(options)
process_codec_prompt(decipher.encode, "visual", options)
process_codec_prompt(decipher.encode, "visual", "encode", options)
end

---@param options decipher.Options
function decipher.decode_selection_prompt(options)
process_codec_prompt(decipher.decode, "visual", options)
process_codec_prompt(decipher.decode, "visual", "decode", options)
end

---@param options decipher.Options
function decipher.encode_motion_prompt(options)
motion.start_motion(function()
process_codec_prompt(decipher.encode, "motion", options)
process_codec_prompt(decipher.encode, "motion", "encode", options)
end)
end

---@param options decipher.Options
function decipher.decode_motion_prompt(options)
motion.start_motion(function()
process_codec_prompt(decipher.decode, "motion", options)
process_codec_prompt(decipher.decode, "motion", "decode", options)
end)
end

Expand All @@ -193,16 +213,14 @@ end
---@param user_config? decipher.Config
function decipher.setup(user_config)
if not vim.fn.has("nvim-0.5.0") then
errors.error_message("This plugin only works with Neovim >= v0.5.0", true)
notifications.error("This plugin only works with Neovim >= v0.5.0")
return
end

if not decipher.has_bit_library() then
errors.error_message({
{ "A bit library is required. Ensure that either " },
{ "neovim has been built with luajit " },
{ "or use neovim v0.9.0+ which includes a bit library" },
}, true)
notifications.error(
"A bit library is required. Ensure that either neovim has been built with luajit or use neovim v0.9.0+ which includes a bit library"
)

return
end
Expand Down
Loading
Loading