vim UltiSnips扩展java包

fzsnzjdm  于 2023-03-02  发布在  Java
关注(0)|答案(3)|浏览(124)

我希望能够编写一个VIM代码段,自动转换为所需的包。
例如,在.../com/theonlygust/project/Main.java内部扩展pkg将变为

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

但我得到了错误
名称__file__不存在
os.getcwd()不起作用,因为它返回的是打开vim的目录,而不是包含当前缓冲区的目录。
我查看了snip对象,因为我知道它提供snip.fn来获取文件名,但我无法确定它是否提供了当前文件的目录。
没关系,最后了解到UltiSnips设置了一个全局变量"path"

tquggr8v

tquggr8v1#

不能用正则表达式实现吗?
像这样:

global !p

def get_file_package():
    input_str = vim.eval('expand("%:p")')
    transformed_str = re.sub(r'^.*/src/(test|main)/java/((.+/)*)(.*?)/.*\.java$', r'\3\4', input_str)
    return re.sub('/', '.', transformed_str)

endglobal

snippet pkg "Declare java package" b
package `!p snip.rv = get_file_package()`;
endsnippet

我用这个,告诉我是否遗漏了什么。

iq3niunx

iq3niunx2#

UltiSnips将Java代码段存储在java.snippets中,在我的机器上也是~/.vim/bundle/vim-snippets/UltiSnips/java.snippets (I am using honza/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)。
您可以在其自述文件中找到有关在截屏视频中创建代码段的详细信息。

9w11ddsr

9w11ddsr3#

我使用文件路径和最近的pom.xml(向上)中的groupId和artifactId的组合

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

相关问题