sudoedit
/sudo -e
is often used for safely editing files as root. The way it works:
sudoedit
copies the named files to temporary files- Then it opens the temporary files using the commands specified by the
SUDO_EDITOR
,VISUAL
orEDITOR
variables, - That command is run as the user who ran
sudo
, instead ofroot
(or whoever the target user is).
So, the editor runs under the user's environment, and not as root. And that is excellent if your user configuration has better completion and syntax highlighting than the system Vim.
The problem
Since the files are copied to temporary files, the filename and location, which are often identifying characteristics for filetype
detection, are lost. So, where /etc/apache2/apache2.conf
would load syntax highlighting suitable for Apache2 configuration files (set ft
returns filetype=apache
), /var/tmp/apache2XXcLFdTD.conf
has filetype=conf
.
So, how do I get Vim called by sudoedit
to correctly detect the filetype as it normally would, as if I'd opened the file directly in Vim?
Bonus: It would be great to have any other settings that might have applied (like autocmd
s) work too.
Useful information
The sudo
command originally ran is available in the environment variable SUDO_COMMAND
. For example, with sudoedit /etc/apache2/apache2.conf
1:
:echo $SUDO_COMMAND
sudoedit /etc/apache2/apache2.conf
It could be split to get the filenames - however, it's not easy to safely do this if filenames contain spaces.
1Surprisingly, SUDO_COMMDAND
contains the same string even if I'd run sudo -e /etc/apache2/apache2.conf
.
Another source could be to use /proc/<PID>/cmdline
, which contains the commandline in a NUL-delimited format. The PID here would be Vim's parent ID, so something like:
:let ppid = system('ps -o ppid:1= -p ' . getpid())
:let cmdline = readfile('/proc/' . ppid . '/cmdline')
(Of course, readfile
splits on LF
and filenames can contain that, but for now, I'm not running around editing files with newlines in the name.)
A third way could be to use a wrapper script in EDITOR
/VISUAL
/SUDO_EDITOR
. The original filenames are not directly available:
$ EDITOR='printf %s\n' sudo -e /etc/apache2/apache2.conf -p
/var/tmp/apache2XXyMSNHX.conf
/var/tmp/-p.XXCW2H47
sudo: /etc/apache2/apache2.conf unchanged
sudo: -p unchanged
However, we could use /proc/<PID>/cmdline
more easily in a shell script, perhaps.
Even if I manage to get the filenames somehow, how do I get Vim to use them to apply the correct filetype
settings?
sudo
isn't a Linux tool, but/proc/<PID>/cmdline
is pretty Linux-specific, I think. At any rate, I don't care about Unices in general - only Linux. (And, at the moment,/proc/<PID>/cmdline
offers the safest way of getting filenames.)/proc
pre-dates Linux by about a decade. Many systems have a procfs (although they're all slightly incompatible, but it's mostly the same; other systems don't have/proc/cpuinfo
and that sort of nonsense, but that's not needed here). And I don't see why you need it anyway, as you can just use$SUDO_COMMAND
(I don't understand why you think it's "not easy to safely do this if filenames contain spaces")?/proc
is old,/proc/.../cmdline
isn't, and even on systems that do have it, there's no guarantee they will be NUL-delimited like Linux's/proc/.../cmdline
. Trysudoedit 'foo.conf bar.conf' baz.conf
and get me back the correct filenames. (To get into the correct frame of mind, read mywiki.wooledge.org/ParsingLs, and imagine you're answering this question on Unix & Linux.)