Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
david_kunz2
Advisor
Advisor

Update: Added Configuration Video Part 1
Update 2: Added Configuration Video Part 2
Update 3: Added Configuration Video Part 3



In my professional career, I've exclusively used IDEs for software development even though they:

  • have long startup times

  • are bloated and slow

  • have inefficient key bindings

  • require a mouse




The reason for that is because I desperately needed (and still need) many of their features which plain text editors couldn't properly provide, namely:

  • language features for all my used languages (go to definition, autocompletion, etc.)

  • a debugger


However, I really like the features of my favourite text editor Vim, it:

  • is 100% keyboard driven

  • has a command centric approach with a huge amount of commands

  • is modal

  • does not need a GUI and can run in your terminal

  • is highly configurable using simple text files

  • has a low memory footprint



Having already invested many years in Vim (which has an immense learning curve), I did not want to give up my acquired skills. Unfortunately, I never managed to add the needed features to Vim.


So instead of adapting Vim to be more IDE-like, I tried to make my IDEs behave more like Vim using plugins and keybindings. Depending on the IDE, this worked to some extend, but I was never really happy with it because a lot of commands were not supported, keystrokes were occasionally ignored, many features still required a mouse and the problem of sluggishness persisted.

My most successful attempt was using VSCode with the Neo Vim extension where keybindings are not just mapped, but a complete instance of Neovim was run inside of VSCode. It worked really well, but the bloat of VSCode, which is an Electron app, still concerned me.

VSCode also introduced two very important innovations: The Language Server Protocol (LSP) and the lesser known Debug Adapter Protocol (DAP), which solve the problem of every editor/IDE having to support every programming language. Now, an editor/IDE only needs to support the LSP and the DAP. These innovations provide unified and standardised access to language and debugger features of specific programming languages.

Vim supports the LSP and DAP through plugins. Neovim is a fork of Vim and has a more modern governance structure (many contributors as opposed to only one), allowing the development of many new features, including native support for the LSP.


And now, after so many years, I finally managed to set up both the LSP and the DAP, providing Neovim with all the language features and debuggers I need. It wasn't easy to set up and I had to write some scripts, but it works. Finally, there's no reason to use IDEs anymore. I made the switch.

I created a short demo, showcasing some of the features.









 

I managed to make Neovim's native LSP client use the LSP server of the SAP Cloud Application Programming Model (CAP) and I added syntax highlighting for cds files. dj.adams.sap' video on cds-lsp was of great help for me.


I can confidently say, I learned a lot during this process and I've grown as a programmer. I'm finally comfortable with my development setup and I'm curious of Neovim's future innovations.

Thanks a lot for your time and keep your programming tools sharp,
David
32 Comments
qmacro
Developer Advocate
Developer Advocate

Now THIS is the sort of blog post that I love to see on a Monday morning! Awesome and inspiring work, David, thanks for that. And I’m already looking forward to the next installment of your video series 💪(btw, subscribed!)

david_kunz2
Advisor
Advisor
0 Kudos

Thanks a lot, DJ!

mariusobert
Developer Advocate
Developer Advocate
Thanks for this super interesting post, David!
It's always nice to see how other developers set up their dev environments (even though I'm happy with mouse navigation 😅).
htammen
Active Contributor
Hi David,

thanks for sharing. I'm also a fan of vim for years but missed a lot of things you mentioned in your video. Curious to read your next blog / watch your next video.
david_kunz2
Advisor
Advisor
Hi Helmut,

I'm glad you found it useful, here's my video on the configuration.

Best regards,
David
htammen
Active Contributor
Great video!!
Already copied most of it to my init.vim

Is there a repository with you configuration on github?

Can't await the next video. Don't have experience with DAP so far.
david_kunz2
Advisor
Advisor

Thanks a lot, Helmut!


The configuration is available here: https://github.com/David-Kunz/vim/blob/master/init.vim


Best regards,

David
NabiZamani
Contributor

This is just such a treasure! And I thought I did pretty well with my vim configuration so far. I was so wrong 😀

I absolutely enjoy how you precisely focus and how you cover exactly what needs to be told.

Thank You!

