Düzenlemeden sonra değiştirilen zaman damgasını koru


20

Belirli bir klasör içindeki dosyalar için vim'in "değiştirilmiş" zaman damgasına asla dokunmamasını istiyorum.

Arka plan, tüm makalelerin kaynağı olarak düz metin dosyalarını kullanan bloglama için Bloxsom kullanmamdır ~/bloxsom. Makale tarihi (ve dolayısıyla ortaya çıkış sırası) metin dosyasının değiştirilme tarihini temel alır. Bir yazım hatası düzelttiğimde makalenin yeni gibi görünmesini istemiyorum . (Yapmak çok ... Bunlardan: D)

Şimdiye kadar, vim zaman damgasını değiştiriyor ve orijinal damga sonsuza dek kayboluyor. Bu sorun değil ve ben sistemdeki dosyaların çoğu için bu şekilde tutmak istiyorum. Ama bunu blog dosyaları için istemiyorum - touchİhtiyacım olursa her zaman dosyayı yapabilirim .

Vim bu davranış içine nasıl tweak için herhangi bir fikir?


2
vim.wikia.com/wiki/… - elbette bunun yerine perl bağlarını kullanabilirsiniz
Ulrich Dangel

Yanıtlar:


22

Vim'in bu özelliği olduğunu sanmıyorum. Bir alternatif, bir kopyayı değiştirmek ve zaman damgasını uygun şekilde ayarlamaktır, örneğin:

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

Ya da daha iyisi:

touch -r post timestamp
vim post
touch -r timestamp post

7

Eğlenmeniz gerekiyorsa:

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

Yolu gerçek dosya yolunuzla değiştirin


5

Bunun için bir Perl senaryosu yazdım.

Vim'in etrafındaki bir sarıcı, kaydedilmiş ~/bin/vim-nomtime.plve alias vim='~/bin/vim-nomtime.pl'.bashrc içinde kullanıma sokuldu .

#!/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->{$_}, $_;
    }
}

Bazı iyi özellikler:

  • birden fazla dosya adını destekler

  • birden çok "izlenen" dizini destekler

  • symlinked dir destekler

  • diğer kriterlerle geliştirilebilir

bunların çoğu muhtemelen saf vim versiyonu ile elde edilebilir. Bu çözeltinin istenen saf vim çözeltim ile karşılaştırıldığında dezavantajları şunlardır:

  • sadece vim çıktıktan sonra damgası geri yükler , bu yüzden uzun bir düzenleme yapar ve düzenli olarak kaydedersem, vim'den çıkana kadar dosya vill "pop-up" yeni olarak açılır

  • komut satırında birden fazla dosyayı destekler, ancak oldukça naif bir şekilde - sadece üzerinde bulunan şeyin @ARGVbir dosya olup olmadığını kontrol eder . Bu muhtemelen joker karakterlerle (örneğin vim note-*.txt) veya diğer komik şeylerle çalışmaz

  • çarpmaya dayanıklı değil, muhtemelen HUP geçirmez bile (bu yapılabilir)

  • ... wel, bir sarıcı. (Yani, her şeyi sarmalayıcıyla çözersek, kötü bir şey olmadan önce kaç sarmalayıcı olurdu?)


3 Mayıs 2019 ve 11 Kasım 2017'den bir dosyayı değiştirdim ve hem değişikliğim var hem de orijinal zaman damgasını koruyor. :)
jmort253

1

Bu kısa komut dosyası, dosyanın üst dizinlerinden herhangi biri dosya içeriyorsa değiştirilen süreyi korur .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

1

Bu bashişlevi deneyin ( Shâu Shắc'ın cevabına dayanarak )

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

Şimdi bunu kullanarak dosyayı düzenleyebilir ve değiştirilen zamanı koruyabiliriz

vi-preserve-time file1.txt file2.txt

(1) Bu, Shâu Shắc'ın beş yıl önceki cevabı ile neredeyse aynı . (2) Bu, kullanıcının viaynı anda yalnızca tek bir dosyayı çağırdığını varsayar ; işe yaramaz vi file1 file2. (3) Kullanıcının farklı bir dosyaya :egeçmesi durumunda, işleme alınmayacağını söylemeye gerek yoktur.
G-Man

Başvurmayı unuttuğum için üzgünüm, şimdi Shâu Shắc'ın cevabına bir referans bağlantısı ekledim.
Steely Wing

3. soru hakkında, bence başka bir dosyayı açtığınızda komut satırında değil, sizin probleminiz.
Steely Wing

1
Demek istediğim, eğer soru “vim'i istediğim gibi nasıl yapabilirim?” Diye sorarsa ve vim'i kullanıcının istediği gibi davranıyor gibi görünen bir işlev sağlıyorsanız, Cevap. Tamam, belki de yorumum biraz haksız, diğer tüm cevapların aynı sınırlamaya sahip olduğu gibi, ve hiçbiri bunu söyleyebildiğim kadarıyla bahsetmiyor. Sadece cevabınızı inceliyordum çünkü yeni bir şeydi; Diğer cevaplara bakmak için fazla zaman harcamadım.
G-Man 'Monica'yı Yeniden

1

Başka bir dosyadan zaman damgası kopyalama seçeneği vardır.

touch -m -r file_source file_target

Örnek:

[oracle@es abc]$ ls -tlr
total 4
-rw-r--r--. 1 oracle oinstall 102 May  8 20:35 aa.txt
[oracle@es abc]$ echo "hi hi" > b
[oracle@es abc]$ ls -ltr
total 4
-rw-r--r--. 1 oracle oinstall 102 May  8 20:35 aa.txt
-rw-r--r--. 1 oracle oinstall   6 May 13 18:58 b
[oracle@es abc]$ touch -m -r aa.txt b
[oracle@es abc]$ ls -tlr
total 8
-rw-r--r--. 1 oracle oinstall   6 May  8 20:35 b
-rw-r--r--. 1 oracle oinstall 102 May  8 20:35 aa.txt
[oracle@es abc]$ cat b
hi hi

1

Bu web sayfasında , varolan değişiklik süresini korurken geçerli dosyayı kaydetmek için bir vim işlevi oluşturan ve bu işlevi F4işlev tuşuna bağlayan harika bir çözüm buldum :

Ancak, orijinal işlevin küçük bir hata içerdiğini gördüm F4, aynı dosyada iki kez kullanılırsa aşağıdaki uyarıyı tetikler , çünkü değişiklik zamanı değiştiğinde vim karışır:

WARNING: The file has been changed since reading it!!!
Do you really want to write to it (y/n)?

Neyse ki, bu düzeltmek kolaydır: Zaman damgasını geri yükledikten sonra dosyayı yeniden yüklemek için özgün işleve bir "düzenle" komutu ekledim, bu yüzden vim dosyanın sahip olması gereken değişiklik süresini biliyor.

İşte bu hata düzeltmesi ile değiştirilmiş vim işlevi ~/.vimrc:

function! WriteSmall()
    let mtime = system("date -d @`stat -c %Y ".shellescape(expand('%:p')) . "`")
    write
    call system("touch --date='".mtime."' ".shellescape(expand('%:p')))
    edit
endfunction
map <F4> :call WriteSmall()<CR>

Not: Bu işlev date, statve öğelerinin GNU sürümlerine dayanır touch.


0

Yukarıda açıklanan bazı kavramları kullanarak, CSH için bu amaçla bir "düzenle" komutu sağlayan çok hızlı ve kirli tek satırlı bir takma ad aşağıda verilmiştir:

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

"Vim" yerine $ VISUAL veya $ EDITOR ortam değişkenini kolayca kullanabilirsiniz. Bu şekilde, varsayılan düzenleyicileri değiştirmek için aşağıdaki komutu verebilirsiniz

setenv VISUAL nano

Şimdi takma adın farklı editörleri barındıracak şekilde yeniden tanımlanması gerekmez, bu da onu biraz daha taşınabilir hale getirir. CSH veya TCSH dışında bir kabuk kullanırsanız, elbette yukarıdaki örnekler buna göre uyarlanabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.