Darwin.configure vim.yml

#!/usr/bin/env ansible-playbook
#
# Copyright © 2025 Florent Claerhout.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

- name: "Vim is configured"
  hosts: "all"

  vars:
    ##
    ## HEADS UP!
    ## variables defined here take precedence over inventory variables;
    ## keep user-defined/able variables commented out.
    ## Use set_fact + | default if a default value is needed.
    ##
    vim_is_small_version: false
    vim_rc_rdir: "{{ ansible_env.HOME }}/.vim"
    vim_settings:
      default:
        rfile: "{{ ansible_env.HOME }}/.vimrc"
        draw_white_space: true
        expand_tabs_to_spaces: false
        font_face: "Source Code Pro"
        font_size: 13
        show_line_numbers: true
        tab_size: 4
        wrap_lines: false
      groovy:
        rfile: "{{ vim_rc_rdir }}/after/ftplugin/groovy.vim"
        expand_tabs_to_spaces: false
        tab_size: 4
      json:
        rfile: "{{ vim_rc_rdir }}/after/ftplugin/json.vim"
        expand_tabs_to_spaces: false
        tab_size: 4
      makefile:
        rfile: "{{ vim_rc_rdir }}/after/ftplugin/make.vim"
        expand_tabs_to_spaces: false
        tab_size: 4
      python:
        rfile: "{{ vim_rc_rdir }}/after/ftplugin/python.vim"
        expand_tabs_to_spaces: true
        tab_size: 4
      yaml:
        rfile: "{{ vim_rc_rdir }}/after/ftplugin/yaml.vim"
        expand_tabs_to_spaces: true
        tab_size: 2

  handlers: []

  tasks:

    - name: "Vim configuration directories are present"
      with_dict: "{{ vim_settings }}"
      file:
        path: "{{ item.value.rfile | dirname }}"
        state: "directory"
        mode: "0755"

    # REF: http://vimdoc.sourceforge.net/htmldoc/options.html
    # " background=light|dark [default: dark]
    # "   When set to "dark", Vim will try to use colors that look good on a
    # "   dark background.  When set to "light", Vim will try to use colors that
    # "   look good on a light background.
    # " display= [default: ""]
    # "   This is comma separated list of flags:
    # "   lastline: When included, as much as possible of the last line
    # "             in a window will be displayed.  When not included, a
    # "             last line that doesn't fit is replaced with "@" lines.
    # "   uhex:     Show unprintable characters hexadecimal as <xx>
    # "             instead of using ^C and ~C.
    - name: "Vim files for configured supported formats are present"
      with_dict: "{{ vim_settings }}"
      copy:
        content: |
          " THIS IS A GENERATED FILE -- DO NOT EDIT.
          {% if item.key == "default" %}
          {% if not vim_is_small_version %}
          filetype plugin on
          {% endif %}
          " [no]ruler
          "   Show the line and column number of the cursor position, separated by a
          "   comma.  When there is room, the relative position of the displayed
          "   text in the file is shown on the far right:
          "      Top first line is visible
          "      Bot last line is visible
          "      All first and last line are visible
          "      45% relative position in the file
          set ruler
          set viminfo=
          set noswapfile
          {% if not vim_is_small_version %}
          syntax on
          {% endif %}
          {% set setter = "set" %}
          {% else %}
          {% set setter = "setlocal" %}
          {% endif %}
          {% if item.value.draw_white_space is defined %}
          " list
          "   List mode: Show tabs as CTRL-I is displayed, display $ after end of
          "   line.  Useful to see the difference between tabs and spaces and for
          "   trailing blanks.  Further changed by the 'listchars' option.
          {% if item.value.draw_white_space %}
          {{ setter }} list
          {{ setter }} listchars=tab:→\ ,trail:·,nbsp:_
          {% else %}
          {{ setter }} nolist
          {% endif %}
          {% endif %}
          {% if item.value.expand_tabs_to_spaces is defined %}
          " expandtab
          "   In Insert mode: Use the appropriate number of spaces to insert a
          "   <Tab>.  Spaces are used in indents with the '>' and '<' commands and
          "   when 'autoindent' is on.  To insert a real tab when 'expandtab' is
          "   on, use CTRL-V<Tab>.
          {{ setter }} {{ "expandtab" if item.value.expand_tabs_to_spaces else "noexpandtab" }}
          {% endif %}
          {% if item.value.show_line_numbers is defined %}
          " [no]number
          "   Print the line number in front of each line.
          {% if item.value.show_line_numbers %}
          {{ setter }} number
          {% else %}
          {{ setter }} nonumber
          {% endif %}
          {% endif %}
          {% if item.value.tab_size is defined %}
          " tabstop=INT [default: 8]
          "   Number of spaces that a <Tab> in the file counts for.
          {{ setter }} tabstop={{ item.value.tab_size | int }}
          {{ setter }} shiftwidth={{ item.value.tab_size | int }}
          {% endif %}
          {% if item.value.wrap_lines is defined %}
          " [no]wrap
          "   When on, lines longer than the width of the window will wrap and
          "   displaying continues on the next line.  When off lines will not wrap
          "   and only part of long lines will be displayed.  When the cursor is
          "   moved to a part that is not shown, the screen will scroll
          "   horizontally.
          {{ setter }} {{ "wrap" if item.value.wrap_lines else "nowrap" }}
          {% endif %}
        dest: "{{ item.value.rfile }}"
        mode: "0644"