Files
topgrade/src/steps/vim.rs
GideonBear b00c4c1503 chore: upgrade to edition 2024
Co-authored-by: Ehren Bendler <a5ehren@gmail.com>
2025-11-23 13:26:47 +01:00

163 lines
4.2 KiB
Rust

use crate::HOME_DIR;
use crate::command::CommandExt;
use crate::error::{SkipStep, TopgradeError};
use color_eyre::eyre::Result;
use etcetera::base_strategy::BaseStrategy;
use crate::executor::{Executor, ExecutorOutput};
use crate::terminal::print_separator;
use crate::{
execution_context::ExecutionContext,
utils::{PathExt, require},
};
use rust_i18n::t;
use std::path::PathBuf;
use std::{
io::{self, Write},
process::Command,
};
use tracing::debug;
const UPGRADE_VIM: &str = include_str!("upgrade.vim");
pub fn vimrc() -> Result<PathBuf> {
HOME_DIR
.join(".vimrc")
.require()
.or_else(|_| HOME_DIR.join(".vim/vimrc").require())
}
fn nvimrc() -> Result<PathBuf> {
#[cfg(unix)]
let bases: Vec<PathBuf> = vec![crate::XDG_DIRS.config_dir()];
#[cfg(windows)]
let mut bases: Vec<PathBuf> = vec![crate::WINDOWS_DIRS.cache_dir()];
#[cfg(windows)]
{
if let Some(xdg) = std::env::var_os("XDG_CONFIG_HOME")
.map(PathBuf::from)
.filter(|path| path.is_absolute())
{
bases.insert(0, xdg);
}
}
for base_dir in bases {
if let Ok(p) = base_dir
.join("nvim/init.vim")
.require()
.or_else(|_| base_dir.join("nvim/init.lua").require())
{
return Ok(p);
}
}
Err(SkipStep(format!("{}", t!("No Neovim config found"))).into())
}
fn upgrade_script() -> Result<tempfile::NamedTempFile> {
let mut tempfile = tempfile::NamedTempFile::new()?;
tempfile.write_all(UPGRADE_VIM.replace('\r', "").as_bytes())?;
debug!("Wrote vim script to {:?}", tempfile.path());
Ok(tempfile)
}
fn upgrade(command: &mut Executor, ctx: &ExecutionContext) -> Result<()> {
if ctx.config().force_vim_plug_update() {
command.env("TOPGRADE_FORCE_PLUGUPDATE", "true");
}
let output = command.output()?;
if let ExecutorOutput::Wet(output) = output {
let status = output.status;
if !status.success() || ctx.config().verbose() {
io::stdout().write_all(&output.stdout).ok();
io::stderr().write_all(&output.stderr).ok();
}
if !status.success() {
return Err(TopgradeError::ProcessFailed(command.get_program(), status).into());
} else {
println!("{}", t!("Plugins upgraded"));
}
}
Ok(())
}
pub fn upgrade_ultimate_vimrc(ctx: &ExecutionContext) -> Result<()> {
let config_dir = HOME_DIR.join(".vim_runtime").require()?;
let git = require("git")?;
let python = require("python3")?;
let update_plugins = config_dir.join("update_plugins.py").require()?;
print_separator(t!("The Ultimate vimrc"));
ctx.execute(&git)
.current_dir(&config_dir)
.args(["reset", "--hard"])
.status_checked()?;
ctx.execute(&git)
.current_dir(&config_dir)
.args(["clean", "-d", "--force"])
.status_checked()?;
ctx.execute(&git)
.current_dir(&config_dir)
.args(["pull", "--rebase"])
.status_checked()?;
ctx.execute(python)
.current_dir(config_dir)
.arg(update_plugins)
.status_checked()?;
Ok(())
}
pub fn upgrade_vim(ctx: &ExecutionContext) -> Result<()> {
let vim = require("vim")?;
let output = Command::new(&vim).arg("--version").output_checked_utf8()?;
if !output.stdout.starts_with("VIM") {
return Err(SkipStep(t!("vim binary might be actually nvim").to_string()).into());
}
let vimrc = vimrc()?;
print_separator("Vim");
upgrade(
ctx.execute(&vim)
.args(["-u"])
.arg(vimrc)
.args(["-U", "NONE", "-V1", "-nNesS"])
.arg(upgrade_script()?.path()),
ctx,
)
}
pub fn upgrade_neovim(ctx: &ExecutionContext) -> Result<()> {
let nvim = require("nvim")?;
let nvimrc = nvimrc()?;
print_separator("Neovim");
upgrade(
ctx.execute(nvim)
.args(["-u"])
.arg(nvimrc)
.args(["--headless", "-V1", "-nS"])
.arg(upgrade_script()?.path()),
ctx,
)
}
pub fn run_voom(ctx: &ExecutionContext) -> Result<()> {
let voom = require("voom")?;
print_separator("voom");
ctx.execute(voom).arg("update").status_checked()
}