diff --git a/.ansible-lint b/.ansible-lint deleted file mode 100644 index e99d805..0000000 --- a/.ansible-lint +++ /dev/null @@ -1,5 +0,0 @@ -parseable: true -quiet: true -skip_list: - - '501' -use_default_rules: true diff --git a/.gitignore b/.gitignore index c17815f..ad2ea9f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ node_modules/ .vaults/ vault vaults/ + +roles/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 369b1c8..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,42 +0,0 @@ -stages: - - lint - - test - -cache: - key: "$CI_COMMIT_REF_SLUG" - paths: - - .cache/pip - - node_modules/ - -lint: - stage: lint - image: python:3.7 - before_script: - - pip install ansible ansible-lint --quiet - script: - - ansible-lint playbook.yml - only: - refs: - - development - - merge_requests - -pretty-lint: - stage: lint - image: node:12 - before_script: - - npm install - script: - - npx prettier "**/*.yml" --check - only: - refs: - - development - - merge_requests - -syntax-test: - stage: test - image: python:3.7 - before_script: - - pip install ansible ansible-lint --quiet - - ansible-galaxy install -r roles/requirements.yml - script: - - ansible-playbook playbook.yml --syntax-check diff --git a/.prettier.json b/.prettier.json deleted file mode 100644 index 9c76f6b..0000000 --- a/.prettier.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "singleQuote": true, - "printWidth": 90, - "tabWidth": 2, - "useTabs": false, - "bracketSpacing": true, - "parser": "yaml" -} - diff --git a/ansible.cfg b/ansible.cfg index 002a50d..ccea318 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,2 +1,6 @@ [defaults] roles_path = ./roles +inventory = inventory.yml + +[privilege_escalation] +become_ask_pass = True diff --git a/files/desktop/docker-daemon.json b/files/desktop/docker-daemon.json new file mode 100644 index 0000000..705c4d0 --- /dev/null +++ b/files/desktop/docker-daemon.json @@ -0,0 +1,3 @@ +{ + "data-root": "/mnt/docker" +} diff --git a/files/nvim.conform.lua b/files/nvim.conform.lua new file mode 100644 index 0000000..801df29 --- /dev/null +++ b/files/nvim.conform.lua @@ -0,0 +1,14 @@ +-- example of a project specific nvim configuration file using :exrc and conform + +local conform = require 'conform'; + +conform.setup { + formatters_by_ft = { + python = { 'isort', 'black' }, + javascript = { 'prettier', }, + }, + + format_on_save = { + lsp_format = 'never', + } +} diff --git a/files/nvim.lsp.lua b/files/nvim.lsp.lua new file mode 100644 index 0000000..ff06a44 --- /dev/null +++ b/files/nvim.lsp.lua @@ -0,0 +1,33 @@ +-- example of a project specific nvim configuration file using :exrc and lsp formatting + +local format_clients = { + 'ruff', + 'lua_ls', + 'bashls', + 'jsonls', + 'ts_ls', + 'ansiblels', + 'yamlls', + 'cssls', + 'html', +} + +vim.api.nvim_create_autocmd('LspAttach', { + group = vim.api.nvim_create_augroup('lsp', { clear = true }), + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + + if client:supports_method('textDocument/formatting') + and vim.tbl_contains(format_clients, client.name) then + vim.api.nvim_create_autocmd('BufWritePre', { + buffer = args.buf, + callback = function() + vim.lsp.buf.format { + async = false, + id = args.data.client_id + } + end, + }) + end + end +}) diff --git a/files/tmux.sh b/files/tmux.sh new file mode 100755 index 0000000..d98c41b --- /dev/null +++ b/files/tmux.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +session_name=${PWD##*/} +project_directory="$HOME/development/$session_name" + +tmux has-session -t $session_name + +if [ $? != 0 ]; +then + tmux new-session \ + -c $project_directory \ + -ds $session_name \ + -e "project_dir=$project_directory" + + # FIRST WINDOW + tmux send-keys -t $session_name:0 'source ./env/bin/activate' C-m + tmux send-keys -t $session_name:0 'nvim' C-m + + # SECOND WINDOW + tmux new-window -t $session_name + + # THIRD WINDOW + tmux new-window -t $session_name + + # FOURTH WINDOW + tmux new-window -t $session_name + + # SELECT DEFAULT PANE AFTER OPENING + tmux select-window -t $session_name:0 +fi + +tmux attach -t $session_name diff --git a/group_vars/all/git.yml b/group_vars/all/git.yml new file mode 100644 index 0000000..4715cd3 --- /dev/null +++ b/group_vars/all/git.yml @@ -0,0 +1,7 @@ +dotfiles_repo: 'git@forgejo.fudiggity.nl:sonny/dotfiles.git' + +git_domain: 'forgejo.fudiggity.nl' +git_host_key: 'forgejo.fudiggity.nl ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBqEej87ukSK7KGi7e0q+oTrru4h7Fm6fK8GgiMtu01+' + +git_name: Sonny Bakker +git_email: sonny871@hotmail.com diff --git a/group_vars/all/neovim.yml b/group_vars/all/neovim.yml new file mode 100644 index 0000000..e67edd3 --- /dev/null +++ b/group_vars/all/neovim.yml @@ -0,0 +1,50 @@ +neovim_plugins: + - url: 'https://forgejo.fudiggity.nl/sonny/source-link.lua' + name: 'source-link' + - url: 'https://github.com/nvim-tree/nvim-tree.lua' + name: 'nvim-tree' + - url: 'https://github.com/nvim-tree/nvim-web-devicons' + name: 'nvim-tree-icons' + - url: 'https://github.com/neovim/nvim-lspconfig' + name: 'nvim-lspconfig' + - url: 'https://github.com/hrsh7th/nvim-cmp' + name: 'nvim-cmp' + - url: 'https://github.com/hrsh7th/cmp-buffer' + name: 'cmp-buffer' + - url: 'https://github.com/hrsh7th/cmp-path' + name: 'cmp-path' + - url: 'https://github.com/hrsh7th/cmp-omni' + name: 'cmp-omni' + - url: 'https://github.com/hrsh7th/cmp-nvim-lsp' + name: 'cmp-nvim-lsp' + - url: 'https://github.com/hrsh7th/cmp-nvim-lua' + name: 'cmp-nvim-lua' + - url: 'https://github.com/nvim-treesitter/nvim-treesitter' + name: 'nvim-treesitter' + version: master # main seems broken? + - url: 'https://github.com/nvim-lua/plenary.nvim' + name: 'plenary.nvim' + - url: 'https://github.com/nvim-telescope/telescope-fzf-native.nvim' + name: 'telescope-fzf-native.nvim' + - url: 'https://github.com/nvim-telescope/telescope.nvim' + name: 'telescope.nvim' + version: '0.1.x' + - url: 'https://github.com/L3MON4D3/LuaSnip' + name: 'luasnip' + version: 'v1.0.0' + - url: 'https://github.com/lewis6991/gitsigns.nvim' + name: 'gitsigns.nvim' + version: 'v0.9.0' + - url: 'https://github.com/nvim-lualine/lualine.nvim' + name: 'lualine' + - url: 'https://github.com/lukas-reineke/indent-blankline.nvim' + name: 'indent-blankline.nvim' + version: 'v3.7.2' + - url: 'https://github.com/projekt0n/github-nvim-theme.git' + name: 'github-colors' + version: 'v1.1.2' + - url: 'https://github.com/stevearc/conform.nvim.git' + name: 'conform.nvim' + version: 'v9.0.0' + +language_servers: [] diff --git a/group_vars/all/system.yml b/group_vars/all/system.yml new file mode 100644 index 0000000..f57d500 --- /dev/null +++ b/group_vars/all/system.yml @@ -0,0 +1,4 @@ +xdg_config_dir: '{{ ansible_env.HOME }}/.config' +xdg_data_dir: '{{ ansible_env.HOME }}/.local/share' + +packages: [] diff --git a/group_vars/arch/aur.yml b/group_vars/arch/aur.yml new file mode 100644 index 0000000..6f1c646 --- /dev/null +++ b/group_vars/arch/aur.yml @@ -0,0 +1,40 @@ +aur_packages: + - url: 'https://aur.archlinux.org/nvm.git' + name: 'nvm' + package_name: 'nvm' + version: '0.40.0-1' + arch: 'any' + +aur_build_dir: '/usr/local/src' +python_build_dir: '/usr/local/src' +python_install_dir: '/opt' + +python_download_url: 'https://www.python.org/ftp/python' +python_versions: + - version: 3.12.9 + path: 'python3.12' + binary: 'python3.12' + + - version: 3.11.9 + path: 'python3.11' + binary: 'python3.11' + + - version: 3.10.0 + path: 'python3.10' + binary: 'python3.10' + + - version: 3.9.14 + path: 'python3.9' + binary: 'python3.9' + + - version: 3.8.14 + path: 'python3.8' + binary: 'python3.8' + + - version: 3.7.14 + path: 'python3.7' + binary: 'python3.7' + + - version: 3.6.15 + path: 'python3.6' + binary: 'python3.6' diff --git a/group_vars/arch/neovim.yml b/group_vars/arch/neovim.yml new file mode 100644 index 0000000..de53353 --- /dev/null +++ b/group_vars/arch/neovim.yml @@ -0,0 +1,48 @@ +language_servers: + - package: ansible-language-server + server_name: 'ansiblels' + auto_setup: true + + - package: typescript-language-server + server_name: 'ts_ls' + auto_setup: true + + - package: vscode-json-languageserver + server_name: 'jsonls' + auto_setup: true + + - package: vscode-css-languageserver + server_name: 'cssls' + auto_setup: true + + - package: bash-language-server + server_name: 'bashls' + auto_setup: true + + - package: marksman + server_name: 'marksman' + auto_setup: true + + - package: esbonio + server_name: 'esbonio' + auto_setup: true + + - package: lua-language-server + server_name: 'lua_ls' + auto_setup: false + + - package: yaml-language-server + server_name: 'yamlls' + auto_setup: false + + - package: vscode-html-languageserver + server_name: 'html' + auto_setup: false + + - package: ruff-lsp + server_name: 'ruff' + auto_setup: false + + - package: pyright + server_name: 'pyright' + auto_setup: false diff --git a/group_vars/arch/system.yml b/group_vars/arch/system.yml new file mode 100644 index 0000000..3bab5fb --- /dev/null +++ b/group_vars/arch/system.yml @@ -0,0 +1,23 @@ +packages: + - python + - git + - vim + - neovim + - python-pynvim + - wl-clipboard + - npm + - docker + - docker-compose + - iptables-nft + - fuse-overlayfs + - ttf-ibm-plex + - slirp4netns + - tree-sitter + - ripgrep + - fd + - uv + - fakeroot + - debugedit + - which + - gcc + - make diff --git a/group_vars/debian/neovim.yml b/group_vars/debian/neovim.yml new file mode 100644 index 0000000..af2c892 --- /dev/null +++ b/group_vars/debian/neovim.yml @@ -0,0 +1,18 @@ +# TODO: add lua language server, see https://github.com/LuaLS/lua-language-server? +language_servers: + - package: "@ansible/ansible-language-server" + server_name: "ansiblels" + auto_setup: true + + - package: yaml-language-server + server_name: "yamlls" + auto_setup: false + + - package: bash-language-server + server_name: "bashls" + auto_setup: true + +neovim: + version: "v0.11.4" + install_path: "/opt/nvim" + download_checksum: sha256:a74740047e73b2b380d63a474282814063d10650cd6cc95efa16d1713c7e616c diff --git a/group_vars/debian/system.yml b/group_vars/debian/system.yml new file mode 100644 index 0000000..56be4aa --- /dev/null +++ b/group_vars/debian/system.yml @@ -0,0 +1,7 @@ +packages: + - python3 + - git + - vim + - npm + - libtree-sitter0 + - ripgrep diff --git a/inventory.yml b/inventory.yml new file mode 100644 index 0000000..7ebdbcf --- /dev/null +++ b/inventory.yml @@ -0,0 +1,27 @@ +personal: + hosts: + xps: &xps + ansible_connection: local + ansible_become_method: community.general.run0 + desktop: &desktop + ansible_connection: local + ansible_become_method: community.general.run0 + htpc: &htpc + ansible_connection: local + ansible_become_method: community.general.run0 + fudiggity: &fudiggity + ansible_connection: local + +debian: + hosts: + fudiggity: + <<: *fudiggity + +arch: + hosts: + xps: + <<: *xps + desktop: + <<: *desktop + htpc: + <<: *htpc diff --git a/playbook.yml b/playbook.yml index e1c5273..8ab70f7 100644 --- a/playbook.yml +++ b/playbook.yml @@ -1,3 +1,71 @@ -- hosts: localhost - roles: - - development +- name: Development provisioning + hosts: + - personal + - arch + - debian + pre_tasks: + - name: Verifying that a limit is set + ansible.builtin.fail: + msg: 'This playbook cannot be run with no limit' + run_once: true + when: ansible_limit is not defined + + - name: Install packages + become: true + ansible.builtin.package: + name: '{{ item }}' + state: present + loop: '{{ packages }}' + + - name: Add git forge to known hosts + ansible.builtin.include_role: + name: common + tasks_from: 'known_hosts.yml' + vars: + user: '{{ ansible_user_id }}' + items: + - domain: '{{ git_domain }}' + key: '{{ git_host_key }}' + when: ansible_hostname != 'fudiggity' + tasks: + - name: Setup dotfiles + ansible.builtin.import_tasks: 'tasks/dotfiles.yml' + tags: dotfiles + + - name: Include generic neovim tasks + ansible.builtin.import_tasks: 'tasks/neovim.yml' + tags: neovim + + - name: Include debian neovim tasks + ansible.builtin.import_tasks: 'tasks/debian/neovim.yml' + when: "'debian' in group_names" + tags: neovim + + - name: Provision Archlinux hosts + when: "'arch' in group_names" + block: + - name: Gather package facts + ansible.builtin.package_facts: + manager: pacman + + - name: Include arch neovim tasks + ansible.builtin.import_tasks: 'tasks/arch/neovim.yml' + when: "'arch' in group_names" + tags: neovim + + - name: Install AUR packages + ansible.builtin.import_tasks: 'tasks/arch/aur.yml' + tags: aur + + - name: Setup docker + ansible.builtin.import_tasks: 'tasks/arch/docker.yml' + tags: docker + + - name: Setup python versions + ansible.builtin.include_tasks: 'tasks/arch/python.yml' + loop: '{{ python_versions }}' + tags: python + + - name: Setup NVM + ansible.builtin.import_tasks: 'tasks/arch/nvm.yml' + tags: nvm diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..b20eeb6 --- /dev/null +++ b/requirements.yml @@ -0,0 +1,4 @@ +- src: git+https://forgejo.fudiggity.nl/sonny/common-ansible.git + name: common + version: master + scm: git diff --git a/roles/.gitignore b/roles/.gitignore deleted file mode 100644 index 906efb0..0000000 --- a/roles/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# ignore all external roles and files in the roles dir -/* - -!.gitignore -!requirements.yml -!development*/ diff --git a/roles/development/defaults/main.yml b/roles/development/defaults/main.yml deleted file mode 100644 index 4699b1b..0000000 --- a/roles/development/defaults/main.yml +++ /dev/null @@ -1,17 +0,0 @@ -packages: [] - -xdg_config_dir: "{{ ansible_env.HOME }}/.config" -xdg_data_dir: "{{ ansible_env.HOME }}/.local/share" - -dotfiles_repo: "git@git.fudiggity.nl:sonny/dotfiles.git" -githook_repo: "git@git.fudiggity.nl:sonny/git-hooks.git" - -vim_plugins: - - { url: "https://github.com/preservim/nerdtree", name: "nerdtree" } - - { url: "https://github.com/neoclide/coc.nvim", name: "coc.nvim" } - - { url: "https://github.com/sheerun/vim-polyglot", name: "vim-polygot" } - -poetry_packages: - - black - - pylint - - autoflake diff --git a/roles/development/handlers/main.yml b/roles/development/handlers/main.yml deleted file mode 100644 index 8b13789..0000000 --- a/roles/development/handlers/main.yml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/roles/development/meta/main.yml b/roles/development/meta/main.yml deleted file mode 100644 index 815c5da..0000000 --- a/roles/development/meta/main.yml +++ /dev/null @@ -1,20 +0,0 @@ -dependencies: - - npm - -galaxy_info: - author: sonny - description: "Sets up development environment" - license: "license GPLv3" - min_ansible_version: 2.7 - issue_tracker_url: "https://git.fudiggity.nl/sonny/ansible-playbooks/-/issues" - platforms: - - name: Debian - versions: - - buster - - name: Ubuntu - versions: - - focal - - name: Archlinux - galaxy_tags: - - development - - system diff --git a/roles/development/tasks/coc.yml b/roles/development/tasks/coc.yml deleted file mode 100644 index f8e4166..0000000 --- a/roles/development/tasks/coc.yml +++ /dev/null @@ -1,33 +0,0 @@ -- name: install coc.nvim node packages - npm: - path: "{{ xdg_data_dir }}/nvim/site/pack/default/start/coc.nvim" - state: present - global: false - -- name: create default coc.nvim venv directory - file: - path: "{{ ansible_env.HOME }}/.local/lib/coc" - state: directory - mode: "0755" - -- name: copy coc pyproject.toml - template: - src: "pyproject.j2" - dest: "{{ ansible_env.HOME }}/.local/lib/coc/pyproject.toml" - mode: "0644" - force: false - -- name: set default venv python version - command: "poetry env use python3" - args: - chdir: "{{ ansible_env.HOME }}/.local/lib/coc" - environment: - PATH: "{{ ansible_env.HOME }}/.local/bin:{{ ansible_env.PATH }}" - when: ansible_distribution == "Debian" - -- name: install default coc.nvim python packages # noqa 301 - command: "poetry install" - args: - chdir: "{{ ansible_env.HOME }}/.local/lib/coc" - environment: - PATH: "{{ ansible_env.HOME }}/.local/bin:{{ ansible_env.PATH }}" diff --git a/roles/development/tasks/dotfiles.yml b/roles/development/tasks/dotfiles.yml deleted file mode 100644 index d8ee079..0000000 --- a/roles/development/tasks/dotfiles.yml +++ /dev/null @@ -1,53 +0,0 @@ -- name: clone dotfiles - git: - repo: "{{ dotfiles_repo }}" - dest: "{{ ansible_env.HOME }}/dotfiles" - version: master - update: yes - -- name: create dotfile folders - file: - state: directory - mode: "0755" - path: "{{ item }}" - loop: - - "{{ xdg_config_dir }}/nvim" - - "{{ xdg_data_dir }}/nvim/site" - - "{{ xdg_config_dir }}/kitty" - -- name: setup dotfiles - file: - path: "{{ item.dest }}" - src: "{{ item.src }}" - mode: "0755" - state: link - force: true - loop: - - { - src: "{{ ansible_env.HOME }}/dotfiles/nvim/init.vim", - dest: "{{ xdg_config_dir }}/nvim/init.vim", - } - - { - src: "{{ ansible_env.HOME }}/dotfiles/.vimrc", - dest: "{{ ansible_env.HOME }}/.vimrc", - } - - { - src: "{{ ansible_env.HOME }}/dotfiles/.bashrc", - dest: "{{ ansible_env.HOME }}/.bashrc", - } - - { - src: "{{ ansible_env.HOME }}/dotfiles/.profile", - dest: "{{ ansible_env.HOME }}/.profile", - } - - { - src: "{{ ansible_env.HOME }}/dotfiles/nvim/colors", - dest: "{{ xdg_data_dir }}/nvim/site/colors", - } - - { - src: "{{ ansible_env.HOME }}/dotfiles/kitty.conf", - dest: "{{ xdg_config_dir }}/kitty/kitty.conf", - } - - { - src: "{{ ansible_env.HOME }}/dotfiles/.gitignore", - dest: "{{ ansible_env.HOME }}/.gitignore", - } diff --git a/roles/development/tasks/main.yml b/roles/development/tasks/main.yml deleted file mode 100644 index 71e29e4..0000000 --- a/roles/development/tasks/main.yml +++ /dev/null @@ -1,54 +0,0 @@ -- name: load OS specific vars - include_vars: "{{ item }}" - with_first_found: - - files: - - "{{ ansible_distribution|lower }}-{{ ansible_distribution_release|lower }}.yml" - - "{{ ansible_distribution|lower }}.yml" - - "{{ ansible_os_family|lower }}.yml" - paths: - - "{{ role_path }}/vars" - -- name: add gitlab to known hosts - include_role: - name: common - tasks_from: known_hosts.yml - vars: - user: "{{ ansible_user_id }}" - items: - - { domain: "{{ gitlab_domain }}", key: "{{ gitlab_host_key }}" } - -- name: install packages - become: true - package: - name: "{{ item }}" - state: present - loop: "{{ packages }}" - -- name: create development dir - file: - path: "{{ ansible_env.HOME }}/development" - state: directory - mode: "0755" - -- include_tasks: "dotfiles.yml" - -- name: clone git hooks - git: - repo: "{{ githook_repo }}" - dest: "{{ ansible_env.HOME }}/development/git-hooks" - update: true - version: master - -- name: clone neovim packages - git: - repo: "{{ item.url }}" - dest: "{{ xdg_data_dir }}/nvim/site/pack/default/start/{{ item.name }}" - version: master - update: true - loop: "{{ vim_plugins }}" - -- include_role: - name: common - tasks_from: "poetry" - -- include_tasks: coc.yml diff --git a/roles/development/templates/pyproject.j2 b/roles/development/templates/pyproject.j2 deleted file mode 100644 index 71768cc..0000000 --- a/roles/development/templates/pyproject.j2 +++ /dev/null @@ -1,19 +0,0 @@ -# {{ ansible_managed }} {{ ansible_date_time.time }} {{ ansible_date_time.date }} - -[tool.poetry] -name = "coc" -version = "0.1.0" -description = "" -authors = ["Sonny Bakker "] - -[tool.poetry.dependencies] -python = "^3.7" -black = "^19.10b0" -pylint = "^2.5.3" -autoflake = "^1.3.1" - -[tool.poetry.dev-dependencies] - -[build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" diff --git a/roles/development/vars/archlinux.yml b/roles/development/vars/archlinux.yml deleted file mode 100644 index f96720f..0000000 --- a/roles/development/vars/archlinux.yml +++ /dev/null @@ -1,11 +0,0 @@ -packages: - - python - - poetry - - git - - vim - - neovim - - npm - - ctags - - kitty - - docker # TODO add tasks - - docker-compose diff --git a/roles/development/vars/debian-buster.yml b/roles/development/vars/debian-buster.yml deleted file mode 100644 index 6f2abf8..0000000 --- a/roles/development/vars/debian-buster.yml +++ /dev/null @@ -1,10 +0,0 @@ -packages: - - git - - vim - - neovim - - python3 - - python3-pip - - python3-venv - - python3-setuptools - - exuberant-ctags - - apt-transport-https diff --git a/roles/development/vars/main.yml b/roles/development/vars/main.yml deleted file mode 100644 index 63d2cfb..0000000 --- a/roles/development/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -gitlab_domain: "git.fudiggity.nl" -gitlab_host_key: "git.fudiggity.nl ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICNmvcxza79T7JZMkifmquwXH/kMUqDnKs9Oob+JrRvn" diff --git a/roles/development/vars/ubuntu-focal.yml b/roles/development/vars/ubuntu-focal.yml deleted file mode 100644 index da4b45a..0000000 --- a/roles/development/vars/ubuntu-focal.yml +++ /dev/null @@ -1,15 +0,0 @@ -dotfiles_repo: "https://git.fudiggity.nl/sonny/dotfiles.git" -githook_repo: "https://git.fudiggity.nl/sonny/git-hooks.git" - -packages: - - git - - vim - - neovim - - python2 - - python3 - - python3-pip - - python3-venv - - python3-setuptools - - exuberant-ctags - - apt-transport-https - - kitty diff --git a/roles/requirements.yml b/roles/requirements.yml deleted file mode 100644 index 276b569..0000000 --- a/roles/requirements.yml +++ /dev/null @@ -1,8 +0,0 @@ -- src: git+https://git.fudiggity.nl/ansible/common.git - name: common - version: master - scm: git -- src: git+https://git.fudiggity.nl/ansible/npm.git - name: npm - version: master - scm: git diff --git a/tasks/arch/aur-package.yml b/tasks/arch/aur-package.yml new file mode 100644 index 0000000..e00f8ab --- /dev/null +++ b/tasks/arch/aur-package.yml @@ -0,0 +1,53 @@ +- name: Set package directory + ansible.builtin.set_fact: + build_dir: '{{ aur_build_dir }}/{{ item.name }}' + +- name: 'Retrieve package name for {{ item.name }}' + command: + argv: + - grep + - --only-matching + - --perl-regexp + - "(?<=pkgname=).*" + - "{{ build_dir }}/PKGBUILD" + register: pkg_name + +- name: 'Retrieve package version for {{ item.name }}' + command: + argv: + - grep + - --only-matching + - --perl-regexp + - "(?<=pkgver=).*" + - "{{ build_dir }}/PKGBUILD" + register: pkg_version + +- name: 'Retrieve package release for {{ item.name }}' + command: + argv: + - grep + - --only-matching + - --perl-regexp + - "(?<=pkgrel=).*" + - "{{ build_dir }}/PKGBUILD" + register: pkg_release + +- name: Set package filename & version + ansible.builtin.set_fact: + package_filename: '{{ pkg_name.stdout }}-{{ pkg_version.stdout }}-{{ pkg_release.stdout }}-{{ item.arch }}.pkg.tar.zst' + installed_version: ansible_facts.packages[item.package_name].version|default('') + +- name: 'Build package {{ item.name }}' + ansible.builtin.command: 'makepkg --syncdeps --rmdeps --clean --noconfirm --force' + args: + chdir: '{{ build_dir }}' + creates: '{{ build_dir }}/{{ package_filename }}' + register: package_build + when: item.version != installed_version + +- name: 'Install {{ item.name }}' + become: true + community.general.pacman: + name: '{{ build_dir }}/{{ package_filename }}' + state: present + when: item.version != installed_version diff --git a/tasks/arch/aur.yml b/tasks/arch/aur.yml new file mode 100644 index 0000000..e31aab7 --- /dev/null +++ b/tasks/arch/aur.yml @@ -0,0 +1,26 @@ +- name: Retrieve directory stats + ansible.builtin.stat: + path: '{{ aur_build_dir }}/{{ item.name }}' + loop: '{{ aur_packages }}' + +- name: Clone aur packages + become: true + ansible.builtin.git: + repo: '{{ item.url }}' + dest: '{{ aur_build_dir }}/{{ item.name }}' + update: true + loop: '{{ aur_packages }}' + +- name: Change aur package directories owner + become: true + ansible.builtin.file: + path: '{{ aur_build_dir }}/{{ item.name }}' + state: directory + owner: '{{ ansible_user_id }}' + group: '{{ ansible_user_id }}' + recurse: true + loop: '{{ aur_packages }}' + +- name: Build & install aur packages + ansible.builtin.include_tasks: 'tasks/arch/aur-package.yml' + loop: '{{ aur_packages }}' diff --git a/tasks/arch/docker.yml b/tasks/arch/docker.yml new file mode 100644 index 0000000..c68a81f --- /dev/null +++ b/tasks/arch/docker.yml @@ -0,0 +1,66 @@ +- name: Remove docker mapping files + become: true + ansible.builtin.file: + path: '{{ item }}' + state: absent + loop: + - /etc/subgid + - /etc/subuid + +- name: Setup desktop configuration + become: true + ansible.builtin.file: + path: 'files/desktop/docker-daemon.json' + dest: '/etc/docker/daemon.json' + mode: '0755' + when: ansible_hostname == 'desktop' + +- name: Remove user setup desktop configuration + ansible.builtin.file: + path: '{{ xdg_config_dir }}/docker/daemon.json' + state: absent + when: ansible_hostname == 'desktop' + +- name: Check for .bashrc.override + ansible.builtin.stat: + path: '{{ ansible_env.HOME }}/.bashrc.override' + register: bashrc_override + +- name: Create .bashrc.override + ansible.builtin.file: + path: '{{ ansible_env.HOME }}/.bashrc.override' + state: touch + mode: '0755' + when: not bashrc_override.stat.exists + +- name: Remove rootless DOCKER_HOST variable assignment + ansible.builtin.lineinfile: + path: '{{ ansible_env.HOME }}/.bashrc.override' + regexp: '^export DOCKER_HOST=' + line: '' + +- name: Disable user docker socket + ansible.builtin.systemd: + name: '{{ item }}' + state: stopped + enabled: false + scope: user + daemon_reload: true + register: disable_stats + ignore_errors: true # TODO: add better error handling + loop: + - docker.socket + - docker.service + +- name: Remove docker rootless package + become: true + ansible.builtin.package: + name: docker-rootless-extras + state: absent + +- name: Enable system docker socket + become: true + ansible.builtin.systemd: + name: docker.socket + state: started + enabled: true diff --git a/tasks/arch/neovim.yml b/tasks/arch/neovim.yml new file mode 100644 index 0000000..0cccfa1 --- /dev/null +++ b/tasks/arch/neovim.yml @@ -0,0 +1,6 @@ +- name: Install language servers + become: true + community.general.pacman: + name: '{{ item }}' + state: present + loop: '{{ language_servers | map(attribute="package") | list }}' diff --git a/tasks/arch/nvm.yml b/tasks/arch/nvm.yml new file mode 100644 index 0000000..b2f2e36 --- /dev/null +++ b/tasks/arch/nvm.yml @@ -0,0 +1,15 @@ +- name: Set NVM install directory + ansible.builtin.set_fact: + install_dir: '{{ xdg_config_dir }}/nvm' + +- name: Remove manually installed nvm install directory + ansible.builtin.file: + path: '{{ install_dir }}' + state: absent + +- name: Remove nvm entry from bashrc + ansible.builtin.lineinfile: + path: '{{ ansible_env.HOME }}/.bashrc.override' + line: > + [ -s "{{ install_dir }}/nvm.sh" ] && \. "{{ install_dir }}/nvm.sh" # This loads nvm + state: absent diff --git a/tasks/arch/python.yml b/tasks/arch/python.yml new file mode 100644 index 0000000..72bfbff --- /dev/null +++ b/tasks/arch/python.yml @@ -0,0 +1,65 @@ +- name: 'check for {{ item.binary }} binary' + command: 'which {{ item.binary }}' + changed_when: false + failed_when: python_installed.rc not in [ 0, 1 ] + register: python_installed + +- name: 'check for {{ item.binary }} download' + stat: + path: '{{ python_build_dir }}/python-{{ item.version }}.tgz' + register: python_download + +- block: + # TODO: verify for checksum + - name: 'retrieve python {{ item.version }} source' + become: true + get_url: + url: '{{ python_download_url }}/{{ item.version }}/Python-{{ item.version }}.tgz' + dest: '{{ python_build_dir }}/python-{{ item.version }}.tgz' + owner: '{{ ansible_user_id }}' + group: '{{ ansible_user_id }}' + when: not python_download.stat.exists + + - name: 'extract python {{ item.version }} sources' + become: true + unarchive: + src: '{{ python_build_dir }}/python-{{ item.version }}.tgz' + dest: '{{ python_build_dir }}' + include: 'Python-{{ item.version }}' + + - name: rename source directory + become: true + ansible.builtin.command: 'mv {{ python_build_dir}}/Python-{{ item.version }} {{ python_build_dir }}/{{ item.path }}' + + - name: set correct permissions + become: true + file: + path: '{{ python_build_dir }}/{{ item.path }}' + recurse: true + owner: '{{ ansible_user_id }}' + group: '{{ ansible_user_id }}' + state: directory + + - name: configure build + ansible.builtin.command: 'sh ./configure --prefix={{ python_install_dir }}/{{ item.path }}' + args: + chdir: '{{ python_build_dir }}/{{ item.path }}/' + + - name: make build + ansible.builtin.command: 'make' + args: + chdir: '{{ python_build_dir }}/{{ item.path }}/' + + - name: install build + become: true + ansible.builtin.command: 'make install' + args: + chdir: '{{ python_build_dir }}/{{ item.path }}/' + + - name: 'create symlink for python {{ item.version }}' + become: true + file: + src: '{{ python_install_dir }}/{{ item.path }}/bin/{{ item.binary }}' + dest: '/usr/bin/{{ item.binary }}' + state: link + when: python_installed.rc not in [ 0 ] diff --git a/tasks/debian/neovim.yml b/tasks/debian/neovim.yml new file mode 100644 index 0000000..939a741 --- /dev/null +++ b/tasks/debian/neovim.yml @@ -0,0 +1,57 @@ +- name: Install language servers on debian hosts + become: true + community.general.npm: + name: '{{ item }}' + global: true + loop: '{{ language_servers | map(attribute="package") | list }}' + +- name: Create neovim install directory + become: true + ansible.builtin.file: + state: directory + path: '{{ neovim.install_path }}' + owner: '{{ ansible_user_id }}' + group: '{{ ansible_user_gid }}' + mode: '0755' + +- name: Register the current neovim version + ansible.builtin.command: + argv: + - '{{ neovim.install_path }}/bin/nvim' + - '--version' + register: neovim_stats + changed_when: false + ignore_errors: true + +- name: Parse the current neovim version + ansible.builtin.set_fact: + neovim_installed_version: neovim_stats.stdout_lines[0] | regex_search('(v\d+\.\d+\.\d+)') + when: neovim_stats.rc == 0 + +- name: Download neovim {{ neovim.version }} + ansible.builtin.get_url: + url: 'https://github.com/neovim/neovim/releases/download/{{ neovim.version }}/nvim-linux-x86_64.tar.gz' + dest: /tmp/nvim-linux64.tar.gz + mode: '0755' + checksum: '{{ neovim.download_checksum }}' + when: neovim_stats.rc > 0 or neovim_installed_version != neovim.version + register: neovim_download + +- name: Extract downloaded neovim version + ansible.builtin.unarchive: + src: /tmp/nvim-linux64.tar.gz + dest: '{{ neovim.install_path }}' + extra_opts: + - '--strip-components=1' + - '--show-stored-names' + - '--overwrite' + when: | + neovim_download.state == 'file' + and (neovim_installed_version is undefined or neovim_installed_version != neovim.version) + +- name: Add neovim to PATH + become: true + ansible.builtin.template: + src: 'templates/debian/nvim.profile.j2' + dest: '/etc/profile.d/neovim.sh' + mode: '0755' diff --git a/tasks/dotfiles.yml b/tasks/dotfiles.yml new file mode 100644 index 0000000..b8c40e6 --- /dev/null +++ b/tasks/dotfiles.yml @@ -0,0 +1,69 @@ +- name: Clone dotfiles + ansible.builtin.git: + repo: '{{ dotfiles_repo }}' + dest: '{{ ansible_env.HOME }}/dotfiles' + version: master + update: true + +- name: Create xdg configuration directories + ansible.builtin.file: + path: '{{ item }}' + state: directory + mode: '0755' + loop: + - '{{ xdg_config_dir }}/git' + - '{{ xdg_config_dir }}/tmux' + +- name: Remove previous dotfiles + ansible.builtin.file: + path: '{{ item }}' + state: absent + loop: + - '{{ ansible_env.HOME }}/.tmux.conf' + - '{{ ansible_env.HOME }}/.gitconfig' + +- name: Setup dotfiles + ansible.builtin.file: + path: '{{ item.dest }}' + src: '{{ item.src }}' + state: link + force: true + loop: + - src: '{{ ansible_env.HOME }}/dotfiles/.vimrc' + dest: '{{ ansible_env.HOME }}/.vimrc' + + - src: '{{ ansible_env.HOME }}/dotfiles/.bashrc' + dest: '{{ ansible_env.HOME }}/.bashrc' + + - src: '{{ ansible_env.HOME }}/dotfiles/.profile' + dest: '{{ ansible_env.HOME }}/.profile' + + - src: '{{ ansible_env.HOME }}/dotfiles/tmux/tmux.conf' + dest: '{{ xdg_config_dir }}/tmux/tmux.conf' + + - src: '{{ ansible_env.HOME }}/dotfiles/tmux/light.conf' + dest: '{{ xdg_config_dir }}/tmux/light.conf' + + - src: '{{ ansible_env.HOME }}/dotfiles/tmux/dark.conf' + dest: '{{ xdg_config_dir }}/tmux/dark.conf' + + - src: '{{ ansible_env.HOME }}/dotfiles/.gitignore' + dest: '{{ xdg_config_dir }}/git/ignore' + +- name: Copy git configuration + ansible.builtin.template: + src: 'templates/gitconfig.j2' + dest: '{{ xdg_config_dir }}/git/config' + mode: '0755' + +- name: Create script directory + ansible.builtin.file: + path: '{{ ansible_env.HOME }}/.local/bin' + state: directory + mode: '0755' + +- name: Copy tmux toggle script + ansible.builtin.template: + src: 'templates/tmux-toggle.j2' + dest: '{{ ansible_env.HOME }}/.local/bin/tmux-toggle.sh' + mode: '0755' diff --git a/tasks/neovim.yml b/tasks/neovim.yml new file mode 100644 index 0000000..e7de9d5 --- /dev/null +++ b/tasks/neovim.yml @@ -0,0 +1,125 @@ +- name: Ensure neovim configuration directories exist + ansible.builtin.file: + path: '{{ item }}' + state: directory + mode: '0755' + loop: + - '{{ xdg_config_dir }}/nvim/' + - '{{ xdg_config_dir }}/nvim/lua' + - '{{ xdg_config_dir }}/nvim/after' + - '{{ xdg_config_dir }}/nvim/after/ftplugin' + - '{{ xdg_data_dir }}/nvim/site' + - '{{ xdg_data_dir }}/nvim/site/pack' + - '{{ xdg_data_dir }}/nvim/site/pack/default' + - '{{ xdg_data_dir }}/nvim/site/pack/default/start' + +- name: Remove old neovim packages + ansible.builtin.file: + path: '{{ item }}' + state: absent + loop: + - '{{ xdg_data_dir }}/nvim/site/pack/default/start/catpuccin' + - '{{ xdg_data_dir }}/nvim/site/pack/default/start/vim-colors-xcode' + +# Note that helptags may need to be regenerated (see `:h helptags`) +- name: Clone neovim packages + ansible.builtin.git: + repo: '{{ item.url }}' + dest: '{{ xdg_data_dir }}/nvim/site/pack/default/start/{{ item.name }}' + update: true + version: '{{ item.version | default("HEAD") }}' + force: true # some maintainers overwrite existing tags :/ + loop: '{{ neovim_plugins }}' + +- name: Install neovim node package + become: true + community.general.npm: + name: neovim + global: true + +- name: Remove old neovim configuration file + ansible.builtin.file: + path: '{{ xdg_config_dir }}/nvim/init.vim' + state: absent + +- name: Remove coc.nvim extension + ansible.builtin.file: + path: '{{ xdg_data_dir }}/nvim/site/pack/default/start/coc.nvim' + state: absent + +- name: Setup neovim configuration files + ansible.builtin.template: + dest: '{{ item.dest }}' + src: '{{ item.src }}' + mode: '0755' + loop: + - src: 'templates/nvim/ftplugin/bash.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/bash.lua' + + - src: 'templates/nvim/ftplugin/css.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/css.lua' + + - src: 'templates/nvim/ftplugin/html.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/html.lua' + - src: 'templates/nvim/ftplugin/htmldjango.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/htmldjango.lua' + + - src: 'templates/nvim/ftplugin/javascript.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/javascript.lua' + + - src: 'templates/nvim/ftplugin/json.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/json.lua' + + - src: 'templates/nvim/ftplugin/lua.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/lua.lua' + + - src: 'templates/nvim/ftplugin/python.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/python.lua' + + - src: 'templates/nvim/ftplugin/scss.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/scss.lua' + + - src: 'templates/nvim/ftplugin/sh.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/sh.lua' + + - src: 'templates/nvim/ftplugin/yaml.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/after/ftplugin/yaml.lua' + + - src: 'templates/nvim/init.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/init.lua' + + - src: 'templates/nvim/lua/lsp.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/lsp.lua' + + - src: 'templates/nvim/lua/options.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/options.lua' + + - src: 'templates/nvim/lua/tree-sitter.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/tree-sitter.lua' + + - src: 'templates/nvim/lua/git-signs.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/git-signs.lua' + + - src: 'templates/nvim/lua/lua-line.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/lua-line.lua' + + - src: 'templates/nvim/lua/telescope.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/_telescope.lua' + + - src: 'templates/nvim/lua/indent-blankline.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/indent-blankline.lua' + + - src: 'templates/nvim/lua/nvim-tree.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/_nvim-tree.lua' + + - src: 'templates/nvim/lua/colorscheme.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/colorscheme.lua' + + - src: 'templates/nvim/lua/source-link.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/_source-link.lua' + + - src: 'templates/nvim/lua/filetype.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/_filetype.lua' + + - src: 'templates/nvim/lua/diagnostic.lua.j2' + dest: '{{ xdg_config_dir }}/nvim/lua/diagnostic.lua' diff --git a/templates/debian/nvim.profile.j2 b/templates/debian/nvim.profile.j2 new file mode 100644 index 0000000..d424aca --- /dev/null +++ b/templates/debian/nvim.profile.j2 @@ -0,0 +1,3 @@ +# {{ ansible_managed }} + +PATH="{{ neovim.install_path }}/bin:$PATH" diff --git a/templates/gitconfig.j2 b/templates/gitconfig.j2 new file mode 100644 index 0000000..84f97da --- /dev/null +++ b/templates/gitconfig.j2 @@ -0,0 +1,54 @@ +# {{ ansible_managed }} + +[user] +email = {{ git_email }} +name = {{ git_name }} + +[core] +editor = nvim +{% if ansible_facts['os_family'] == 'Archlinux' %} +pager = delta +{% endif %} + +{% if ansible_facts['os_family'] == 'Archlinux' %} +[interactive] +diffFilter = delta --color-only +{% endif %} + +[init] +defaultBranch = main + +[commit] +verbose = true + +[push] +default = simple +autoSetupRemote = true + +[pull] +rebase = false + +[fetch] +prune = true +pruneTags = true +all = true + +[merge] +tool = nvimdiff +conflictstyle = zdiff3 + +[diff] +colorMoved = default +mnemonicPrefix = true +renames = true + +[help] +autocorrect = prompt + +{% if ansible_facts['os_family'] == 'Archlinux' %} +[delta] +navigate = true +hyperlinks = true +line-numbers = true +map-styles = bold purple => syntax magenta, bold cyan => syntax blue, bold yellow => syntax yellow +{% endif %} diff --git a/templates/nvim/ftplugin/bash.lua.j2 b/templates/nvim/ftplugin/bash.lua.j2 new file mode 100644 index 0000000..420fc24 --- /dev/null +++ b/templates/nvim/ftplugin/bash.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 4 +vim.opt.softtabstop = 4 +vim.opt.shiftwidth = 4 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/css.lua.j2 b/templates/nvim/ftplugin/css.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/css.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/html.lua.j2 b/templates/nvim/ftplugin/html.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/html.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/htmldjango.lua.j2 b/templates/nvim/ftplugin/htmldjango.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/htmldjango.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/javascript.lua.j2 b/templates/nvim/ftplugin/javascript.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/javascript.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/json.lua.j2 b/templates/nvim/ftplugin/json.lua.j2 new file mode 100644 index 0000000..420fc24 --- /dev/null +++ b/templates/nvim/ftplugin/json.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 4 +vim.opt.softtabstop = 4 +vim.opt.shiftwidth = 4 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/lua.lua.j2 b/templates/nvim/ftplugin/lua.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/lua.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/python.lua.j2 b/templates/nvim/ftplugin/python.lua.j2 new file mode 100644 index 0000000..420fc24 --- /dev/null +++ b/templates/nvim/ftplugin/python.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 4 +vim.opt.softtabstop = 4 +vim.opt.shiftwidth = 4 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/scss.lua.j2 b/templates/nvim/ftplugin/scss.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/scss.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/sh.lua.j2 b/templates/nvim/ftplugin/sh.lua.j2 new file mode 100644 index 0000000..420fc24 --- /dev/null +++ b/templates/nvim/ftplugin/sh.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 4 +vim.opt.softtabstop = 4 +vim.opt.shiftwidth = 4 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/ftplugin/yaml.lua.j2 b/templates/nvim/ftplugin/yaml.lua.j2 new file mode 100644 index 0000000..058970f --- /dev/null +++ b/templates/nvim/ftplugin/yaml.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +vim.opt.tabstop = 2 +vim.opt.softtabstop = 2 +vim.opt.shiftwidth = 2 +vim.opt.expandtab = true +vim.opt.autoindent = true diff --git a/templates/nvim/init.lua.j2 b/templates/nvim/init.lua.j2 new file mode 100644 index 0000000..a18b81c --- /dev/null +++ b/templates/nvim/init.lua.j2 @@ -0,0 +1,14 @@ +-- {{ ansible_managed }} + +require('options') +require('_filetype') +require('colorscheme') +require('lsp') +require('tree-sitter') +require('git-signs') +require('_telescope') +require('indent-blankline') +require('_nvim-tree') +require('lua-line') +require('_source-link') +require('diagnostic') diff --git a/templates/nvim/lua/colorscheme.lua.j2 b/templates/nvim/lua/colorscheme.lua.j2 new file mode 100644 index 0000000..9ae709f --- /dev/null +++ b/templates/nvim/lua/colorscheme.lua.j2 @@ -0,0 +1,100 @@ +-- {{ ansible_managed }} + +local background_callback = function() + if vim.o.background == 'dark' then + vim.cmd('colorscheme github_dark_dimmed') + else + vim.cmd('colorscheme github_light_tritanopia') + end + + -- force a full redraw: + vim.cmd('mode') +end + +-- set the colorscheme whenever the background setting changes +vim.api.nvim_create_autocmd( + { 'OptionSet' }, + { pattern = { 'background' }, callback = background_callback } +) + + +{% if ansible_facts['os_family'] == 'Debian' %} +background_callback() +{% endif %} + +{% if ansible_facts['os_family'] == 'Archlinux' %} +--[[ +Use `busctl --user tree` to show a tree of available services. +Use the `Introspect` option to inspect available options: + +dbus-send \ +--session \ +--print-reply \ +--reply-timeout=2000 \ +--type=method_call \ +--dest=org.freedesktop.portal.Desktop \ +/org/freedesktop/portal/desktop \ +org.freedesktop.DBus.Introspectable.Introspect + +--]] +local oneshot = { + 'dbus-send', + '--session', + '--print-reply', + '--reply-timeout=2000', + '--type=method_call', + '--dest=org.freedesktop.portal.Desktop', + '/org/freedesktop/portal/desktop', + 'org.freedesktop.portal.Settings.ReadOne', + 'string:org.freedesktop.appearance', + 'string:color-scheme' +} + +local set_background = vim.schedule_wrap( + function(object) + local default_background = 'light' + + if object.code ~= 0 then + print(string.format('An error occured: \n %s', object.stderr)) + vim.api.nvim_command(string.format('set background=%s', default_background)) + end + + local colorscheme_output = tonumber(string.match(object.stdout, 'uint32 (%d)')) + + if colorscheme_output == 1 then + vim.api.nvim_command('set background=dark') + elseif colorscheme_output == 2 then + vim.api.nvim_command('set background=light') + end + end +) + +vim.schedule( + function() vim.system(oneshot, { text = true }, set_background) end +) + +-- Note that the last argument is a match rule, +-- see https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules. +local monitor_command = { + 'dbus-monitor', + '--session', + 'path=/org/freedesktop/portal/desktop,' .. + 'interface=org.freedesktop.portal.Settings,' .. + 'member=SettingChanged,' .. + 'arg0=org.freedesktop.appearance,'.. + 'arg1=color-scheme' +} + +local detect_scheme_change = function(channel_id, data, name) + local line = table.concat(data) + local match_output = tonumber(string.match(line, "uint32 (%d)")) + + if match_output == 1 then + vim.api.nvim_command('set background=dark') + elseif match_output == 2 then + vim.api.nvim_command('set background=light') + end +end + +vim.fn.jobstart(monitor_command, { on_stdout = detect_scheme_change } ) +{% endif %} diff --git a/templates/nvim/lua/diagnostic.lua.j2 b/templates/nvim/lua/diagnostic.lua.j2 new file mode 100644 index 0000000..97baa9e --- /dev/null +++ b/templates/nvim/lua/diagnostic.lua.j2 @@ -0,0 +1,11 @@ +-- {{ ansible_managed }} + +vim.diagnostic.config { + float = { + suffix = function(diagnostic) + return (' %s | [%s]'):format(diagnostic.code, diagnostic.source) + end + }, + + virtual_text = { current_line = true } +} diff --git a/templates/nvim/lua/filetype.lua.j2 b/templates/nvim/lua/filetype.lua.j2 new file mode 100644 index 0000000..2066b7c --- /dev/null +++ b/templates/nvim/lua/filetype.lua.j2 @@ -0,0 +1,42 @@ +local ansible_keywords = { + 'hosts', + 'tasks', + 'vars', + 'vars_files', + 'vars_prompt', + 'handlers', + 'roles', + 'import_tasks', + 'import_playbook', + 'import_role', +} + +vim.filetype.add { + pattern = { + ['playbook*.y(a?)ml'] = 'yaml.ansible', + ['site*.y(a?)ml'] = 'yaml.ansible', + ['inventory*.y(a?)ml'] = 'yaml.ansible', + ['task*.y(a?)ml'] = 'yaml.ansible', + ['requirement*.y(a?)ml'] = 'yaml.ansible', + + + ['.*/tasks/.*.y(a?)ml'] = 'yaml.ansible', + ['.*/vars/.*.y(a?)ml'] = 'yaml.ansible', + ['.*/host_vars/.*.y(a?)ml'] = 'yaml.ansible', + ['.*/group_vars/.*.y(a?)ml'] = 'yaml.ansible', + ['.*/playbooks/.*.y(a?)ml'] = 'yaml.ansible', + + ['*.ansible.y(a?)ml'] = 'yaml.ansible', + + ['.*.y(a?)ml'] = { + function(path, bufnr) + local content = vim.api.nvim_buf_get_lines(bufnr, 0, 1, false)[1] or '' + + for _, keyword in pairs(ansible_keywords) do + local pattern = string.format('^- %s:', keyword) + if content:match(pattern) then return 'yaml.ansible' end + end + end, + }, + }, +} diff --git a/templates/nvim/lua/git-signs.lua.j2 b/templates/nvim/lua/git-signs.lua.j2 new file mode 100644 index 0000000..1925d1c --- /dev/null +++ b/templates/nvim/lua/git-signs.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +local gitsigns = require('gitsigns'); + +gitsigns.setup({ + numhl = true; +}) diff --git a/templates/nvim/lua/indent-blankline.lua.j2 b/templates/nvim/lua/indent-blankline.lua.j2 new file mode 100644 index 0000000..458b6a9 --- /dev/null +++ b/templates/nvim/lua/indent-blankline.lua.j2 @@ -0,0 +1,10 @@ +-- {{ ansible_managed }} + +local indent_blankline = require("ibl"); + +indent_blankline.setup { + scope = { + show_start = false, + show_end = false, + } +} diff --git a/templates/nvim/lua/lsp.lua.j2 b/templates/nvim/lua/lsp.lua.j2 new file mode 100644 index 0000000..1da3fdc --- /dev/null +++ b/templates/nvim/lua/lsp.lua.j2 @@ -0,0 +1,198 @@ +-- {{ ansible_managed }} + +--use an on_attach function to only map the following keys +--after the language server attaches to the current buffer +local on_attach = function(client, bufnr) + local opts = { buffer = bufnr, noremap = true, silent = true } + + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) + vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, opts) + vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, opts) + vim.keymap.set('n', 'la', vim.lsp.buf.code_action, opts) + + vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, opts) + vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, opts) + vim.keymap.set('n', 'wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, opts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, opts) + + vim.keymap.set('n', 'e', vim.diagnostic.open_float, opts) + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) + vim.keymap.set('n', 'q', vim.diagnostic.setloclist, opts) +end + +--enable some language servers with the additional completion capabilities +--offered by nvim-cmp +local auto_setup_servers = { + {% for item in language_servers %} + {% if item.auto_setup and not loop.last %} + '{{ item.server_name }}', + {% elif item.auto_setup %} + '{{ item.server_name }}' + {% endif %} + {% endfor %} +} + +--add additional capabilities supported by nvim-cmp +local capabilities = vim.lsp.protocol.make_client_capabilities() +capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities) + +for _, lsp in ipairs(auto_setup_servers) do + vim.lsp.config[lsp] = { + on_attach = on_attach, + capabilities = capabilities, + } +end + +local util = require('lspconfig/util') + +{% if ansible_facts.os_family == 'Archlinux' %} +local python_root_dir = function(fname) + return util.root_pattern('.git', 'setup.cfg', 'requirements')(fname) or + util.path.dirname(fname) +end + +vim.lsp.config['ruff'] = { + on_attach = on_attach, + capabilities = capabilities, + root_dir = python_root_dir +} + + +vim.lsp.config['pyright'] = { + settings = { + pyright = { + -- Using Ruff's import organizer + disableOrganizeImports = true, + }, + } +} + +local snippet_capabilities = vim.deepcopy(capabilities); +snippet_capabilities.textDocument.completion.completionItem.snippetSupport = true + +vim.lsp.config['html'] = { + on_attach = on_attach, + capabilities = snippet_capabilities, + filetypes = { 'html', 'htmldjango' }, + settings = { + html = { + format = { + templating = true + } + } + } +} + +vim.lsp.config['cssls'] = { + on_attach = on_attach, + capabilities = snippet_capabilities, +} + +vim.lsp.config['jsonls'] = { + on_attach = on_attach, + capabilities = snippet_capabilities, +} + +vim.lsp.config['lua_ls'] = { + on_attach = on_attach, + capabilities = snippet_capabilities, + settings = { + Lua = { + diagnostics = { + globals = { 'vim' } + } + } + } +} + +{% endif %} +vim.lsp.config['yamlls'] = { + on_attach = on_attach, + capabilities = capabilities, + filetypes = { 'yaml', 'yaml.ansible', 'yaml.docker-compose', 'yaml.gitlab' } +} + +local servers = { + {% for item in language_servers %} + {% if not loop.last %} + '{{ item.server_name }}', + {% else %} + '{{ item.server_name }}' + {% endif %} + {% endfor %} +} + +vim.lsp.enable { unpack(servers) } + +local cmp = require('cmp') +local luasnip = require('luasnip') + +cmp.setup { + sources = { + { name = 'nvim_lsp', }, + { name = 'buffer' }, + { name = 'path' }, + { name = 'nvim_lua' }, + { + name = 'omni', + option = { + disable_omnifuncs = { 'v:lua.vim.lsp.omnifunc' } + } + }, + { name = 'luasnip', }, -- TODO: add snippets + }, + + formatting = { + format = function(entry, vim_item) + if entry.source.name == 'nvim_lsp' then + vim_item.menu = string.format('[%s]', entry.source.source.client.name) + else + vim_item.menu = string.format('[%s]', entry.source.name) + end + + return vim_item + end, + }, + + mapping = cmp.mapping.preset.insert({ + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.close(), + [''] = cmp.mapping.confirm { + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }, + [''] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_next_item() + elseif luasnip.expand_or_jumpable() then + luasnip.expand_or_jump() + else + fallback() + end + end, { 'i', 's' }), + ['S-'] = cmp.mapping(function(fallback) + if cmp.visible() then + cmp.select_prev_item() + elseif luasnip.jumpable(-1) then + luasnip.jump(-1) + else + fallback() + end + end, { 'i', 's' }), + }), + + snippet = { + expand = function(args) + luasnip.lsp_expand(args.body) + end, + }, +} diff --git a/templates/nvim/lua/lua-line.lua.j2 b/templates/nvim/lua/lua-line.lua.j2 new file mode 100644 index 0000000..e271750 --- /dev/null +++ b/templates/nvim/lua/lua-line.lua.j2 @@ -0,0 +1,50 @@ +-- {{ ansible_managed }} + +local lualine = require('lualine'); + +local function active_lsps() + local buffer = vim.api.nvim_get_current_buf() + local attached_clients = vim.lsp.get_clients({ bufnr = buffer }) + + if #attached_clients == 0 then return 'LSP: 0' end + + local preview_client = attached_clients[1] + + return ('LSP: %s (%d)'):format(preview_client.name, #attached_clients) +end + +local function diff_source() + local gitsigns = vim.b.gitsigns_status_dict + if gitsigns then + return { + added = gitsigns.added, + modified = gitsigns.changed, + removed = gitsigns.removed + } + end +end + +lualine.setup { + sections = { + lualine_a = {'mode'}, + lualine_b = { + {'b:gitsigns_head', icon = ''}, + {'diff', source = diff_source}, + 'diagnostics', + active_lsps + }, + lualine_c = { + { + 'filename', + path = 1, + } + }, + lualine_x = { + 'encoding', + 'fileformat', + 'filetype' + }, + lualine_y = {'progress'}, + lualine_z = {'location'} + }, +} diff --git a/templates/nvim/lua/nvim-tree.lua.j2 b/templates/nvim/lua/nvim-tree.lua.j2 new file mode 100644 index 0000000..6715d70 --- /dev/null +++ b/templates/nvim/lua/nvim-tree.lua.j2 @@ -0,0 +1,39 @@ +-- {{ ansible_managed }} + +local nvim_tree = require('nvim-tree'); +local nvim_tree_icons = require('nvim-web-devicons'); +local api = require('nvim-tree.api') + +local function toggle_tree() + api.tree.toggle({ find_file = true, update_root = true, focus = true }) +end + +vim.keymap.set('n', '', toggle_tree, { noremap = true, silent = true }) + +local function my_on_attach(bufnr) + local function opts(desc) + return { desc = 'nvim-tree: ' .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true } + end + + vim.keymap.set('n', '', api.tree.change_root_to_node, opts('CD')) + vim.keymap.set('n', '', api.tree.toggle_hidden_filter, opts('Toggle filter: Dotfiles')) + vim.keymap.set('n', '', api.node.open.edit, opts('Open')) + vim.keymap.set('n', 'E', api.tree.expand_all, opts('Expand All')) + vim.keymap.set('n', 'F', api.live_filter.clear, opts('Live filter: Clear')) + vim.keymap.set('n', 'f', api.live_filter.start, opts('Live filter: Start')) + vim.keymap.set('n', 'g?', api.tree.toggle_help, opts('Help')) + vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle filter: Git Ignore')) + vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle bookmark')) + vim.keymap.set('n', 'q', api.tree.close, opts('Close')) + vim.keymap.set('n', 'R', api.tree.reload, opts('Refresh')) + vim.keymap.set('n', 'S', api.tree.search_node, opts('Search')) + vim.keymap.set('n', 'a', api.fs.create, opts('Create a file')) + vim.keymap.set("n", "r", api.fs.rename, opts("Rename")) + vim.keymap.set('n', 'd', api.fs.remove, opts('Delete a file')) +end + +nvim_tree.setup { + on_attach = my_on_attach, +} + +nvim_tree_icons.setup(); diff --git a/templates/nvim/lua/options.lua.j2 b/templates/nvim/lua/options.lua.j2 new file mode 100644 index 0000000..fe35a80 --- /dev/null +++ b/templates/nvim/lua/options.lua.j2 @@ -0,0 +1,66 @@ +-- {{ ansible_managed }} + +-- fix different locale settings when ssh'ing +vim.o.encoding = 'utf-8' + +vim.o.syntax = 'on' + +-- display all matching files when we tab complete +vim.o.wildmenu = true + +-- Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable +-- delays and poor user experience. +vim.o.updatetime = 300 + +vim.o.splitright = true +vim.o.splitbelow = true + +-- switch buffers without writing to file +vim.o.hidden = true + +-- folding +vim.o.foldmethod = 'expr' +vim.o.foldlevel = 99 +vim.o.foldexpr = 'v:lua.vim.treesitter.foldexpr()' + +-- don't open folds when jumping over one with (, {, [[ or [{ +vim.opt.foldopen = vim.opt.foldopen - { 'block' } + +-- search down into subfolders +-- provides tab-completion for all file-related tasks +vim.opt.path = vim.opt.path + { '**' } + +-- line numbers +vim.o.number = true + +-- higlhight search +vim.o.hls = true + +-- search as characters are entered +vim.o.incsearch = true + +-- line for linewrapping +vim.o.colorcolumn = '80' + +-- wrap text instead of being on one line +vim.o.lbr = true + +-- default Colors for CursorLine +vim.o.cursorline = true + +-- theme related +vim.o.termguicolors = true + +-- use a dedicated file explorer +vim.g.loaded_netrw = 1 +vim.g.loaded_netrwPlugin = 1 + +-- load project specific configuration files +vim.o.exrc = true +vim.o.secure = true + +-- disable mouse options +vim.opt.mouse = '' + +-- python interpreter +vim.g.python3_host_prog = '/usr/bin/python3' diff --git a/templates/nvim/lua/source-link.lua.j2 b/templates/nvim/lua/source-link.lua.j2 new file mode 100644 index 0000000..8b7df92 --- /dev/null +++ b/templates/nvim/lua/source-link.lua.j2 @@ -0,0 +1,7 @@ +-- {{ ansible_managed }} + +local source_link = require('source-link') + +source_link.setup() + +vim.keymap.set('n', '', ':SourceOpen', { noremap = true, silent = true }) diff --git a/templates/nvim/lua/telescope.lua.j2 b/templates/nvim/lua/telescope.lua.j2 new file mode 100644 index 0000000..4de57a6 --- /dev/null +++ b/templates/nvim/lua/telescope.lua.j2 @@ -0,0 +1,37 @@ +-- {{ ansible_managed }} + +local telescope = require('telescope') +local builtin = require('telescope.builtin') + +local opts = { noremap = true, silent = true } + +local find_files_unignored = function() + builtin.find_files { hidden = true, no_ignore = true } +end + +local live_grep_unignored = function() + builtin.live_grep { additional_args = { '--unrestricted', '--unrestricted' } } +end + +vim.keymap.set('n', 'ff', builtin.find_files, opts) +vim.keymap.set('n', 'fF', find_files_unignored, opts) +vim.keymap.set('n', 'fg', builtin.live_grep, opts) +vim.keymap.set('n', 'fG', live_grep_unignored, opts) +vim.keymap.set('n', 'fb', builtin.current_buffer_fuzzy_find, opts) +vim.keymap.set('n', 'fB', builtin.buffers, opts) +vim.keymap.set('n', 'fh', builtin.help_tags, opts) +vim.keymap.set('n', 'fj', builtin.jumplist, opts) +vim.keymap.set('n', 'fl', builtin.loclist, opts) +vim.keymap.set('n', 'fq', builtin.quickfix, opts) +vim.keymap.set('n', 'fm', builtin.marks, opts) +vim.keymap.set('n', 'ft', builtin.treesitter, opts) + +telescope.setup({ + defaults = { + layout_strategy = 'vertical', + layout_config = { + prompt_position = 'bottom', + vertical = { width = 0.8, height = 0.9 } + }, + }, +}) diff --git a/templates/nvim/lua/tree-sitter.lua.j2 b/templates/nvim/lua/tree-sitter.lua.j2 new file mode 100644 index 0000000..d1730ad --- /dev/null +++ b/templates/nvim/lua/tree-sitter.lua.j2 @@ -0,0 +1,26 @@ +-- {{ ansible_managed }} + +-- Tree sitter language parsers are installed automatically (through `auto_install`). +-- To update installed parsers use `:TSUpdate {language}`. +-- See https://github.com/nvim-treesitter/nvim-treesitter for more info. +local tree_sitter_config = require('nvim-treesitter.configs') + +tree_sitter_config.setup { + ensure_installed = { + 'lua', 'yaml', 'bash', 'python', 'javascript', 'typescript', 'css', 'scss', + 'html', 'htmldjango', 'sql', 'json', 'dockerfile', 'markdown', 'rst', 'tmux', + 'xml', 'toml', 'editorconfig', 'diff', 'gitcommit', 'git_config', 'gitignore', + 'gitattributes', 'make', 'nginx', 'vim', 'vimdoc', 'passwd', 'regex' + }, + auto_install = true, + highlight = { + enable = true, + additional_vim_regex_highlighting = false, + }, + indent = { + enable = true, + }, + incremental_selection = { + enable = true, + }, +} diff --git a/templates/tmux-toggle.j2 b/templates/tmux-toggle.j2 new file mode 100644 index 0000000..3a2bda6 --- /dev/null +++ b/templates/tmux-toggle.j2 @@ -0,0 +1,19 @@ +#!/usr/bin/env sh +# +# {{ ansible_managed }} +# +# Toggle the current window (all panes) between light and dark themes. + +set -e + +current_window_style=$(tmux show -Av window-style) + +case $current_window_style in + 'fg=#000000,bg=#eff0f1') + tmux source-file ~/.config/tmux/dark.conf + ;; + *) + # Change back to the default window style. + tmux source-file ~/.config/tmux/light.conf + ;; +esac