david_kunz2
Advisor
Advisor
Hi pars.man,

Thanks a lot for your kind words!
david_kunz2
Advisor
Advisor
0 Kudos
Thanks a lot mariusobert!

Regarding speed, I'm on the Keyboard > Mouse > Touchpad front 🙂
mariusobert
Developer Advocate
Developer Advocate
I actually only use the touchpad and almost never touch the mouse 🙈
js2
Product and Topic Expert
Product and Topic Expert
david.kunz2  I  also use vim where possible. Some awesome ideas here which I’ve now adopted. Wondering with the LSP if it’s possible to also get the annotations editors to work.
Does the cds lsp also include annotations in the cds files?
david_kunz2
Advisor
Advisor

Hi Jason,

Great to see another Vim user! I haven't tried the server for annotations yet, but in principle it should also work.

There's a plugin https://github.com/hrsh7th/nvim-cmp which should allow you to use snippets from your server.

Best regards,
David

js2
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi david.kunz2 I'm trying to work out how you have got the CDS LSP working... Watching DJ's videos shows that he's using ALE for the LSP integration; however from your init.vim file I can see you're not using that.

So where do you place the CDS syntax file and what does your "$HOME/projects/startcdslsp" script look like?
david_kunz2
Advisor
Advisor
Hi jasonscott ,

Yes, I got it working with the following configuration:


 

// init.lua:
local lspconfig = require'lspconfig'
local configs = require'lspconfig/configs'
local on_attach = function(client, bufnr)
local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
end

configs.sapcds_lsp = {
default_config = {
cmd = {vim.fn.expand("$HOME/projects/startcdslsp")}; -- this executable must be there
filetypes = {'cds'};
root_dir = function(fname)
return vim.fn.getcwd()
end;
settings = {};
};
}
if lspconfig.sapcds_lsp.setup then
lspconfig.sapcds_lsp.setup{ on_attach = on_attach }
end

cmd([[
augroup MyCDSCode
autocmd!
autocmd BufReadPre,FileReadPre *.cds set ft=cds
augroup END
]])

and the syntax file in ~/.config/nvim/syntax/cds.vim
if exists("b:current_syntax")
finish
endif

syntax match cdsComment "\v\/\/.*$"
syntax region cdsComment start="\v/\*" end="\v\*/"

syntax match cdsOtherStuff /=/
syntax match cdsAnnotation /\v\@\S*/

syntax match supportClassCds /\v(<|>)(Association to (one|many|)|Composition of (one|many|)|Boolean|Date|Time|DateTime|Timestamp|Number|Integer|Decimal|String)(<|>)/
syntax match keywordStrongCds /\v(<|>)(key|as|on|with|namespace|import|using|define|extend|annotate|expose|context|service|abstract|aspect|entity|projection|view|event|type|facet|annotation|actions|action|function)(<|>)/
syntax match keywordStrongControlCds /\v(<|>)from(<|>)/
syntax region stringQuotedSingleCds start="\v'" end="\v'"
syntax region stringQuotedDoubleCds start="\v\"" end="\v\""

highlight link keywordStrongCds Keyword
highlight link keywordStrongControlCds Keyword
highlight link cdsOtherStuff Keyword
highlight link cdsComment Comment
highlight link stringQuotedSingleCds String
highlight link stringQuotedDoubleCds String
highlight link supportClassCds Constant
highlight link cdsAnnotation Function

let b:curent_syntax = "cds"

 


 

autocomplete

js2
Product and Topic Expert
Product and Topic Expert
0 Kudos
david.kunz2 thanks. I have it sort-of working now.

I just installed the cds-lsp via npm i -g @sap/cds-lsp and pointed the startcdslsp script to the executable.

So I can start nvim and open a cds file. Syntax highlighting works... but commands like go-to-defintion and so on only work once and then not again. After the first use I get errors like this in the file:

using {
E 2 managed, ■ Artifact “managed” has not been found
E 3 Currency, ■ Artifact “Currency” has not been found
E 4 sap.common.CodeList ■ Artifact “sap” has not been found
5 } from './common';

It can no longer resolve any CDS dependencies. So I need to exit nvim and open it again for it to work each time.

 

