简体   繁体   English

UltiSnips 扩展java包

[英]UltiSnips expand java package

I want to be able to write a vim snippet that automatically turns into the required package.我希望能够编写一个自动转换为所需包的 vim 片段。

Eg expanding pkg while inside of .../com/theonlygust/project/Main.java would become例如,在.../com/theonlygust/project/Main.java内部扩展pkg将变成

package com.theonlygusti.project;

I think the ways to do this are to either: read up the directory tree until seeing a TLD directory name (com, io, net, etc.) and then use the encountered directory names to build the package string, or to look up the directory tree for the pom.xml and find the package from there.我认为这样做的方法是:读取目录树直到看到 TLD 目录名称(com、io、net 等),然后使用遇到的目录名称来构建包字符串,或者查找pom.xml目录树并从那里找到包。

I learned about python interpolation.我了解了python插值。

I'm now trying this:我现在正在尝试这个:

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

But I get the error但我得到了错误

Name __file__ does not exist名称__file__不存在

And os.getcwd() doesn't work because that returns the directory from which vim was opened, not the directory that contains the current buffer.并且os.getcwd()不起作用,因为它返回打开 vim 的目录,而不是包含当前缓冲区的目录。

I had a look at the snip object because I know it provides snip.fn to get the filename, but I couldn't find out if it provides the current file's directory.我查看了snip对象,因为我知道它提供了snip.fn来获取文件名,但是我无法确定它是否提供了当前文件的目录。

Nevermind, finally learned that UltiSnips sets a global variable " path "没关系,终于知道UltiSnips设置了一个全局变量“ path

UltiSnips stores Java snippets in java.snippets , which on my machine is ~/.vim/bundle/vim-snippets/UltiSnips/java.snippets (I am using honza/vim-snippets` as well). UltiSnips 将 Java 片段存储在java.snippets 中,在我的机器上是~/.vim/bundle/vim-snippets/UltiSnips/java.snippets (I am using honza/vim-snippets`)。

Snippets for Java are implemented using Python, so I have implemented the snippet below using Python as well (you can do it using multiple languages in UltiSnips). Java 代码片段是使用 Python 实现的,因此我也使用 Python 实现了下面的代码片段(您可以在 UltiSnips 中使用多种语言来实现)。

There is already a snippet for package , which adds simply "package" word followed with a placeholder:已经有一个package的片段,它添加了简单的“package”词,后跟一个占位符:

snippet pa "package" b
package $0
endsnippet

Let's create a pad snippet that will automatically insert package name, based on the directory chain, instead of the $0 placeholder:让我们创建一个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

Note that this solution is based on the fact that in many Java projects, there is an src directory with main/java and test/java directories in it and you are editing one of the files in java directory (eg for src/main/com/google/common it will return com.google.common ).请注意,此解决方案基于以下事实:在许多 Java 项目中,有一个包含main/javatest/java目录的src目录,并且您正在编辑java目录中的文件之一(例如,对于src/main/com/google/common它将返回com.google.common )。 You may need to modify this to be more flexible.您可能需要对此进行修改以使其更加灵活。

You can find more information about creating snippets in screencasts linked in its README .您可以在其 README 中链接的截屏视频中找到有关创建片段的更多信息。

I use a combination of the file path and the groupId and the artifactId from the nearest pom.xml (upwards)我使用文件路径和 groupId 以及最近的 pom.xml 中的 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM