concat-path

xyzzy には、パス文字列を連結する merge-pathnames という関数がある。

;; test
(merge-pathnames "bar.l" "c:/foo")
"c:/foo/bar.l"

第1引数がスラで始まっているかどうかや第2引数がスラで終わっているかどうかを心配しなくても、きれいに連結してくれる。
ただ、引数が2個固定なのと、引数の並び順が今ひとつ直感的でない。merge-pathnames という関数名も覚えづらい。
どうやら、この関数の用途は パス文字列を連結するというより、xyzzy起動時の作業フォルダを基準にパスを作成することのようだ。

concat みたいな感じで使えるのがほしい。
そこで、先ほど覚えた dolist を使ってでっち上げとく。

(defun concat-path (path1 &rest path)
  (let ((ret (string-right-trim "/" (map-backslash-to-slash path1))))
	(dolist (p path ret)
	  (setq ret (concat ret "/" (string-trim "/" (map-backslash-to-slash p)))))))

;; test
(concat-path "D:/work/tmp" "hoge" "/hage/hagege" "\\foo\\foo-foo\\" "bar/bar-bar\\bar-bar-bar\\")
"D:/work/tmp/hoge/hage/hagege/foo/foo-foo/bar/bar-bar/bar-bar-bar"

これで、スラを気にせずに引数を左から順に連結してくれる。
下記の挙動は、オリジナルの merge-pathnames をまねてみた。

  • 連結後の パス文字列の両端は スラをつけない
  • 引数がバスラ区切りであってもスラ区切りに直す