• 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
    • Wa chevron_right

      Git Hooks

      pubsub.slavino.sk / warlord0blog · Monday, 5 December, 2022 - 08:27 edit

    I wanted to ensure I wasn’t pushing unencrypted data onto our Git repo. It’s set as private anyhow, but the repo I’m using is for our Ansible library. It contains all kinds of details about the builds of equipment and software delivery, that would be a risk. How do I ensure that I don’t push &ellipsisRead the full post »

    Značky: #Linux, #ansible, #Uncategorized, #git

    • Sl chevron_right

      How to lookup specific element in Ansible dictionary or list of these

      pubsub.slavino.sk / sleeplessbestie · Monday, 26 September, 2022 - 11:00 edit

    Lookup specific element in Ansible dictionary or list of these. Sample playbook to look for elements from elements_to_look_for in first_variable, second_variable and third_variable. $ cat playbook.yml --- - hosts: localhost vars: elements_to_look_for: - alpha - beta - gamma - delta first_variable: - key: beta value: beta_value - key: gamma value: gamma_value - key: delta value: […]

    Značky: #DevOps, #Linux, #Ansible

    • Wa chevron_right

      polkit-error-quark

      pubsub.slavino.sk / warlord0blog · Friday, 4 March, 2022 - 18:02 edit

    I caused myself a few hours of frustration today. I installed a new instance of Manjaro today, and it applied some Lynis security suggestions that I didn’t fully realise the impact of. Error registering authentication agent: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: Cannot determine user of subject (polkit-error-quark, 0) When I went to run pamac to install Visual Studio Code &ellipsisRead the full post »

    Značky: #ansible, #Linux, #manjaro, #security

    • Sl chevron_right

      How to execute multiple Ansible tasks once per group

      pubsub.slavino.sk / sleeplessbestie · Friday, 28 January, 2022 - 07:00 edit

    Execute multiple Ansible tasks once per group and use a dedicated variable to store custom data. Define hosts that will contain multiple application clusters. $ cat hosts [application:children] application_cluster_development application_cluster_production [application_cluster_development] dev_server_1 ansible_host=127.0.0.1 dev_server_2 ansible_host=127.0.0.1 dev_server_3 ansible_host=127.0.0.1 [application_cluster_production] prod_server1 ansible_host=127.0.0.1 prod_server2 ansible_host=127.0.0.1 prod_server3 ansible_host=127.0.0.1 Define per cluster configuration. $ cat group_vars/application_cluster_production/application_cluster.yml --- cluster_items: - name: […]

    Značky: #Linux, #DevOps, #Ansible

    • Li chevron_right

      How to Clone a Git Repository with Ansible

      pubsub.slavino.sk / linuxhandbook.com · Monday, 28 June, 2021 - 13:41 edit

    Need to clone a Git repo on the remote node in your Ansible setup? Here's how to do that.

    Značky: #Linux, #Ansible

    • Wa chevron_right

      Ansible and Linux Mint

      pubsub.slavino.sk / warlord0blog · Thursday, 10 June, 2021 - 20:32 edit

    When running an Ansible playbook on a Linux Mint host I found that the variable distribution_release returned the Mint code name of ulyssa. This isn’t very helpful with adding things like hte docker repository as that needs the underlying Ubuntu codename. To get the Ubuntu code name I resorted to reading the /etc/os-releases file. This &ellipsisRead the full post »

    Značky: #ansible, #Linux

    • Wa chevron_right

      Installing Ansible Public Key Not Available

      pubsub.slavino.sk / warlord0blog · Monday, 30 November, 2020 - 13:02 edit

    When trying to install Ansible on Debian following the install guide here: https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-debian We get an error: Then the apt install fails with the expected NO_PUBKEY error. I don’t know why it fails to find it this way as the workaround resolves the issue using the same key from the same server by adding it &ellipsisRead the full post »

    Značky: #ansible, #Linux

    • Wa chevron_right

      Installing Ansible AWX

      pubsub.slavino.sk / warlord0blog · Monday, 14 September, 2020 - 09:57 edit

    Starting to look at a nice front end for Ansible and found a few quirks with the process that need to be taken care of. The actual installation of AWX needs Ansible installing on the system you’re installing from. As I’m installing from localhost to localhost this means I need Ansible installed locally. Sounds obvious, &ellipsisRead the full post »

    Značky: #ansible, #Linux, #docker