Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

For files within a specific folder, I would like vim to never touch "modified" timestamp at all.

The background is that I use Bloxsom for blogging, which uses plain text files in ~/bloxsom as source of all articles. The article date (and therefore order of appearence) is based on modification date of the text file. I don't want article pop up like if it's new whenever I just fix a typo. (I do lots of them... :D)

So far, vim changes timestamp and the original stamp is lost forever. This is OK and I want to keep it that way for most of files on the system. But I don't want that for the blog files - I can always touch the file if I need.

Any ideas on how to tweak vim into this behavior?

share|improve this question
1  
vim.wikia.com/wiki/… - you can of course use perl bindings instead –  Ulrich Dangel Jul 15 '12 at 21:23

4 Answers 4

I don't think vim has this feature. One alternative is to modify a copy and set timestamp appropriately, e.g.:

cp -p post temp
vim temp
touch -r post temp
cp -p temp post
share|improve this answer
    
This is not an alternative. ;-) –  Nicolas Barbulesco Nov 3 '13 at 0:14

I wrote a Perl script for that.

It's a wrapper around vim, saved in ~/bin/vim-nomtime.pl and brought into use via alias vim='~/bin/vim-nomtime.pl' in my .bashrc.

#!/usr/bin/perl
use strict;
use warnings;
use Cwd qw/ abs_path /;

my @dirs = qw( ~/blosxom /srv/relief/blosxom );

s/^~/$ENV{HOME}/ foreach @dirs;

# do we want to preserve stamp on this file?
sub fits {
    my $dir = abs_path($_[0]);
    my $fits = 0;
    foreach (@dirs) {
        my $preserved_dir = abs_path($_);
        $fits++ if $dir =~ m|^$preserved_dir|;
    }
    return $fits != 0;
}

# store original stamps
my $original_stamp;
foreach (@ARGV) {
    if ( -f $_ and fits($_) ) {
        $original_stamp->{$_} = (stat($_))[9];
    }
}

# run vim as you would
my $cmd = join ' ', 'vim', @ARGV;  
system($cmd) == 0
    or die "vim failed: $!";

# restore stamps if they have changed
foreach (keys %$original_stamp) {
    next unless -f $_;
    my $current_stamp = (stat($_))[9];
    unless ($current_stamp == $original_stamp->{$_}) {
        utime $original_stamp->{$_}, $original_stamp->{$_}, $_;
    }
}

Some good features:

  • supports multiple filenames

  • supports multiple "watched" dirs

  • supports symlinked dir

  • can be enhanced with other criteria

most of which could be probably also achieved with pure vim version. Disadvantages of this solution compared to my desired pure-vim solution are:

  • it restores stamp only after vim has quit, so if I do a long edit and save regularly, the file vill "pop-up" as new until I quit vim

  • it supports multiple files on command line, but in a quite naive way--it only checks if the thing on @ARGV is a file. This probably would not work with wildcards (e.g. vim note-*.txt) or other funny stuff

  • it's not crash proof, probably not even HUP-proof (that could be done)

  • ...wel, it's a wrapper. (I mean, if we solved everything via wrapper, how many wrappers would we have before something bad happened?)

share|improve this answer

This short script will preserve the modified time if any parent dir of the file contains a .nomtime file:

#!/bin/bash

dir="${1%/*}"
[ "$dir" = "$1" ] && dir=.
dir=$( readlink -f "$dir" )

nomtime=
while [ -n "$dir" ]; do
    if [ -f "$dir/.nomtime" ]; then
        nomtime=1
        break
    fi
    dir="${dir%/*}"
done

if [ "$nomtime" = 1 ]; then
    T=`tempfile`
    touch -r "$1" $T
fi

vi "$1"

if [ "$nomtime" = 1 ]; then
    touch -r $T "$1"
    rm $T
fi
share|improve this answer

If you need to have some fun:

file=path; mtime=`stat -c %y $file`; vi $file; touch -d "$mtime" $file

Replace path with your actual file path

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.