Skip to content

Instantly share code, notes, and snippets.

@roycewilliams
Created January 18, 2022 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roycewilliams/e559e2d60c05d285b613dd540788693f to your computer and use it in GitHub Desktop.
Save roycewilliams/e559e2d60c05d285b613dd540788693f to your computer and use it in GitHub Desktop.
malign.pl - align code blocks in context (called from vim)
# /usr/bin/perl
#-----------------------------------------------------------------------
# $Id: malign,v 1.2 2018/06/16 22:25:40 root Exp root $
# Created: 2010-02-08
# Description: Determine the narrowest left margin in passed text,
# then pad the output of align with this pad (less 1, align's left margin).
#-----------------------------------------------------------------------
use strict;
use warnings;
use File::Temp;
use Fcntl qw(:DEFAULT :flock LOCK_EX); # built-in for file control and I/O
my $debug = 0;
my $tabstop = '';
#-----------------------------------------------------------------------
# STUB - respect tabstop.
if (exists($ENV{'TABSTOP'})) {
if ( $debug > 1) { print "Tabstop: $ENV{'TABSTOP'}\n"; }
} else {
if ( $debug > 1) { print "No TABSTOP found."; }
}
#-----------------------------------------------------------------------
# MAIN
#------------------------------
# Slurp stdin to tempfile.
my $tmpfile;
my $tmpfile2;
do { $tmpfile = tmpnam() }
until sysopen(TMPFILE, $tmpfile, O_RDWR|O_CREAT|O_EXCL);
do { $tmpfile2 = tmpnam() }
until sysopen(TMPFILE2, $tmpfile2, O_RDWR|O_CREAT|O_EXCL);
# As stdin comes in, write it to first tempfile.
while (<>) {
print TMPFILE $_;
}
# Go back to top of tempfile for reading
seek (TMPFILE,0,0);
#------------------------------
# Determine the left margin of the first tempfile.
my $min_margin = 0;
my $marginpad = '';
while (<TMPFILE>) {
# If there are leading spaces ...
if (m/^([ ]+)/) {
# Get their length.
my $margin_text = $1;
my $my_margin = length($margin_text);
# If the minimum margin isn't set yet, set it.
if ($min_margin eq 0) {
$min_margin = $my_margin;
$marginpad = $margin_text;
}
# If our current margin is less than the minimum, save it.
if ($my_margin < $min_margin) {
$min_margin = $my_margin;
}
if ( $debug > 1) { print "\nDEBUG: Minimum margin is now " . $min_margin . "\n";}
}
if ( $debug > 1) { print; }
}
if ( $debug > 1) { print "Minimum margin is " . $min_margin . "\n"; }
# Go back to top of tempfile for reading.
seek (TMPFILE,0,0);
# Run align against the output, writing it to a second tempfile.
open(CMD, "| /usr/local/scripts/align -s s+ -j _> $tmpfile2 ");
while (<TMPFILE>) {
chomp;
print CMD "$_\n";
}
close CMD || warn "cmd exited $?";
if ($debug > 1) {
print "tmp 1: $tmpfile\n";
system('cat',$tmpfile);
print "tmp 2: $tmpfile2\n";
system('cat',$tmpfile2);
}
# Calculate one less than the margin.
# FIXME: "negative repeat count does nothing"
my $alignpad;
if ($min_margin > 0) {
$alignpad = ' ' x ($min_margin - 1);
} else {
$alignpad = '';
}
# Pad the left margin of the align output with the pad.
while (<TMPFILE2>) {
chomp;
print $alignpad . $_ . "\n";
}
# Remove tempfiles.
unlink($tmpfile) or warn "Couldn't unlink $tmpfile : $!";
unlink($tmpfile2) or warn "Couldn't unlink $tmpfile : $!";
#-----------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment