Skip to content

Instantly share code, notes, and snippets.

@aiya000
Created July 21, 2025 14:32
Show Gist options
  • Save aiya000/c0a8b61083c082353d681254706fa7a8 to your computer and use it in GitHub Desktop.
Save aiya000/c0a8b61083c082353d681254706fa7a8 to your computer and use it in GitHub Desktop.
関数型プログラミングっぽい僕の.vim/autoload/vimrc.vimを、Claude Codeが.luaに変換してくれたやつ
-- Main vimrc module (replacement for autoload/vimrc.vim)
local list_util = require('utils.list')
local msg_util = require('utils.message')
local M = {}
-- Allows to reuse `self`.
-- Params:
-- self: A
-- f: (self: A) -> B
-- Result: B
-- Example:
-- join(a:stdout, '')->vimrc#let({ result ->
-- \ result ==# foo
-- \ ? bar
-- \ : result
-- \ })
function M.let(self, f)
return f(self)
end
-- Applies `f` if `p(value)`.
-- To re-use a:value.
-- Params:
-- value: A
-- p: (value: A) -> Bool
-- f: (value: A) -> B
-- Result: A | B
function M.apply_if(value, p, f)
return M.let(value, function(val)
return p(val) and f(val) or val
end)
end
function M.identity(x)
return x
end
-- Returns alt if f() throws an exception.
function M.catch(f, alt)
local ok, result = pcall(f)
return ok and result or alt
end
-- Parse git root output
local function parse_git_root(cont, stdout, stderr)
if type(stderr) == 'table' and #stderr > 0 then
error(table.concat(stderr, '\n'))
end
if type(stderr) == 'string' and stderr ~= '' then
error(stderr)
end
local stdout_str = type(stdout) == 'table' and table.concat(stdout, '') or stdout
-- Replace to the wsl2's path if git_root is a windows path (by git.exe)
local git_root = M.apply_if(vim.fn.fnameescape(stdout_str),
function(root) return not root:match('^/') and vim.fn.executable('wslpath') == 1 end,
function(root_windows)
return vim.fn.fnameescape(vim.fn.system('wslpath "' .. root_windows .. '"')):sub(1, -3)
end
)
return cont(git_root)
end
function M.read_git_root(cont)
-- Use vim.system for Neovim job handling
vim.system({'git', 'rev-parse', '--show-toplevel'}, {
stdout = true,
stderr = true,
}, function(result)
if result.code == 0 then
parse_git_root(cont, result.stdout, result.stderr)
else
cont(nil)
end
end)
end
local function set_git_root_to_g_vimrc(git_root)
if git_root then
vim.schedule(function()
print('vimrc: a git root detected: ' .. git_root)
vim.g.vimrc.git_root = git_root
end)
end
end
function M.read_git_root_to_set_g_vimrc_async()
M.read_git_root(set_git_root_to_g_vimrc)
end
function M.read_git_root_sync()
local result = vim.fn.system('git rev-parse --show-toplevel')
if vim.v.shell_error ~= 0 then
error('Failed to read a git root directory')
end
return result
end
-- git-clones dein.vim to install_dirname.
function M.fetch_dein(install_dirname)
if vim.fn.executable('git') == 1 then
print('dein.vim was not installed yet.')
print('Installing dein.vim now.')
vim.cmd('!git clone https://github.com/Shougo/dein.vim ' .. install_dirname)
else
msg_util.error('Sorry, You do not have git command.')
msg_util.error('I cannot introduce dein.vim.')
error('FAILED: cloning dein.vim failed.')
end
end
-- Compresses continuously spaces to a space.
function M.compress_spaces()
local recent_pattern = vim.fn.getreg('/')
vim.cmd('try | s/\\s\\+/ /g | execute "normal! ==" | finally | let @/ = "' .. recent_pattern .. '" | endtry')
vim.cmd('nohlsearch')
end
-- Removes trailing spaces of all lines.
function M.remove_trailing_spaces()
local recent_pattern = vim.fn.getreg('/')
local curpos = vim.fn.getcurpos()
local ok = pcall(function()
vim.cmd('%s/\\s*\\?$//g')
end)
if not ok then
print('nothing todo')
end
vim.fn.setreg('/', recent_pattern)
vim.fn.setpos('.', curpos)
end
-- Toggles diffthis and diffoff with some keymappings.
function M.toggle_diff()
if vim.wo.diff then
vim.cmd('diffoff')
-- NOTE: This restores [c and ]c of .vimrc,
-- Please see [c, ]c, [ale-previous], and [ale-next] in .vimrc.
vim.keymap.set('n', '[c', '[ale-previous]', { buffer = true })
vim.keymap.set('n', ']c', '[ale-next]', { buffer = true })
else
vim.cmd('diffthis')
-- Get original
vim.keymap.set('n', '[c', '[c', { buffer = true })
vim.keymap.set('n', ']c', ']c', { buffer = true })
end
vim.cmd('set diff?')
end
-- Closes buffers of a specified filetypes.
function M.bufclose_filetype(filetypes)
local closed = false
for w = 1, vim.fn.winnr('$') do
local buf_ft = vim.fn.getwinvar(w, '&filetype')
if list_util.has(filetypes, buf_ft) then
vim.cmd(':' .. w .. 'wincmd w')
vim.cmd('quit')
closed = true
end
end
return closed
end
-- Toggles a file explorer
function M.toggle_explorer(path)
path = path or vim.fn.expand('%:p:h')
local closed = M.bufclose_filetype({'dirvish'})
if not closed then
M.open_explorer('vsplit', path)
end
end
function M.open_explorer(split, path)
path = path or vim.fn.expand('%:p:h')
local cmd =
split == 'stay' and ':Dirvish' or
split == 'split' and ':split | silent Dirvish' or
split == 'vsplit' and ':vsplit | silent Dirvish' or
split == 'tabnew' and ':tabnew | silent Dirvish' or
error('an unexpected way to open the explorer: ' .. split)
if vim.fn.isdirectory(path) == 0 then
-- :silent to ignore an error message. Because opening seems success.
vim.cmd('silent ' .. cmd)
return
end
vim.cmd(cmd .. ' ' .. path)
end
-- Fetches a detail of <title> from a URL
function M.get_webpage_title(url)
local ok, result = pcall(function()
print('fetching now...')
return vim.fn.system(string.format('curl --silent %s | pup --plain "title json{}" | jq -r ".[0].text"', url))
end)
if not ok then
return 'vimrc#get_webpage_title(): something happened: ' .. result
end
return result
end
-- :quit if only a window is existent.
-- :hide otherwise.
function M.hide_or_quit()
local tabnum = vim.fn.tabpagenr('$')
local winnum = vim.fn.tabpagewinnr(vim.fn.tabpagenr(), '$')
if tabnum == 1 and winnum == 1 then
vim.cmd('quit')
else
vim.cmd('hide')
end
end
function M.toggle_ale_at_buffer()
vim.b.ale_enabled = not (vim.b.ale_enabled or true)
-- Refresh the state
vim.cmd('ALEToggle')
vim.cmd('ALEToggle')
end
-- Toggles indent-guides
function M.toggle_indent_guides()
vim.g['vimrc#indent_guides_enable'] = not (vim.g['vimrc#indent_guides_enable'] or true)
vim.cmd('IndentGuidesToggle')
end
-- Puts a register as stdin into the terminal buffer.
function M.put_as_stdin(detail)
local current_bufnr = vim.fn.bufnr('%')
vim.defer_fn(function()
vim.fn.term_sendkeys(current_bufnr, detail)
end, 0)
return 'i'
end
-- Moves a current buffer to left of tab.
function M.move_window_forward()
local tabwin_num = #vim.fn.tabpagebuflist()
vim.cmd('mark Z')
vim.cmd('hide')
if tabwin_num ~= 1 then
vim.cmd('tabnext')
end
vim.cmd('vsp')
vim.cmd("normal! 'Z")
if vim.fn.foldlevel('.') > 0 then
vim.cmd('normal! zO')
end
vim.cmd('normal! zz')
end
-- Moves a current buffer to right of tab.
function M.move_window_backward()
vim.cmd('mark Z')
vim.cmd('hide')
vim.cmd('tabprevious')
vim.cmd('vsp')
vim.cmd("normal! 'Z")
if vim.fn.foldlevel('.') > 0 then
vim.cmd('normal! zO')
end
vim.cmd('normal! zz')
end
-- Moves tab to left.
function M.move_tab_prev()
if vim.fn.tabpagenr() == 1 then
vim.cmd('$tabmove')
else
vim.cmd('tabmove -1')
end
end
-- Moves tab to right.
function M.move_tab_next()
if vim.fn.tabpagenr() == vim.fn.tabpagenr('$') then
vim.cmd('0tabmove')
else
vim.cmd('+tabmove')
end
end
-- Moves the cursor position to the last position of a file.
function M.visit_past_position()
local past_posit = vim.fn.line('"')
if past_posit > 0 and past_posit <= vim.fn.line('$') then
vim.cmd('normal! g`"')
end
end
-- Renames a file name of the current buffer.
function M.rename_to(new_name)
local this_file = vim.fn.fnameescape(vim.fn.expand('%'))
local new_name_esc = vim.fn.fnameescape(new_name)
if vim.fn.fnamemodify(this_file, ':t') == new_name then
msg_util.error('New name is same old name, operation abort')
return
end
local file_editing = vim.bo.modified
if file_editing then
msg_util.error('Please :write this file')
return
end
local new_file = vim.fn.fnamemodify(this_file, ':h') .. '/' .. new_name
local failed = vim.fn.rename(this_file, new_file)
if failed ~= 0 then
msg_util.error(string.format('Rename %s to %s is failed', this_file, new_file))
return
end
vim.cmd('edit ' .. new_file)
vim.cmd('silent write')
vim.cmd('silent bdelete ' .. this_file)
print(string.format('Renamed %s to %s', this_file, new_file))
end
-- Get current buffer directory with fallback
function M.get_current_buffer_dir(options)
options = options or {}
local dir = vim.bo.buftype ~= 'terminal' and vim.bo.buftype ~= 'nofile'
and vim.fn.expand('%:p:h')
or vim.g.vimrc.git_root
local alt_dir = options.alt_dir
if dir and dir ~= '' then
return dir
elseif alt_dir then
return alt_dir
else
error('The current buffer directory does not exist and an alter directory is not specified')
end
end
-- cd to git root
function M.cd_git_root(cd)
M.read_git_root(function(git_root)
if git_root then
print('vimrc: The current directory changed to: ' .. git_root)
if type(cd) == 'string' then
vim.cmd(cd .. ' ' .. git_root)
else
cd(git_root)
end
end
end)
end
-- Shows a popup window by vim.notify with good options
function M.popup_atcursor(messages)
vim.notify(messages, vim.log.levels.INFO)
end
-- Export functions for backward compatibility with vim function calls
_G.vimrc = M
return M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment