客户端程序无法直接调用CMP之间one-many关系的cmrfield的问题

博客讲述了在处理CMP之间的RelationShip时遇到的问题。以学生表和学生电话表的one - many关系为例,客户端程序无法直接通过CMR field获取电话列表,因EJB规范规定CMP容器管理的CMR不能直接被客户端调用。读取需克隆返回,而修改则不可行。

在做CMP之间的RelationShip时发现的一个问题:
比如有一个学生表,一个学生电话表。一个学生可以有多个电话,是one-many关系。
在客户端程序中,查找到一个学生之后,以为可以直接通过CMR field得到其电话列表,但程序出错,提示“由CMP容器管理的CMR不能直接被客户端调用”。
看来这是EJB的规范规定的原则。
因此如果需要读取CMR,要CLONE一个,把CLONE的COLLECTION/SET返回。
但想修改(写)这个CMR就是不可能的了。

<think>我们正在配置nvim-cmp使用vim-lsp作为源。首先,我们需要确保已经安装了nvim-cmp和vim-lsp插件。 根据引用[1]和[4],我们知道nvim-cmp是一个高度可定制化的补全系统,而vim-lsp是一个语言服务器客户端。 配置步骤大致如下: 1. 安装nvim-cmp和vim-lsp(以及cmp-nvim-lsp等可能需要的插件)。 2. 配置vim-lsp服务器(例如,为特定语言添加服务器)。 3. 配置nvim-cmp,指定vim-lsp作为补全源。 但是,注意:nvim-cmp本身并不直接与vim-lsp交互,而是通过一个叫做`cmp-nvim-lsp`的源(或者可能是`cmp-vim-lsp`)来获取补全数据。 实际上,标准的做法是使用`cmp-nvim-lsp`(为neovim内置的lsp客户端提供补全源)或者为vim-lsp使用对应的源。 然而,问题中提到的是vim-lsp(而不是neovim内置的lsp)。所以我们需要一个能够将vim-lsp的补全数据提供给nvim-cmp的源。 在nvim-cmp的官方文档中,有一个源叫做`cmp-vim-lsp`,它正是为了这个目的。 因此,我们需要: 1. 安装`nvim-cmp` 2. 安装`vim-lsp` 3. 安装`cmp-vim-lsp`(这个插件负责将vim-lsp的补全数据转换成nvim-cmp可以使用的格式) 如果没有`cmp-vim-lsp`,我们可能需要自己写一个源,但通常已经存在这样的插件。 现在,假设我们已经通过插件管理器(如packer.nvim或vim-plug)安装了这些插件,然后进行配置。 配置示例: 首先,配置vim-lsp(这里以安装一个语言服务器为例,比如typescript): ```lua -- 注意:这里使用lua配置,但也可以使用vimscript require('vim-lsp').setup { -- 这里可以配置vim-lsp,但通常我们使用vim-lsp的设置函数 } -- 或者使用vim.cmd来执行vimscript配置 vim.cmd[[ if executable('typescript-language-server') au User lsp_setup call lsp#register_server({ \ 'name': 'typescript-language-server', \ 'cmd': {server_info->['typescript-language-server', '--stdio']}, \ 'root_uri': {server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'tsconfig.json'))}, \ 'whitelist': ['typescript'], \ }) endif ]] ``` 然后,配置nvim-cmp,并添加`cmp-vim-lsp`作为源: ```lua local cmp = require'cmp' cmp.setup({ sources = { -- 其他源,比如buffer、path等 { name = 'vim_lsp' }, -- 注意:这里源的名字是'vim_lsp',对应cmp-vim-lsp提供的源 -- 还可以添加其他源,例如: { name = 'buffer' }, } }) ``` 注意:源的名字是'vim_lsp'(这是cmp-vim-lsp插件注册的源名)。 但是,我们需要确保已经安装了`cmp-vim-lsp`插件。如果没有这个插件,我们可以去GitHub上搜索,或者使用其他类似的源。 实际上,在nvim-cmp的官方文档中,有一个源列表:https://github.com/hrsh7th/nvim-cmp/wiki/List-of-sources 在这个列表中,我们可以找到`cmp-vim-lsp`:https://github.com/hrsh7th/cmp-vim-lsp 因此,安装`cmp-vim-lsp`(使用Packer.nvim): ```lua use 'hrsh7th/cmp-vim-lsp' ``` 总结步骤: 1. 安装插件:nvim-cmp, vim-lsp, cmp-vim-lsp(以及你可能需要的其他cmp源,如cmp-buffer, cmp-path等) 2. 配置vim-lsp,注册你需要的语言服务器。 3. 配置nvim-cmp,在sources数组中添加`{ name = 'vim_lsp' }`。 注意:nvim-cmp还需要设置其他一些东西,比如映射(mapping),但这里我们只关注源。 另外,引用[4]提到nvim-cmp和其扩展提供了高度可定制化的补全系统,所以我们可以根据需求添加其他源。 下面是一个更完整的配置示例(仅关注cmp和vim-lsp部分): ```lua -- 安装插件(以packer.nvim为例) require('packer').startup(function(use) use 'neovim/nvim-lspconfig' -- 注意:这里我们实际上使用的是vim-lsp,而不是neovim内置的lsp,所以这个不是必须的。但如果你同时使用内置lsp,可以保留。 use 'prabirshrestha/vim-lsp' use 'hrsh7th/nvim-cmp' use 'hrsh7th/cmp-vim-lsp' -- 为vim-lsp提供源的插件 use 'hrsh7th/cmp-buffer' -- 从当前缓冲区提供补全 use 'hrsh7th/cmp-path' -- 路径补全 -- 其他插件... end) -- 配置vim-lsp(这里以typescript为例,你需要确保已经安装了typescript-language-server) vim.cmd[[ if executable('typescript-language-server') au User lsp_setup call lsp#register_server({ \ 'name': 'typescript-language-server', \ 'cmd': {server_info->['typescript-language-server', '--stdio']}, \ 'root_uri': {server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'tsconfig.json'))}, \ 'whitelist': ['typescript', 'javascript'], \ }) endif ]] -- 配置nvim-cmp local cmp = require'cmp' cmp.setup({ snippet = { -- 需要配置snippet引擎,这里不展开 expand = function(args) -- 例如,使用vsnip vim.fn["vsnip#anonymous"](args.body) end, }, mapping = { ['<C-b>'] = cmp.mapping(cmp.mapping.scroll_docs(-4), { 'i', 'c' }), ['<C-f>'] = cmp.mapping(cmp.mapping.scroll_docs(4), { 'i', 'c' }), ['<C-Space>'] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }), ['<C-y>'] = cmp.config.disable, -- 移除默认的`<C-y>`映射 ['<C-e>'] = cmp.mapping({ i = cmp.mapping.abort(), c = cmp.mapping.close(), }), ['<CR>'] = cmp.mapping.confirm({ select = true }), -- 回车确认 }, sources = cmp.config.sources({ { name = 'vim_lsp' }, -- 来自vim-lsp的补全 -- 可以添加其他源,比如: { name = 'buffer' }, -- 当前缓冲区 { name = 'path' }, -- 文件路径 }) }) -- 还可以为特定文件类型设置源,例如: -- cmp.setup.filetype('gitcommit', { -- sources = cmp.config.sources({ -- { name = 'cmp_git' }, -- 如果安装了git源 -- }, { -- { name = 'buffer' }, -- }) -- }) ``` 注意:上面的配置中,我们使用了`vim_lsp`作为源,这就是`cmp-vim-lsp`提供的。 最后,请确保你的语言服务器已经正确安装并在运行,这样vim-lsp才能提供补全数据。 如果遇到问题,可以检查: - 语言服务器是否安装并可用(在命令行中执行命令,例如`typescript-language-server --version`) - vim-lsp是否成功注册了服务器(通过`:LspStatus`等命令查看) - nvim-cmp的配置中是否正确添加了`vim_lsp`源 这样,nvim-cmp就可以使用vim-lsp作为补全源了。 相关问题: 1. 如何为特定的语言服务器配置vim-lsp? 2. nvim-cmp除了vim-lsp源,还有哪些常用的补全源? 3. 如何配置nvim-cmp的快捷键以更符合个人习惯? 4. 在使用nvim-cmp时,如何同时使用多个补全源(比如vim-lsp和buffer)?</think>### 在 Neovim 中配置 nvim-cmp 使用 vim-lsp 作为补全源 以下是完整的配置步骤(需 Lua 配置): #### 1. **安装必要插件** 在插件管理器(如 `packer.nvim`)中添加: ```lua -- init.lua require('packer').startup(function(use) use 'prabirshrestha/vim-lsp' -- LSP 客户端 use 'hrsh7th/nvim-cmp' -- 补全引擎 use 'hrsh7th/cmp-vim-lsp' -- vim-lsp 与 nvim-cmp 的桥接器 use 'hrsh7th/cmp-buffer' -- 可选:缓冲区补全 use 'hrsh7th/cmp-path' -- 可选:路径补全 end) ``` #### 2. **配置 vim-lsp 服务器** 以 Python 为例(其他语言类似): ```lua vim.cmd [[ augroup LspPython autocmd! autocmd User lsp_setup call lsp#register_server({ \ 'name': 'pylsp', \ 'cmd': {server_info->['pylsp']}, \ 'allowlist': ['python'], \ }) augroup END ]] ``` #### 3. **配置 nvim-cmp 使用 vim-lsp 源** 核心配置: ```lua local cmp = require('cmp') cmp.setup({ sources = { { name = 'vim_lsp' }, -- 关键:使用 vim-lsp 作为源 { name = 'buffer' }, -- 可选:当前缓冲区补全 { name = 'path' }, -- 可选:文件路径补全 }, mapping = { ['<C-Space>'] = cmp.mapping.complete(), ['<CR>'] = cmp.mapping.confirm({ select = true }), ['<Tab>'] = cmp.mapping.select_next_item(), ['<S-Tab>'] = cmp.mapping.select_prev_item(), }, snippet = { expand = function(args) vim.fn["UltiSnips#Anon"](args.body) -- 若使用 UltiSnips end, }, }) ``` #### 4. **验证配置** - 重启 Neovim - 打开 Python 文件输入 `import os`,输入 `os.` 时应有补全提示 - 用命令检查补全源状态:`:lua print(vim.inspect(require('cmp.core').sources))` #### 关键说明 1. **桥接插件**:必须通过 `cmp-vim-lsp` 转换数据格式(直接调用会失败)[^1] 2. **源名称**:配置中必须使用 `vim_lsp`(不是 `vim-lsp` 或 `lsp`) 3. **优先级**:vim-lsp 源应放在 `sources` 数组首位以确保优先显示 4. **自动触发**:默认在输入字母时触发,可通过 `completion = { autocomplete = true }` 调整 > 示例:JavaScript 的额外配置 > ```lua > vim.cmd [[ > autocmd User lsp_setup call lsp#register_server({ > 'name': 'typescript-language-server', > 'cmd': {server_info->['typescript-language-server', '--stdio']}, > 'allowlist': ['javascript', 'typescript'], > }) > ]] > ``` ### 常见问题解决 | 问题现象 | 解决方案 | |---------|----------| | 无补全提示 | 1. 检查 `:LspStatus` 确认语言服务器运行<br>2. 确认 `cmp-vim-lsp` 已安装 | | 补全内容不完整 | 在 vim-lsp 配置中添加:<br>`let g:lsp_settings = { 'pylsp': { 'workspace_config': { 'pylsp': { 'plugins': { 'jedi_completion': { 'include_params': v:true }}}}}} ` | | 补全延迟高 | 添加 `performance = { debounce = 50 }` 到 cmp.setup | 最终效果:vim-lsp 提供的补全项将与其他源(如 buffer)混合排序显示[^4]。 --- ### 相关问题 1. 如何为 vim-lsp 配置特定语言服务器(如 Clangd/C++)? 2. nvim-cmp 如何同时使用 vim-lsp 和 Neovim 内置 LSP 作为补全源? 3. 补全菜单排序策略如何自定义(如按类型/来源优先级)? 4. 如何为 nvim-cmp 添加签名帮助(函数参数提示)? [^1]: 通过 `cmp-vim-lsp` 桥接器实现数据格式转换 [^4]: 混合排序机制由 nvim-cmp 的排序引擎统一处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值