Skip to content

lpanebr/file-clip.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

file-clip.nvim

Vibe coded by Codex with gpt-5.6-sol. Read disclamer section. Use at your own risc.

Attach arbitrary files to Neovim buffers.

file-clip.nvim complements img-clip.nvim. While img-clip.nvim provides a much richer, image-focused workflow, this plugin has the narrower goal of copying and linking arbitrary existing files. It copies a source file into a project asset directory, creates missing directories, and inserts the appropriate Markdown or HTML link.

Features

  • Attach an explicit file path or a textual path from the system clipboard.
  • Accept absolute paths and file:// URIs.
  • Preserve the original file name and extension.
  • Create nested asset directories automatically.
  • Render image-aware Markdown and HTML templates.
  • Keep filesystem destinations separate from public URL paths.
  • Override settings per project with .file-clip.lua.

Requirements

  • Neovim 0.10 or newer
  • A working Neovim clipboard provider for :PasteFile

Installation

With lazy.nvim:

{
  "lpanebr/file-clip.nvim",
  opts = {},
}

Usage

:AttachFile /tmp/diagram.pdf
:PasteFile

:AttachFile prompts for the source path when called without an argument. :PasteFile reads a path or file:// URI from the + clipboard register.

The same operation is available through Lua:

require("file-clip").attach_file(opts, source)
require("file-clip").paste_file(opts)

Configuration

By default, files are copied to assets under Neovim's working directory and keep their original name and extension. Inserted links are made relative to the current buffer when needed.

require("file-clip").setup({
  default = {
    dir_path = "assets",
    url_path = nil,
    use_absolute_path = false,
    relative_to_current_file = false,
    relative_template_path = true,
    prompt_for_file_name = false,
    overwrite = false,
    confirm_on_overwrite = true,
  },
})

Set prompt_for_file_name = true to rename an attachment before copying it. The prompt changes only the base name; the original extension is retained.

Project configuration

The nearest .file-clip.lua in the current file's directory or one of its ancestors overrides the global configuration. The file must return a setup table.

Filesystem destinations and public URLs can be configured separately. For an Astro project with content in src/content/sinapses and public assets in public/sinapses:

local slug = vim.fn.expand("%:t:r")

return {
  default = {
    dir_path = "public/sinapses/" .. slug,
    url_path = "/sinapses/" .. slug,
  },
}

This copies diagram.pdf to public/sinapses/<slug>/diagram.pdf while inserting [](/sinapses/<slug>/diagram.pdf) into Markdown and placing the cursor inside the brackets.

Templates

Markdown uses image syntax for png, jpg, jpeg, gif, webp, svg, and avif; other extensions use regular links. HTML uses <img> and <a> in the same way.

Templates support $FILE_NAME, $FILE_NAME_NO_EXT, $FILE_PATH, $LABEL, $CURSOR, and $EXTENSION. Per-extension templates can be supplied with templates_by_extension.

Development

Run the headless test suite with:

make test

The initial specification and v1 acceptance criteria are documented in file-clip-spec.md.

Contributions

Contributions are welcome through issues and pull requests. Please keep changes focused, explain the behavior being changed, and add or update tests when appropriate. Before submitting a pull request, run:

make test
stylua --check lua plugin tests

Disclaimer

This plugin was created using Codex with the gpt-5.6-sol model for the author's personal use. The author has performed functional tests but has not reviewed the generated code in detail. The plugin is provided as-is, without warranty; review the code and assess the risks before using it in your own environment.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages