Preservar o registro de data e hora modificado após a edição

18

Para arquivos dentro de uma pasta específica, eu gostaria que o vim nunca tocasse em "modificado" timestamp em tudo.

O pano de fundo é que eu uso Bloxsom para blogar, que usa texto sem formatação arquivos em ~/bloxsom como fonte de todos os artigos. A data do artigo (e, portanto, ordem de aparecimento) é baseada na data de modificação do arquivo de texto. Eu não quero artigo aparecer como se fosse novo sempre que eu apenas corrigir um erro de digitação. (Eu faço lotes deles ...: D)

Até agora, o vim muda o timestamp e o carimbo original é perdido para sempre. Isto é OK e quero continuar assim para a maioria dos arquivos no sistema. Mas eu não quero que para os arquivos do blog - eu sempre posso touch o arquivo se eu precisar.

Alguma idéia de como ajustar o vim nesse comportamento?

    
por Alois Mahdal 15.07.2012 / 19:05

6 respostas

19

Eu não acho que o vim tenha esse recurso. Uma alternativa é modificar uma cópia e definir o registro de data e hora de forma adequada, por exemplo:

cp -p post temp
vim temp
touch -r post temp
cp -p temp post

Ou melhor ainda:

touch -r post timestamp
vim post
touch -r timestamp post
    
por 15.07.2012 / 19:20
4

Se você precisar se divertir:

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

Substitua o caminho pelo caminho real do arquivo

    
por 10.05.2013 / 23:24
2

Eu escrevi um script em Perl para isso.

É um wrapper em torno do vim, salvo em ~/bin/vim-nomtime.pl e colocado em uso via alias vim='~/bin/vim-nomtime.pl' em meu .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->{$_}, $_;
    }
}

Algumas boas características:

  • suporta vários nomes de arquivos

  • suporta vários diretórios "assistidos"

  • suporta o link com link simbólico

  • pode ser aprimorado com outros critérios

a maioria dos quais provavelmente também pode ser obtida com a versão pura do vim. As desvantagens desta solução em comparação com a minha solução pura de vim são:

  • restaura o selo somente após o vim ser encerrado, por isso, se eu fizer uma edição longa e salvar regularmente, o arquivo vill "pop-up" como novo até eu sair do vim

  • suporta múltiplos arquivos na linha de comando, mas de uma maneira bastante ingênua - só verifica se a coisa em @ARGV é um arquivo. Isso provavelmente não funcionaria com curingas (por exemplo, vim note-*.txt ) ou outras coisas engraçadas

  • não é à prova de falhas, provavelmente nem à prova de HUP (isso pode ser feito)

  • ... bem, é um invólucro. (Quero dizer, se resolvêssemos tudo via wrapper, quantos wrappers teríamos antes de algo ruim acontecer?)

por 15.07.2012 / 22:05
1

Este script curto preservará o horário modificado se qualquer diretório pai do arquivo contiver um arquivo .nomtime :

#!/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
    
por 11.05.2013 / 01:26
1

Experimente esta função bash (com base na resposta do Shâu Shắc )

vi-preserve-time () {
    for file in "$@"; do
        local mtime=$(stat -c %y "$file")
        vi "$file"
        touch -d "$mtime" "$file"
    done
}

Agora podemos editar o arquivo e preservar o horário modificado usando este

vi-preserve-time file1.txt file2.txt
    
por 15.03.2018 / 02:38
0

Usando alguns dos conceitos descritos acima, aqui está um alias de uma linha muito rápida e suja para o CSH que disponibiliza um comando "edit" para esse propósito:

alias edit 'touch -r \!:1 /tmp/~mtime ; vim \!:1 ; touch -r /tmp/~mtime \!:1 ; rm /tmp/~mtime'

Você poderia facilmente usar a variável de ambiente $ VISUAL ou $ EDITOR no lugar de "vim". Dessa forma, você pode emitir o seguinte comando para alterar os editores padrão

setenv VISUAL nano

Agora, o alias em si não precisa ser redefinido para acomodar diferentes editores, o que o torna um pouco mais portátil. Se você usar uma casca diferente de CSH ou TCSH, é claro, os exemplos acima podem ser adaptados de acordo.

    
por 23.01.2018 / 17:56