btw. I'm using an init.vim file and not init.lua - however it has the same code in it like so:
" CDS - Add @sap/cds-lsp to lspconfig
augroup MyCDSCode
autocmd!
autocmd BufReadPre,FileReadPre *.cds set ft=cds
augroup END
lua << EOF
local lspconfig = require'lspconfig'
local configs = require'lspconfig/configs'
local on_attach = function(client, bufnr)
local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
end

configs.sapcds_lsp = {
default_config = {
cmd = {vim.fn.expand("$HOME/dev/startcdslsp")}; -- this executable must be there
filetypes = {'cds'};
root_dir = function(fname)
return vim.fn.getcwd()
end;
settings = {};
};
}
if lspconfig.sapcds_lsp.setup then
lspconfig.sapcds_lsp.setup{ on_attach = on_attach }
end
EOF
david_kunz2
Advisor
Advisor
0 Kudos
Hi jasonscott ,

Yes, init.vim is also fine!

I think you always make sure
1) to install the dependencies, so you have a local node_modules folder
2) that the root path is correct, you can check that with :LspInfo

Best regards,
David
js2
Product and Topic Expert
Product and Topic Expert
Hi david.kunz2  I think I found the issue by fluke. I simply ran :LspRestart and now it all works fine and I can 'gd' and ctrl-o back all day long.
Maybe exiting neovim is not killing the cdslsp process such that all my config changes weren't taking effect?!? All good now.
david_kunz2
Advisor
Advisor
0 Kudos
Hi jasonscott ,

That's good to hear, glad it works!

Best regards,
David
htammen
Active Contributor
0 Kudos
Hi david.kunz2, hi jasonscott,

I recently updated my NeoVim to v0.6.1. Then I thought it was a good idea to switch from init.vim to init.lua configuration, install the CDS language server (was not installed before) and use it in NVIM. Everything works fine except the CDS LSP.

There are lots of changes in my environment: new NVIM, new LSPCONFIG, init.lua (instead of init.vim). So there are a lot of possible causes for errors.

Would be nice if you could tell me if it's working at your side and maybe you can have a look at my configuration an give me a hint?

Here's my configuration

NVIM: v0.6.0
nvim-lspconfig: udpated to newest version on 2022/01/06
cds-lsp: Installed newest version (2022/01/05) like described in INSTALLATION.md of the npm package.

cds-lsp config in init.lua:
local lspconfig = require'lspconfig'
local configs = require'lspconfig.configs'
local on_attach = function(client, bufnr)
vim.notify("sapcds_lsp attached to buffer", vim.log.levels.WARN)
local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
end

configs.sapcds_lsp = {
default_config = {
-- cmd = {vim.fn.expand("$HOME/bin/startcdslsp")}; -- this executable must be there
cmd = {vim.fn.expand("$HOME/bin/sapcdslsp/node_modules/.bin/cds-lsp")}; -- this executable must be there
filetypes = {'cds'};
-- root_dir = lspconfig.util.root_pattern('.git', 'package.json'),
root_dir = function(fname)
return vim.fn.getcwd()
end;
settings = {};
};
}
if lspconfig.sapcds_lsp.setup then
vim.notify("Calling sapcds_lsp setup", vim.log.levels.WARN)
lspconfig.sapcds_lsp.setup{ on_attach = on_attach }
end

cmd([[
augroup MyCDSCode
autocmd!
autocmd BufReadPre,FileReadPre *.cds set ft=cds
augroup END
]])

 

After I opened a cds file into a buffer the output from LspInfo looks like this:
The language server is installed and configured but it is not attached to the buffer

 


Output from LspInfo


I also set the log level of lspconfig to trace and looked at the log. From there I get the following info:


lspconfig log with trace level


 

Best regards
Helmut

P.S. I had to change the line "local configs = require'lspconfig/configs'" from your config to "local configs = require'lspconfig.configs'". Otherwise I get an error message that lspconfig.sapcds_lsp is not defined.
david_kunz2
Advisor
Advisor
0 Kudos
Hi Helmut,

