如何根据缓冲区的目录编写扩展为Java包声明的YASnippet?

时间:2012-10-21 17:27:35

标签: java emacs yasnippet

定义Java类的文件可以通过声明它们属于特定包来组织成包,例如。

package foo.bar;

声明有问题的文件属于包bar的子包foo。然后将文件存储在具有与包的层次结构相对应的层次结构的目录中。此外,包层次结构的根通常是某个目录src。是否可以编写一个扩展为包声明的YASnippet,以便从当前文件的路径中获取包名?

2 个答案:

答案 0 :(得分:7)

您可以使用嵌入式Emacs Lisp编写a snippet来获取缓冲区的路径,并将目录src视为包层次结构中的根目录,将其转换为包名称:

# -*- mode: snippet -*-
#name : package
#key : pa
# --
package ${1:`(mapconcat 'identity (cdr (member "src" (split-string default-directory "/" t))) ".")`};$0

这将识别多级包层次结构,即如果您正在编辑的文件的缓冲区的路径是/home/nn/src/foo/bar/Baz.java,则该代码段将扩展为

package foo.bar;

请注意,这要求您使用src作为存储包层次结构的根目录。如果缓冲区路径中有名为src的目录,则代码段将扩展为

package ;

要让代码段将其他目录识别为包层次结构中的根目录,只需将"src"替换为所需的目录名称。

答案 1 :(得分:0)

这是我在尝试Java时的设置:

# -*- mode: snippet -*-
# name: package
# key: pa
# --
`(insert (concat "package " (java-package-name (buffer-file-name)) ";\n"))`

上面的函数定义为:

(defun java-package-name (file)
  "Generates package name for FILE, based on path."
  (let* ((f (file-name-directory file))
         (rem
          (car
           (sort
            (delq nil
                  (mapcar
                   (lambda(x)
                     (and (string-match (expand-file-name x) f)
                          (substring f (match-end 0))))
                   (parse-colon-path (getenv "CLASSPATH"))))
            (lambda (a b) (< (length a) (length b)))))))
    (cond
     ((null rem)
      "Not on CLASSPATH.")
     ((= 0 (length rem))
      "At root of CLASSPATH")
     (t
      (mapconcat
       #'downcase
       (delete "" (split-string rem "[\\\\/]"))
       ".")))))

它检查您的CLASSPATH寻找最短的包名。