• chevron_right

      Perfect Neovim Ansible Setup

      Slixfeed · Wednesday, 13 March - 22:51 · 9 minutes

    Lets start with information that I did not created that config. This Ansible oriented config was handed to me by one of my mates from the Linux world … and as it takes some steps needed to make it work specific only to FreeBSD – I thought that it may be a good reason to share them.

    I have split the article into the following parts is shown in Table of Contents below.

    • Neovim Config
    • Neovim Plugins
    • Needed Packages
    • Ansible Language Server
    • Some Modules Linuxisms
    • Alternatives
    • Summary

    Lets start then.

    Neovim Config

    Below are the Neovim config files located at ~/.config/nvim/lua/config place.

    % wc -l ~/.config/nvim/lua/config/*
           3 /home/vermaden/.config/nvim/lua/config/globals.lua
          43 /home/vermaden/.config/nvim/lua/config/init.lua
          24 /home/vermaden/.config/nvim/lua/config/keymaps.lua
          53 /home/vermaden/.config/nvim/lua/config/options.lua
         123 total
    
    
    
    % cat ~/.config/nvim/lua/config/globals.lua
    vim.g.mapleader      = " "
    vim.g.maplocalleader = " "
    
    
    
    % cat /home/vermaden/.config/nvim/lua/config/init.lua
    local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
    if not vim.loop.fs_stat(lazypath) then
      vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "https://github.com/folke/lazy.nvim.git",
        "--branch=stable", -- latest stable release
        lazypath,
      })
    end
    vim.opt.rtp:prepend(lazypath)
    
    require('config.globals')
    require('config.options')
    require('config.keymaps')
    
    local opts = {
      defaults = {
        lazy = true,
      },
      install = {
        colorscheme = { "nightfox" }
      },
      rtp = {
        disabled_plugins = {
          "gzip",
          "matchit",
          "matchparen",
          "netrw",
          "netrwPlugin",
          "tarPlugin",
          "tohtml",
          "tutor",
          "zipPlugin",
        }
      },
      change_detection = {
        notify = true
      },
    }
    
    require("lazy").setup('plugins', opts)
    
    
    
    % cat ~/.config/nvim/lua/config/keymaps.lua
    local keymap = vim.keymap
    
    local opts = { noremap = true, silent = true }
    
    -- DIRECTORY NAVIGATION ------------------------------------------------------
    keymap.set("n", "<leader>m", ":NvimTreeFocus<CR>", opts)
    keymap.set("n", "<leader>f", ":NvimTreeToggle<CR>", opts)
    keymap.set("n", "<C-k>", "<C-w>k", opts) -- NAVIGATE [^] UP
    keymap.set("n", "<C-h>", "<C-w>h", opts) -- NAVIGATE [<] LEFT
    keymap.set("n", "<C-l>", "<C-w>l", opts) -- NAVIGATE [>] RIGHT
    keymap.set("n", "<C-j>", "<C-w>j", opts) -- NAVIGATE [v] DOWN
    
    -- WINDOW MANAGEMENT ---------------------------------------------------------
    keymap.set("n", "<leader>sv", ":vsplit<CR>", opts) -- SPLIT VERTICALLY
    keymap.set("n", "<leader>sh", ":split<CR>", opts)  -- SPLIT HORIZONTALLY
    
    -- INDENT --------------------------------------------------------------------
    keymap.set("v", "<", "<gv")
    keymap.set("v", ">", ">gv")
    
    -- COMMENTS ------------------------------------------------------------------
    vim.api.nvim_set_keymap("n", "<C-_>", "gcc", { noremap = false })
    vim.api.nvim_set_keymap("v", "<C-_>", "gcc", { noremap = false })
    
    
    
    % cat ~/.config/nvim/lua/config/options.lua
    local opt = vim.opt
    
    -- TAB/INDENT ----------------------------------------------------------------
    opt.tabstop     = 2
    opt.shiftwidth  = 2
    opt.softtabstop = 2
    opt.expandtab   = true
    opt.smartindent = true
    opt.wrap        = false
    
    -- SEARCH --------------------------------------------------------------------
    opt.incsearch  = true
    opt.ignorecase = true
    opt.smartcase  = true
    opt.hlsearch   = false
    
    -- APPEARANCE ----------------------------------------------------------------
    opt.number         = true
    opt.relativenumber = false
    opt.termguicolors  = true
    opt.colorcolumn    = "100"
    opt.signcolumn     = "yes"
    opt.cmdheight      = 1
    opt.scrolloff      = 10
    opt.completeopt    = "menuone,noinsert,noselect"
    
    -- MISC ----------------------------------------------------------------------
    opt.hidden     = true
    opt.errorbells = false
    opt.swapfile   = false
    opt.backup     = false
    opt.undodir    = vim.fn.expand("~/.vim/undodir")
    opt.undofile   = true
    opt.backspace  = "indent,eol,start"
    opt.splitright = true
    opt.splitbelow = true
    opt.autochdir  = false
    opt.modifiable = true
    opt.encoding   = "UTF-8"
    
    -- APPEND --------------------------------------------------------------------
    opt.mouse:append('a')
    opt.iskeyword:append("-")
    opt.clipboard:append("unnamedplus")
    
    -- ANSIBLE/YAML --------------------------------------------------------------
    vim.filetype.add({
      extension = {
        yml = 'yaml.ansible'
      }
    })
    
    

    That much for configs – now plugins.

    Neovim Plugins

    The list of Neovim plugins in this config is shown below.

    neovim.plugins

    … if some search engine would like to point here I will also list them in text.

    • comment.lua
    • indent-blankline.lua
    • init.lua
    • lualine-nvim.lua
    • mason-lspconfig.lua
    • mason.lua
    • nightfox.lua
    • noice.lua
    • nvim-cmp.lua
    • nvim-lspconfig.lua
    • nvim-tree.lua
    • nvim-treesitter.lua
    • nvim-ts-autotag.lua
    • nvim-web-devicons.lua
    • telescope.lua
    • vim-highlightedyank.lua
    • vim-illuminate.lua
    • whichkey.lua

    Here are their contents.

    % grep -A 1 return ~/.config/nvim/lua/plugins/* \
        | grep -v -e -- -e return \
        | awk '{print $NF}' \
        | tr -d "\"',{}" \
        | sort -u
    
    EdenEast/nightfox.nvim
    folke/noice.nvim
    folke/which-key.nvim
    hrsh7th/nvim-cmp
    lukas-reineke/indent-blankline.nvim
    machakann/vim-highlightedyank
    neovim/nvim-lspconfig
    numToStr/Comment.nvim
    nvim-lualine/lualine.nvim
    nvim-telescope/telescope.nvim
    nvim-tree/nvim-tree.lua
    nvim-tree/nvim-web-devicons
    nvim-treesitter/nvim-treesitter
    RRethy/vim-illuminate
    williamboman/mason-lspconfig.nvim
    williamboman/mason.nvim
    windwp/nvim-ts-autotag
    
    

    All these plugins are available – nvim-lua-plugins.tar.gz – here.

    Execute below command to add them to Your Neovim dir.

    % fetch -o - \
        https://github.com/vermaden/scripts/raw/master/distfiles/nvim-lua-plugins.tar.gz \
        | tar -C ~/.config/nvim/lua -xvf -
    -                                                     3696  B 9804 kBps    00s
    x plugins/
    x plugins/noice.lua
    x plugins/telescope.lua
    x plugins/indent-blankline.lua
    x plugins/whichkey.lua
    x plugins/nvim-web-devicons.lua
    x plugins/comment.lua
    x plugins/nvim-tree.lua
    x plugins/mason.lua
    x plugins/nightfox.lua
    x plugins/nvim-cmp.lua
    x plugins/vim-highlightedyank.lua
    x plugins/mason-lspconfig.lua
    x plugins/init.lua
    x plugins/nvim-treesitter.lua
    x plugins/vim-illuminate.lua
    x plugins/nvim-ts-autotag.lua
    x plugins/lualine-nvim.lua
    x plugins/nvim-lspconfig.lua
    
    

    Just in case if WordPress would mess any part of Neovim config – You may find all of the configuration and plugins in one file – ~/.config/nvim – available here.

    Needed Packages

    Besides the obvious Neovim packages there are some additional ones needed to make entire setup work.

    # pkg install -y \
        neovim \
        npm    \
        node   \
        gcc13  \
        gmake
    

    That is it. That is probably the most simple part of this article.

    Ansible Language Server

    After I dumped that Neovim config into the ~/.config/nvim dir I learned that it is a lot more advanced then I thought – to the point that it needs an external dedicated ansible-language-server needed for the Ansible playbook completions.

    neovim.ansible-language-server

    I used the most recent 1.2.1 release of ansible-language-server … and used the ALS Documentation for the instructions to build it properly.

    % fetch https://github.com/ansible/ansible-language-server/archive/refs/tags/v1.2.1.tar.gz
    
    % tar -xzvf v1.2.1.tar.gz
    
    % cd ansible-language-server-1.2.1
    
    % npm install .
    

    Lets check if the ansible-language-server built properly … and that it actually works.

    % find . -name server.js -o -name ansible-language-server
    ./bin/ansible-language-server
    ./out/server/src/server.js
    ./node_modules/vscode-languageserver/lib/common/server.js
    
    % node ./out/server/src/server.js --stdio  
    ^C
    

    Seems to work as desired.

    As I already use ~/scripts/bin place as additional ingredient to my PATH environment I will put it there … kinda.

    % echo ${PATH} | tr ':' '\n' | grep scripts
    /home/vermaden/scripts
    /home/vermaden/scripts/bin
    
    % pwd
    /home/vermaden/ansible-language-server-1.2.1
    
    % cd ..
    
    % mv ansible-language-server-1.2.1 ~/scripts/
    
    % ln -s \
        ~/scripts/ansible-language-server-1.2.1/bin/ansible-language-server \
        ~/scripts/bin/ansible-language-server
    
    % rehash || hash -r
    

    When we now start Neovim it does not cry that ansible-language-server is not available – so that part seems to work properly.

    Some Modules Linuxisms

    When You first start that Neovim setup it will start to fetch/build/configure all these plugins.

    neovim.1st.start

    For the record – if something fails its safe to remove the ~/.local/share/nvim dir and start over.

    % rm -rf ~/.local/share/nvim
    % nvim
    

    … and it fails to build LuaSnip module.

    neovim.linuxisms

    Maybe it will do better with GNU make(1) instead of BSD make(1) – lets try that.

    ~ # cd /usr/bin
    /usr/bin # mv make make.FreeBSD
    /usr/bin # ln -s /usr/local/bin/gmake make
    

    Lets try now with GNU make(1) instead.

    neovim.setup.GNU.make

    Now the gcc seems to be missing … but we installed lang/gcc13 packages at the beginning …

    % pkg info -l gcc13 | grep bin/gcc
            /usr/local/bin/gcc-ar13
            /usr/local/bin/gcc-nm13
            /usr/local/bin/gcc-ranlib13
            /usr/local/bin/gcc13

    Right … its gcc13 and not gcc

    Lets create the gcc link that points to gcc13 then.

    # ln -s /usr/local/bin/gcc13 /usr/local/bin/gcc
    
    # /bin/ls -l /usr/local/bin/gcc
    lrwxr-xr-x  1 root wheel 20 Mar 11 07:27 /usr/local/bin/gcc -> /usr/local/bin/gcc13
    

    Lets try again …

    neovim.setup.gcc

    Seems that it worked. All modules fetched/built/configured successfully as shown below.

    neovim.setup.complete

    Lets now check how it runs with some Ansible YAML file.

    neovim.YAML.before

    Seems that its processing it …

    neovim.YAML.after

    Yeah … a lot of hints for a start … sounds kinda like Clippy from some oldschool Office suite.

    clippy

    … always helpful with a bunch of hints 🙂

    The same Ansible playbook after applying the suggestions.

    neovim.YAML.fixed

    Seems like fixed.

    Now … lets revoke the GNU make(1) change.

    ~ # cd /usr/bin
    /usr/bin # rm make
    /usr/bin # mv make.FreeBSD make
    

    I tried to submit this behavior as issue on LuaSnip page – https://github.com/L3MON4D3/LuaSnip/issues/1140 – but no reaction till now.

    Alternatives

    Before I got this config I tried to setup plain vim(1) as Ansible oriented setup … and to be honest it also works quite well for me. It’s also calmer as the Clippy is not available here and does not share its thoughts all the time.

    vim.config

    Seems pretty decent. The completion also works – but its limited and based on file contents. One may overcome that with opening TWO files at once each time to edit an Ansible playbook. The first file would be the one You want to edit – the second one would be prepared Ansible playbook that contains all modules and all options for these modules … of course the completion would not be per module aware but still – somewhat helpful. Below is simple vim(1) completion spawned by [CTRL]+[N] (also known as ^n in UNIX notation) shortcut in INSERT mode.

    vim.config.completions

    … and Neovim completion for comparison with the same shortcut used.

    neovim.server.completion

    It is very simple and basic vim(1) config w/o any additional modules or plugins – just plain ~/vimrc file.

    % cat ~/.vimrc
    " -- GENERAL --------------------------------------------------------------- "     
      syntax on                                                                            
      set nomodeline                                                                                                                                                
      set nocompatible                                                                                                                                              
      set backspace=indent,eol,start                                                                                                                                
      set autoindent                                                                                                                                                
      set nobackup                                                                                                                                                  
      set cursorline                                                                                                                                                
      set number                                                                                                                                                    
      set nowrap                                                                                                                                                    
      set history=32                                                                                                                                                
      set ignorecase                                                                                                                                                
      set showcmd                                                                                                                                                   
      set incsearch
      set hlsearch
      set tabstop=2
      set shiftwidth=2
      set softtabstop=2
      set shiftwidth=2
      set expandtab 
      set ruler
      set mouse-=a
      highlight ColorColumn ctermbg=0 guibg=blue
      let &colorcolumn="100,".join(range(100,999),",")
      let g:indentLine_char = '¦' 
    
    " -- DISABLE ~/.viminfo FILE ----------------------------------------------- "
      let skip_defaults_vim=1
      set viminfo=""
    
    " -- COMMANDS -------------------------------------------------------------- "
      command WQ wq
      command Wq wq
      command W  w
      command Q  q
    
    

    I am also a big fan of Geany IDE/editor (depending on how you configure it) and its also a good companion in the Ansible world.

    geany.YAML

    Summary

    Hope that this Neovim config would help You in your daily Ansible work … and let me know it now and why 🙂

    Regards.

    UPDATE 1 – Lua and General Purpose Language Servers

    After I opened some Lua config in this nvim(1) config it welcomed me with this message below.

    neovim.lua.efm

    So I started to dig this topic … and as as result added both lua-language-server and efm-langserver servers to this config.

    Lua Language Server

    While initial research did not encouraged – https://github.com/LuaLS/lua-language-server/issues/2361 – I manged to omit the tests that are broken on FreeBSD … and the lua-language-server seems to just work.

    Below are build/install instructions.

    # pkg install ninja
    
    % git clone https://github.com/LuaLS/lua-language-server.git
    
    % cd lua-language-server
    
    % :> 3rd/bee.lua/test/test.lua
    
    % :> test.lua
    
    % ./make.sh
    
    % ./bin/lua-language-server
    Content-Length: 120
    
    {"jsonrpc":"2.0","method":"$/status/report","params":{"text":"Lua","tooltip":"Cached files: 0/0\nMemory usage: 2M"}}
    

    Seems to work – will now copy to my preferred ${PATH} place – feel free to choose your own different place.

    % cp bin/lua-language-server ~/scripts/bin
    
    % rm -rf ~/lua-language-server
    

    General Purpose Language Server

    … and now the efm-langserver part.

    # pkg install go gmake
    
    % git clone https://github.com/mattn/efm-langserver.git
    
    % cd efm-langserver
    
    % gmake
    
    % ./efm-langserver
    2024/03/14 07:54:26 efm-langserver: no configuration file
    2024/03/14 07:54:26 efm-langserver: reading on stdin, writing on stdout
    

    Seems to work – now the install part as previously.

    % cp efm-langserver ~/scripts/bin
    
    % rm -rf ~/efm-langserver
    

    … and now Neovim starts and behaves properly.

    neovim.lua.efm.works

    Regards.

    EOF
    • chevron_right

      Trying to get Movim running at home...

      Roelof Pieter · Tuesday, 16 May, 2017 - 20:22 edit · 3 minutes

    This is a description of the problems I encountered when trying to install a Movim "compatible" XMPP server. This is mainly a reminder to myself, in case I want to try again in some time. I have written this in afterwards, and some of the details have blurred. Be skeptical of everything you read here :-)

    #movim #ejabberd #prosody

    So, I've been trying to get a complete Movim "suite" running on my Raspberry Pi @ home. For me this means running the following components:

    1. Movim itself
    2. A web server for presenting the Movim interface (Nginx)
    3. A database server for storing Movim "stuff" (MySQL/MariaDB )
    4. A XMPP server for the actual transportation of messages and storage of "content"

    I did already have Nginx and MySQL running. Installing Movim was quite straightforward, thanks to the instructions in the wiki. Also, I had already implemented things like DNS (a .nl domain through Yourhosting) and encryption using Letsencrypt. The tough nut to crack here is the XMPP server. I haven't been able to get this running in a way that I can fully enjoy Movim.

    First up: Prosody.

    I already had Prosody running as an alternative to the evil "Whatsapp". I use it mainly for chatting with my wife, who of course also has a Whatsapp account. She always looks a bit weary of me when we use Conversations. So, since it was already there, I tried this first. Despite the warnings that it has some drawbacks. Well, it works fine as a chat client, but the "news" section is disabled. The configuration section tells me that Movim is working in a "degraded" mode. Trying to get it running has at least had me configure http_upload (XEP-0363) so file uploading works better now.

    Next Ejabberd (Version 15.X)

    So, use my Raspberry Pi for many things. It's main purpose however is running as a media-center running Kodi. For this reason I have installed OSMC as it's operating system. It is basically Raspbian, optimized for playing media. Being based on Raspbian it means there are a lot of packages available. Amongst them Ejabberd, albeit in an old version (14.07) . I installed Ejabberd and disabled prosody. After plowing through the terrible configuration file* (in Yaml, which was new for me) in the end I finally had it running. Chat works and Movim appears in it's full glory (with "News"). The only thing missing is the ability to upload files/photo's to it. But hey, there is a module for that. I couldn't get it running though. A lot of scary errors, that I forgot to write down though :-( . I Googled a lot (well Duckduckgo'd) but the suggested configurations all led to an error and a crash of Ejabberd. So, this was no good either.

    Finally, Ejabberd (17.04) from source

    As there was no later version of Ejabberd as a package available, I decided to just download the source of more recent version of Ejabberd. After remembering how this compiling goes, I did a "./configure --enable-user ejabberd & make & make install". Installation was fine. But here also I have a problem with mod_http_upload. Gajim, which I use for testing my XMPP account, with the http-upload-plugin recognizes the possibility to upload a file. I see in the logging that the upload request reaches the server and is processed, without error by the server, but the file doesn't seem to end up anywhere on the server. Gajim just tells me there is a HTTP error. Conversations only tells me the upload has failed. I spent several hours trying different combinations of configurations, mainly trying alternating docroots, but to no avail.

    So, nope... (for now)

    So, by now I have given up for now. Perhaps I will try Ejabberd later again. With some more luck I might succeed. I have prosody running again, for chatting with my wife. If I understand correct, in the next version 0.10 (or the next 0.11) Pep persistence might be available in prosody, making it run better with Movim.

    • ) Yes, I know there is a web-interface but I found the screen shots not very promising. I go the impression it was mainly for day-to-day administration, and not for setting the damn thin up. And, it more easy and therefore not nearly as cool :-) .