Thanks for this nice write-up! At the moment I also have problems to enable the language server in cds. It's strange that LspInfo tells us that it's running, but diagnostics are not shown.

Changing the line from lspconfig/configs to lspconfig.configs is correct.

I will investigate further!

Best regards,
David
htammen
Active Contributor
Hi David,

thanks for your answer. I invested already quite a lot of time (learned a lot) and thought that it's my lack of knowledge. As you face the same problem I might invest some more time at the weekend.

I will keep you up to date if I find a solution.

Best regards
Helmut
htammen
Active Contributor
Quick update. Just installed the new nightly prerelease build 0.7.0 of NVIM. Didn't fix the problem.
js2
Product and Topic Expert
Product and Topic Expert
helmut.tammen2 david.kunz2 the CDS LSP also does not work for me in nvim anymore. If I follow the @sap/cds-lsp installation instructions it does not result in a cds-lsp script in the .bin folder so something is wrong with the latest cds-lsp.
htammen
Active Contributor
Today (a year later :-D) I fixed my problem with the CDS LSP server.

To have it easier the next time I wrote a bit of documentation (not exhaustive) and added two bash scripts.
If anyone wants to have a look at it goto this codeberg repo.

Have fun with NVIM.
htammen
Active Contributor
0 Kudos
@jasonscott Please have a look at the comment above I made a minute ago.
stijnme
Explorer
0 Kudos

Hi,

I've noticed that the latest version (@sap/cds-lsp@7.4.0) is not working as expected.

~/tmp/cds-lsp-7.4.0/package $ node dist/main.js --stdio
~/tmp/cds-lsp-7.4.0/package $ echo $?
72

While executing this one an older version, the process keeps running as expected:

~/tmp/cds-lsp-6.2.2/package $ node dist/main.js --stdio
^C

When looking at the instructions in `doc/CONTRIBUTING.MD` it is referring to 2 SAP internal github locations to report an issue... Is there somewhere else as a non-SAP employee to report this?
I could open an OSS...

Stijn

david_kunz2
Advisor
Advisor
0 Kudos
Hi smertens_expertum , thank you for reporting.
I successfully installed https://www.npmjs.com/package/@sap/cds-lsp and it works in my Neovim instance:

Language client log: /Users/******/.local/state/nvim/lsp.log
Detected filetype: cds

1 client(s) attached to this buffer:

Client: sapcds_lsp (id: 1, bufnr: [1])
filetypes: cds
autostart: true
root directory: /Users/******/SAPDevelop/issues/cds1122
cmd: /Users/******/apps/cds-lsp/node_modules/.bin/cds-lsp --stdio

Configured servers list: sapcds_lsp, tsserver, zls, rust_analyzer

 

Hi joerg.mann , could you look into this? The links in the README don't seem to work.

 
stijnme
Explorer
I've made pull requests to add cds-lsp to:

  1. https://github.com/neovim/nvim-lspconfig

  2. https://github.com/mason-org/mason-registry


Both are now in the master branches. This makes it easy to install both plugins. In my case, via Packer. And installing the lsp with MasonInstall cds-lsp.

Currently only the LSP, formatting isn't (yet) configured.
david_kunz2
Advisor
Advisor
Wow, that's great! I'm a user of mason myself, I will try it out soon! Thank you so much for this contribution!
stijnme
Explorer
No problem, thanks to this blogpost and all the information above, I was able to wrap my head around "What is an LSP" rather quickly.

If anyone is interested in my setup, in particular the cds-lsp config:

https://github.com/stijnme/dotfiles/blob/main/.config/nvim/lua/melxaco/plugins/lsp/lspconfig.lua

This should be enough (after the setup of lspconfig and mason):
-- cds-lsp
lspconfig["cds_lsp"].setup({
capabilities = capabilities,
on_attach = on_attach,
})

-- Add cds file type
vim.cmd([[
augroup MyCDSCode
autocmd!
autocmd BufReadPre,FileReadPre *.cds set ft=cds
augroup END
]])

Remark: I still had to add the code to recognize/set the file type for cds files.
bztoy
Participant
0 Kudos

Thanks Dr. David Kunz for sharing this great stuff.