nvim-genghis ⚔️
Convenience file operations for neovim, written in lua.
- How is this different from
vim.eunuch
? - Installation and Setup
- Available Commands
- Autocompletion of directories
- Why that name
- About me
vim.eunuch
?
How is this different from - Various improvements like automatically keeping the extensions when no extension is given, or moving files to the trash instead of removing them.
- Uses only vim-commands or lua os-modules, so it has no dependencies and works cross-platform.
- Makes use of up-to-date nvim features like
vim.ui.input
orvim.notify
. This means you can get nicer input fields with normal mode support via plugins like dressing.nvim, and confirmation notices with plugins like nvim-notify, if they are installed and setup. - If used with dressing and cmp, you can also get autocompletion of directories.
- Written 100% in lua.
Installation and Setup
-- Packer
use {"chrisgrieser/nvim-genghis", requires = "stevearc/dressing.nvim"}
-- Lazy
{"chrisgrieser/nvim-genghis", dependencies = "stevearc/dressing.nvim"},
nvim-genghis
(and dressing.nvim
) require no .setup()
function. Just create keybindings for the commands you want to use:
local keymap = vim.keymap.set
local genghis = require("genghis")
keymap("n", "<leader>yp", genghis.copyFilepath)
keymap("n", "<leader>yn", genghis.copyFilename)
keymap("n", "<leader>cx", genghis.chmodx)
keymap("n", "<leader>rf", genghis.renameFile)
keymap("n", "<leader>mf", genghis.moveAndRenameFile)
keymap("n", "<leader>nf", genghis.createNewFile)
keymap("n", "<leader>yf", genghis.duplicateFile)
keymap("n", "<leader>df", function () genghis.trashFile{trashLocation = "your/path"} end) -- default: "$HOME/.Trash".
keymap("x", "<leader>x", genghis.moveSelectionToNewFile)
Available Commands
File Operation Command
.createNewFile
or:New
: Create a new file..duplicateFile
or:Duplicate
: Duplicate the current file..moveSelectionToNewFile
or:NewFromSelection
: Prompts for a new file name and moves the current selection to that new file. (Note that this is a Visual Line Mode command; the selection is moved linewise.).renameFile
or:Rename
: Rename the current file..moveAndRenameFile
or:Move
: Move and Rename the current file. Works like the UNIXmv
command. Best used with autocompletion of directories.
The following applies to all commands above:
- If no extension has been provided, uses the extension of the original file.
- If the new file name includes a
/
, the new file is placed in the respective subdirectory, creating any non-existing folders. Except for.moveAndRenameFile
, all operations take only place in the current working directory, so.moveAndRenameFile
is the only command that can move to a parent directory. - All commands support autocompletion of existing directories.
File Utility Commands
.trashFile{trashLocation = "/your/path/"}
or:Trash
: Move the current file to the trash location. Defaults to the operating-system-specific trash directory.⚠️ Any existing file in the trash location with the same name is overwritten, making that file irretrievable. If bufdelete.nvim is available,require'bufdelete.nvim'.bufwipeout
would be used to keep window layout intact instead ofvim.cmd.bwipeout
..copyFilename
or:CopyFilename
: Copy the file name. Whenclipboard="unnamed[plus]"
has been set, copies to the+
register, otherwise to"
..copyFilepath
or:CopyFilepath
: Copy the absolute file path. Whenclipboard="unnamed[plus]"
has been set, copies to the+
register, otherwise to"
..chmodx
or:Chmodx
: Makes current file executable. Equivalent tochmod +x
.
Disable Ex-Commands
Put this in your configuration file:
-- lua
vim.g.genghis_disable_commands = true
-- viml
let g:genghis_disable_commands = v:true
Autocompletion of directories
You can get autocompletion for directories by using dressing.nvim
, nvim-cmp
, and vim's omnifunc:
-- packer
use { "chrisgrieser/nvim-genghis", requires = {
"stevearc/dressing.nvim",
"hrsh7th/nvim-cmp",
"hrsh7th/cmp-omni",
},
}
-- lazy
{ "chrisgrieser/nvim-genghis", dependencies = {
"stevearc/dressing.nvim",
"hrsh7th/nvim-cmp",
"hrsh7th/cmp-omni",
},
},
-- required setup for cmp, somewhere after your main cmp-config
require("cmp").setup.filetype("DressingInput", {
sources = cmp.config.sources { {name = "omni"} },
})
Why that name
A nod to vim.eunuch - as opposed to childless eunuchs, it is said that Genghis Khan has fathered thousands of children.
About me
In my day job, I am a sociologist studying the social mechanisms underlying the digital economy. For my PhD project, I investigate the governance of the app economy and how software ecosystems manage the tension between innovation and compatibility. If you are interested in this subject, feel free to get in touch.
Blog
I also occassionally blog about vim: Nano Tips for Vim
Profiles