From ce67d298712b957fbea534b0631eaae2e44be5be Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 25 Mar 2013 19:11:26 +0100 Subject: [PATCH] Always use absolute path for file buffer names, compact paths for display --- src/client_manager.cc | 8 ++++++-- src/commands.cc | 5 +++-- src/file.cc | 41 ++++++++++++++++++++++++++++++++++++++--- src/file.hh | 3 ++- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/client_manager.cc b/src/client_manager.cc index d220a69d..9e8e9d64 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -3,6 +3,7 @@ #include "event_manager.hh" #include "buffer_manager.hh" #include "command_manager.hh" +#include "file.hh" namespace Kakoune { @@ -194,8 +195,11 @@ static String generate_status_line(const Context& context) { BufferCoord cursor = context.editor().main_selection().last().coord(); std::ostringstream oss; - oss << context.buffer().name() - << " " << (int)cursor.line+1 << "," << (int)cursor.column+1; + String name = context.buffer().name(); + if (context.buffer().flags() & Buffer::Flags::File) + name = compact_path(name); + + oss << name << " " << (int)cursor.line+1 << "," << (int)cursor.column+1; if (context.buffer().is_modified()) oss << " [+]"; if (context.input_handler().is_recording()) diff --git a/src/commands.cc b/src/commands.cc index 90ba937a..11f97720 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -48,7 +48,7 @@ Buffer* open_or_create(const String& filename, Context& context) Buffer* open_fifo(const String& name , const String& filename, Context& context) { - int fd = open(filename.c_str(), O_RDONLY); + int fd = open(parse_filename(filename).c_str(), O_RDONLY); fcntl(fd, F_SETFD, FD_CLOEXEC); if (fd < 0) throw runtime_error("unable to open " + filename); @@ -97,7 +97,8 @@ void edit(const CommandParameters& params, Context& context) if (param_count == 0 or param_count > 3) throw wrong_argument_count(); - String name = canonicalize_filename(parse_filename(parser[0])); + const bool file = not parser.has_option("scratch") and not parser.has_option("fifo"); + String name = file ? real_path(parse_filename(parser[0])) : parser[0]; Buffer* buffer = nullptr; if (not force_reload) diff --git a/src/file.cc b/src/file.cc index 807b09cd..bd611426 100644 --- a/src/file.cc +++ b/src/file.cc @@ -46,9 +46,44 @@ String parse_filename(const String& filename) return result; } -String canonicalize_filename(const String& filename) +String real_path(const String& filename) { - return filename.replace(R"(((^|(?<=/))\./)+|[^/]+/\.\./)", ""); + String dirname = "."; + String basename = filename; + + auto it = find(reversed(filename), '/'); + if (it != filename.rend()) + { + dirname = String{filename.begin(), it.base()}; + basename = String{it.base(), filename.end()}; + } + + char buffer[PATH_MAX+1]; + char* res = realpath(dirname.c_str(), buffer); + if (not res) + throw file_not_found{dirname}; + return res + "/"_str + basename; +} + +String compact_path(const String& filename) +{ + String real_filename = real_path(filename); + + char cwd[1024]; + getcwd(cwd, 1024); + String real_cwd = real_path(cwd); + if (real_filename.substr(0, real_cwd.length()) == real_cwd) + return real_filename.substr(real_cwd.length()+1); + + const char* home = getenv("HOME"); + if (home) + { + ByteCount home_len = (int)strlen(home); + if (real_filename.substr(0, home_len) == home) + return "~" + real_filename.substr(home_len); + } + + return filename; } String read_file(const String& filename) @@ -78,7 +113,7 @@ String read_file(const String& filename) Buffer* create_buffer_from_file(String filename) { - filename = canonicalize_filename(parse_filename(filename)); + filename = real_path(parse_filename(filename)); int fd = open(filename.c_str(), O_RDONLY); if (fd == -1) diff --git a/src/file.hh b/src/file.hh index 37621745..2b6105f1 100644 --- a/src/file.hh +++ b/src/file.hh @@ -26,7 +26,8 @@ class Buffer; // parse ~/ and $env values in filename and returns the translated filename String parse_filename(const String& filename); -String canonicalize_filename(const String& filename); +String real_path(const String& filename); +String compact_path(const String& filename); String read_file(const String& filename); Buffer* create_buffer_from_file(String filename);