Last active
July 16, 2025 05:07
-
-
Save nvlled/4fb61d727a76dee53c3182a5043ee85c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! This is a tool used to change the indent size. | |
//! | |
//! ## Purpose | |
//! I wrote this tool because: | |
//! - some projects uses a non-standard indent-size (like 2-space) | |
//! - a lot of editors autoformat the file on save, hence converts the 2-space to 4-space) | |
//! - in particular, zls currently doesn't have an option to change indent size | |
//! | |
//! The solution: revert the indent size back to 2-space after I'm done editing | |
//! ``` | |
//! $ indent-scale weird-file.zig 0.5 | |
//! ``` | |
//! Alternative 1: use notepad or other prehistoric editor | |
//! Alternative 2: turn off autoformat on save, but I still need autoformatting for other things | |
//! so nope | |
//! | |
//! ## Usage | |
//! | |
//! To build the file: | |
//! ``` | |
//! zig build-exe indent-scale.zig | |
//! ``` | |
//! | |
//! To run the file without building: | |
//! ``` | |
//! zig run indent-scale.zig -- filename 2 | |
//! ``` | |
const std = @import("std"); | |
const stderr = std.io.getStdErr().writer(); | |
const debugf = std.debug.print; | |
pub fn usage(args: [][:0]u8) !void { | |
const progname = std.fs.path.basename(args[0]); | |
try stderr.print("usage: {s} <filename> <indent_scale>\n", .{progname}); | |
try stderr.print("\n", .{}); | |
try stderr.print("DESC: A tool used to change the indent size (spaces only).\n", .{}); | |
try stderr.print(" An indent_scale of 0.5 will half the indent.\n", .{}); | |
try stderr.print(" An indent_scale of 2.0 will double the indent.\n", .{}); | |
try stderr.print("\n", .{}); | |
try stderr.print("WARNING: This will modify the filename, make sure to use version control or have a backup first.\n", .{}); | |
} | |
pub fn main() !void { | |
var gpa = std.heap.DebugAllocator(.{}){}; | |
const allocator = gpa.allocator(); | |
const args = try std.process.argsAlloc(allocator); | |
defer std.process.argsFree(allocator, args); | |
if (args.len < 3) { | |
try usage(args); | |
return; | |
} | |
const filename = args[1]; | |
const file = try std.fs.cwd().openFile(filename, .{ .mode = .read_only }); | |
defer file.close(); | |
const indent_scale = std.fmt.parseFloat(f32, args[2]) catch { | |
try stderr.writeAll("invalid indent scale, must be a decimal number"); | |
return; | |
}; | |
const temp_name = try getTempFilename(allocator); | |
const temp_file = try std.fs.cwd().createFile(temp_name, .{}); | |
defer temp_file.close(); | |
defer allocator.free(temp_name); | |
var line_buf: [1024 * 1024]u8 = undefined; | |
const r = file.reader(); | |
while (true) { | |
const line = try r.readUntilDelimiterOrEof(&line_buf, '\n') orelse break; | |
var i: usize = 0; | |
while (i < line.len) : (i += 1) { | |
if (line[i] != ' ') break; | |
} | |
const num_spaces: f32 = @floatFromInt(i); | |
const target_spaces: usize = @intFromFloat(std.math.ceil(num_spaces * indent_scale)); | |
for (0..target_spaces) |_| { | |
try temp_file.writeAll(" "); | |
} | |
try temp_file.writeAll(line[i..]); | |
try temp_file.writeAll("\n"); | |
} | |
try std.fs.cwd().rename(temp_name, filename); | |
} | |
fn getTempFilename(allocator: std.mem.Allocator) ![]const u8 { | |
var buf: std.ArrayList(u8) = .init(allocator); | |
var w = buf.writer(); | |
try w.writeAll("./indent-temp-"); | |
try w.print("{d}", .{std.time.milliTimestamp()}); | |
return buf.toOwnedSlice(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment