特定のフォルダ内のファイルについては、「変更された」タイムスタンプにまったく触れないようにしたいと思います。
背景は、私がブログに Bloxsom を使用していることです。これは、すべての記事のソースとして~/bloxsom
のプレーンテキストファイルを使用します。記事の日付(したがって、表示される順序)は、テキストファイルの変更日に基づいています。タイプミスを修正するだけで、記事がnewであるかのようにポップアップを表示したくありません。 (私はそうしますそれらのロット...:D)
これまでのところ、vimはタイムスタンプを変更し、元のスタンプは永久に失われます。これは問題ありません。システム上のほとんどのファイルでこの方法を維持します。しかし、ブログファイルにはそれを使いたくありません。必要な場合はいつでもファイルをtouch
できます。
Vimをこの動作に微調整する方法に関するアイデアはありますか?
Vimにこの機能はないと思います。 1つの代替策は、コピーを変更してタイムスタンプを適切に設定することです。例:
cp -p post temp
vim temp
touch -r post temp
cp -p temp post
またはさらに良い:
touch -r post timestamp
vim post
touch -r timestamp post
楽しみたいなら:
file=path; mtime=$(stat -c %y "$file"); vi "$file"; touch -d "$mtime" "$file"
パスを実際のファイルパスに置き換えます
そのためのPerlスクリプトを書きました。
これはvimのラッパーで、~/bin/vim-nomtime.pl
に保存され、.bashrcのalias vim='~/bin/vim-nomtime.pl'
を介して使用されます。
#!/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->{$_}, $_;
}
}
いくつかの優れた機能:
複数のファイル名をサポート
複数の「監視」ディレクトリをサポート
シンボリックリンクされたディレクトリをサポート
他の基準で強化できます
そのほとんどは、おそらく純粋なvimバージョンでも実現できます。このソリューションの欠点は、希望するpure-vimソリューションと比べて次のとおりです。
スタンプのみを復元します変更後 vimが終了したため、長い編集を行って定期的に保存すると、vimを終了するまで、ファイルは新規として「ポップアップ」されます
コマンドラインで複数のファイルをサポートしますが、非常に単純な方法で@ARGV
上のものがファイルであるかどうかのみをチェックします。これはおそらくワイルドカード(例:vim note-*.txt
)またはその他の面白いものでは機能しません。
耐衝突性ではなく、おそらくHUPにも対応していません(それは可能です)。
...それはラッパーです。 (つまり、ラッパーを介してすべてを解決した場合、何か問題が発生する前にラッパーはいくつあるでしょうか?)
別のファイルからタイムスタンプをコピーするオプションがあります。
touch -m -r file_source file_target
例:
[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
私は this web page で素晴らしい解決策を見つけました。これは、既存の変更時間を維持しながら現在のファイルを保存するvim関数を作成し、この関数を F4 ファンクションキー:
ただし、元の関数に軽微なバグが含まれていることがわかりました。 F4 変更時刻が変更されるとvimが混乱するため、同じファイルで2回使用されます。
WARNING: The file has been changed since reading it!!!
Do you really want to write to it (y/n)?
幸いなことに、これは簡単に修正できます。タイムスタンプを復元した後でファイルをリロードするために、元の関数に「編集」コマンドを追加したので、vimはファイルに必要な変更時間を認識しています。
これは、このバグ修正を含む変更されたvim関数で、~/.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>
注:この関数は、GNU date
、stat
のバージョンに依存し、 touch
。
この短いスクリプトは、ファイルの親ディレクトリに.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
このbash
関数を試してください( ShâuShắcの答え に基づいてください)
vi-preserve-time () {
for file in "$@"; do
local mtime=$(stat -c %y "$file")
vi "$file"
touch -d "$mtime" "$file"
done
}
これを使用してファイルを編集し、変更された時間を保存できます
vi-preserve-time file1.txt file2.txt
上記の概念のいくつかを使用して、CSHの非常に速くて汚い1行のエイリアスを以下に示します。これにより、この目的で「編集」コマンドを使用できるようになります。
alias edit 'touch -r \!:1 /tmp/~mtime ; vim \!:1 ; touch -r /tmp/~mtime \!:1 ; rm /tmp/~mtime'
"vim"の代わりに$ VISUALまたは$ EDITOR環境変数を簡単に使用できます。これにより、次のコマンドを発行してデフォルトのエディターを変更できます
setenv VISUAL nano
エイリアス自体は、さまざまなエディターに対応するために再定義する必要がないため、多少移植性が高くなります。もちろん、CSHまたはTCSH以外のシェルを使用する場合は、上記の例を適宜変更できます。