4

我对 Lisp 非常陌生——尤其是 Elisp——我在字符串处理方面遇到了问题:

我想将 Windows 样式路径转换为 ​​Unix 样式路径 - 特别是我需要将从 Visual Studio 获得的路径转换为 ​​Cygwin 路径,因为我希望能够在 Emacs 中从 Visual Studio 打开文件(我希望为此使用 emacsclient --eval ):

Visual Studio 路径具有以下格式:

C:\Users\name\documents\visual studio 2010\projects\test

我想将其更改为适当的 Cygwin 路径,即:

/cygdrive/c/Users/name/documents/visual studio 2010/projects/test

但是在暂存缓冲区中尝试以下操作已经失败:

(replace-regexp-in-string "\\" "\/" "C:\users\someone")
(subst-char-in-string ?\ ?/ "C:\users\someone")

>> Debugger entered--Lisp error: (error "Non-hex digit used for Unicode escape")

有什么方法可以让 Elisp逃避每个字符串中的反斜杠吗?

编辑

以下是我通过外部工具从 Visual Studio 调用 emacs 的方法:

emacsclient -d 127.0.0.1:0.0 --eval '(convert-win-to-cygwin-path $(ItemPath))'

$(ItemPath)将被替换为C:\Users\asf我无法影响的 - 因此它将带有单个反斜杠的字符串传递给我需要在 emacs 中修改的 emacs。

我可以让emacs知道它需要从单个反斜杠中制作双反斜杠吗?

编辑2:解决方案

我通过实际调用将启动 emacs 的 shell 脚本更改了尝试启动 emacs 的方式 - 这样我可以确保 emacs 获得正确的路径:

#!/bin/bash

export PATH="/usr/bin/:/bin/:$PATH"

filename=$1
line=$2
column=$3

cyged_path=$(cygpath "$filename")

echo "Cyged path: $cyged_path"

emacsclient -d 127.0.0.1:0.0 -n +$line:$column "$cyged_path"

我从 Visual Studio 调用它,并在外部工具窗口中使用以下参数:

Path: <path_to_cygwin>\bin\bash.exe
Arguments: <path_to_script> $(ItemPath) $(CurLine) $(CurCol)
4

6 回答 6

3

你不需要做任何这些。

Cygwin 提供了一个专门用于将 Windows 路径转换为 ​​Cygwin 路径的命令,这样您就不必为这类事情操心了。

cmd> C:\cygwin\bin\cygpath.exe "C:\Users\name\documents\visual studio 2010\projects\test"

/cygdrive/c/Users/name/documents/visual studio 2010/projects/test

编辑:我很好奇 Windows shell 等效于反引号,并发现Batch 等效于 Bash backticks,这表明您可以用这个单行符完成所有操作?

cmd> for /f "usebackq tokens=*" %a in (`C:\cygwin\bin\cygpath.exe "$(ItemPath)"`) do emacsclient -d 127.0.0.1:0.0 "%a"
于 2012-10-16T10:45:38.850 回答
1

查看问题的另一种方法是emacsclient -d 127.0.0.1:0.0 --eval '(convert-win-to-cygwin-path $(ItemPath))'在 Elisp 字符串中传递文件名,这就是反斜杠被视为转义的原因。所以解决方案是将其作为数据传递,如emacsclient -d 127.0.0.1:0.0 $(ItemPath). 下一个问题是让您的 Emacs 理解这些文件名。如果您使用 Emacs 的正常 Windows 构建,无需做任何特殊操作即可工作,但如果您使用 Cygwin 构建,则需要执行与 cygwin-mout.el 等效(但相反)的操作。

于 2012-10-16T14:28:48.820 回答
1

这是 emacs lisp 中的答案,尽管我喜欢 Phils 的回答。此函数将预期为完整 Windows 文件路径(包括驱动器)的区域转换为 cygwin 路径。

例如:

C:\Users\name\documents\visual studio 2010\projects\test

变成……

/cygdrive/C/Users/name/documents/visual studio 2010/projects/test

这是代码:

(defun win32-to-cygwin-path()
  "Converts a win32 path into a cygwin happy one"
  (interactive)
  (save-excursion
    (save-restriction
      (narrow-to-region (point) (mark))
      (goto-char (point-min))
      (insert "/cygdrive/")
      (goto-char (point-min))
      (while (search-forward ":" nil t)
    (replace-match "" nil t))
      (while (search-forward "\\" nil t)
    (replace-match "/" nil t)))))
于 2012-10-17T03:23:19.400 回答
0

需要转义反斜杠。这会起作用:

ELISP> (subst-char-in-string ?\\ ?/ "C:\\users\\someone")
"C:/users/someone"
于 2012-10-16T09:06:14.767 回答
0

您确定 Windows 没有发送预先转义的反斜杠吗?如果它不这样做会很奇怪。

有关其他人如何解决此问题,请参阅此wiki 页面

于 2012-10-16T10:34:23.373 回答
0

这些解决方案都不适合我(emacs 24.3.1),无论如何,一个简单的 .bat 脚本就可以了:

@ECHO OFF

c:\cygwin64\bin\cygpath.exe %1 > tmp.txt
set /p FILE_TO_EDIT= < tmp.txt
del tmp.txt
C:\cygwin64\bin\cygstart.exe -- /bin/emacs-w32.exe %FILE_TO_EDIT%

将其保存在 file.bat 中并将您要编辑的文件作为参数发送,对于 WinSCP,将如下所示:C:\Users\xxxxx\Desktop\open.bat !!

于 2013-09-06T09:16:20.823 回答