有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

vim UltiSnips扩展java包

我希望能够编写一个自动转换为所需包的vim代码段

例如,扩展pkg,而.../com/theonlygust/project/Main.java的内部将变为

package com.theonlygusti.project;

我认为这样做的方法是:读取目录树直到看到TLD目录名(com、io、net等),然后使用遇到的目录名来构建包字符串,或者查找目录树中的pom.xml并从中找到包

我学习了python插值

我现在正在尝试:

snippet pkg "Create package" b
package `!p

import os
from xml.etree import ElementTree

def get_package_name(pom_file_path):
  namespaces = {'xmlns' : 'http://maven.apache.org/POM/4.0.0'}

  tree = ElementTree.parse(pom_file_path)
  root = tree.getroot()

  groupId = root.find(".//xmlns:groupId", namespaces=namespaces)
  artifactId = root.find(".//xmlns:artifactId", namespaces=namespaces)
  return groupId.text + '.' + artifactId.text

def find_nearest_pom():
  absolute_path = os.path.abspath(os.path.dirname('__file__')).split("/")
  pom_dir_index = -1

  # Find index of 'base_dir_name' element
  while not os.path.isfile('/'.join(absolute_path[:pom_dir_index]) + '/pom.xml'):
    pom_dir_index -= 1

  return '/'.join(absolute_path[:pom_dir_index]) + '/pom.xml'

snip.rv = get_package_name(find_nearest_pom())`;
endsnippet

但是我得到了错误

Name __file__ does not exist

而且os.getcwd()不起作用,因为它返回打开vim的目录,而不是包含当前缓冲区的目录

我查看了snip对象,因为我知道它提供了snip.fn来获取文件名,但我无法确定它是否提供了当前文件的目录

Nevermind最终了解到UltiSnips设置了一个全局变量“path


共 (2) 个答案

  1. # 1 楼答案

    我使用文件路径、groupId和来自最近pom的artifactId的组合。xml(向上)

    global !p
    import os
    from xml.etree import ElementTree
    
    def get_package_name(pom_file_path):
      namespaces = {'xmlns' : 'http://maven.apache.org/POM/4.0.0'}
    
      tree = ElementTree.parse(pom_file_path)
      root = tree.getroot()
    
      groupId = root.find(".//xmlns:groupId", namespaces=namespaces)
      artifactId = root.find(".//xmlns:artifactId", namespaces=namespaces)
      return groupId.text + '.' + artifactId.text
    
    def find_nearest_pom():
      current_file_dir = '/'.join((os.getcwd() + ('/' if os.getcwd()[-1] != '/' else '') + path).split('/')[:-1])
      absolute_path = current_file_dir.split("/")
      pom_dir_index = -1
    
      if os.path.isfile('/'.join(absolute_path) + '/pom.xml'):
        return '/'.join(absolute_path) + '/pom.xml'
    
      # Find index of 'base_dir_name' element
      while not os.path.isfile('/'.join(absolute_path[:pom_dir_index]) + '/pom.xml'):
        pom_dir_index -= 1
    
      return '/'.join(absolute_path[:pom_dir_index]) + '/pom.xml'
    
    def get_file_package():
      current_file_location = '.'.join((os.getcwd() + ('/' if os.getcwd()[-1] != '/' else '') + path).split('/')[:-1])
      package = get_package_name(find_nearest_pom())
      return package + current_file_location.split(package)[1]
    
    endglobal
    
    snippet pkg "package" b
    package `!p snip.rv = get_file_package()`;
    endsnippet
    
  2. # 2 楼答案

    UltiSnips将Java代码片段存储在java.snippets中,在我的机器上也是~/.vim/bundle/vim-snippets/UltiSnips/java.snippets (I am usinghonza/vim snippets`)

    Java代码段是使用Python实现的,因此我也使用Python实现了下面的代码段(您可以在UltiSnips中使用多种语言)

    已经有一个package的代码段,它简单地添加了“package”单词,后跟一个占位符:

    snippet pa "package" b
    package $0
    endsnippet
    

    让我们创建一个pad代码段,它将根据目录链自动插入包名,而不是$0占位符:

    snippet pad "package" b
    package `!p
    
    def get_package_string(base_dir_name):
      import os
      # Get absolute path of the package (without filename)
      absolute_path = os.getcwd().split("/")
      src_dir_index = 0
    
      # Find index of 'base_dir_name' element
      while absolute_path[src_dir_index] != base_dir_name:
        src_dir_index+=1
    
      # Create a 'package ' string, joining with dots
      package_string = ".".join(absolute_path[src_dir_index+1:])
      return package_string
    
    # snip.rv is UltiSnips' return value we want to paste between ``
    snip.rv = get_package_string("java")`
    
    endsnippet
    

    请注意,此解决方案基于以下事实:在许多Java项目中,有一个src目录,其中包含main/javatest/java目录,并且您正在编辑java目录中的一个文件(例如,对于src/main/com/google/common,它将返回com.google.common)。您可能需要对此进行修改以使其更加灵活

    您可以在screencasts linked in its README中找到有关创建代码段的更多信息