【问题标题】:Escaped strings in elispelisp中的转义字符串
【发布时间】:2012-10-16 09:01:00
【问题描述】:

我对 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)

【问题讨论】:

  • 要将反斜杠加倍,请让 Emacs 将其读入 minibuffer 中的字符串,而不是将其直接粘贴到 Emacs 中。如果不以某种方式加倍反斜杠,就无法将C:\users 转换为文字字符串(\u 在 Emacs 字符串中具有特殊含义;它是 Unicode 序列的开头)。

标签: string emacs lisp elisp


【解决方案1】:

你不需要这样做。

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 equivalent of 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"

【讨论】:

  • 这很有帮助 - 我只需将它放入一个从 Visual Studio 调用的 shell 脚本中,该脚本将启动 emacsclient
【解决方案2】:

查看问题的另一种方法是 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 等效(但相反)的操作。

【讨论】:

  • 是否将 $(ItemPath) 作为第一个参数传递,而不是简单地将其作为要打开的文件传递,因为它有 windows 而不是 cygwin-filepath?
  • 是的,它会将它作为文件名传递,但我建议你教 Emacs 理解 Windows 文件名(就像 cygwin-mount.el 教 Windows Emacs 理解 Cygwin 文件名一样)。
【解决方案3】:

这是 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)))))

【讨论】:

    【解决方案4】:

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

    ELISP> (subst-char-in-string ?\\ ?/ "C:\\users\\someone")
    "C:/users/someone"
    

    【讨论】:

    • 问题是 Visual Studio 只会在文件路径中传递单个反斜杠 - 这是主要问题。
    • @Gjallar:然后您需要将它们转换为双反斜杠。 Emacs Lisp 阅读器使用反斜杠作为字符串中的转义字符。
    • 我对问题进行了澄清 - 路径是由 Visual Studio 插入的,我无法修改它。
    【解决方案5】:

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

    请参阅此wiki page,了解其他人如何解决此问题。

    【讨论】:

      【解决方案6】:

      这些解决方案都不适合我(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 !.!

      【讨论】:

        猜你喜欢
        • 2011-06-06
        • 1970-01-01
        • 2011-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多